Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions ardupilot_methodic_configurator/backend_filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,10 @@ def re_init(self, vehicle_dir: str, vehicle_type: str, blank_component_data: boo
if not self.file_parameters:
return # No files intermediate parameters files found, no need to continue, the rest needs them

fw_version = re_compile(r"[ _-]").split(self.fw_version, 1)[0]
# Read ArduPilot parameter documentation
xml_url = get_xml_url(vehicle_type, self.fw_version)
fallback_xml_url = get_fallback_xml_url(vehicle_type, self.fw_version)
xml_url = get_xml_url(vehicle_type, fw_version)
fallback_xml_url = get_fallback_xml_url(vehicle_type, fw_version)
xml_dir = get_xml_dir(vehicle_dir)
self.doc_dict = parse_parameter_metadata(
xml_url, xml_dir, PARAM_DEFINITION_XML_FILE, vehicle_type, TOOLTIP_MAX_LENGTH, fallback_xml_url
Expand Down
2 changes: 1 addition & 1 deletion ardupilot_methodic_configurator/data_model_par_dict.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ def export_to_param(

"""
formatted_params = self._format_params(file_format)
with open(filename_out, "w", encoding="utf-8") as output_file:
with open(filename_out, "w", encoding="utf-8", newline="\n") as output_file: # use Linux line endings even on windows
if content_header:
output_file.write("\n".join(content_header) + "\n")
output_file.writelines(line + "\n" for line in formatted_params)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ def update_json_structure(self) -> None:

# Merge existing data onto default structure (preserves existing values)
self._data = self._deep_merge_dicts(default_structure, self._data)
self._data["Components"] = self._reorder_components(self._data.get("Components", {}))
self._data["Program version"] = __version__

def _deep_merge_dicts(self, default: dict[str, Any], existing: dict[str, Any]) -> dict[str, Any]:
Expand Down Expand Up @@ -292,6 +293,63 @@ def _deep_merge_dicts(self, default: dict[str, Any], existing: dict[str, Any]) -

return result

def _reorder_components(self, existing_components: ComponentData) -> ComponentData:
"""
Reorder components according to the desired structure while preserving existing data.

Args:
existing_components: The existing components dictionary

Returns:
A new dictionary with components reordered according to the desired structure

"""
desired_component_order = [
"Flight Controller",
"Frame",
"Battery Monitor",
"Battery",
"ESC",
"Motors",
"Propellers",
"GNSS Receiver",
"RC Controller",
"RC Transmitter",
"RC Receiver",
"Telemetry",
]

# Create reordered components dict
reordered_components = {}
remaining_components = existing_components.copy()

# First, add components in the desired order
for component_name in desired_component_order:
if component_name in remaining_components:
reordered_components[component_name] = remaining_components.pop(component_name)

# Then add any remaining unknown components at the end
reordered_components.update(remaining_components)

# Second step: for each component, ensure Product fields are in correct order (Version before URL)
for component_name, component_data in reordered_components.items():
if "Product" in component_data and isinstance(component_data["Product"], dict):
product = component_data["Product"]
if "Version" in product and "URL" in product:
# Create new ordered product dict
ordered_product = {}
# Add fields in desired order
for field in ["Manufacturer", "Model", "Version", "URL"]:
if field in product:
ordered_product[field] = product[field]
# Add any remaining fields
for field, value in product.items():
if field not in ordered_product:
ordered_product[field] = value
reordered_components[component_name]["Product"] = ordered_product

return reordered_components

def init_battery_chemistry(self) -> None:
self._battery_chemistry = (
self._data.get("Components", {}).get("Battery", {}).get("Specifications", {}).get("Chemistry", "")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"Product": {
"Manufacturer": "CubePilot",
"Model": "CubeOrange",
"URL": "https://www.robotshop.com/products/cubepilot-the-cube-orange-standard-set-ads-b-carrier-board",
"Version": "1.0"
"Version": "1.0",
"URL": "https://www.robotshop.com/products/cubepilot-the-cube-orange-standard-set-ads-b-carrier-board"
},
"Firmware": {
"Type": "ArduCopter",
Expand All @@ -21,81 +21,21 @@
"Product": {
"Manufacturer": "Aircar Technology and Aviation ",
"Model": "prototype",
"URL": "https://www.aircar.aero/",
"Version": "v1"
"Version": "v1",
"URL": "https://www.aircar.aero/"
},
"Specifications": {
"TOW min Kg": 320,
"TOW max Kg": 500
},
"Notes": "Frame is custom, X type frame. Arm length is 2650mm."
},
"RC Controller": {
"Product": {
"Manufacturer": "",
"Model": "",
"URL": "",
"Version": ""
},
"Firmware": {
"Type": "",
"Version": ""
},
"Notes": ""
},
"RC Transmitter": {
"Product": {
"Manufacturer": "",
"Model": "",
"URL": "",
"Version": ""
},
"Firmware": {
"Type": "",
"Version": ""
},
"Notes": "integrated in RC controller"
},
"RC Receiver": {
"Product": {
"Manufacturer": "",
"Model": "",
"URL": "",
"Version": ""
},
"Firmware": {
"Type": "",
"Version": ""
},
"FC Connection": {
"Type": "RCin/SBUS",
"Protocol": "All"
},
"Notes": "This receiver is on the vehicle and is connected to the flight controller"
},
"Telemetry": {
"Product": {
"Manufacturer": "",
"Model": "",
"URL": "",
"Version": ""
},
"Firmware": {
"Type": "",
"Version": ""
},
"FC Connection": {
"Type": "SERIAL1",
"Protocol": "MAVLink2"
},
"Notes": ""
},
"Battery Monitor": {
"Product": {
"Manufacturer": "CubePilot",
"Model": "HX4-06008",
"URL": "https://docs.cubepilot.org/user-guides/autopilot/the-cube-user-manual#power-module-connection",
"Version": "PB01A21"
"Version": "PB01A21",
"URL": "https://docs.cubepilot.org/user-guides/autopilot/the-cube-user-manual#power-module-connection"
},
"Firmware": {
"Type": "",
Expand All @@ -111,8 +51,8 @@
"Product": {
"Manufacturer": "",
"Model": "",
"URL": "",
"Version": ""
"Version": "",
"URL": ""
},
"Specifications": {
"Chemistry": "LipoHV",
Expand All @@ -128,8 +68,8 @@
"Product": {
"Manufacturer": "",
"Model": "",
"URL": "",
"Version": ""
"Version": "",
"URL": ""
},
"Firmware": {
"Type": "",
Expand All @@ -145,8 +85,8 @@
"Product": {
"Manufacturer": "",
"Model": "",
"URL": "",
"Version": ""
"Version": "",
"URL": ""
},
"Specifications": {
"Poles": 14
Expand All @@ -157,8 +97,8 @@
"Product": {
"Manufacturer": "",
"Model": "",
"URL": "",
"Version": ""
"Version": "",
"URL": ""
},
"Specifications": {
"Diameter_inches": 52
Expand All @@ -169,8 +109,8 @@
"Product": {
"Manufacturer": "CubePilot",
"Model": "Here 3",
"URL": "https://docs.cubepilot.org/user-guides/here-3/here-3-manual",
"Version": "1"
"Version": "1",
"URL": "https://docs.cubepilot.org/user-guides/here-3/here-3-manual"
},
"Firmware": {
"Type": "UBlox",
Expand All @@ -181,6 +121,66 @@
"Protocol": "DroneCAN"
},
"Notes": "uBlox M8P GNSS with a patch antenna."
},
"RC Controller": {
"Product": {
"Manufacturer": "",
"Model": "",
"Version": "",
"URL": ""
},
"Firmware": {
"Type": "",
"Version": ""
},
"Notes": ""
},
"RC Transmitter": {
"Product": {
"Manufacturer": "",
"Model": "",
"Version": "",
"URL": ""
},
"Firmware": {
"Type": "",
"Version": ""
},
"Notes": "integrated in RC controller"
},
"RC Receiver": {
"Product": {
"Manufacturer": "",
"Model": "",
"Version": "",
"URL": ""
},
"Firmware": {
"Type": "",
"Version": ""
},
"FC Connection": {
"Type": "RCin/SBUS",
"Protocol": "All"
},
"Notes": "This receiver is on the vehicle and is connected to the flight controller"
},
"Telemetry": {
"Product": {
"Manufacturer": "",
"Model": "",
"Version": "",
"URL": ""
},
"Firmware": {
"Type": "",
"Version": ""
},
"FC Connection": {
"Type": "SERIAL1",
"Protocol": "MAVLink2"
},
"Notes": ""
}
},
"Program version": "2.0.1"
Expand Down
Loading