Skip to content

Generalize motor wizard for variable motor counts#2580

Open
sensei-hacker wants to merge 8 commits intoiNavFlight:maintenance-9.xfrom
sensei-hacker:motor-wizard-no-msp
Open

Generalize motor wizard for variable motor counts#2580
sensei-hacker wants to merge 8 commits intoiNavFlight:maintenance-9.xfrom
sensei-hacker:motor-wizard-no-msp

Conversation

@sensei-hacker
Copy link
Member

@sensei-hacker sensei-hacker commented Mar 1, 2026

Redesigns the motor mixer wizard from a dropdown-based interface to a guided step-by-step flow, making motor identification more intuitive and less error-prone. Motors are identified by briefly spinning each one in turn — no firmware changes required.

image

New wizard UI with three screens:
Intro screen with safety checklist
Progress screen with visual step indicators and position buttons
Completion screen with apply button
Uses MSP_SET_MOTOR to briefly pulse each motor for identification — no firmware changes needed, works with any protocol
Position buttons show visual feedback (blue=waiting, green=assigned)
Auto-advances through motors with 2-second locate cycles
Emergency stop button halts motor pulses immediately
Button positions adapt to quad-X (corners) and quad-plus (cardinal edges) layouts
Modal size increased to 500x560 to avoid scrolling

Supports tricopter (3), quad (4), hex (6), and octo flat (8) presets.


Diagram Walkthrough

flowchart LR
  A["Mixer Preset Selected"] -->|Check WIZARD_MOTOR_POSITIONS| B["Wizard Supported?"]
  B -->|Yes| C["Show Wizard UI"]
  B -->|No| D["Hide Wizard"]
  C --> E["User Clicks Start"]
  E --> F["Disable DShot Beeper"]
  F --> G["Pulse Motor 1"]
  G --> H["User Clicks Position"]
  H --> I["Record Mapping"]
  I --> J{All Motors Done?}
  J -->|No| K["Pulse Next Motor"]
  K --> H
  J -->|Yes| L["Show Complete Screen"]
  L --> M["User Clicks Apply"]
  M --> N["Build Motor Rules"]
  N --> O["Restore DShot Beeper"]
  O --> P["Close Modal"]
Loading

File Walkthrough

Relevant files
Configuration changes
MSPCodes.js
Add motor locate MSP code                                                               

js/msp/MSPCodes.js

  • Add MSP2_INAV_MOTOR_LOCATE (0x2042) MSP code definition
+2/-0     
Enhancement
MSPHelper.js
Add motor locate MSP helper                                                           

js/msp/MSPHelper.js

  • Add handler for MSP2_INAV_MOTOR_LOCATE response (single byte:
    1=success, 0=failure)
  • Add sendMotorLocate() function to send motor locate command with motor
    index
+9/-1     
mixer.js
Rewrite motor wizard with dynamic multi-preset support     

tabs/mixer.js

  • Add WIZARD_MOTOR_POSITIONS lookup table with SVG arm-tip coordinates
    for 9 presets (quad_x, quad_p, vtail_quad, atail_quad, hex_x, hex_p,
    octo_flat_x, octo_flat_p, tri)
  • Replace hardcoded dropdown-based wizard with guided step-by-step flow
    using state machine (wizardState)
  • Implement motor pulsing via sendMotorValues() with safety-first 20ms
    twitch pattern (three twitches per 800ms cycle)
  • Add dynamic progress step generation and position button creation
    based on motor count
  • Implement delegated click handler on .wizard-motor-preview for
    dynamically generated position buttons
  • Add DShot beeper disable/restore logic around wizard execution
  • Update motor preview positioning logic to support quad_p (Plus
    configuration) with centered motors
  • Update wizard visibility toggle to check WIZARD_MOTOR_POSITIONS
    instead of hardcoded preset ID
  • Add onOpen and onClose callbacks to modal for initialization and
    cleanup
+252/-41
mixer.html
Redesign wizard HTML for dynamic motor counts                       

tabs/mixer.html

  • Replace hardcoded dropdown table with three wizard sections: intro,
    progress, and complete
  • Add dynamic progress bar container (steps generated by JavaScript)
  • Add motor preview area with dynamically generated position buttons
  • Add Emergency Stop button (red warning style)
  • Remove hardcoded HTML for 4 motors and old wizard-execute-button
+43/-56 
main.css
Add warning button style                                                                 

src/css/main.css

  • Add .modal__button--warning style for Emergency Stop button (red
    background #e74c3c)
  • Add hover and active states for warning button
+16/-0   
mixer.css
Add motor wizard CSS styles                                                           

src/css/tabs/mixer.css

  • Add comprehensive wizard styling: sections, checklist, prompt text
  • Add progress bar with circular step indicators (active=red,
    complete=green)
  • Add motor preview container and position button styles (waiting=blue
    glow, assigned=green)
  • Add pulse and glow animations for visual feedback
  • Add wizard button container styling
+134/-0 
Documentation
messages.json
Add wizard i18n translations                                                         

locale/en/messages.json

  • Change modal title from "Quadcopter Mixer Wizard" to "Motor Mixer
    Wizard"
  • Add new i18n keys for wizard flow: intro, steps 1-3, locating prompt,
    completion message
  • Add keys for Start Wizard and Emergency Stop buttons
  • Add helper text keys for motor identification hints
+34/-1   

sensei-hacker and others added 7 commits January 7, 2026 12:05
Redesign motor wizard from dropdown-based UI to guided step-by-step flow:

- Add MSP2_INAV_MOTOR_LOCATE (0x2042) support for motor spin identification
- New wizard UI with intro screen, progress indicators, and completion screen
- Position buttons show assigned motors with visual feedback
- Auto-advances through motors with 2-second locate cycles
- Buttons placed inside sections for proper show/hide behavior

Requires firmware support for MSP2_INAV_MOTOR_LOCATE command.
- Add stopMotors() function that sends motor index 255 to stop locate
- Add Emergency Stop button (red) visible during wizard operation
- Call stopMotors() when:
  - User clicks a position (between motors)
  - User clicks Emergency Stop button
  - Modal closes for any reason
  - Wizard is reset
- Add warning button CSS style (modal__button--warning)
- Add i18n translation for stop button

Addresses Qodo review feedback about proper motor cleanup.
- Add idempotent check to start button (ignore if wizard already active)
- Clear existing interval in startLocatingMotor() before creating new one

Prevents multiple polling loops if user double-clicks start button.
Remove dependency on unreleased firmware command MSP2_INAV_MOTOR_LOCATE
(0x2042) by using standard MSP_SET_MOTOR (214) to pulse motors for
identification. This makes the wizard backward-compatible with any 9.x
firmware without requiring a firmware-side PR.

Motor identification uses a safety-first pulsing pattern: three 20ms
twitches at 15% throttle with 20ms gaps, repeating every 800ms. A 10ms
interval timer defaults to OFF unless inside an ON window, ensuring
motors cannot run away if timing drifts.

DShot beeper is temporarily disabled during the wizard to prevent all
motors twitching, and restored when the wizard closes.
The motor wizard was hardcoded for exactly 4 motors (quad only).
Extend it to support tricopter (3), quad (4), hex (6), and octo (8)
presets by driving the progress steps and position buttons from a
SVG coordinate table keyed by mixer preset image name.

- Add WIZARD_MOTOR_POSITIONS lookup table with arm-tip coordinates
  for 9 presets (quad_x, quad_p, vtail_quad, atail_quad, hex_x,
  hex_p, octo_flat_x, octo_flat_p, tri)
- Replace positionWizardButtons() with buildPositionButtons(positions)
  that dynamically creates buttons at SVG-coordinate-derived pixel offsets
- Update resetWizard() to accept numMotors and regenerate progress steps
- Switch click handler to delegated event on .wizard-motor-preview to
  support dynamically generated buttons
- Update completion check and apply loop from hardcoded 4 to
  currentMixerPreset.motorMixer.length
- Update wizard visibility check from hardcoded preset IDs to
  WIZARD_MOTOR_POSITIONS.hasOwnProperty() lookup
- Add null guard in onOpen callback for safety
- Remove hardcoded wizard-progress-step and wizard-position-btn divs
  from mixer.html (now JS-generated)
- Remove hardcoded #wizardPos0-3 CSS position rules (positions now
  set inline by buildPositionButtons)
- Rename modal title from "Quadcopter Mixer Wizard" to "Motor Mixer
  Wizard" in locale/en/messages.json

Coaxial presets (octo_x8, y4, y6) intentionally omitted from the
coordinate table — their wizard button remains hidden since stacked
motors share physical positions and cannot be visually distinguished.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@sensei-hacker sensei-hacker added Enhancement Enhancement of existing functions Testing required labels Mar 1, 2026
@qodo-code-review
Copy link
Contributor

qodo-code-review bot commented Mar 1, 2026

PR Compliance Guide 🔍

All compliance sections have been disabled in the configurations.

Remove the MSP2_INAV_MOTOR_LOCATE code constant, response handler, and
sendMotorLocate helper since the motor wizard was refactored to use
MSP_SET_MOTOR for motor identification.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant