DRC controls — input + authority
Manual drone control in ARGUS is driven by a shared input-mapping layer
(controls-prefs.service.ts) that routes operator inputs through a transport
abstraction to the drone — handhelds, MAVLink aircraft, or DJI dock aircraft.
The same mapping works across all three; the transport layer handles the
protocol differences.
The control map
Bindings live in a ControlsMapping object in
Settings → Input controls. All bindings are
unbound by default — the system ships with an empty mapping so operators
explicitly bind what they want. This is intentional to avoid surprise
inputs.
The full set of bindable controls:
Flight commands
droneTakeoff— initiate auto-takeoff.droneLand— initiate auto-land.droneGoHome— send RTH.droneCancelTakeoff/droneCancelLand/droneCancelGoHome— cancel each of the above while they’re in progress.emergencyStop— ESTOP, full power cut. Use with extreme caution — the aircraft falls.
Authority grab (DJI DRC)
authorityGrabFlight— take DJI DRC Class-A flight authority.authorityGrabPayload— take DJI DRC Class-B payload (camera/gimbal) authority.
Authority is single-operator at a time. Grabbing while another operator holds triggers a force-grab confirmation in the UI.
Dock commands (DJI dock only)
dockCoverOpen/dockCoverClose— physical cover.poiModeToggle— start / stop DJI POI orbit mode.
Camera + gimbal
camLensChange— cycle lens (WIDE / ZOOM / IR).camTakePicture— shutter.camStartRecording/camStopRecording— video record toggle.droneFlyToPoint/takeoffToPoint— autonomous flight to a target.
UI / safety
masterCaution— acknowledge current critical alerts.
Analog axes (continuous-value inputs)
droneAxisPitch,droneAxisRoll,droneAxisYaw,droneAxisThrottle— flight-stick axes.gimbalAxisPitch,gimbalAxisYaw,gimbalAxisZoom— gimbal axes.
Each axis binds to a physical axis on a gamepad or a keyboard “digital axis” (two keys that flip a virtual stick hard left / hard right).
Gamepad support
The input layer detects gamepads via the browser Gamepad API + WebHID fallback for HOTAS controllers that don’t expose themselves as standard gamepads.
- Auto-detect — plug in a device, it appears in the input-controls page.
- Mode-2 default — if you accept the suggested mapping, it binds left stick to pitch/roll, right stick to yaw/throttle. Mode 1, 3, and 4 are available via manual re-mapping.
- Stick curve (expo) — per-axis expo value 0-1 via the stick-curve slider. 0 = linear, 1 = maximum expo. Most operators settle around 0.3.
- Preferred source —
preferredDroneInputSourcecan bewebhid,gamepad,native-bridge, orserial. If multiple sources are connected they all produce events; the preferred one wins.
Keyboard
Any control can bind to a keyboard key via the Settings → Input controls panel. Common bindings operators set themselves (none shipped out of the box):
- T — takeoff.
- L — land.
- H — return-to-home.
- Esc — release authority.
- Space — PTT (see PTT — already reserved by the PTT system; don’t rebind).
Safety envelope
The input layer clamps inputs before sending them to the transport:
- Stick saturation — every analog axis is clamped to
[-1.0, 1.0]. - Virtual-stick mode gate — if
isVirtualStickModeEnabledisfalseon the drone, flight-stick inputs are dropped before transmission; the aircraft rejects them anyway but the UI short-circuits. - Advanced mode —
isVirtualStickAdvancedModeEnabledunlocks extended flight-envelope commands (altitude-cap override, higher horizontal speeds). Admin-configurable. - Geofence / no-fly — the geofence safety pipeline clips inputs that would push the drone past a polygon boundary.
There is NOT currently a soft-clipping option (e.g. “50 % max throttle”) — the clamp is hard at ±1.0.
DRC authority flow (DJI dock only)
To manually fly a DJI dock aircraft via DRC:
- Select the drone in the fleet tile. The tile binds to it.
- Grab authority — click Take control in the drone-stream toolbar, or
trigger the
authorityGrabFlightbound input. ARGUS publishesdrc_grab_authority. If someone else is flying, a confirmation dialog offers force-grab or wait. - Heartbeat starts — the DjiCloudControlTransport begins sending a 1 Hz heartbeat command to keep the DRC session alive. Pauses when the browser tab is hidden (no wasted bandwidth) but the session expires after ~60 s of silence.
- Fly — your input axes + button commands stream to the drone. The heartbeat keeps running.
- Release — hit the bound
Releasekey, close the drone-stream tile, or navigate away. ARGUS publishesdrc_release_authorityto hand authority back.
If the heartbeat stalls (tab crashed, network dropped), the dock’s flight-controller-layer DRC session times out autonomously and the aircraft hovers in place — it doesn’t crash.
Camera controls via DRC
- Gimbal aim — the two gimbal axes (pitch / yaw) plus zoom; gimbal pose tracks axis values in near-real-time.
- Lens change —
camLensChangecycles through available lenses. - Photo —
camTakePicturetriggers a single shot. - Record —
camStartRecording/camStopRecordingtoggle. - Look-at a point on the map — right-click a map point → Look at this point. Dispatches an absolute-gimbal-pose command so the gimbal aims at the coordinate.
- Fly-to a point — right-click the map → Fly to here. Dispatches
droneFlyToPoint.
The peer identity for DJI DRC
When the drone-stream tile is in djiCloud mode, commands flow via the
DjiCloudControlTransport. That transport uses peer
id dji-dock-{sn} (the same peer id the LivekitParticipantManager uses
on the argus-dji side) so the dock’s telemetry + control streams share one
identity.
Known limitations
- No curve-profile per-control — one stick-curve slider applies to all flight axes. Per-axis curves are planned.
- No “soft cap” on throttle / yaw / roll — only the hard ±1.0 clamp.
- No joystick deadband editor — relies on each device’s natural deadband.
Related
- Input controls — the bindings UI.
- Stream tile — where the DRC authority chip lives.
- Geofence safety — how the safety envelope interacts with polygons.
- DJI DRC — DJI-specific DRC details.