From 688d2e4d257f7cf29f4f1d8622a1b97fab2d1da4 Mon Sep 17 00:00:00 2001 From: Willian Galvani Date: Tue, 14 Jan 2025 23:39:43 -0300 Subject: [PATCH 1/3] autopilot manager: add Unmanaged board for ethernet connections --- .../api/v1/routers/endpoints.py | 10 +++++++ .../ardupilot_manager/autopilot_manager.py | 28 +++++++++++++++++++ .../flight_controller_detector/Detector.py | 5 +++- core/services/ardupilot_manager/typedefs.py | 3 ++ 4 files changed, 45 insertions(+), 1 deletion(-) diff --git a/core/services/ardupilot_manager/api/v1/routers/endpoints.py b/core/services/ardupilot_manager/api/v1/routers/endpoints.py index 7b5d6f6635..bb5503efa8 100644 --- a/core/services/ardupilot_manager/api/v1/routers/endpoints.py +++ b/core/services/ardupilot_manager/api/v1/routers/endpoints.py @@ -34,3 +34,13 @@ async def remove_endpoints(endpoints: Set[Endpoint] = Body(...)) -> Any: @endpoints_router_v1.put("/", status_code=status.HTTP_200_OK) async def update_endpoints(endpoints: Set[Endpoint] = Body(...)) -> Any: await autopilot.update_endpoints(endpoints) + + +@endpoints_router_v1.post("/unmanaged_board_master_endpoint", summary="Set the master endpoint for an unmanaged board.") +async def set_unmanaged_board_master_endpoint(endpoint: Endpoint) -> bool: + return autopilot.set_unmanaged_board_master_endpoint(endpoint) + + +@endpoints_router_v1.get("/unmanaged_board_master_endpoint", summary="Get the master endpoint for an unmanaged board.") +def get_unmanaged_board_master_endpoint() -> Any: + return autopilot.get_unmanaged_board_master_endpoint() diff --git a/core/services/ardupilot_manager/autopilot_manager.py b/core/services/ardupilot_manager/autopilot_manager.py index 7ce6e5b258..bc5665c79a 100644 --- a/core/services/ardupilot_manager/autopilot_manager.py +++ b/core/services/ardupilot_manager/autopilot_manager.py @@ -322,6 +322,12 @@ def load_preferred_router(self) -> Optional[str]: def get_available_routers(self) -> List[str]: return [router.name() for router in self.mavlink_manager.available_interfaces()] + async def start_unmanaged_board(self, board: FlightController) -> None: + self._current_board = board + self.master_endpoint = self.get_unmanaged_board_master_endpoint() + self.ardupilot_subprocess = None + await self.start_mavlink_manager(self.master_endpoint) + async def start_sitl(self) -> None: self._current_board = BoardDetector.detect_sitl() if not self.firmware_manager.is_firmware_installed(self._current_board): @@ -583,6 +589,8 @@ async def start_ardupilot(self) -> None: await self.start_serial(flight_controller) elif flight_controller.platform == Platform.SITL: await self.start_sitl() + elif flight_controller.platform == Platform.Unmanaged: + await self.start_unmanaged_board(flight_controller) else: raise RuntimeError(f"Invalid board type: {flight_controller}") finally: @@ -661,3 +669,23 @@ def install_firmware_from_url( def restore_default_firmware(self, board: FlightController) -> None: self.firmware_manager.restore_default_firmware(board) + + def set_unmanaged_board_master_endpoint(self, endpoint: Endpoint) -> bool: + self.configuration["unmanaged_board_master_endpoint"] = endpoint.as_dict() + self.settings.save(self.configuration) + return True + + def get_unmanaged_board_master_endpoint(self) -> Endpoint: + default_master_endpoint = Endpoint( + name="Unmanaged Board Master Endpoint", + owner=self.settings.app_name, + connection_type=EndpointType.UDPServer, + place="0.0.0.0", + argument=14550, + persistent=True, + enabled=True, + ) + endpoint = self.configuration.get("unmanaged_board_master_endpoint", None) + if endpoint is None: + return default_master_endpoint + return Endpoint(**endpoint) diff --git a/core/services/ardupilot_manager/flight_controller_detector/Detector.py b/core/services/ardupilot_manager/flight_controller_detector/Detector.py index a1753a14b8..b5367da545 100644 --- a/core/services/ardupilot_manager/flight_controller_detector/Detector.py +++ b/core/services/ardupilot_manager/flight_controller_detector/Detector.py @@ -77,7 +77,7 @@ def detect_sitl() -> FlightController: return FlightController(name="SITL", manufacturer="ArduPilot Team", platform=Platform.SITL) @classmethod - async def detect(cls, include_sitl: bool = True) -> List[FlightController]: + async def detect(cls, include_sitl: bool = True, include_unmanaged: bool = True) -> List[FlightController]: """Return a list of available flight controllers Arguments: @@ -99,4 +99,7 @@ async def detect(cls, include_sitl: bool = True) -> List[FlightController]: if include_sitl: available.append(Detector.detect_sitl()) + if include_unmanaged: + available.append(FlightController(name="Unmanaged", manufacturer="Unmanaged", platform=Platform.Unmanaged)) + return available diff --git a/core/services/ardupilot_manager/typedefs.py b/core/services/ardupilot_manager/typedefs.py index 94bcf03348..dbbe4f88bb 100644 --- a/core/services/ardupilot_manager/typedefs.py +++ b/core/services/ardupilot_manager/typedefs.py @@ -97,6 +97,7 @@ class PlatformType(LowerStringEnum): Linux = auto() SITL = auto() Unknown = auto() + Unmanaged = auto() class Platform(str, Enum): @@ -113,6 +114,7 @@ class Platform(str, Enum): Navigator64 = "navigator64" Argonot = "argonot" SITL = get_sitl_platform_name(machine()) + Unmanaged = "Unmanaged" @property def type(self) -> PlatformType: @@ -127,6 +129,7 @@ def type(self) -> PlatformType: Platform.Navigator64: PlatformType.Linux, Platform.Argonot: PlatformType.Linux, Platform.SITL: PlatformType.SITL, + Platform.Unmanaged: PlatformType.Unmanaged, } return platform_types.get(self, PlatformType.Unknown) From b40382ddee1c2dc464af3b0185dc0f6d40bfffbc Mon Sep 17 00:00:00 2001 From: Willian Galvani Date: Wed, 15 Jan 2025 12:08:17 -0300 Subject: [PATCH 2/3] frontend: add master endpoint management interface --- .../autopilot/MasterEndpointManager.vue | 217 ++++++++++++++++++ core/frontend/src/views/Autopilot.vue | 17 +- 2 files changed, 233 insertions(+), 1 deletion(-) create mode 100644 core/frontend/src/components/autopilot/MasterEndpointManager.vue diff --git a/core/frontend/src/components/autopilot/MasterEndpointManager.vue b/core/frontend/src/components/autopilot/MasterEndpointManager.vue new file mode 100644 index 0000000000..9d7d42c01c --- /dev/null +++ b/core/frontend/src/components/autopilot/MasterEndpointManager.vue @@ -0,0 +1,217 @@ + + + + + diff --git a/core/frontend/src/views/Autopilot.vue b/core/frontend/src/views/Autopilot.vue index d739676c72..9fe49ae440 100644 --- a/core/frontend/src/views/Autopilot.vue +++ b/core/frontend/src/views/Autopilot.vue @@ -29,7 +29,17 @@
- + + + + Master endpoint + + + + + + + Firmware update @@ -112,6 +122,7 @@ import { import AutopilotSerialConfiguration from '@/components/autopilot/AutopilotSerialConfiguration.vue' import BoardChangeDialog from '@/components/autopilot/BoardChangeDialog.vue' import FirmwareManager from '@/components/autopilot/FirmwareManager.vue' +import MasterEndpointManager from '@/components/autopilot/MasterEndpointManager.vue' import NotSafeOverlay from '@/components/common/NotSafeOverlay.vue' import { MavAutopilot } from '@/libs/MAVLink2Rest/mavlink2rest-ts/messages/mavlink2rest-enum' import Notifier from '@/libs/notifier' @@ -132,6 +143,7 @@ export default Vue.extend({ FirmwareManager, AutopilotSerialConfiguration, NotSafeOverlay, + MasterEndpointManager, }, data() { return { @@ -184,6 +196,9 @@ export default Vue.extend({ } return ['Navigator', 'Navigator64', 'SITL'].includes(boardname) }, + is_external_board(): boolean { + return autopilot.current_board?.name === 'Unmanaged' + }, current_board(): FlightController | null { return autopilot.current_board }, From 8e3eb60374acb5f71d6eea7eeccc42def9e4bee5 Mon Sep 17 00:00:00 2001 From: Willian Galvani Date: Wed, 15 Jan 2025 21:47:27 -0300 Subject: [PATCH 3/3] frontend: autopilot manager: only show buttons when it makes sense to do so --- core/frontend/src/views/Autopilot.vue | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/core/frontend/src/views/Autopilot.vue b/core/frontend/src/views/Autopilot.vue index 9fe49ae440..cb39796f42 100644 --- a/core/frontend/src/views/Autopilot.vue +++ b/core/frontend/src/views/Autopilot.vue @@ -73,7 +73,7 @@ Change board { let version = 'Unknown' if (this.firmware_info) {