ardupilot-methodic-configurator 2.5.0__py3-none-any.whl → 2.6.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ardupilot-methodic-configurator might be problematic. Click here for more details.
- ardupilot_methodic_configurator/__init__.py +1 -1
- ardupilot_methodic_configurator/backend_filesystem_program_settings.py +15 -20
- ardupilot_methodic_configurator/configuration_manager.py +113 -1
- ardupilot_methodic_configurator/data_model_configuration_step.py +40 -3
- ardupilot_methodic_configurator/frontend_tkinter_base_window.py +4 -0
- ardupilot_methodic_configurator/frontend_tkinter_component_editor_base.py +1 -1
- ardupilot_methodic_configurator/frontend_tkinter_motor_test.py +853 -0
- ardupilot_methodic_configurator/frontend_tkinter_parameter_editor.py +8 -12
- ardupilot_methodic_configurator/frontend_tkinter_parameter_editor_table.py +78 -108
- ardupilot_methodic_configurator/frontend_tkinter_usage_popup_window.py +11 -6
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/Holybro_X500/07_esc.param +1 -1
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/Holybro_X500/42_system_id_roll.param +5 -3
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/Holybro_X500/43_system_id_pitch.param +3 -3
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/Holybro_X500/44_system_id_yaw.param +1 -1
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/Holybro_X500/vehicle.jpg +0 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/Holybro_X500/vehicle_components.json +3 -4
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/Holybro_X500_V2/05_remote_controller.param +7 -7
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/Holybro_X500_V2/06_telemetry.param +2 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/Holybro_X500_V2/07_esc.param +6 -6
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/Holybro_X500_V2/10_gnss.param +4 -4
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/Holybro_X500_V2/13_general_configuration.param +5 -5
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/Holybro_X500_V2/15_motor.param +1 -1
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/Holybro_X500_V2/16_pid_adjustment.param +10 -10
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/Holybro_X500_V2/18_notch_filter_setup.param +3 -3
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/Holybro_X500_V2/20_throttle_controller.param +1 -1
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/Holybro_X500_V2/22_quick_tune_setup.param +1 -1
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/Holybro_X500_V2/26_quick_tune_setup.param +2 -2
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/Holybro_X500_V2/30_autotune_roll_setup.param +1 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/Holybro_X500_V2/34_autotune_yaw_setup.param +1 -1
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/Holybro_X500_V2/37_autotune_yawd_results.param +1 -1
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/Holybro_X500_V2/vehicle.jpg +0 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/00_default.param +1352 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/02_imu_temperature_calibration_setup.param +8 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/03_imu_temperature_calibration_results.param +42 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/04_board_orientation.param +4 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/05_remote_controller.param +13 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/06_telemetry.param +4 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/07_esc.param +43 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/08_batt1.param +15 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/10_gnss.param +11 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/11_initial_atc.param +18 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/12_mp_setup_mandatory_hardware.param +99 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/13_general_configuration.param +17 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/14_logging.param +6 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/15_motor.param +4 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/16_pid_adjustment.param +13 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/17_remote_id.param +4 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/18_notch_filter_setup.param +10 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/19_notch_filter_results.param +7 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/20_throttle_controller.param +5 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/21_ekf_config.param +2 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/22_quick_tune_setup.param +14 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/23_quick_tune_results.param +10 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/24_inflight_magnetometer_fit_setup.param +8 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/24_inflight_magnetometer_fit_setup.pdef.xml +57 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/25_inflight_magnetometer_fit_results.param +15 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/26_quick_tune_setup.param +14 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/27_quick_tune_results.param +10 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/28_evaluate_the_aircraft_tune_ff_disable.param +4 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/29_evaluate_the_aircraft_tune_ff_enable.param +1 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/30_autotune_roll_setup.param +2 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/31_autotune_roll_results.param +5 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/32_autotune_pitch_setup.param +2 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/33_autotune_pitch_results.param +5 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/34_autotune_yaw_setup.param +3 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/35_autotune_yaw_results.param +5 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/36_autotune_yawd_setup.param +3 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/37_autotune_yawd_results.param +5 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/38_autotune_roll_pitch_retune_setup.param +2 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/39_autotune_roll_pitch_retune_results.param +10 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/40_windspeed_estimation.param +5 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/41_barometer_compensation.param +7 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/42_system_id_roll.param +21 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/43_system_id_pitch.param +10 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/44_system_id_yaw.param +10 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/45_system_id_thrust.param +10 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/46_analytical_pid_optimization.param +4 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/47_position_controller.param +13 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/48_guided_operation.param +4 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/49_precision_land.param +27 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/50_optical_flow_setup.param +19 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/51_optical_flow_results.param +3 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/52_use_optical_flow_instead_of_gnss.param +8 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/53_everyday_use.param +7 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/vehicle.jpg +0 -0
- ardupilot_methodic_configurator/vehicle_templates/ArduCopter/TarotFY680Hexacopter/vehicle_components.json +188 -0
- {ardupilot_methodic_configurator-2.5.0.dist-info → ardupilot_methodic_configurator-2.6.0.dist-info}/METADATA +74 -134
- {ardupilot_methodic_configurator-2.5.0.dist-info → ardupilot_methodic_configurator-2.6.0.dist-info}/RECORD +101 -43
- {ardupilot_methodic_configurator-2.5.0.dist-info → ardupilot_methodic_configurator-2.6.0.dist-info}/WHEEL +0 -0
- {ardupilot_methodic_configurator-2.5.0.dist-info → ardupilot_methodic_configurator-2.6.0.dist-info}/entry_points.txt +0 -0
- {ardupilot_methodic_configurator-2.5.0.dist-info → ardupilot_methodic_configurator-2.6.0.dist-info}/licenses/LICENSE.md +0 -0
- {ardupilot_methodic_configurator-2.5.0.dist-info → ardupilot_methodic_configurator-2.6.0.dist-info}/licenses/LICENSES/Apache-2.0.txt +0 -0
- {ardupilot_methodic_configurator-2.5.0.dist-info → ardupilot_methodic_configurator-2.6.0.dist-info}/licenses/LICENSES/BSD-3-Clause.txt +0 -0
- {ardupilot_methodic_configurator-2.5.0.dist-info → ardupilot_methodic_configurator-2.6.0.dist-info}/licenses/LICENSES/GPL-3.0-or-later.txt +0 -0
- {ardupilot_methodic_configurator-2.5.0.dist-info → ardupilot_methodic_configurator-2.6.0.dist-info}/licenses/LICENSES/LGPL-3.0-or-later.txt +0 -0
- {ardupilot_methodic_configurator-2.5.0.dist-info → ardupilot_methodic_configurator-2.6.0.dist-info}/licenses/LICENSES/MIT-CMU.txt +0 -0
- {ardupilot_methodic_configurator-2.5.0.dist-info → ardupilot_methodic_configurator-2.6.0.dist-info}/licenses/LICENSES/MIT.txt +0 -0
- {ardupilot_methodic_configurator-2.5.0.dist-info → ardupilot_methodic_configurator-2.6.0.dist-info}/licenses/LICENSES/MPL-2.0.txt +0 -0
- {ardupilot_methodic_configurator-2.5.0.dist-info → ardupilot_methodic_configurator-2.6.0.dist-info}/licenses/LICENSES/PSF-2.0.txt +0 -0
- {ardupilot_methodic_configurator-2.5.0.dist-info → ardupilot_methodic_configurator-2.6.0.dist-info}/licenses/credits/CREDITS.md +0 -0
- {ardupilot_methodic_configurator-2.5.0.dist-info → ardupilot_methodic_configurator-2.6.0.dist-info}/top_level.txt +0 -0
|
@@ -10,7 +10,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
10
10
|
|
|
11
11
|
# from sys import exit as sys_exit
|
|
12
12
|
import glob
|
|
13
|
-
import
|
|
13
|
+
from importlib.resources import files as importlib_files
|
|
14
14
|
from json import dump as json_dump
|
|
15
15
|
from json import load as json_load
|
|
16
16
|
from logging import debug as logging_debug
|
|
@@ -18,6 +18,7 @@ from logging import error as logging_error
|
|
|
18
18
|
from os import makedirs as os_makedirs
|
|
19
19
|
from os import path as os_path
|
|
20
20
|
from os import sep as os_sep
|
|
21
|
+
from pathlib import Path
|
|
21
22
|
from platform import system as platform_system
|
|
22
23
|
from re import escape as re_escape
|
|
23
24
|
from re import match as re_match
|
|
@@ -107,13 +108,13 @@ class ProgramSettings:
|
|
|
107
108
|
|
|
108
109
|
@staticmethod
|
|
109
110
|
def application_icon_filepath() -> str:
|
|
110
|
-
|
|
111
|
-
return
|
|
111
|
+
package_path = importlib_files("ardupilot_methodic_configurator")
|
|
112
|
+
return str(package_path / "images" / "ArduPilot_icon.png")
|
|
112
113
|
|
|
113
114
|
@staticmethod
|
|
114
115
|
def application_logo_filepath() -> str:
|
|
115
|
-
|
|
116
|
-
return
|
|
116
|
+
package_path = importlib_files("ardupilot_methodic_configurator")
|
|
117
|
+
return str(package_path / "images" / "ArduPilot_logo.png")
|
|
117
118
|
|
|
118
119
|
@staticmethod
|
|
119
120
|
def create_new_vehicle_dir(new_vehicle_dir: str) -> str:
|
|
@@ -256,15 +257,14 @@ class ProgramSettings:
|
|
|
256
257
|
|
|
257
258
|
@staticmethod
|
|
258
259
|
def get_templates_base_dir() -> str:
|
|
259
|
-
|
|
260
|
+
package_path = importlib_files("ardupilot_methodic_configurator")
|
|
261
|
+
logging_debug("current script directory1: %s", package_path)
|
|
260
262
|
if platform_system() == "Windows":
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
logging_debug("current script directory: %s", current_script_dir)
|
|
264
|
-
site_directory = current_script_dir
|
|
263
|
+
package_path = Path(ProgramSettings._site_config_dir())
|
|
264
|
+
logging_debug("current script directory2: %s", package_path)
|
|
265
265
|
|
|
266
|
-
logging_debug(_("site_directory: %s"),
|
|
267
|
-
return
|
|
266
|
+
logging_debug(_("site_directory: %s"), package_path)
|
|
267
|
+
return str(package_path / "vehicle_templates")
|
|
268
268
|
|
|
269
269
|
@staticmethod
|
|
270
270
|
def get_recently_used_dirs() -> tuple[str, str, str]:
|
|
@@ -357,20 +357,15 @@ class ProgramSettings:
|
|
|
357
357
|
"""
|
|
358
358
|
# See https://github.com/ArduPilot/ardupilot_wiki/pull/6215
|
|
359
359
|
# Determine the application directory (where images are stored)
|
|
360
|
-
|
|
361
|
-
# Running as compiled executable
|
|
362
|
-
application_path = os_path.dirname(sys.executable)
|
|
363
|
-
else:
|
|
364
|
-
# Running as script
|
|
365
|
-
application_path = os_path.dirname(os_path.dirname(os_path.abspath(__file__)))
|
|
360
|
+
package_path = importlib_files("ardupilot_methodic_configurator")
|
|
366
361
|
|
|
367
|
-
images_dir =
|
|
362
|
+
images_dir = package_path / "images" / "motor_diagrams_png"
|
|
368
363
|
|
|
369
364
|
# Generate PNG filename based on frame configuration
|
|
370
365
|
filename = f"m_{frame_class:02d}_{frame_type:02d}_*.png"
|
|
371
366
|
|
|
372
367
|
# Search for matching PNG file (since exact naming varies)
|
|
373
|
-
matching_files = glob.glob(
|
|
368
|
+
matching_files = glob.glob(str(images_dir / filename))
|
|
374
369
|
|
|
375
370
|
err_msg = (
|
|
376
371
|
""
|
|
@@ -22,6 +22,8 @@ from ardupilot_methodic_configurator import _
|
|
|
22
22
|
from ardupilot_methodic_configurator.backend_filesystem import LocalFilesystem
|
|
23
23
|
from ardupilot_methodic_configurator.backend_flightcontroller import FlightController
|
|
24
24
|
from ardupilot_methodic_configurator.backend_internet import download_file_from_url
|
|
25
|
+
from ardupilot_methodic_configurator.data_model_ardupilot_parameter import ArduPilotParameter
|
|
26
|
+
from ardupilot_methodic_configurator.data_model_configuration_step import ConfigurationStepProcessor
|
|
25
27
|
from ardupilot_methodic_configurator.data_model_par_dict import Par, ParDict, is_within_tolerance
|
|
26
28
|
from ardupilot_methodic_configurator.tempcal_imu import IMUfit
|
|
27
29
|
|
|
@@ -32,10 +34,19 @@ ShowWarningCallback = Callable[[str, str], None] # (title, message) -> None
|
|
|
32
34
|
ShowErrorCallback = Callable[[str, str], None] # (title, message) -> None
|
|
33
35
|
ShowInfoCallback = Callable[[str, str], None] # (title, message) -> None
|
|
34
36
|
|
|
37
|
+
|
|
38
|
+
class OperationNotPossibleError(Exception):
|
|
39
|
+
"""Raised when an operation cannot be performed due to missing prerequisites or state."""
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class InvalidParameterNameError(Exception):
|
|
43
|
+
"""Raised when a parameter name is invalid or already exists."""
|
|
44
|
+
|
|
45
|
+
|
|
35
46
|
# pylint: disable=too-many-lines
|
|
36
47
|
|
|
37
48
|
|
|
38
|
-
class ConfigurationManager:
|
|
49
|
+
class ConfigurationManager: # pylint: disable=too-many-public-methods
|
|
39
50
|
"""
|
|
40
51
|
Manages configuration state, including flight controller and filesystem access.
|
|
41
52
|
|
|
@@ -48,6 +59,11 @@ class ConfigurationManager:
|
|
|
48
59
|
self.current_file = current_file
|
|
49
60
|
self.flight_controller = flight_controller
|
|
50
61
|
self.filesystem = filesystem
|
|
62
|
+
self.config_step_processor = ConfigurationStepProcessor(self.filesystem)
|
|
63
|
+
|
|
64
|
+
# self.parameters is rebuilt on every repopulate(...) call and only contains the ArduPilotParameter
|
|
65
|
+
# objects needed for the current table view.
|
|
66
|
+
self.parameters: dict[str, ArduPilotParameter] = {}
|
|
51
67
|
|
|
52
68
|
@property
|
|
53
69
|
def connected_vehicle_type(self) -> str:
|
|
@@ -77,6 +93,10 @@ class ConfigurationManager:
|
|
|
77
93
|
else False
|
|
78
94
|
)
|
|
79
95
|
|
|
96
|
+
@property
|
|
97
|
+
def current_file_parameters(self) -> ParDict:
|
|
98
|
+
return self.filesystem.file_parameters.get(self.current_file, ParDict())
|
|
99
|
+
|
|
80
100
|
def handle_imu_temperature_calibration_workflow( # pylint: disable=too-many-arguments, too-many-positional-arguments
|
|
81
101
|
self,
|
|
82
102
|
selected_file: str,
|
|
@@ -1038,3 +1058,95 @@ class ConfigurationManager:
|
|
|
1038
1058
|
show_info(_("Parameter files zipped"), msg.format(zip_file_path=zip_file_path))
|
|
1039
1059
|
|
|
1040
1060
|
return should_write_file
|
|
1061
|
+
|
|
1062
|
+
def repopulate_configuration_step_parameters(
|
|
1063
|
+
self,
|
|
1064
|
+
) -> tuple[bool, list[tuple[str, str]], list[tuple[str, str]]]:
|
|
1065
|
+
"""
|
|
1066
|
+
Process the configuration step for the current file and update the self.parameters.
|
|
1067
|
+
|
|
1068
|
+
Returns:
|
|
1069
|
+
tuple: (config_step_edited, ui_errors, ui_infos)
|
|
1070
|
+
|
|
1071
|
+
"""
|
|
1072
|
+
self.parameters, config_step_edited, ui_errors, ui_infos = self.config_step_processor.process_configuration_step(
|
|
1073
|
+
self.current_file, self.fc_parameters
|
|
1074
|
+
)
|
|
1075
|
+
return config_step_edited, ui_errors, ui_infos
|
|
1076
|
+
|
|
1077
|
+
def get_different_parameters(self) -> dict[str, ArduPilotParameter]:
|
|
1078
|
+
"""
|
|
1079
|
+
Get parameters that are different from FC values or missing from FC.
|
|
1080
|
+
|
|
1081
|
+
Returns:
|
|
1082
|
+
Dictionary of parameters that are different from FC
|
|
1083
|
+
|
|
1084
|
+
"""
|
|
1085
|
+
return self.config_step_processor.filter_different_parameters(self.parameters)
|
|
1086
|
+
|
|
1087
|
+
def delete_parameter_from_current_file(self, param_name: str) -> None:
|
|
1088
|
+
"""
|
|
1089
|
+
Delete a parameter from the current file parameters.
|
|
1090
|
+
|
|
1091
|
+
Args:
|
|
1092
|
+
param_name: The name of the parameter to delete
|
|
1093
|
+
|
|
1094
|
+
"""
|
|
1095
|
+
del self.current_file_parameters[param_name]
|
|
1096
|
+
if param_name in self.parameters:
|
|
1097
|
+
del self.parameters[param_name]
|
|
1098
|
+
|
|
1099
|
+
def get_possible_add_param_names(self) -> list[str]:
|
|
1100
|
+
"""Return a sorted list of possible parameter names to add, or raise OperationNotPossibleError if not possible."""
|
|
1101
|
+
param_dict = self.filesystem.doc_dict or self.fc_parameters
|
|
1102
|
+
if not param_dict:
|
|
1103
|
+
raise OperationNotPossibleError(
|
|
1104
|
+
_("No apm.pdef.xml file and no FC connected. Not possible autocomplete parameter names.")
|
|
1105
|
+
)
|
|
1106
|
+
possible_add_param_names = [param_name for param_name in param_dict if param_name not in self.current_file_parameters]
|
|
1107
|
+
possible_add_param_names.sort()
|
|
1108
|
+
return possible_add_param_names
|
|
1109
|
+
|
|
1110
|
+
def add_parameter_to_current_file(self, param_name: str) -> bool:
|
|
1111
|
+
"""
|
|
1112
|
+
Add a parameter to the current file.
|
|
1113
|
+
|
|
1114
|
+
Returns True if the parameter was added, False if not.
|
|
1115
|
+
|
|
1116
|
+
Raises InvalidParameterNameError or OperationNotPossibleError if not possible.
|
|
1117
|
+
"""
|
|
1118
|
+
param_name = param_name.upper()
|
|
1119
|
+
if not param_name:
|
|
1120
|
+
raise InvalidParameterNameError(_("Parameter name can not be empty."))
|
|
1121
|
+
|
|
1122
|
+
if param_name in self.current_file_parameters:
|
|
1123
|
+
raise InvalidParameterNameError(_("Parameter already exists, edit it instead"))
|
|
1124
|
+
|
|
1125
|
+
fc_parameters = self.fc_parameters
|
|
1126
|
+
if fc_parameters:
|
|
1127
|
+
if param_name in fc_parameters:
|
|
1128
|
+
self.current_file_parameters[param_name] = Par(fc_parameters[param_name], "")
|
|
1129
|
+
self.parameters[param_name] = self.config_step_processor.create_ardupilot_parameter(
|
|
1130
|
+
param_name, self.current_file_parameters[param_name], self.current_file, fc_parameters
|
|
1131
|
+
)
|
|
1132
|
+
return True
|
|
1133
|
+
raise InvalidParameterNameError(_("Parameter name not found in the flight controller."))
|
|
1134
|
+
|
|
1135
|
+
if self.filesystem.doc_dict:
|
|
1136
|
+
if param_name in self.filesystem.doc_dict:
|
|
1137
|
+
self.current_file_parameters[param_name] = Par(
|
|
1138
|
+
self.filesystem.param_default_dict.get(param_name, Par(0, "")).value, ""
|
|
1139
|
+
)
|
|
1140
|
+
self.parameters[param_name] = self.config_step_processor.create_ardupilot_parameter(
|
|
1141
|
+
param_name, self.current_file_parameters[param_name], self.current_file, fc_parameters
|
|
1142
|
+
)
|
|
1143
|
+
return True
|
|
1144
|
+
raise InvalidParameterNameError(
|
|
1145
|
+
_("'{param_name}' not found in the apm.pdef.xml file.").format(param_name=param_name)
|
|
1146
|
+
)
|
|
1147
|
+
|
|
1148
|
+
if not fc_parameters and not self.filesystem.doc_dict:
|
|
1149
|
+
raise OperationNotPossibleError(
|
|
1150
|
+
_("Can not add parameter when no FC is connected and no apm.pdef.xml file exists.")
|
|
1151
|
+
)
|
|
1152
|
+
return False
|
|
@@ -17,7 +17,7 @@ from typing import Any, Optional
|
|
|
17
17
|
from ardupilot_methodic_configurator import _
|
|
18
18
|
from ardupilot_methodic_configurator.backend_filesystem import LocalFilesystem
|
|
19
19
|
from ardupilot_methodic_configurator.data_model_ardupilot_parameter import ArduPilotParameter
|
|
20
|
-
from ardupilot_methodic_configurator.data_model_par_dict import ParDict
|
|
20
|
+
from ardupilot_methodic_configurator.data_model_par_dict import Par, ParDict
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
class ConfigurationStepProcessor:
|
|
@@ -38,11 +38,14 @@ class ConfigurationStepProcessor:
|
|
|
38
38
|
"""
|
|
39
39
|
self.local_filesystem = local_filesystem
|
|
40
40
|
|
|
41
|
+
# A dictionary that maps variable names to their values
|
|
42
|
+
# These variables are used by the forced_parameters and derived_parameters in configuration_steps_*.json files
|
|
43
|
+
self.variables = self.local_filesystem.get_eval_variables()
|
|
44
|
+
|
|
41
45
|
def process_configuration_step(
|
|
42
46
|
self,
|
|
43
47
|
selected_file: str,
|
|
44
48
|
fc_parameters: dict[str, float],
|
|
45
|
-
variables: dict,
|
|
46
49
|
) -> tuple[dict[str, ArduPilotParameter], bool, list[tuple[str, str]], list[tuple[str, str]]]:
|
|
47
50
|
"""
|
|
48
51
|
Process a configuration step including parameter computation and domain model creation.
|
|
@@ -50,7 +53,6 @@ class ConfigurationStepProcessor:
|
|
|
50
53
|
Args:
|
|
51
54
|
selected_file: The name of the selected parameter file
|
|
52
55
|
fc_parameters: Dictionary of flight controller parameters
|
|
53
|
-
variables: Variables dictionary for evaluation
|
|
54
56
|
|
|
55
57
|
Returns:
|
|
56
58
|
Tuple containing:
|
|
@@ -66,6 +68,7 @@ class ConfigurationStepProcessor:
|
|
|
66
68
|
|
|
67
69
|
# Process configuration step operations if configuration steps exist
|
|
68
70
|
if self.local_filesystem.configuration_steps and selected_file in self.local_filesystem.configuration_steps:
|
|
71
|
+
variables = self.variables
|
|
69
72
|
variables["fc_parameters"] = fc_parameters
|
|
70
73
|
|
|
71
74
|
# Compute derived parameters
|
|
@@ -261,3 +264,37 @@ class ConfigurationStepProcessor:
|
|
|
261
264
|
renamed_pairs.append((old_name, new_name))
|
|
262
265
|
|
|
263
266
|
return duplicates, renamed_pairs
|
|
267
|
+
|
|
268
|
+
def create_ardupilot_parameter(
|
|
269
|
+
self,
|
|
270
|
+
param_name: str,
|
|
271
|
+
param: Par,
|
|
272
|
+
selected_file: str,
|
|
273
|
+
fc_parameters: dict[str, float],
|
|
274
|
+
) -> ArduPilotParameter:
|
|
275
|
+
"""
|
|
276
|
+
Create an ArduPilotParameter domain model object.
|
|
277
|
+
|
|
278
|
+
Args:
|
|
279
|
+
param_name: The name of the parameter
|
|
280
|
+
param: The parameter object from the file
|
|
281
|
+
selected_file: The name of the selected parameter file
|
|
282
|
+
fc_parameters: Dictionary of flight controller parameters
|
|
283
|
+
|
|
284
|
+
Returns:
|
|
285
|
+
ArduPilotParameter: The created domain model parameter
|
|
286
|
+
|
|
287
|
+
"""
|
|
288
|
+
# Get parameter metadata and default values
|
|
289
|
+
metadata = self.local_filesystem.doc_dict.get(param_name, {})
|
|
290
|
+
default_par = self.local_filesystem.param_default_dict.get(param_name, None)
|
|
291
|
+
|
|
292
|
+
# Check if parameter is forced or derived
|
|
293
|
+
forced_par = self.local_filesystem.forced_parameters.get(selected_file, ParDict()).get(param_name, None)
|
|
294
|
+
derived_par = self.local_filesystem.derived_parameters.get(selected_file, ParDict()).get(param_name, None)
|
|
295
|
+
|
|
296
|
+
# Get FC value if available
|
|
297
|
+
fc_value = fc_parameters.get(param_name)
|
|
298
|
+
|
|
299
|
+
# Create domain model parameter
|
|
300
|
+
return ArduPilotParameter(param_name, param, metadata, default_par, fc_value, forced_par, derived_par)
|
|
@@ -281,9 +281,13 @@ class BaseWindow:
|
|
|
281
281
|
parent_height = parent.winfo_height()
|
|
282
282
|
window_width = window.winfo_width()
|
|
283
283
|
window_height = window.winfo_height()
|
|
284
|
+
# logging_error(_("Parent position: %d,%d"), parent.winfo_x(), parent.winfo_y())
|
|
285
|
+
# logging_error(_("Parent size: %dx%d"), parent_width, parent_height)
|
|
286
|
+
# logging_error(_("Window size: %dx%d"), window_width, window_height)
|
|
284
287
|
x = parent.winfo_x() + (parent_width // 2) - (window_width // 2)
|
|
285
288
|
y = parent.winfo_y() + (parent_height // 2) - (window_height // 2)
|
|
286
289
|
window.geometry(f"+{x}+{y}")
|
|
290
|
+
window.update()
|
|
287
291
|
|
|
288
292
|
def put_image_in_label( # pylint: disable=too-many-locals
|
|
289
293
|
self,
|
|
@@ -289,7 +289,7 @@ class ComponentEditorWindowBase(BaseWindow): # pylint: disable=too-many-instanc
|
|
|
289
289
|
"""Check if usage instructions should be displayed."""
|
|
290
290
|
if UsagePopupWindow.should_display("component_editor"):
|
|
291
291
|
# Cast to Tk since we know root is a Tk instance in this context
|
|
292
|
-
self.root.after(
|
|
292
|
+
self.root.after(1, lambda: self._display_component_editor_usage_instructions(cast("tk.Tk", self.root)))
|
|
293
293
|
|
|
294
294
|
def _display_component_editor_usage_instructions(self, parent: tk.Tk) -> None:
|
|
295
295
|
"""Display usage instructions for the component editor."""
|