Skip to content

Commit 9651232

Browse files
Williangalvanipatrickelectric
authored andcommitted
core: ArdupilotManager: try detecting boards up to 5 times
1 parent cb18b8f commit 9651232

File tree

3 files changed

+31
-19
lines changed

3 files changed

+31
-19
lines changed

core/services/ardupilot_manager/ArduPilotManager.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -394,15 +394,15 @@ async def start_mavlink_manager(self, device: Endpoint) -> None:
394394
await self.mavlink_manager.start(device)
395395

396396
@staticmethod
397-
def available_boards(include_bootloaders: bool = False) -> List[FlightController]:
398-
all_boards = BoardDetector.detect(True)
397+
async def available_boards(include_bootloaders: bool = False) -> List[FlightController]:
398+
all_boards = await BoardDetector.detect(True)
399399
if include_bootloaders:
400400
return all_boards
401401
return [board for board in all_boards if FlightControllerFlags.is_bootloader not in board.flags]
402402

403403
async def change_board(self, board: FlightController) -> None:
404404
logger.info(f"Trying to run with '{board.name}'.")
405-
if board not in self.available_boards():
405+
if board not in await self.available_boards():
406406
raise ValueError(f"Cannot use '{board.name}'. Board not detected.")
407407
self.set_preferred_board(board)
408408
await self.kill_ardupilot()
@@ -513,7 +513,7 @@ async def kill_ardupilot(self) -> None:
513513
async def start_ardupilot(self) -> None:
514514
await self.setup()
515515
try:
516-
available_boards = self.available_boards()
516+
available_boards = await self.available_boards()
517517
if not available_boards:
518518
raise RuntimeError("No boards available.")
519519
if len(available_boards) > 1:

core/services/ardupilot_manager/flight_controller_detector/Detector.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import asyncio
12
from typing import List, Optional
23

34
from commonwealth.utils.general import is_running_as_root
@@ -10,8 +11,17 @@
1011

1112

1213
class Detector:
13-
@staticmethod
14-
def detect_linux_board() -> Optional[FlightController]:
14+
@classmethod
15+
async def detect_linux_board(cls) -> Optional[FlightController]:
16+
for _i in range(5):
17+
board = cls._detect_linux_board()
18+
if board:
19+
return board
20+
await asyncio.sleep(0.1)
21+
return None
22+
23+
@classmethod
24+
def _detect_linux_board(cls) -> Optional[FlightController]:
1525
"""Returns Linux board if connected.
1626
Check for connection using the sensors on the I²C and SPI buses.
1727
@@ -35,7 +45,8 @@ def is_navigator_r5_connected() -> bool:
3545
PCA9685_address = 0x40
3646
bus.read_byte_data(PCA9685_address, 0)
3747
return True
38-
except Exception:
48+
except Exception as error:
49+
logger.warning(f"Navigator not detected: {error}")
3950
return False
4051

4152
def is_argonot_r1_connected() -> bool:
@@ -44,7 +55,8 @@ def is_argonot_r1_connected() -> bool:
4455
swap_multiplexer_address = 0x77
4556
bus.read_byte_data(swap_multiplexer_address, 0)
4657
return True
47-
except Exception:
58+
except Exception as error:
59+
logger.warning(f"Argonot not detected: {error}")
4860
return False
4961

5062
logger.debug("Trying to detect Linux board.")
@@ -105,7 +117,7 @@ def detect_sitl() -> FlightController:
105117
return FlightController(name="SITL", manufacturer="ArduPilot Team", platform=Platform.SITL)
106118

107119
@classmethod
108-
def detect(cls, include_sitl: bool = True) -> List[FlightController]:
120+
async def detect(cls, include_sitl: bool = True) -> List[FlightController]:
109121
"""Return a list of available flight controllers
110122
111123
Arguments:
@@ -118,7 +130,7 @@ def detect(cls, include_sitl: bool = True) -> List[FlightController]:
118130
if not is_running_as_root():
119131
return available
120132

121-
linux_board = cls.detect_linux_board()
133+
linux_board = await cls.detect_linux_board()
122134
if linux_board:
123135
available.append(linux_board)
124136

core/services/ardupilot_manager/main.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
raise RuntimeError("ArduPilot manager needs to run with root privilege.")
5353

5454

55-
def target_board(board_name: Optional[str]) -> FlightController:
55+
async def target_board(board_name: Optional[str]) -> FlightController:
5656
"""Returns the board that should be used to perform operations on.
5757
5858
Most of the API routes that have operations related to board management will give the option to perform those
@@ -64,7 +64,7 @@ def target_board(board_name: Optional[str]) -> FlightController:
6464
"""
6565
if board_name is not None:
6666
try:
67-
return next(board for board in autopilot.available_boards(True) if board.name == board_name)
67+
return next(board for board in await autopilot.available_boards(True) if board.name == board_name)
6868
except StopIteration as error:
6969
raise ValueError("Chosen board not available.") from error
7070
if autopilot.current_board is None:
@@ -153,8 +153,8 @@ async def get_firmware_vehicle_type() -> Any:
153153
summary="Retrieve dictionary of available firmwares versions with their respective URL.",
154154
)
155155
@version(1, 0)
156-
def get_available_firmwares(vehicle: Vehicle, board_name: Optional[str] = None) -> Any:
157-
return autopilot.get_available_firmwares(vehicle, target_board(board_name).platform)
156+
async def get_available_firmwares(vehicle: Vehicle, board_name: Optional[str] = None) -> Any:
157+
return autopilot.get_available_firmwares(vehicle, (await target_board(board_name)).platform)
158158

159159

160160
@app.post("/install_firmware_from_url", summary="Install firmware for given URL.")
@@ -168,7 +168,7 @@ async def install_firmware_from_url(
168168
) -> Any:
169169
try:
170170
await autopilot.kill_ardupilot()
171-
autopilot.install_firmware_from_url(url, target_board(board_name), make_default, parameters)
171+
autopilot.install_firmware_from_url(url, await target_board(board_name), make_default, parameters)
172172
finally:
173173
await autopilot.start_ardupilot()
174174

@@ -188,7 +188,7 @@ async def install_firmware_from_file(
188188
logger.debug("Going to kill ardupilot")
189189
await autopilot.kill_ardupilot()
190190
logger.debug("Installing firmware from file")
191-
autopilot.install_firmware_from_file(custom_firmware, target_board(board_name), parameters)
191+
autopilot.install_firmware_from_file(custom_firmware, await target_board(board_name), parameters)
192192
os.remove(custom_firmware)
193193
except InvalidFirmwareFile as error:
194194
raise StackedHTTPException(status_code=status.HTTP_415_UNSUPPORTED_MEDIA_TYPE, error=error) from error
@@ -260,15 +260,15 @@ async def stop() -> Any:
260260
async def restore_default_firmware(board_name: Optional[str] = None) -> Any:
261261
try:
262262
await autopilot.kill_ardupilot()
263-
autopilot.restore_default_firmware(target_board(board_name))
263+
autopilot.restore_default_firmware(await target_board(board_name))
264264
finally:
265265
await autopilot.start_ardupilot()
266266

267267

268268
@app.get("/available_boards", response_model=List[FlightController], summary="Retrieve list of connected boards.")
269269
@version(1, 0)
270-
def available_boards() -> Any:
271-
return autopilot.available_boards(True)
270+
async def available_boards() -> Any:
271+
return await autopilot.available_boards(True)
272272

273273

274274
app = VersionedFastAPI(app, version="1.0.0", prefix_format="/v{major}.{minor}", enable_latest=True)

0 commit comments

Comments
 (0)