Ground drive activity

Remote-side activity for any robot exposing intent:ground-drive-2d

The canonical Remote-side control surface for any robot whose active stanza exposes intent:ground-drive-2d. Replaces the pre-CIV RemoteSteeringActivity. Drives ground vehicles (wheeled, tracked, legged-via-legged_gait_2d) interchangeably — the activity doesn't know about robot morphology; that lives entirely on the Agent side.


Manifest

Ground Drive declares the canonical CIV manifest:

Field Value
name "Ground Drive"
requiredIntents { "intent:ground-drive-2d" }
channelScope "*" (matches any channel)
binds switch:parking_brake → P, momentary:horn → Space
absorbs switch:*, momentary:*, axis:*, event:*

A channel is eligible whenever its active stanza exposes both intent:ground-drive-2d.forward and .yaw. Multiple eligible channels = the activity binds to the first one in channel declaration order.


UI layout

  • Top region — a CarSteeringControlAdapter-derived widget (joystick or steering-wheel surface). Writes the vertical axis to intent:ground-drive-2d.forward and the horizontal axis to intent:ground-drive-2d.yaw.
  • Middle region — bound keys (P for parking brake, Space for horn). When the active stanza exposes the bound port kind, the indicator lights up; pressing the key writes to the port.
  • Bottom region — OptionalPortBank mounted with the manifest's absorbs patterns, with the bound port kinds excluded so they don't double-render. Renders one strip per kind family (switch toggles, momentary press-and-hold, axis sliders, event buttons).
  • Bottom-anchored — the standard Done button per the project's button-placement rule.

The activity is enabled iff manifestMatches() returns true for at least one channel's active stanza. When disabled, the widget remains visible but greyed; switching the Agent to a non-eligible stanza (e.g. a turret-aiming stanza) greys the activity in real time.


Lobe-side counterparts

The activity is morphology-agnostic. The lobe consuming the intent values is the one currently active on the matching channel:

Lobe Source Behaviour
differential_drive Phase CIV-3 canonical Two-side accumulating step targets; drives wheels or tracks based on the preset's actuator semantic tags
legged_gait_2d Phase CIV-3 intent face Thin wrapper over the 6-input LeggedGaitLobe, mapping forward → velocity, yaw → turn, others zero

A custom lobe declaring intent:ground-drive-2d on its input ports also Just Works — the activity doesn't know or care about the implementation.


Class hierarchy

Activity (libwidgets/components/navigation)
└── PortBoundActivity (libfixo/fixo/widget)
    └── GroundDriveActivity (libremote/remote)

PortBoundActivity provides manifest gating + OptionalPortBank mounting. GroundDriveActivity adds the joystick / steering-wheel widget on top.


Phase history

  • Phase CIV-2 — ActivityManifest, OptionalPortBank, PortBoundActivity host.
  • Phase CIV-3 — differential_drive + legged_gait_2d lobes shipped.
  • Phase CIV-4a — RemoteSteeringActivity renamed to GroundDriveActivity; manifest declaration added; cross-lobe testing.
  • Phase CIV-4b — load-time tolerance: personalities that still reference the legacy RemoteSteeringActivity id rewrite to GroundDriveActivity on read.

In this section
Topics
reference widgets remote intent ground-drive