MethodicConfigurator

Motor Test Sub-application Architecture

Status Legend

Overview

The Motor Test sub-application provides a graphical interface for testing individual motors on ArduPilot vehicles, similar to Mission Planner’s motor test functionality. It allows users to test motor functionality, verify motor order and direction, and configure motor parameters before flight.

Requirements Analysis

Functional Requirements

  1. Frame Configuration Interface
    • βœ… FRAME_TYPE dropdown populated from parameter documentation metadata
    • βœ… Immediate parameter application to flight controller on selection
    • βœ… Dynamic motor count calculation based on frame configuration
    • βœ… Motor diagram display showing the currently selected frame configuration
    • βœ… SVG motor diagrams loaded from local images directory (downloaded from ArduPilot documentation)
      • The original diagrams are the .svg files in the https://ardupilot.org/copter/_images/ directory
  2. Motor Parameter Configuration
    • βœ… β€œSet Motor Spin Arm” button with parameter dialog for MOT_SPIN_ARM
    • βœ… β€œSet Motor Spin Min” button with parameter dialog for MOT_SPIN_MIN
    • βœ… Immediate parameter save and upload to flight controller
    • βœ… Current value display and validation
  3. Motor Testing Interface
    • βœ… Display N motor test buttons based on detected/configured frame
    • βœ… Label buttons with letters (A, B, C, D…) following ArduPilot conventions
    • βœ… Expected direction labels (CW/CCW) for each motor position
    • βœ… Detected order dropdown comboboxes for user feedback
    • βœ… Configurable test duration (default: 2 seconds)
    • βœ… Real-time BATT1 voltage and current display with color-coded status
  4. Battery Status Display
    • βœ… Current BATT1 voltage and current readings (only when BATT_MONITOR != 0)
    • βœ… When BATT_MONITOR == 0: Display β€œN/A”
    • βœ… Color-coded voltage display based on BATT_ARM_VOLT and MOT_BAT_VOLT_MAX thresholds:
      • Green: Voltage within BATT_ARM_VOLT to MOT_BAT_VOLT_MAX range (safe for motor testing)
      • Red: Voltage outside the safe range (unsafe for motor testing)
    • βœ… Safety popup when motor testing attempted with voltage outside safe range
    • βœ… Real-time updates during motor testing operations
  5. Safety Controls
    • βœ… Prominent red β€œStop all motors” emergency button
    • βœ… β€œTest in Sequence” button for automated testing
    • βœ… Safety warnings and operational guidelines at top
    • βœ… Parameter validation before motor testing
    • βœ… Automatic motor timeout for safety
  6. Order Detection and Validation
    • βœ… User-selectable β€œDetected” comboboxes for each motor
    • 🟑 Comparison between expected and detected motor order
    • βœ… Visual feedback for correct/incorrect motor placement
    • 🟑 Guidance for correcting wiring issues

Non-Functional Requirements

  1. Safety
    • Multiple safety warnings prominently displayed
    • Clear indication of active motor testing
    • Emergency stop functionality always accessible
    • Safe parameter defaults and validation
  2. Usability
    • Intuitive frame-based layout with logical workflow progression
    • Clear visual feedback for active operations
    • Immediate parameter application with confirmation
    • Responsive UI with real-time feedback
    • Keyboard shortcuts for critical functions
  3. Reliability
    • Active flight controller connection required for all motor testing operations
    • Robust error handling for communication failures
    • Parameter validation and bounds checking
    • Graceful degradation when features unavailable
    • Comprehensive logging for debugging
  4. Performance
    • Responsive UI updates during motor testing
    • Efficient parameter reading/writing
    • Minimal latency for emergency stop operations
    • Low resource usage

System Design

Architecture Pattern

The motor test sub-application follows the Model-View separation pattern established in the project:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   GUI Layer     β”‚    β”‚   Data Model Layer   β”‚
β”‚                 β”‚    β”‚                      β”‚
β”‚ frontend_tkinter│◄──►│ data_model_motor     β”‚
β”‚ _motor_test.py  β”‚    β”‚ _test.py             β”‚
β”‚                 β”‚    β”‚                      β”‚
β”‚ - UI Layout     β”‚    β”‚ - Business Logic     β”‚
β”‚ - Event Handlingβ”‚    β”‚ - Parameter Mgmt     β”‚
β”‚ - User Feedback β”‚    β”‚ - Frame Detection    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                β”‚
                                β–Ό
                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                β”‚         Backend Layer                 β”‚
                β”‚                                       β”‚
                β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
                β”‚ β”‚ backend_flightcontroller.py         β”‚
                β”‚ β”‚ - Motor test commands (individual,   β”‚
                β”‚ β”‚   all, sequence, emergency stop)    β”‚
                β”‚ β”‚ - Battery monitoring & safety        β”‚
                β”‚ β”‚ β”‚ - Frame detection & motor count    β”‚
                β”‚ β”‚ - MAVLink communication              β”‚
                β”‚ β”‚ - Parameter read/write               β”‚
                β”‚ └──────────────────────────────────────
                β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
                β”‚ β”‚ backend_filesystem.py                β”‚
                β”‚ β”‚ - Safety validation logic            β”‚
                β”‚ β”‚ - Frame configuration support        β”‚
                β”‚ β”‚ - Parameter documentation metadata   β”‚
                β”‚ └──────────────────────────────────────
                β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
                β”‚ β”‚ backend_filesystem_program_settings.py β”‚
                β”‚ β”‚ - Motor diagram SVG file access      β”‚
                β”‚ β”‚ - Settings persistence (test duration)β”‚
                β”‚ β”‚ - Application configuration          β”‚
                β”‚ └──────────────────────────────────────
                β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Component Responsibilities

Data Model Layer (data_model_motor_test.py)

Primary Responsibilities:

Key Methods:

def __init__(self, flight_controller: FlightController, filesystem: LocalFilesystem, settings: ProgramSettings) -> None
def get_motor_count(self) -> int
def get_motor_labels(self) -> list[str]
def get_motor_numbers(self) -> list[int]
def get_motor_directions(self) -> list[str]  # Returns CW/CCW direction labels for each motor
def get_battery_status(self) -> Optional[tuple[float, float]]  # voltage, current or None if BATT_MONITOR == 0
def get_voltage_status(self) -> str  # "safe", "critical" "unavailable" or "disabled"
def is_battery_monitoring_enabled(self) -> bool  # True if BATT_MONITOR != 0
def is_motor_test_safe(self) -> tuple[bool, str]  # (is_safe, reason)
def set_parameter(self, param_name: str, value: float) -> tuple[bool, str]  # (success, error_message)
def get_parameter(self, param_name: str) -> Optional[float]
def test_motor(self, motor_number: int, throttle_percent: int, timeout_seconds: int) -> tuple[bool, str]
def test_all_motors(self, throttle_percent: int, timeout_seconds: int) -> tuple[bool, str]
def test_motors_in_sequence(self, throttle_percent: int, timeout_seconds: int) -> tuple[bool, str]
def stop_all_motors(self) -> tuple[bool, str]
def get_motor_diagram_path(self) -> tuple[str, str]  # Returns (filepath, description)
def motor_diagram_exists(self) -> bool
def get_test_duration(self) -> float
def set_test_duration(self, duration: float) -> bool
def get_test_throttle_pct(self) -> int
def set_test_throttle_pct(self, throttle: int) -> bool
def update_frame_configuration(self, frame_class: int, frame_type: int) -> tuple[bool, str]
def get_frame_options(self) -> dict[str, dict[int, str]]
def refresh_connection_status(self) -> bool
def get_voltage_thresholds(self) -> tuple[float, float]  # Returns (BATT_ARM_VOLT, MOT_BAT_VOLT_MAX)

Data Attributes:

Backend Layer Distribution

The motor test sub-application backend logic is distributed across three specialized backend modules:

backend_flightcontroller.py - Flight Controller Communication

Responsibilities:

Key Motor Test Methods:

def test_motor(self, motor_number: int, throttle_percent: int, timeout_seconds: int) -> tuple[bool, str]
def test_all_motors(self, throttle_percent: int, timeout_seconds: int) -> tuple[bool, str]
def test_motors_in_sequence(self, throttle_percent: int, timeout_seconds: int) -> tuple[bool, str]
def stop_all_motors(self) -> tuple[bool, str]
def get_battery_status(self) -> tuple[Union[tuple[float, float], None], str]
def get_voltage_thresholds(self) -> tuple[float, float]
def is_battery_monitoring_enabled(self) -> bool
def get_frame_info(self) -> tuple[int, int]
def get_motor_count_from_frame(self) -> int
backend_filesystem.py - Safety & Parameter Support

Responsibilities:

backend_filesystem_program_settings.py - Diagrams & Settings

Responsibilities:

Key Motor Test Methods:

@staticmethod
def motor_diagram_filepath(frame_class: int, frame_type: int) -> str
@staticmethod
def motor_diagram_exists(frame_class: int, frame_type: int) -> bool
# Settings persistence methods (protected methods for test duration, etc.)

GUI Layer (frontend_tkinter_motor_test.py)

Primary Responsibilities:

Key UI Components:

Layout Structure:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Information & Safety Warnings                               β”‚
β”‚ β€’ Remove propellers before testing                          β”‚
β”‚ β€’ Ensure vehicle is secured                                 β”‚
β”‚ β€’ Emergency stop always available                           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 1. Frame configuration                                      β”‚
β”‚ Frame Type: [FRAME_TYPE β–Ό]  Frame Class: [FRAME_CLASS β–Ό]   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 2. Arm and min throttle configuration                      β”‚
β”‚ [Set Motor Spin Arm] [Set Motor Spin Min]                  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 3. Motor order/direction configuration                     β”‚
β”‚ Duration: [____] seconds    Battery: 12.4V/2.1A            β”‚
β”‚                                                             β”‚
β”‚ [Motor A] Motor 1 CW  [Detected: β–Ό]                       β”‚
β”‚ [Motor B] Motor 2 CCW [Detected: β–Ό]                       β”‚
β”‚ [Motor C] Motor 3 CCW [Detected: β–Ό]                       β”‚
β”‚ [Motor D] Motor 4 CW  [Detected: β–Ό]                       β”‚
β”‚ ...                                                         β”‚
β”‚                                                             β”‚
β”‚ [πŸ›‘ STOP ALL MOTORS] [Test in Sequence]                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Data Flow

User Workflow Sequence

  1. Safety Setup
    • User reads safety warnings and ensures propellers are removed
    • User secures vehicle to prevent movement during tests
  2. Frame Configuration
    • User selects appropriate FRAME_TYPE from dropdown (populated from parameter documentation)
    • Parameters are immediately applied to flight controller on selection
  3. Motor Parameter Configuration
    • User clicks β€œSet Motor Spin Arm” to configure MOT_SPIN_ARM parameter
    • User clicks β€œSet Motor Spin Min” to configure MOT_SPIN_MIN parameter
    • Each button opens parameter dialog and saves/uploads value immediately
  4. Motor Testing and Order Detection
    • User monitors real-time battery voltage and current display (if BATT_MONITOR != 0)
    • User sets throttle % (default: 1%)
    • User sets test duration (default: 2 seconds)
    • User tests individual motors using labeled buttons (Motor A, B, C, etc.)
    • User observes actual motor spinning and records in β€œDetected” comboboxes
    • System provides color-coded voltage feedback (green=safe, red=outside safe range)
    • Safety popup appears when attempting motor test with voltage outside BATT_ARM_VOLT to MOT_BAT_VOLT_MAX range
    • User can run β€œTest in Sequence” to automatically test all motors
    • Emergency stop button available at all times during testing
  5. Order Validation
    • System compares expected vs detected motor order
    • User corrects any wiring issues based on feedback
    • System provides guidance on proper motor/ESC connections

Motor Testing Workflow

  1. Initialization: GUI requests motor count and labels from data model
  2. Frame Detection: Data model reads FRAME_CLASS/FRAME_TYPE parameters
  3. Battery Monitoring: Data model reads BATT1 voltage/current and BATT_ARM_VOLT/MOT_BAT_VOLT_MAX thresholds (if BATT_MONITOR != 0)
  4. UI Setup: Dynamic button creation based on detected frame configuration
  5. Battery Validation: System checks voltage status before allowing motor tests
  6. User Action: User clicks motor test button
  7. Safety Validation: Data model validates parameters, battery status (if enabled), and safety conditions
  8. Execution: Motor command sent to flight controller via backend
  9. Feedback: UI updates to show active motor testing status and battery monitoring
  10. Completion: Automatic timeout or user stop action

Battery Safety Validation Workflow

  1. Motor Test Request: User clicks any motor test button
  2. Battery Monitor Check: Data model checks if BATT_MONITOR != 0
  3. Voltage Range Check: If battery monitoring enabled, validate voltage is within BATT_ARM_VOLT to MOT_BAT_VOLT_MAX range
  4. Safety Popup: If voltage outside safe range, display popup: β€œBattery voltage outside safe range. Please connect battery and/or ensure battery is in charged state.”
  5. User Action: User can choose to:
    • Cancel motor test and address battery issue
    • Override and proceed (with additional warning)
  6. Test Execution: Motor test proceeds only if voltage is safe or user explicitly overrides

Parameter Configuration Workflow

  1. Frame Selection: User selects FRAME_TYPE from dropdowns
  2. Immediate Application: Parameters uploaded to flight controller immediately
  3. Parameter Button: User clicks β€œSet Motor Spin Arm/Min” button
  4. Current Value: Data model reads current parameter value
  5. User Input: GUI presents input dialog with current value
  6. Validation: Data model validates new parameter value
  7. Update: Parameter uploaded to flight controller
  8. Confirmation: UI confirms successful parameter update

Testing Strategy

Current Test Coverage Status

Data Model Tests (tests/test_data_model_motor_test.py) - βœ… IMPLEMENTED

Status: 54 comprehensive BDD pytest tests implemented covering all functionality

Test Coverage Areas:

GUI Tests (tests/test_frontend_tkinter_motor_test.py) - ❌ NOT IMPLEMENTED

Status: Frontend tests not yet implemented

Planned Test Coverage:

Integration Testing

End-to-End Scenarios

Mock Testing Strategy

Test Fixtures and Patterns

Following project pytest guidelines with BDD structure:

@pytest.fixture
def mock_flight_controller() -> MagicMock:
    """Fixture providing mocked flight controller with realistic responses."""

@pytest.fixture
def motor_test_data_model(mock_flight_controller) -> MotorTestDataModel:
    """Fixture providing configured motor test data model."""

@pytest.fixture
def motor_test_window(motor_test_data_model) -> MotorTestWindow:
    """Fixture providing configured motor test GUI window."""

def test_user_can_test_individual_motor(self, motor_test_window) -> None:
    """
    User can test individual motors safely.

    GIVEN: A configured vehicle with detected frame type
    WHEN: User clicks a motor test button
    THEN: The corresponding motor should activate with feedback
    """

Implementation Guidelines

Code Style Requirements

  1. Type Hints: All functions must include complete type annotations
  2. Documentation: Comprehensive docstrings following project standards
  3. Error Handling: Graceful error handling with user feedback
  4. Logging: Appropriate logging for debugging and audit trail
  5. Internationalization: All user-facing strings wrapped with _()

Safety Implementation

  1. Parameter Validation: All parameters validated before sending to FC
  2. Battery Monitoring: Real-time battery voltage monitoring with BATT_ARM_VOLT/MOT_BAT_VOLT_MAX threshold validation (when BATT_MONITOR != 0)
  3. Voltage Safety: Safety popup when attempting motor test with voltage outside safe range, prompting user to connect battery and/or ensure charged state
  4. Timeout Mechanisms: Automatic motor stop after configured timeout
  5. Emergency Stop: Always accessible stop functionality
  6. User Confirmation: Display a Safety confirmation popup the first time a Motor test button is pressed
  7. Visual Feedback: Clear indication of active motor testing (status column) and battery status (green/red voltage display)

Performance Considerations

  1. Lazy Loading: UI components created only when needed
  2. Efficient Updates: Minimal UI updates during motor testing
  3. Resource Management: Proper cleanup of timers and connections
  4. Responsive Design: Non-blocking operations for UI responsiveness

Integration Points

Main Application Integration

The motor test sub-application integrates with the main ArduPilot Methodic Configurator through:

  1. Menu Integration: Accessible from dedicated button
  2. Flight Controller Sharing: Uses existing FC connection
  3. Parameter Context: Reads current vehicle configuration (LocalFilesystem)
  4. Logging Integration: Uses application logging framework
  5. Settings Persistence: Saves user settings (test duration in ProgramSettings)

Backend Architecture Integration

The motor test sub-application leverages the existing backend infrastructure without requiring additional backend modules:

Flight Controller Backend Integration (backend_flightcontroller.py)

Filesystem Backend Integration (backend_filesystem.py)

Program Settings Integration (backend_filesystem_program_settings.py)

This architecture demonstrates the project’s modular design - new sub-applications can be implemented by primarily creating frontend and data model layers while leveraging the robust, tested backend infrastructure that already exists.

ArduPilot Integration

Communication with ArduPilot flight controller via:

  1. MAVLink Protocol: Standard parameter and command protocols
  2. Parameter System: Read/write MOT_* parameters
  3. Motor Commands: Direct motor control via MAVLink
  4. Status Monitoring: Real-time status and safety monitoring
  5. Frame Detection: Automatic vehicle configuration detection

Future Enhancements

Planned Features

  1. Motor Health Monitoring: Current draw and performance metrics
  2. Calibration Assistance: Guided motor calibration procedures
  3. Visual Frame Display: Graphical representation of motor layout

Security Considerations

Safety Measures

  1. Parameter Bounds: Strict validation of all motor parameters

Risk Mitigation

  1. Hardware Safety: Clear warnings about propeller removal
  2. Software Safety: Multiple layers of safety checks
  3. Communication Safety: Robust error handling for comm failures
  4. User Safety: Clear operational guidelines and warnings

This architecture provides a comprehensive foundation for implementing a safe, reliable, and user-friendly motor test sub-application that integrates seamlessly with the ArduPilot Methodic Configurator while maintaining the highest safety standards for motor testing operations.