Ground Drive Activity

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

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