Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.almond.bot/llms.txt

Use this file to discover all available pages before exploring further.

Connects a VR headset to the robot (or simulator) for teleoperation. IK runs in a dedicated subprocess to keep JAX off the asyncio event loop. The pipeline is: VR frames → One Euro filtering → IK solve → EMA smoothing → trapezoidal velocity profiling → motion_control().
from almond_axol.teleop import VRTeleop, VRTeleopConfig
import asyncio
from almond_axol.robot import Axol
from almond_axol.teleop import VRTeleop

async def main():
    async with VRTeleop(Axol()) as teleop:
        await teleop.run()  # blocking; Ctrl+C to exit

asyncio.run(main())
Use step() instead of run() to integrate teleoperation into your own control loop:
async with VRTeleop(axol) as teleop:
    while True:
        left_q, right_q = teleop.step()  # returns latest smoothed (8,) arrays
        # ... custom logic ...
        await asyncio.sleep(1 / 120)
See the teleop CLI command for the equivalent command-line entry point.

VRTeleopConfig fields

FieldDefaultDescription
frequency120 HzControl loop rate used by run() and reset trajectory density
teleop_max_vel1.0 rev/sTrapezoidal filter velocity cap during normal teleoperation
teleop_max_accel3.5 rev/s²Trapezoidal filter acceleration cap
engage_max_vel0.1 rev/sSlower velocity limit when the deadman switch is first pressed after a reset
engage_duration1.0 sHow long engage_max_vel is held before restoring teleop_max_vel
ik_alpha0.5EMA blend factor on IK output; 1.0 disables smoothing
pose_min_cutoff1.5 HzOne Euro Filter tremor cutoff for raw VR poses
pose_beta5.0One Euro Filter speed coefficient (raises cutoff during fast moves)
reset_speed0.1 rev/sAverage joint velocity of the worst-case joint during return-to-rest (peak is 1.5× this)
reset_min_duration1.5 sFloor on return-to-rest duration so near-rest starts don’t snap home
rest_pose_left / rest_pose_rightnear-zeroReset target for each arm, shape (7,) in ARM_JOINTS order
Deadman switch behaviour. Grip is a toggle, not a hold. Press both grip buttons together to enable arm movement; press either grip alone to freeze the arms. A rising edge on the reset button triggers a collision-aware trajectory back to the rest pose.