Virtual Field commands

Per-arm and multi-arm command payloads used by the runtime.

These types correspond to the controller-input flow described in docs/virtual_field/dual_arm_inputs.md and the runtime communication schema.

class virtual_field.core.commands.ArmCommand(arm_id, active, target, velocity=<factory>, joystick=<factory>, buttons=<factory>)[source]

One controller input for a simulation step.

Built from ControllerSample by SessionArmControlMapper; the Virtual Field Interacting with Controller Data doc describes the mapping from XR samples to these fields.

Attributes:
arm_id

Stable arm identifier; must match the corresponding key in MultiArmCommand.commands.

active

Typically True when analog grip is at or above the session clutch threshold; used to gate pass-through updates. Simulation-backed modes may still read buttons every frame.

target

Controller pose as Transform (same role as ControllerSample.pose).

velocity

Optional twist from the controller (linear and angular); defaults to zeros if omitted on the wire.

joystick

Two floats after deadbanding (thumbstick axes), length validated to 2.

buttons

Named booleans passed through from the frontend. The dual-arm backend uses grip_click, trigger_click, primary, and secondary (rising edge on secondary resets/rests and recalibrates orientation).

to_dict()[source]

Serialize to JSON-compatible dictionary.

Return type:

dict[str, Any]

class virtual_field.core.commands.MultiArmCommand(timestamp, commands, head_pose=None, actions=<factory>)[source]

One frame of controller commands for all currently tracked arms.

This is the runtime-level command packet consumed by MultiArmPassThroughBackend.step(). Each entry in commands is keyed by arm_id and must contain a matching ArmCommand.

Attributes:
timestamp

Sample time from the originating XR input frame.

commands

Mapping from arm_id to per-arm command data. In the dual-arm setup this usually contains zero, one, or two entries depending on which controllers are currently present in the XR sample.

to_dict()[source]

Serialize to a JSON-compatible dictionary.

Return type:

dict[str, Any]

class virtual_field.core.commands.ControllerSample(pose, velocity=<factory>, grip=0.0, trigger=0.0, joystick=<factory>, buttons=<factory>)[source]

Raw XR controller sample before mapping into arm-space commands.

SessionArmControlMapper consumes this data and produces an ArmCommand. The Interacting with Controller Data guide describes the default mapping used by the virtual field runtime.

Attributes:
pose

World-space controller pose as a Transform.

velocity

Optional world-space linear and angular controller velocity.

grip

Analog grip value, typically in [0, 1]. The default mapper compares this against the clutch threshold to determine ArmCommand.active.

trigger

Analog trigger value, typically in [0, 1].

joystick

Two thumbstick axes in [x, y] order. The default mapper applies a deadband before copying these values into ArmCommand.

buttons

Frontend-supplied boolean button state. Common keys include primary, secondary, grip_click, and trigger_click.

to_dict()[source]

Serialize to a JSON-compatible dictionary.

Return type:

dict[str, Any]

classmethod from_dict(data)[source]

Deserialize a controller sample from JSON-compatible data.

Return type:

ControllerSample

class virtual_field.core.commands.XRInputSample(timestamp, head_pose, controllers, actions=<factory>)[source]

One WebXR input frame containing head and controller state.

This is the Python-side representation of the xr_input payload described in the communication and controller-input guides.

Attributes:
timestamp

Client-provided sample time.

head_pose

World-space head pose for the XR frame.

controllers

Mapping from controller hand labels such as "left" and "right" to ControllerSample values.

classmethod from_dict(data)[source]

Deserialize an XR input sample from JSON-compatible data.

Return type:

XRInputSample

to_dict()[source]

Serialize to a JSON-compatible dictionary.

Return type:

dict[str, Any]