Skip to content

Recovery - #1941

Open
amilcarlucas wants to merge 1 commit into
masterfrom
recovery
Open

Recovery#1941
amilcarlucas wants to merge 1 commit into
masterfrom
recovery

Conversation

@amilcarlucas

@amilcarlucas amilcarlucas commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator

Description

Recover from invalid FRAME_CLASS, FRAME_TYPE combinations

Checklist

  • Run pre-commit checks locally
  • Verified by a human programmer
  • All commits are signed off (use git commit --signoff)
  • Code follows our coding standards
  • Documentation updated if needed
  • No breaking changes or properly documented

Testing

Describe how you tested these changes:

  • Unit tests pass
  • Integration tests pass
  • Manual testing performed
  • Tested on flight controller hardware

Copilot AI lite review requested due to automatic review settings August 15, 2026 11:14

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank You

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

This PR improves resilience when dealing with MAVFTP parameter transfer failures and ambiguous/invalid frame/vehicle identifiers, preventing hard exits and enabling UI-level recovery paths.

Changes:

  • Replace sys.exit() behavior during MAVFTP param decode/read failures with error returns and fallback handling.
  • Resolve ambiguous VTOL vehicle type classification using firmware banner parsing.
  • Allow motor-test UI/model to remain usable when FRAME_CLASS/FRAME_TYPE combos are invalid, including metadata-based recovery and new layouts.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
tests/test_data_model_flightcontroller_info.py Updates classification expectations for ambiguous VTOL MAV type.
tests/test_backend_mavftp.py Adds coverage ensuring MAVFTP decode failures return an error instead of exiting.
tests/test_backend_flightcontroller_params.py Adds coverage for fallback behavior when MAVFTP transfer raises.
tests/test_backend_flightcontroller_connection.py Adds tests for early vehicle-type logging and banner-based resolution.
tests/plugins/test_data_model_motor_test.py Adds/updates tests for invalid frame-type correction and motor layout population.
ardupilot_methodic_configurator/plugins/frontend_tkinter_motor_test.py Hardens combobox selection and forces diagram refresh on frame-type changes/activation.
ardupilot_methodic_configurator/plugins/data_model_motor_test.py Refactors motor layout loading; introduces invalid-frame-type recovery and metadata fallback.
ardupilot_methodic_configurator/plugins/AP_Motors_test.json Adds a BiCopter (class 10) layout for motor testing.
ardupilot_methodic_configurator/log_analysis/data_model_quality_fft.py Minor simplification of return path.
ardupilot_methodic_configurator/data_model_flightcontroller_info.py Marks VTOL_DUOROTOR as ambiguous vehicle type.
ardupilot_methodic_configurator/backend_mavftp.py Returns MAVFTP error codes instead of terminating on param read/decode failures.
ardupilot_methodic_configurator/backend_flightcontroller_params.py Converts MAVFTP download exceptions into logged fallback results.
ardupilot_methodic_configurator/backend_flightcontroller_connection.py Extracts firmware type from banner more robustly; resolves ambiguous heartbeat vehicle types.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread ardupilot_methodic_configurator/plugins/data_model_motor_test.py Outdated
Comment on lines +1038 to +1041
class_name = next(
(str(name).strip().upper() for code, name in class_values.items() if int(code) == frame_class),
None,
)
Comment on lines +206 to +211
try:
mavftp = create_mavftp(self.master)

def get_params_progress_callback(completion: float) -> None:
if progress_callback is not None and completion is not None:
progress_callback(int(completion * 100), 100)
Comment on lines +236 to +241
except Exception as error: # pylint: disable=broad-exception-caught
logging_warning(
_("MAVFTP parameter download failed; falling back to MAVLink: %(error)s"),
{"error": str(error)},
)
return {}, ParDict()
Comment on lines +1456 to +1463
data = fh.read()
except OSError as exp:
logging.error("FTP: Failed to read file param.pck: %s", exp)
sys.exit(1)
return MAVFTPReturn("GetParams", ERR_Fail)
pdata = MAVFTP.ftp_param_decode(data)
if pdata is None:
sys.exit(1)
logging.error("FTP: Failed to decode parameter file param.pck")
return MAVFTPReturn("GetParams", ERR_Fail)
frame_type_pairs = self.model.get_frame_type_pairs()
current_selection = self.model.get_current_frame_selection_key() if frame_type_pairs else None
current_selection_key = self.model.get_current_frame_selection_key() if frame_type_pairs else None
current_selection = current_selection_key if current_selection_key in {key for key, _ in frame_type_pairs} else None
Comment thread ardupilot_methodic_configurator/backend_flightcontroller_connection.py Outdated
@github-actions

github-actions Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

☂️ Code Coverage

current status: ✅

Overall Coverage

Statements Covered Coverage Threshold Status
17590 15940 91% 89% 🟢

New Files

File Coverage Status
ardupilot_methodic_configurator/frontend_tkinter_fc_banner_window.py 35% 🟢
ardupilot_methodic_configurator/frontend_tkinter_parameter_compare_and_upload.py 39% 🟢
TOTAL 37% 🟢

Modified Files

File Coverage Status
ardupilot_methodic_configurator/main.py 89% 🟢
ardupilot_methodic_configurator/backend_flightcontroller.py 93% 🟢
ardupilot_methodic_configurator/backend_flightcontroller_connection.py 99% 🟢
ardupilot_methodic_configurator/backend_flightcontroller_params.py 100% 🟢
ardupilot_methodic_configurator/backend_flightcontroller_protocols.py 100% 🟢
ardupilot_methodic_configurator/data_model_ardupilot_parameter.py 99% 🟢
ardupilot_methodic_configurator/data_model_flightcontroller_info.py 100% 🟢
ardupilot_methodic_configurator/data_model_parameter_editor.py 99% 🟢
ardupilot_methodic_configurator/frontend_tkinter_parameter_editor.py 95% 🟢
ardupilot_methodic_configurator/frontend_tkinter_parameter_editor_table.py 77% 🟢
ardupilot_methodic_configurator/frontend_tkinter_show.py 91% 🟢
ardupilot_methodic_configurator/plugins/data_model_motor_test.py 99% 🟢
ardupilot_methodic_configurator/plugins/frontend_tkinter_motor_test.py 89% 🟢
TOTAL 95% 🟢

updated for commit: c274b9a by action🐍

@github-actions

Copy link
Copy Markdown
Contributor

Test Results

     4 files       4 suites   43m 35s ⏱️
 4 618 tests  4 611 ✅  7 💤 0 ❌
18 254 runs  18 209 ✅ 45 💤 0 ❌

Results for commit 19b6c2d.

… state

Keep the motor-test plugin usable when the flight controller reports a
valid frame class with an unsupported FRAME_TYPE. Show an informative error
dialog while still rendering the plugin and allowing the user to select a
valid frame type.

Refresh motor controls and diagrams after frame changes and flight-controller
resets. Avoid invalid combobox selections and suppress diagram lookups while
the frame type is invalid.

Add regression coverage for invalid frame recovery, plugin rendering,
diagram refresh.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Suppressed comments (3)

ardupilot_methodic_configurator/data_model_flightcontroller_info.py:252

  • Encoding “ambiguity” as a human-readable string (and then keying logic off " or " elsewhere) is brittle and mixes display text with decision logic. A more robust approach is to store ambiguity as structured state (e.g., vehicle_type_candidates: set[str] or a dedicated enum/flag) and derive a user-facing string separately; then banner resolution can update the structured field without relying on substring checks.
            mavutil.mavlink.MAV_TYPE_VTOL_DUOROTOR: "ArduPlane or ArduCopter",

ardupilot_methodic_configurator/plugins/frontend_tkinter_motor_test.py:937

  • Displaying a modal UI dialog inside a model factory couples model instantiation to the UI layer and makes the factory harder to reuse/test (and can be problematic if invoked before Tk is fully initialized, depending on call site). Prefer returning the model + error status to the view layer (or raising a recoverable exception) and letting the UI decide how/when to notify the user.
    model = MotorTestDataModel(context.flight_controller, context.local_filesystem)
    if model.invalid_frame_type_error:
        showerror(_("Invalid Frame Type"), model.invalid_frame_type_error)
    return model

tests/test_backend_flightcontroller_connection.py:1325

  • This assertion is likely brittle because it depends on the exact MAVLink enum description formatting (punctuation/capitalization) from pymavlink and could change across versions/localization. Consider asserting on more stable substrings (e.g., "Vehicle type:" and "running ArduPlane firmware") and relying primarily on connection.info.vehicle_type == "ArduPlane" for correctness.
        assert "Vehicle type: Fixed wing aircraft." in caplog.text

break
if layout.get("Class") == self._frame_class and layout.get("motors"):
has_frame_class_configuration = True
if layout.get("Class") == self._frame_class and layout.get("Type") == self._frame_type:
@coveralls

coveralls commented Aug 20, 2026

Copy link
Copy Markdown

Coverage Report for CI Build 32292213333

Warning

Build has drifted: This PR's base is out of sync with its target branch, so coverage data may include unrelated changes.
Quick fix: rebase this PR. Learn more →

Coverage decreased (-0.3%) to 90.654%

Details

  • Coverage decreased (-0.3%) from the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • 249 coverage regressions across 9 files.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

249 previously-covered lines in 9 files lost coverage.

File Lines Losing Coverage Coverage
frontend_tkinter_parameter_editor_table.py 139 76.92%
frontend_tkinter_parameter_editor.py 32 94.99%
plugins/frontend_tkinter_motor_test.py 28 88.86%
backend_flightcontroller.py 13 93.1%
data_model_parameter_editor.py 13 98.71%
main.py 10 89.32%
plugins/data_model_motor_test.py 7 98.83%
backend_flightcontroller_connection.py 4 98.86%
data_model_ardupilot_parameter.py 3 98.89%

Coverage Stats

Coverage Status
Relevant Lines: 17590
Covered Lines: 15946
Line Coverage: 90.65%
Relevant Branches: 5220
Covered Branches: 4408
Branch Coverage: 84.44%
Branches in Coverage %: No
Coverage Strength: 2.7 hits per line

💛 - Coveralls

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants