Multi GCS update#14560
Open
Davidsastresas wants to merge 17 commits into
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Updates QGroundControl’s multi-GCS operator-control support to align with the finalized MAV_CMD_REQUEST_OPERATOR_CONTROL / CONTROL_STATUS protocol by moving control-status handling into a dedicated manager, gating manual-control outputs, and expanding the toolbar UI and settings needed for multi-operator workflows.
Changes:
- Introduces
GCSControlManagerto own CONTROL_STATUS parsing, operator-control request/release flow, and role state exposed to QML. - Gates joystick/RC override output in
Vehiclebased on operator-control ownership. - Refreshes the toolbar indicator/panel UI, adds a persisted “secondary GCS IDs” setting, and updates bundled indicator artwork and MAVLink dependency pin.
Reviewed changes
Copilot reviewed 11 out of 17 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Vehicle/Vehicle.h | Exposes gcsControlManager to QML and adds an atomic gate setter for joystick output. |
| src/Vehicle/Vehicle.cc | Instantiates/routs control messages to GCSControlManager and gates joystick send paths. |
| src/Vehicle/GCSControlManager.h | New QObject/QML-facing manager API and properties for operator-control state and actions. |
| src/Vehicle/GCSControlManager.cc | Implements CONTROL_STATUS parsing, operator-control request/release, and takeover ACK handshake. |
| src/Vehicle/CMakeLists.txt | Adds new manager sources to the build. |
| src/Toolbar/GCSControlIndicator.qml | Reworks indicator UI for MAIN/SEC role display, roster, actions, and expanded settings UI. |
| src/Toolbar/CMakeLists.txt | Updates toolbar resource list to the new multi-GCS indicator SVGs. |
| src/Settings/FlyViewSettings.h | Adds operatorControlSecondaryGCS SettingFact. |
| src/Settings/FlyViewSettings.cc | Registers operatorControlSecondaryGCS SettingFact. |
| src/Settings/FlyView.SettingsGroup.json | Defines persisted operatorControlSecondaryGCS string setting metadata. |
| resources/gcscontrolIndicator/multigcs_lock_open.svg | New lock-open role glyph artwork. |
| resources/gcscontrolIndicator/multigcs_lock_closed.svg | New lock-closed role glyph artwork. |
| resources/gcscontrolIndicator/multigcs_line.svg | New “control relationship” line artwork. |
| resources/gcscontrolIndicator/multigcs_device.svg | New primary-role device glyph artwork. |
| resources/gcscontrolIndicator/multigcs_device_alt.svg | New secondary-role outlined device glyph artwork. |
| resources/gcscontrolIndicator/multigcs_aircraft.svg | New aircraft glyph artwork. |
| cmake/CustomOptions.cmake | Updates the pinned MAVLink git tag to a commit containing the finalized protocol. |
- Send the actual GCS sysid in param4 of MAV_CMD_REQUEST_OPERATOR_CONTROL (spec changed from #2158 to #2313; autopilot rejects param4=0), with optional param4/param5 range computed from configured secondary GCS ids - Gate MANUAL_CONTROL and RC override sends on operator control: block joystick output while another GCS is in control - Parse full CONTROL_STATUS (gcs_main + gcs_secondary[10]) and expose secondary GCS list to QML - Add release control support and secondary GCS range configuration UI to GCSControlIndicator - New persisted setting operatorControlSecondaryGCS (comma-separated secondary GCS sysids)
The request countdown could keep running (or restart from a stale value) after the request was already resolved: - The stop check in _handleControlStatus() missed the uncontrolled case: when the owning GCS releases control, CONTROL_STATUS arrives with gcs_main=0 and takeover not allowed, so neither stop condition matched. Add _sysid_in_control == 0 to the check. - The QML progress tracker only stopped on the takeover-allowed transition. Add watchers so it also stops when this GCS gains control or when the C++ side re-allows sending requests. - requestOperatorControlRemainingMsecs was declared CONSTANT but wraps QTimer::remainingTime(), so reopening the popup restored the countdown from a stale cached value. Tie it to sendControlRequestAllowedChanged instead. - releaseOperatorControl() left the request and takeover-revert timers running, firing stale signals after release. Stop them first. - A pending takeover revert also kept running when control moved to another GCS. Stop it on control loss in _handleControlStatus().
When takeover is not allowed, the autopilot forwards MAV_CMD_REQUEST_OPERATOR_CONTROL to the GCS in control as a notification. QGC showed the popup but never sent COMMAND_ACK, leaving the autopilot notification pending and the command unacknowledged at the MAVLink level. Reply with MAV_RESULT_ACCEPTED to the sender.
…onent The spec says a GCS should monitor for CONTROL_STATUS with the GCS_CONTROL_STATUS_FLAGS_SYSTEM_MANAGER flag and address MAV_CMD_REQUEST_OPERATOR_CONTROL to that component, which is not necessarily the autopilot. Learn the component id from CONTROL_STATUS and use it as the command target, falling back to the default component id until the first CONTROL_STATUS is seen.
_joystickSendAllowed was read and written with memory_order_relaxed. On weakly ordered architectures the store could in principle be observed by the joystick thread after other effects of the CONTROL_STATUS handling. Use release on the store and acquire on the loads so the gate change is properly ordered with the control status update that caused it.
The operator control request encodes secondary GCS as a contiguous sysid range, so non-contiguous configured ids (e.g. 200, 254) silently grant control to every id in between. Show a warning in the range configuration panel with the number of unconfigured ids the computed range would accept.
Replace the line/device/gcs icon set with a state-driven composition using new artwork (aircraft, line, solid/outlined device, open/closed lock): - aircraft (top-left): green when any GCS controls the vehicle - line (bottom-left): green only when this GCS has an operator role (its own control link) - role glyph (right), always white: solid device = primary, outlined device = secondary, lock when this GCS has no role - open when control is acquirable now (uncontrolled or takeover allowed), closed when a request is required - PRIM/SEC label shown in green when this GCS is primary/secondary The lock open/closed condition reuses controlGrantedImmediately, so it always agrees with the request button (Take Control / Acquire / Send Request). > Co-authored-by: alexdelatorre <alex.delatorre@lincesystems.com>
Replace the flat label list with a labelled status roster (Control status / Main GCS / Secondary GCS / Takeover), mark this GCS in each row, and move editable settings behind a More options expander with a control group toggle. Recognize a secondary's role even when the vehicle is uncontrolled (gcs_main == 0).
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
817d6ee to
47d0f04
Compare
Member
Author
Pending items after discussions in ArduPilot/ardupilot#33332 and ArduPilot/mavlink#503
|
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.
What this does
Brings QGC's GCS operator-control support up to the final MAV_CMD_REQUEST_OPERATOR_CONTROL / CONTROL_STATUS protocol (mavlink/mavlink#2313), succeeding the earlier work in #12410.
Long story short - Now multiple GCS can share a vehicle with one primary holding exclusive manual control; others are recognized secondaries and can send commands, missions, etc but not manual control. Adds the operator-control panel, request/release flow, takeover handshake, and a configurable secondary-GCS range.
Tested against peterbarker/ardupilot#46 in multi-GCS SITL (4× QGC + MAVProxy for routing).
Changes
Protocol / Vehicle
UI (GCSControlIndicator)
Settings
operatorControlSecondaryGCS(secondary sysids, comma- or space-separated).Some screenshots, Artwork and UI by @alexdelatorre
Top toolbar Icon, depending on status:
reduced popup, after single click, depending on status:
Command request from a GCS to the main GCS:
expanded panel with aditional options:
Secondary GCS input, detail of warning for user awareness: