Generalize motor wizard for variable motor counts#2580
Open
sensei-hacker wants to merge 8 commits intoiNavFlight:maintenance-9.xfrom
Open
Generalize motor wizard for variable motor counts#2580sensei-hacker wants to merge 8 commits intoiNavFlight:maintenance-9.xfrom
sensei-hacker wants to merge 8 commits intoiNavFlight:maintenance-9.xfrom
Conversation
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>
Contributor
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.
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_MOTORto briefly pulse each motor for identification — no firmware changes needed, works with any protocolPosition 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"]File Walkthrough
MSPCodes.js
Add motor locate MSP codejs/msp/MSPCodes.js
MSP2_INAV_MOTOR_LOCATE(0x2042) MSP code definitionMSPHelper.js
Add motor locate MSP helperjs/msp/MSPHelper.js
MSP2_INAV_MOTOR_LOCATEresponse (single byte:1=success, 0=failure)
sendMotorLocate()function to send motor locate command with motorindex
mixer.js
Rewrite motor wizard with dynamic multi-preset supporttabs/mixer.js
WIZARD_MOTOR_POSITIONSlookup table with SVG arm-tip coordinatesfor 9 presets (quad_x, quad_p, vtail_quad, atail_quad, hex_x, hex_p,
octo_flat_x, octo_flat_p, tri)
using state machine (
wizardState)sendMotorValues()with safety-first 20mstwitch pattern (three twitches per 800ms cycle)
based on motor count
.wizard-motor-previewfordynamically generated position buttons
configuration) with centered motors
WIZARD_MOTOR_POSITIONSinstead of hardcoded preset ID
onOpenandonClosecallbacks to modal for initialization andcleanup
mixer.html
Redesign wizard HTML for dynamic motor countstabs/mixer.html
progress, and complete
main.css
Add warning button stylesrc/css/main.css
.modal__button--warningstyle for Emergency Stop button (redbackground #e74c3c)
mixer.css
Add motor wizard CSS stylessrc/css/tabs/mixer.css
complete=green)
glow, assigned=green)
messages.json
Add wizard i18n translationslocale/en/messages.json
Wizard"
completion message