MAVLink and MSP command-control parity#11717
Open
xznhj8129 wants to merge 8 commits into
Open
Conversation
Contributor
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
This was referenced Jul 12, 2026
xznhj8129
force-pushed
the
mav/06-command-guided
branch
from
July 12, 2026 21:42
57cb25b to
fd1233f
Compare
xznhj8129
force-pushed
the
mav/06-command-guided
branch
from
July 14, 2026 14:07
fd1233f to
b25bb9f
Compare
xznhj8129
force-pushed
the
mav/06-command-guided
branch
from
July 19, 2026 01:19
b25bb9f to
efd562a
Compare
Rewritten mission protocol replacing the old ad-hoc counters (absent since the modular split): owned transfers tracking initiating system, component and ingress port; upload retries and timeouts; one-item retransmission; final MISSION_ACK; out-of-sequence recovery; explicit cancellation; legacy MISSION_REQUEST answered with MISSION_ITEM_INT. Uploads are staged and committed only on success, QGC planned-home item 0 is skipped, modifier items (speed/delay/altitude) fold onto the correct INAV waypoint, and persistence failures restore the previous mission. Successful uploads and clears update nonvolatile storage. Adds 1 Hz MISSION_CURRENT, active-item download flags, and MISSION_ITEM_REACHED broadcast from a navigation-side reached latch. Includes the live SITL mission test rig (src/test/mavlink/missions) and routing compliance harness (src/test/mavlink/routing). Unit slice: 58/58 passing. Mission translation to INAV's MSP waypoint model is lossy; downloads are best-effort reconstruction, not canonical mission backups.
Standalone 8-check pass/fail rig against a self-started SITL with the known-good multiport serial layout: MSP on UART1, MAVLink receiver telemetry and RC override on UART2, GCS heartbeat, mission upload and readback, stream-rate and message-rate control on UART3. Previously lived only in the development workspace and was never committed.
NAV_STATE_WAYPOINT_RTH_LAND success maps straight to NAV_STATE_WAYPOINT_FINISHED, bypassing NAV_STATE_WAYPOINT_NEXT where the reached latch is normally set, and a mission LAND item that hands off to the fixed-wing autoland FSM terminates in NAV_STATE_FW_LANDING_FINISHED without touching either path. In both cases a mission terminated by NAV_WP_ACTION_LAND never fired MISSION_ITEM_REACHED for its final item and MISSION_CURRENT stayed NOT_STARTED after touchdown. Mark the item in the simple-landing success branch, and in FW_LANDING_FINISHED when the autoland was entered from a mission LAND item (fwLandState.landWp), using landState to guard the self-looping re-entry. The aborted-landing paths intentionally do not mark.
…ad encoder MISSION_CLEAR_ALL now denies a sender that is not the owning partner of an in-progress transfer, matching MISSION_COUNT and MISSION_REQUEST_LIST; previously any local-target sender could cancel another partner's transfer mid-flight. Downloads always answer MISSION_ITEM_INT (per MAVLink deprecation guidance for MISSION_REQUEST), so the float MISSION_ITEM response encoder was unreachable - removed, with a comment explaining why legacy requests get INT replies. Upload-side float support is unaffected.
Two ways the completion signal could be lost or misreported: - mavlinkSendPendingMissionItemReached() consumed the one-slot reached latch before checking for an active port. A shared MAVLink port that closes on disarm right after landing destroyed the final item's MISSION_ITEM_REACHED and left missionCompleted false. Check for a delivery target first; the latch stays pending until a port can send. - MISSION_CURRENT ranked WP-mode activity above completion, and NAV_STATE_WAYPOINT_FINISHED still maps to NAV_WP_MODE, so a landed vehicle reported ACTIVE until the pilot left WP mode. Completion now outranks activity, and missionCompleted is cleared on the WP-mode rising edge so a re-flown mission reports ACTIVE, not stale COMPLETE.
Covers the fixes in the previous commits: - MISSION_CURRENT completion outranks WP-mode activity and clears on a fresh WP-mode engagement - the reached latch survives cycles with no active MAVLink port - MISSION_CLEAR_ALL from a non-owning sender is denied and leaves the owner's transfer usable; the owning sender can still cancel its own
- MAV_CMD_COMPONENT_ARM_DISARM and MSP2_INAV_ARM_DISARM through the normal arming path, succeeding only when the requested state is reached - RTH via a temporary BOXNAVRTH source on the RC mode selector (activateRTHMode) instead of the failsafe/geozone forced-RTH latch; wired to MAV_CMD_NAV_RETURN_TO_LAUNCH, ArduPilot DO_SET_MODE RTL, MSP2_INAV_ACTIVATE_RTH, and Programming Framework operation 61. Cleared by a pilot flight-mode change or disarm - QGC/ArduPilot pause: DO_SET_MODE Loiter/PosHold/Brake enters normal PosHold at the current position via a temporary BOXNAVPOSHOLD source - Normal current-position LAND (transient waypoint, uploaded mission untouched) via MAV_CMD_NAV_LAND, MSP2_INAV_ACTIVATE_LANDING, PF op 62 - MAV_CMD_DO_SET_HOME through the native waypoint-0 backend - MSP2_INAV_TIMESYNC returning the MAVLink TIMESYNC boot clock - Temporary fixed-wing loiter-radius override: DO_REPOSITION.param3 (meters) or int32 loiterRadius appended to MSP2_INAV_SET_GLOBAL_TARGET (cm); volatile, cleared on disarm/reboot, only active in PosHold - SET_POSITION_TARGET_GLOBAL_INT / _LOCAL_NED guided handling - MAV_CMD_CONDITION_YAW; explicit unsupported MAV_CMD_NAV_TAKEOFF stub - GCSN OSD flight-mode element while GCS navigation is active Unit slice: 81/81 passing.
A command-triggered landing (MAV_CMD_NAV_LAND / MSP direct land) borrows NAV_STATE_WAYPOINT_RTH_LAND and the FW autoland FSM with a transient waypoint, while activeWaypointIndex still points at whatever mission item was last active. The unconditional reached-marking added for mission LAND items would emit MISSION_ITEM_REACHED for that stale index and could mark a loaded mission complete. Capture forcedLandingActivated before the existing clears and skip the marking for commanded landings at both finish sites.
xznhj8129
force-pushed
the
mav/06-command-guided
branch
from
July 19, 2026 16:13
efd562a to
0cc2e89
Compare
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.
Part 6/7 of the mavlink_multiport2 stack.
Command-control parity between MAVLink, MSP, and the Programming Framework, so GCS and companion software can arm, navigate, and land through standard commands.
Arming
MAV_CMD_COMPONENT_ARM_DISARMandMSP2_INAV_ARM_DISARM(0x2227) go through the normal INAV arming/disarming path and ACK success only when the requested state is actually reached.RTH
MAV_CMD_NAV_RETURN_TO_LAUNCH, the ArduPilot-styleMAV_CMD_DO_SET_MODERTL request,MSP2_INAV_ACTIVATE_RTH(0x2225), and Programming Framework operation 61 all enter the normal INAV RTH mode path viaactivateRTHMode(), which adds a temporaryBOXNAVRTHsource to the RC mode selector. This deliberately does not use the failsafe/geozone forced-RTH latch — live testing showedactivateForcedRTH()is not equivalent to switching into RTH mode. The temporary source clears on a pilot RC flight-mode change or disarm, so a command-triggered RTH cannot survive into a later arming attempt.Pause / position hold
MAV_CMD_DO_SET_MODEalso accepts ArduPilot pause-style modes (PLANE_MODE_LOITER,COPTER_MODE_LOITER,COPTER_MODE_POSHOLD,COPTER_MODE_BRAKE) and enters normal INAV PosHold at the current position/altitude/heading via a temporaryBOXNAVPOSHOLDsource (this is what QGC's Pause button sends). Other GCS mode changes remainUNSUPPORTED.Landing
MAV_CMD_NAV_LAND,MSP2_INAV_ACTIVATE_LANDING(0x2224), and PF operation 62 perform a normal waypoint-style landing at the current position through a transient waypoint — the uploaded mission is not modified, and this is not emergency landing. Mission LAND items keep their supplied coordinates; direct LAND commands ignore coordinate fields.Home, time, guided
MAV_CMD_DO_SET_HOMEuses the existing waypoint-0 backend (param1 = 1= current GNSS position; explicit global location otherwise) and retains all native WP#0 safety gates. MSP set-home remainsMSP_SET_WPwaypoint 0 — no duplicate command added.MSP2_INAV_TIMESYNC(0x2228) returns the same monotonic nanosecond boot clock as MAVLinkTIMESYNC.SET_POSITION_TARGET_GLOBAL_INT/_LOCAL_NEDguided handling (waypoint 255 / altitude-only requests, gated on valid GCS navigation).MAV_CMD_CONDITION_YAWheading changes while the nav state has yaw control.MAV_CMD_DO_REPOSITION.param3in meters, orint32 loiterRadius(cm) appended toMSP2_INAV_SET_GLOBAL_TARGET(17-byte payload; 13-byte payload = no change; 0 clears).MSP2_INAV_NAV_TARGETreports the active override. Volatile: cleared on disarm/reboot, applied only while the nav FSM is in PosHold so RTH/mission/autoland loiter keeps configured defaults.MAV_CMD_NAV_TAKEOFFstub returningUNSUPPORTED(foundation for later takeoff work, no behavior introduced).GCSNwhile GCS-assisted navigation is actually active.All float command parameters are validated (finite/range) before integer conversion.
Companion PR:
mspapi2:mavlink_multiport2(synchronized message metadata + arm/RTH/land/timesync helpers).Testing
mavlink_unittest).