MethodicConfigurator

Flight Controller Communication Sub-Application Architecture

Overview

The Flight Controller Communication sub-application establishes connection to the flight controller, retrieves hardware information, downloads parameters and their default values. This is a critical component that enables the ArduPilot Methodic Configurator to communicate with ArduPilot-based flight controllers using the MAVLink protocol.

Requirements Analysis

Functional Requirements - Implementation Status

  1. Connection Management
    • ✅ Supports multiple connection types via discover_connections() (USB, TCP, UDP, serial)
    • ✅ Auto-detects available flight controllers using serial.tools.list_ports and network ports
    • ✅ Handles connection establishment via connect(), maintenance via heartbeat, and termination via disconnect()
    • ✅ Supports reconnection after connection loss with retry logic in __create_connection_with_retry()
    • ✅ Validates connection integrity through MAVLink protocol and timeout handling
  2. Hardware Information Retrieval
    • ✅ Identifies flight controller type via BackendFlightcontrollerInfo class
    • ✅ Retrieves firmware version information via __process_autopilot_version()
    • ✅ Detects available sensors through MAVLink AUTOPILOT_VERSION message
    • ✅ Reads hardware configuration and board type from autopilot version message
    • ✅ Supports multiple ArduPilot vehicle types (Copter, Plane, Rover, etc.) via vehicle type detection
  3. Parameter Operations
    • ✅ Downloads all parameters via download_params() with both MAVLink and MAVFTP methods
    • ✅ Retrieves parameter metadata using annotate_params.Par class
    • ✅ Downloads default parameter values via download_params_via_mavftp()
    • ✅ Handles parameter validation and bounds checking through parameter type validation
    • ✅ Supports parameter upload via set_param() and verification
  4. Protocol Support
    • ✅ Implements MAVLink parameter protocol using pymavlink.mavutil
    • ✅ Supports FTP-over-MAVLink via MAVFTP class (1656 lines of implementation)
    • ✅ Handles protocol version negotiation through mavutil connection
    • ✅ Supports heartbeat and keepalive mechanisms built into pymavlink
    • ✅ Handles message sequencing and acknowledgments via pymavlink framework
  5. Error Recovery ⚠️ PARTIALLY IMPLEMENTED
    • ✅ Detects and handles communication timeouts via connection timeout parameters
    • ✅ Retries failed operations with exponential backoff in __create_connection_with_retry()
    • ⚠️ Partial parameter download recovery (basic retry logic, no resume capability)
    • ✅ Recovers from protocol errors gracefully with comprehensive exception handling
    • ✅ Maintains connection state awareness through connection status tracking

Non-Functional Requirements - Implementation Status

  1. Performance
    • ✅ Connection establishment completes efficiently with retry mechanism
    • ✅ Parameter download handles 1000+ parameters via optimized MAVFTP and MAVLink methods
    • ✅ Supports concurrent operations through progress callbacks and non-blocking operations
    • ✅ Memory usage optimized for large parameter sets using streaming and chunked operations
  2. Reliability ⚠️ PARTIALLY IMPLEMENTED
    • ✅ Handles unstable connections gracefully with comprehensive error handling
    • ✅ Parameter operations include verification via set_param() confirmation
    • ✅ Maintains data integrity during transfers using MAVLink/MAVFTP protocols
    • ❌ TODO: No operation resumption after interruption (would need state persistence)
  3. Compatibility
    • ✅ Supports multiple ArduPilot firmware versions via dynamic protocol handling
    • ✅ Handles different flight controller hardware variants through auto-detection
    • ✅ Adapts to different MAVLink protocol versions via pymavlink compatibility layer
    • ✅ Supports legacy and current parameter formats through flexible parameter parsing
  4. Security ⚠️ PARTIALLY IMPLEMENTED
    • ✅ Validates received data through MAVLink protocol validation
    • ✅ Protects against malformed messages via pymavlink message validation
    • ❌ TODO: No authentication implementation (MAVLink auth not implemented)
    • ✅ Parameter modification protection through validation and confirmation

Architecture

Architectural Pattern - Delegation with Specialized Managers

The flight controller communication system uses a delegation pattern where the main FlightController class acts as a facade, delegating operations to specialized manager classes. This architecture provides:

Components

Flight Controller Facade

Connection Manager

Automatic reconnection in the parameter editor

backend_flightcontroller_reconnect.py keeps the original nonempty FC hardware UID, selected endpoint and active baud rate for one editor session. Its PyMAVLink message hook only timestamps heartbeats from the selected system and component. Hooks run before receive filters, so plugin reads continue to receive their expected replies.

frontend_tkinter_connection_recovery.py owns the timer, recovery worker and lifecycle states: MONITORING, RECOVERING, STOPPING and STOPPED. The editor supplies typed callbacks for receiver suspension, control locking, status display and parameter-cell refresh. Worker threads perform backend I/O; UI callbacks run on the Tk thread.

The coordinator checks once per second. It reads a bounded batch only when no plugin or sub-application owns reception. Synchronous operations retain an operation() lease across nested Tk event loops; the file browser holds an acquire_operation() lease until its close callback runs. Parameter upload previews and export windows retain a lease until their root is destroyed, including when withdrawn or running without a modal grab. Releases are idempotent, and the last release renews the heartbeat grace period. Navigation locks and modal grabs remain defensive checks for callers without an explicit lease. Window visibility alone does not imply receive ownership; tools that outlive their opening callback must retain a lease for their full lifetime.

With an active plugin, checks are passive. After eight seconds without an observed target heartbeat, the coordinator pauses the plugin and checks buffered packets before reconnecting. The optional SuspendablePlugin protocol accepts a PluginPauseReason: EXCLUSIVE_OPERATION stops actuators before FC tools take reception; CONNECTION_RECOVERY yields reception without sending actuator commands. resolve_plugin_lifecycle() selects the same paired hooks for recovery eligibility and suspension, preferring suspend/resume over the legacy hide/show pair. Plugins must stop receive timers when suspended or deactivated; a view without either paired lifecycle interface retains ownership and defers reconnection.

During recovery, navigation and plugin controls are disabled. One worker attempts the original endpoint at the original baud rate; USB metadata can locate renumbered interfaces. The original endpoint is preferred when available. If metadata is shared or the USB interface description changes, other matching interfaces are tried too, and each failed attempt logs its reason. The hardware UID and original MAVLink system/component IDs must match before downloading fresh parameters. This prevents a routed version message from the original FC from authorizing a different target. Changed or unknown IDs, connection failures and incomplete downloads leave the editor waiting and retrying. A missing original UID disables automatic recovery. Hardware identification uses uid2, falling back to uid, as decoded by the connection manager.

Refresh downloads use temporary files. Local parameter edits and the selected step remain intact; interrupted uploads and commands are never replayed. The editor resumes the plugin after a verified recovery. Closing cancels retries, waits for an in-flight worker to return from backend I/O and removes only the editor’s observer hook. The coordinator retains control ownership until that worker yields, discards late success after cancellation, and never resumes the plugin while closing. Recovery passes its cancellation event through the parameter facade to both download protocols. MAVLink reception checks cancellation in short (at most 100 ms) receive slices; only new parameter names renew its no-progress deadline, so repeated replies cannot retain ownership indefinitely. MAVFTP checks cancellation inside its reply loop and performs session cleanup on the worker before yielding. Normal transport-specific download budgets remain unchanged. A single pending-close chain keeps Tk responsive, displays the shutdown wait status, and offers to save only after the worker exits.

Parameters Manager

Commands Manager

Files Manager

Protocol Definitions

Business Logic Functions

MAVFTP Utilities

Flight Controller Info Backend

Flight Controller ID data_model

Connection Selection UI

Flight Controller Info UI

Data Flow

  1. Application Startup and Connection Initialization
    • Called from __main__.py via connect_to_fc_and_set_vehicle_type() function
    • FlightController facade created with dependency injection support
    • Connection manager initialized with FlightControllerInfo instance
    • Params, commands, and files managers initialized with protocol references
    • discover_connections() delegates to connection manager for port detection
    • If connection fails, ConnectionSelectionWindow is displayed for manual selection
  2. Connection Establishment Phase
    • User selects connection via GUI or auto-detection attempts first available
    • FlightController.connect() delegates to connection_manager.connect()
    • Connection manager handles retry logic via create_connection_with_retry()
    • Heartbeat detection via _detect_vehicles_from_heartbeats()
    • Autopilot selection via _select_supported_autopilot()
    • Connection manager mutates FlightControllerInfo (sole mutator)
    • Connection validation via heartbeat and banner text reception
  3. Hardware Information Gathering
    • Connection manager requests AUTOPILOT_VERSION message
    • _retrieve_autopilot_version_and_banner() processes responses
    • Hardware capabilities extracted via _process_autopilot_version()
    • Firmware version, board type, and capabilities stored in FlightControllerInfo
    • Banner text parsed for firmware type via _extract_firmware_type_from_banner()
    • ChibiOS version validated via _extract_chibios_version_from_banner()
  4. Parameter Operations Phase
    • FlightController.download_params() delegates to params manager
    • Params manager checks MAVFTP support via info.is_mavftp_supported
    • Attempts MAVFTP download first, falls back to MAVLink if unavailable
    • Progress tracking through callbacks to update GUI
    • Parameters stored in params_manager.fc_parameters dictionary
    • Default parameters downloaded separately when MAVFTP available
    • Commands manager queries params manager for fresh parameter values (no caching)
  5. Command Execution Flow
    • FlightController.test_motor() delegates to commands manager
    • Commands manager queries params manager for battery parameters
    • send_command_and_wait_ack() handles MAVLink command protocol
    • Battery readings retrieved via get_battery_statuses() with independent caching and expiry per battery ID
    • Voltage thresholds calculated via business logic functions
    • All operations check master is not None before execution
  6. UI Updates and Status Reporting
    • Real-time progress updates via ProgressWindow during operations
    • Error reporting through show_no_connection_error() and message boxes
    • Connection status feedback via GUI state changes and tooltips
    • Final status display in FlightControllerInfoWindow with formatted information
    • set_param() now returns tuple[bool, str] for explicit error handling

Integration Points

Protocol Implementation

Error Handling Strategy

Testing Strategy

Test Organization and Coverage

The flight controller communication system has comprehensive test coverage organized by testing approach:

Unit Tests (Mocked Dependencies)

  1. test_backend_flightcontroller.py - Main facade integration tests
    • Connection lifecycle workflows (initialization, connection, disconnection)
    • Parameter management workflows (download, modify, verify, reset)
    • Motor testing workflows (individual, all motors, emergency stop)
    • Battery monitoring workflows (enable, check status, verify configuration)
    • Error handling and recovery scenarios
    • All tests use @pytest.mark.integration for integration test scenarios
    • Uses BDD (Behavior-Driven Development) naming: test_user_can_*
    • GIVEN/WHEN/THEN structure in all test docstrings
  2. test_backend_flightcontroller_business_logic.py - Pure business logic tests
    • Voltage threshold calculations and battery monitoring detection
    • Frame information extraction and battery voltage validation
    • Battery telemetry conversions and throttle validation
    • Motor test duration validation and sequence number calculations
    • Zero mocking (pure functions) - fastest test execution
    • Comprehensive edge case coverage (boundaries, invalid inputs, missing data)
  3. test_backend_flightcontroller_connection.py - Connection manager tests
    • Connection manager initialization and port discovery
    • Connection lifecycle (connect/disconnect/reconnect)
    • Baudrate configuration and custom connection strings
    • Flight controller info management and property delegation
    • 14 tests covering all connection management scenarios
  4. test_backend_flightcontroller_params.py - Parameters manager tests
    • Parameter initialization and setting (with/without connection)
    • Parameter fetching from flight controller and cache retrieval
    • Cache clearing and constants validation (PARAM_FETCH_POLL_DELAY)
    • Property delegation and parameter downloads
    • File operations and error handling
    • 18 tests covering all parameter operations
  5. test_backend_flightcontroller_commands.py - Commands manager tests
    • Command manager initialization and motor testing
    • Battery status requests and parameter reset commands
    • Command acknowledgment waiting and timeout handling
    • Property delegation to connection manager
    • 10 tests covering all command execution scenarios
  6. test_backend_flightcontroller_files.py - Files manager tests
    • Files manager initialization and file uploads via MAVFTP
    • Log file downloads and MAVFTP availability handling
    • Progress callback support and constants validation
    • Property delegation and error handling
    • 11 tests covering all file operation scenarios

Integration Tests (Real SITL)

  1. test_backend_flightcontroller_sitl.py - Real MAVLink protocol tests
    • Uses @pytest.mark.integration and @pytest.mark.sitl markers
    • Real TCP connection to ArduCopter SITL simulation
    • Actual MAVLink protocol behavior (not mocked)
    • Tests validate:
      • Real parameter downloads via MAVLink PARAM_REQUEST_LIST/PARAM_VALUE
      • Authentic command acknowledgments (COMMAND_ACK with real timing)
      • True async communication patterns and timeout behavior
      • Actual telemetry streaming (BATTERY_STATUS messages)
      • Real parameter persistence in SITL memory
      • Genuine retry logic and error conditions
    • 12 tests exercising real protocol that mocks cannot simulate
    • Comprehensive module docstring explains “why SITL matters”
    • Each test documents what real behavior is validated vs mocked tests

Test Quality Metrics

Running Tests Selectively

# Run all flight controller tests
pytest tests/test_*flightcontroller*.py -v

# Run only unit tests (skip SITL integration tests)
pytest tests/test_*flightcontroller*.py -m "not sitl" -v

# Run only integration tests
pytest -m integration tests/ -v

# Run only SITL integration tests
pytest -m sitl tests/ -v

# Run with coverage for backend flight controller modules
pytest tests/test_*flightcontroller*.py --cov=ardupilot_methodic_configurator.backend_flightcontroller --cov-report=html

# Run specific test file
pytest tests/test_backend_flightcontroller_params.py -v

File Structure

# Facade and coordination
backend_flightcontroller.py              # Main facade delegating to managers

# Specialized managers (delegation pattern)
backend_flightcontroller_connection.py   # Connection management
backend_flightcontroller_params.py       # Parameter operations
backend_flightcontroller_commands.py     # Command execution
backend_flightcontroller_files.py        # File operations via MAVFTP

# Protocol definitions and utilities
backend_flightcontroller_protocols.py    # Protocol interfaces for DI
backend_flightcontroller_business_logic.py # Pure business logic functions
backend_flightcontroller_factory_mavftp.py # MAVFTP factory functions

# Data models and supporting files
data_model_flightcontroller_info.py      # Flight controller metadata
backend_mavftp.py                        # FTP-over-MAVLink implementation
data_model_fc_ids.py                     # Hardware identification (auto-generated)

# User interface
frontend_tkinter_connection_selection.py # Connection selection GUI
frontend_tkinter_flightcontroller_info.py # Information display GUI

Dependencies