Skip to content

Commit 62588e1

Browse files
committed
FEATURE: Use and present board/firmware type information
1 parent 11046ab commit 62588e1

5 files changed

+63
-84
lines changed

MethodicConfigurator/ardupilot_methodic_configurator.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,19 @@ def component_editor(
104104
component_editor_window.populate_frames()
105105
component_editor_window.set_vehicle_type_and_version(vehicle_type, flight_controller.info.flight_sw_version_and_type)
106106
component_editor_window.set_fc_manufacturer(flight_controller.info.vendor)
107-
component_editor_window.set_fc_model(flight_controller.info.product)
107+
component_editor_window.set_fc_model(flight_controller.info.firmware_type)
108108
if vehicle_dir_window and vehicle_dir_window.configuration_template:
109109
component_editor_window.set_vehicle_configuration_template(vehicle_dir_window.configuration_template)
110110
if args.skip_component_editor:
111111
component_editor_window.root.after(10, component_editor_window.root.destroy)
112+
elif bool(ProgramSettings.get_setting("auto_open_doc_in_browser")) and flight_controller.info.firmware_type != _(
113+
"Unknown"
114+
):
115+
url = (
116+
"https://github.com/ArduPilot/ardupilot/blob/master/libraries/AP_HAL_ChibiOS/hwdef/"
117+
f"{flight_controller.info.firmware_type}/README.md"
118+
)
119+
webbrowser_open(url=url, new=0, autoraise=True)
112120
component_editor_window.root.mainloop()
113121

114122
if vehicle_dir_window and vehicle_dir_window.configuration_template and vehicle_dir_window.use_fc_params.get():

MethodicConfigurator/backend_flightcontroller.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -299,10 +299,10 @@ def __process_autopilot_version(self, m: MAVLink_autopilot_version_message, bann
299299
)
300300
self.info.set_capabilities(m.capabilities)
301301
self.info.set_flight_sw_version(m.flight_sw_version)
302+
self.info.set_usb_vendor_and_product_ids(m.vendor_id, m.product_id) # must be done before set_board_version()
302303
self.info.set_board_version(m.board_version)
303304
self.info.set_flight_custom_version(m.flight_custom_version)
304305
self.info.set_os_custom_version(m.os_custom_version)
305-
self.info.set_vendor_id_and_product_id(m.vendor_id, m.product_id)
306306

307307
os_custom_version = ""
308308
os_custom_version_index = None
@@ -320,14 +320,16 @@ def __process_autopilot_version(self, m: MAVLink_autopilot_version_message, bann
320320
logging_info("FC banner %s", msg)
321321

322322
# the banner message after the ChibiOS one contains the FC type
323-
fc_product = ""
323+
firmware_type = ""
324324
if os_custom_version_index is not None and os_custom_version_index + 1 < len(banner_msgs):
325-
fc_product_banner_substrings = banner_msgs[os_custom_version_index + 1].split(" ")
326-
if len(fc_product_banner_substrings) >= 3:
327-
fc_product = fc_product_banner_substrings[0]
328-
if fc_product != self.info.product:
329-
logging_warning(_("FC product mismatch: %s (BANNER) != %s (AUTOPILOT_VERSION)"), fc_product, self.info.product)
330-
self.info.product = fc_product # force the one from the banner because it is more reliable
325+
firmware_type_banner_substrings = banner_msgs[os_custom_version_index + 1].split(" ")
326+
if len(firmware_type_banner_substrings) >= 3:
327+
firmware_type = firmware_type_banner_substrings[0]
328+
if firmware_type and firmware_type != self.info.firmware_type:
329+
logging_warning(
330+
_("FC firmware type mismatch: %s (BANNER) != %s (AUTOPILOT_VERSION)"), firmware_type, self.info.firmware_type
331+
)
332+
self.info.firmware_type = firmware_type # force the one from the banner because it is more reliable
331333
return ""
332334

333335
def download_params(

MethodicConfigurator/backend_flightcontroller_info.py

Lines changed: 36 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@
1414
from pymavlink import mavutil
1515

1616
# import pymavlink.dialects.v20.ardupilotmega
17+
from MethodicConfigurator import _
18+
from MethodicConfigurator.middleware_fc_ids import (
19+
APJ_BOARD_ID_NAME_DICT,
20+
APJ_BOARD_ID_VENDOR_DICT,
21+
VID_PID_PRODUCT_DICT,
22+
VID_VENDOR_DICT,
23+
)
1724

1825

1926
class BackendFlightcontrollerInfo: # pylint: disable=too-many-instance-attributes
@@ -29,10 +36,12 @@ def __init__(self) -> None:
2936
self.component_id: str = ""
3037
self.autopilot: str = ""
3138
self.vehicle_type: str = ""
39+
self.firmware_type: str = ""
3240
self.mav_type: str = ""
3341
self.flight_sw_version: str = ""
3442
self.flight_sw_version_and_type: str = ""
3543
self.board_version: str = ""
44+
self.apj_board_id: str = ""
3645
self.flight_custom_version: str = ""
3746
self.os_custom_version: str = ""
3847
self.vendor: str = ""
@@ -48,18 +57,20 @@ def __init__(self) -> None:
4857

4958
def get_info(self) -> dict[str, Union[str, dict[str, str]]]:
5059
return {
51-
"Vendor": self.vendor_and_vendor_id,
52-
"Product": self.product_and_product_id,
53-
"Hardware Version": self.board_version,
54-
"Autopilot Type": self.autopilot,
55-
"ArduPilot FW Type": self.vehicle_type,
56-
"MAV Type": self.mav_type,
57-
"Firmware Version": self.flight_sw_version_and_type,
58-
"Git Hash": self.flight_custom_version,
59-
"OS Git Hash": self.os_custom_version,
60-
"Capabilities": self.capabilities,
61-
"System ID": self.system_id,
62-
"Component ID": self.component_id,
60+
_("USB Vendor"): self.vendor_and_vendor_id,
61+
_("USB Product"): self.product_and_product_id,
62+
_("Board Type"): self.apj_board_id,
63+
_("Hardware Version"): self.board_version,
64+
_("Autopilot Type"): self.autopilot,
65+
_("ArduPilot Vehicle Type"): self.vehicle_type,
66+
_("ArduPilot FW Type"): self.firmware_type,
67+
_("MAV Type"): self.mav_type,
68+
_("Firmware Version"): self.flight_sw_version_and_type,
69+
_("Git Hash"): self.flight_custom_version,
70+
_("OS Git Hash"): self.os_custom_version,
71+
_("Capabilities"): self.capabilities,
72+
_("System ID"): self.system_id,
73+
_("Component ID"): self.component_id,
6374
}
6475

6576
def set_system_id_and_component_id(self, system_id: str, component_id: str) -> None:
@@ -80,29 +91,28 @@ def set_flight_sw_version(self, version: int) -> None:
8091
self.flight_sw_version_and_type = self.flight_sw_version + " " + v_fw_type
8192

8293
def set_board_version(self, board_version: int) -> None:
83-
self.board_version = str(board_version)
94+
self.board_version = str(board_version & 0x0FFFF)
95+
apj_board_id = board_version >> 16
96+
self.apj_board_id = str(apj_board_id)
97+
self.firmware_type = str(APJ_BOARD_ID_NAME_DICT.get(apj_board_id, _("Unknown")))
98+
99+
vendor_derived_from_apj_board_id = str(APJ_BOARD_ID_VENDOR_DICT.get(apj_board_id, "ArduPilot"))
100+
if vendor_derived_from_apj_board_id != "ArduPilot" and self.vendor in ["ArduPilot", _("Unknown")]:
101+
self.vendor = vendor_derived_from_apj_board_id
84102

85103
def set_flight_custom_version(self, flight_custom_version: Sequence[int]) -> None:
86104
self.flight_custom_version = "".join(chr(c) for c in flight_custom_version)
87105

88106
def set_os_custom_version(self, os_custom_version: Sequence[int]) -> None:
89107
self.os_custom_version = "".join(chr(c) for c in os_custom_version)
90108

91-
def set_vendor_id_and_product_id(self, vendor_id: int, product_id: int) -> None:
92-
pid_vid_dict = self.__list_ardupilot_supported_usb_pid_vid()
93-
94-
self.vendor_id = f"0x{vendor_id:04X}" if vendor_id else "Unknown"
95-
if vendor_id and vendor_id in pid_vid_dict:
96-
self.vendor = f"{pid_vid_dict[vendor_id]['vendor']}"
97-
elif vendor_id:
98-
self.vendor = "Unknown"
109+
def set_usb_vendor_and_product_ids(self, vendor_id: int, product_id: int) -> None:
110+
self.vendor_id = f"0x{vendor_id:04X}" if vendor_id else _("Unknown")
111+
self.vendor = str(VID_VENDOR_DICT.get(vendor_id, _("Unknown")))
99112
self.vendor_and_vendor_id = f"{self.vendor} ({self.vendor_id})"
100113

101-
self.product_id = f"0x{product_id:04X}" if product_id else "Unknown"
102-
if vendor_id and product_id and product_id in pid_vid_dict[vendor_id]["PID"]:
103-
self.product = f"{pid_vid_dict[vendor_id]['PID'][product_id]}"
104-
elif product_id:
105-
self.product = "Unknown"
114+
self.product_id = f"0x{product_id:04X}" if product_id else _("Unknown")
115+
self.product = str(VID_PID_PRODUCT_DICT.get((vendor_id, product_id), _("Unknown")))
106116
self.product_and_product_id = f"{self.product} ({self.product_id})"
107117

108118
def set_capabilities(self, capabilities: int) -> None:
@@ -234,49 +244,3 @@ def __classify_vehicle_type(mav_type_int: int) -> str:
234244

235245
# Return the classified vehicle type based on the MAV_TYPE enum
236246
return mav_type_to_vehicle_type.get(mav_type_int, "")
237-
238-
@staticmethod
239-
def __list_ardupilot_supported_usb_pid_vid() -> dict[int, dict[str, Union[str, dict[int, str]]]]:
240-
"""
241-
List all ArduPilot supported USB vendor ID (VID) and product ID (PID).
242-
243-
source: https://ardupilot.org/dev/docs/USB-IDs.html
244-
"""
245-
return {
246-
0x0483: {"vendor": "ST Microelectronics", "PID": {0x5740: "ChibiOS"}},
247-
0x1209: {
248-
"vendor": "ArduPilot",
249-
"PID": {
250-
0x5740: "MAVLink",
251-
0x5741: "Bootloader",
252-
},
253-
},
254-
0x16D0: {"vendor": "ArduPilot", "PID": {0x0E65: "MAVLink"}},
255-
0x26AC: {"vendor": "3D Robotics", "PID": {}},
256-
0x2DAE: {
257-
"vendor": "CubePilot",
258-
"PID": {
259-
0x1001: "CubeBlack bootloader",
260-
0x1011: "CubeBlack",
261-
0x1101: "CubeBlack+",
262-
0x1002: "CubeYellow bootloader",
263-
0x1012: "CubeYellow",
264-
0x1005: "CubePurple bootloader",
265-
0x1015: "CubePurple",
266-
0x1016: "CubeOrange",
267-
0x1058: "CubeOrange+",
268-
0x1059: "CubeRed",
269-
},
270-
},
271-
0x3162: {"vendor": "Holybro", "PID": {0x004B: "Durandal"}},
272-
0x27AC: {
273-
"vendor": "Laser Navigation",
274-
"PID": {
275-
0x1151: "VRBrain-v51",
276-
0x1152: "VRBrain-v52",
277-
0x1154: "VRBrain-v54",
278-
0x1910: "VRCore-v10",
279-
0x1351: "VRUBrain-v51",
280-
},
281-
},
282-
}

MethodicConfigurator/frontend_tkinter_component_editor.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,11 +292,11 @@ def set_vehicle_type_and_version(self, vehicle_type: str, version: str) -> None:
292292
self._set_component_value_and_update_ui(("Flight Controller", "Firmware", "Version"), version)
293293

294294
def set_fc_manufacturer(self, manufacturer: str) -> None:
295-
if manufacturer and manufacturer not in ("Unknown", "ArduPilot"):
295+
if manufacturer and manufacturer not in (_("Unknown"), "ArduPilot"):
296296
self._set_component_value_and_update_ui(("Flight Controller", "Product", "Manufacturer"), manufacturer)
297297

298298
def set_fc_model(self, model: str) -> None:
299-
if model and model not in ("Unknown", "MAVLink"):
299+
if model and model not in (_("Unknown"), "MAVLink"):
300300
self._set_component_value_and_update_ui(("Flight Controller", "Product", "Model"), model)
301301

302302
def set_vehicle_configuration_template(self, configuration_template: str) -> None:

MethodicConfigurator/frontend_tkinter_flightcontroller_info.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,19 @@ def __init__(self, flight_controller: FlightController) -> None:
4949
else:
5050
text_field.insert(tk.END, attr_value)
5151
else:
52-
text_field.insert(tk.END, "N/A") # Insert "Not Available" if the attribute is missing or empty
52+
text_field.insert(tk.END, _("N/A")) # Insert "Not Available" if the attribute is missing or empty
5353
text_field.configure(state="readonly")
5454

5555
self.info_frame.columnconfigure(1, weight=1)
5656

5757
logging_info(_("Firmware Version: %s"), flight_controller.info.flight_sw_version_and_type)
5858
logging_info(_("Firmware first 8 hex bytes of the FC git hash: %s"), flight_controller.info.flight_custom_version)
5959
logging_info(_("Firmware first 8 hex bytes of the ChibiOS git hash: %s"), flight_controller.info.os_custom_version)
60+
logging_info(
61+
_("Flight Controller firmware type: %s (%s)"),
62+
flight_controller.info.firmware_type,
63+
flight_controller.info.apj_board_id,
64+
)
6065
logging_info(_("Flight Controller HW / board version: %s"), flight_controller.info.board_version)
6166
logging_info(_("Flight Controller USB vendor ID: %s"), flight_controller.info.vendor)
6267
logging_info(_("Flight Controller USB product ID: %s"), flight_controller.info.product)

0 commit comments

Comments
 (0)