Skip to content

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 sourcepreferredDroneInputSource can be webhid, gamepad, native-bridge, or serial. 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 isVirtualStickModeEnabled is false on the drone, flight-stick inputs are dropped before transmission; the aircraft rejects them anyway but the UI short-circuits.
  • Advanced modeisVirtualStickAdvancedModeEnabled unlocks 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:

  1. Select the drone in the fleet tile. The tile binds to it.
  2. Grab authority — click Take control in the drone-stream toolbar, or trigger the authorityGrabFlight bound input. ARGUS publishes drc_grab_authority. If someone else is flying, a confirmation dialog offers force-grab or wait.
  3. 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.
  4. Fly — your input axes + button commands stream to the drone. The heartbeat keeps running.
  5. Release — hit the bound Release key, close the drone-stream tile, or navigate away. ARGUS publishes drc_release_authority to 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 changecamLensChange cycles through available lenses.
  • PhotocamTakePicture triggers a single shot.
  • RecordcamStartRecording / camStopRecording toggle.
  • 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.