-
Notifications
You must be signed in to change notification settings - Fork 38
Motor test gui #700
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Motor test gui #700
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces a comprehensive motor test GUI for ArduPilot flight controllers, implementing a complete Model-View architecture with robust testing capabilities. The implementation adds motor testing functionality, frame configuration management, battery safety monitoring, and SVG diagram rendering through new GUI components and data models.
- Motor test GUI implementation with safety features and real-time feedback
- Exception-based error handling refactoring in data model with comprehensive validation
- SVG conversion utilities for motor diagrams with multiple backend support
Reviewed Changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 7 comments.
Show a summary per file
File | Description |
---|---|
tests/test_data_model_motor_test.py | Updated tests to use exception-based error handling and properties instead of method calls |
scripts/download_motor_diagrams.py | Added SVG to PNG conversion functionality with multiple backend support |
pyproject.toml | Added scikit-build and tksvg dependencies for GUI functionality |
ardupilot_methodic_configurator/frontend_tkinter_motor_test.py | New comprehensive motor test GUI implementation with safety features |
ardupilot_methodic_configurator/data_model_motor_test.py | Major refactoring to exception-based error handling and property-based API |
ardupilot_methodic_configurator/backend_flightcontroller.py | Added fetch_param method for parameter verification |
ardupilot_methodic_configurator/backend_filesystem_program_settings.py | Restructured motor test settings to nested configuration |
ARCHITECTURE_motor_test.md | Updated documentation to reflect implemented features |
.vscode/launch.json | Added debug configuration for motor test frontend |
if __name__ == "__main__": | ||
download_motor_diagrams() | ||
# download_motor_diagrams() | ||
convert_svg_to_png(result_height=320) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The commented out function call suggests this is development/testing code. Consider either removing this comment or making it conditional based on command-line arguments for cleaner production code.
convert_svg_to_png(result_height=320) | |
parser = argparse.ArgumentParser( | |
description="Download and/or convert ArduPilot motor diagram SVG files." | |
) | |
parser.add_argument( | |
"--download", | |
action="store_true", | |
help="Download all motor diagram SVG files." | |
) | |
parser.add_argument( | |
"--convert", | |
action="store_true", | |
help="Convert all SVG files to PNG." | |
) | |
parser.add_argument( | |
"--height", | |
type=int, | |
default=320, | |
help="Resulting PNG height in pixels (default: 320)." | |
) | |
args = parser.parse_args() | |
if args.download: | |
download_motor_diagrams() | |
if args.convert: | |
convert_svg_to_png(result_height=args.height) | |
if not args.download and not args.convert: | |
parser.print_help() |
Copilot uses AI. Check for mistakes.
self._diagrams_path = diagram_path | ||
|
||
if diagram_path and diagram_path.endswith(".svg"): | ||
logging_error(_("Found SVG diagram at: %(path)s"), {"path": diagram_path}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using logging_error for a successful operation is incorrect. This should be logging_info or logging_debug since finding the SVG diagram is expected behavior, not an error condition.
logging_error(_("Found SVG diagram at: %(path)s"), {"path": diagram_path}) | |
logging_info(_("Found SVG diagram at: %(path)s"), {"path": diagram_path}) |
Copilot uses AI. Check for mistakes.
self.diagram_canvas.create_text(200, 150, text=_("Error loading diagram"), fill="red") | ||
else: | ||
# Fallback: just show the path | ||
logging_error(error_msg) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider including the original exception in the logging call for better debugging information. Use logging_error with exception details or logging.exception() to include traceback.
Copilot uses AI. Check for mistakes.
ProgramSettings.set_setting("motor_test/duration", duration) | ||
return True | ||
self._test_duration_s = int(duration) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Converting duration to int loses precision. The duration should remain as a float since it can have decimal values (e.g., 2.5 seconds), but the property getter returns int which is inconsistent.
self._test_duration_s = int(duration) | |
self._test_duration_s = float(duration) |
Copilot uses AI. Check for mistakes.
int: Throttle percentage (1-100) | ||
|
||
""" | ||
return int(self._test_throttle_pct) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider storing throttle_pct as int consistently throughout the class instead of converting on every access. The internal storage as float but return as int creates unnecessary type conversions.
return int(self._test_throttle_pct) | |
return self._test_throttle_pct |
Copilot uses AI. Check for mistakes.
return float(msg.param_value) | ||
time_sleep(0.01) # Small sleep to prevent busy waiting | ||
|
||
raise TimeoutError(_("Timeout waiting for parameter %s") % param_name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error message should include the timeout duration for better debugging. Consider changing to: 'Timeout waiting for parameter %s after %d seconds' to provide more context.
raise TimeoutError(_("Timeout waiting for parameter %s") % param_name) | |
raise TimeoutError(_("Timeout waiting for parameter %s after %d seconds") % (param_name, timeout)) |
Copilot uses AI. Check for mistakes.
patch.object(MotorTestDataModel, "_update_frame_configuration", side_effect=Exception("Test exception")), | ||
# Act & Assert: Exception should be caught and re-raised | ||
pytest.raises(Exception, match="Test exception"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The context manager syntax is split across lines unnecessarily. Consider reformatting for better readability by keeping the opening parenthesis on the same line as the first context manager.
pytest.raises(Exception, match="Test exception"), | |
with (patch.object(MotorTestDataModel, "_update_frame_configuration", side_effect=Exception("Test exception")), | |
pytest.raises(Exception, match="Test exception"), |
Copilot uses AI. Check for mistakes.
…rror_messages in tuples. This is more pythonic
Required because TKinter can not display .svg files
for more information, see https://pre-commit.ci
f55c184
to
260b790
Compare
No description provided.