Introduction
The iteration loop
An embodied policy is produced by a closed loop, not a single training run: collect demonstration data on the real robot, train a policy from it, deploy the checkpoint back to the robot, then run on-robot evaluation; whatever the eval exposes feeds the next round of collection, and the model gets stronger loop by loop.
Inside that loop, training runs in your own stack; everything else is real-robot work — and EVA is exactly the real-robot infrastructure that handles it: data collection, model deployment, and on-robot evaluation, in one piece of software.
Terms: a chunk is a short action sequence emitted by one policy inference; an episode is one recorded attempt. Live capture uses EVA's LeRobot v2.1 raw layout. After quality review, the accepted and rejected sets can be exported as LeRobot v2.1, LeRobot v3.0, HDF5, or MCAP.
Software architecture
The action signal for a run originates at a policy server (the trained VLA) or from human teleoperation, passes through EVA-Client — which buffers, smooths, and converts it — then is dispatched to the real robot hardware to execute; the camera and joint observations the robot publishes travel back through EVA to the signal source.
Connecting the policy, stepping inference, recording, and evaluation all run from a single web console served on a local port. A run is fully determined by the config file passed on the command line — a .py file naming the robot, transport, policy server, and strategy. Changing behavior means pointing --config at a different file, not editing flags. See Configuration.
Consoles and workflow
The console tabs aren't isolated features — they fall onto three flows: collection, deployment, and evaluation. Establish that logical path first, then look at what each tab does:
Collection
| Tab | What it does |
|---|---|
| MANUAL | Slider-driven joint control for hardware adaptation and link checks — verify control and observation links before connecting a policy. See MANUAL. |
| COLLECT | Teleop capture, QC, and export. Each attempt first lands in the LeRobot v2.1 raw layout; reviewed episodes can then be exported to four supported formats. See Data collection and Data formats. |
| REPLAY | Open-loop playback of a recorded episode for offline QC; reuses the same visualization pipeline, no robot or policy server required. |
Deployment
| Tab | What it does |
|---|---|
| DEBUG | Connect the policy and run inference — continuous, simulation-preview-only, or step-by-chunk in 3D before dispatching to hardware. See DEBUG. |
Evaluation
| Tab | What it does |
|---|---|
| EVAL | Multi-checkpoint sweep; each checkpoint is shown as a slot letter (Model A / B / …) plus its real name, and scored per instruction. See EVAL. |
| RESULT | Synchronized camera video, 3D replay, joint charts, and scores over recorded attempts. See RESULT. |
The landing tab is determined by the config: evaluation configs (configs/03_evaluation/) open into EVAL/RESULT; deploy configs open into DEBUG.
Launching EVA
Prerequisites: eva on PATH (see Installation) and a reachable policy server (address comes from the config; see Policy backends). Offline replay needs neither.
eva requires --config pointing at a .py file; --web-port defaults to 8080.
# Deploy config — opens in DEBUG. eva --config configs/01_deploy/dual_agilex_piper/openpi_qpos.py # Offline replay — no policy server, no robot. eva --config configs/00_openloop/dual_agilex_piper_openloop.py # Checkpoint-sweep evaluation — opens EVAL/RESULT. eva --config configs/03_evaluation/arx_r5_eval.py
Bundled config folders are named after the target robot (dual_agilex_piper, arx_r5, …). See Configuration for adapting one.
--web-port.eva --config configs/01_deploy/arx_r5/openpi_qpos.py 12:14:24.426 INFO Creating transport: type=zmq robot=arx_r5 12:14:24.430 INFO ZMQ transport ready: sub=tcp://127.0.0.1:5555 pub=tcp://127.0.0.1:5556 robot=arx_r5 12:14:24.430 INFO Transport ready: type=zmq obs_mode=JointState 12:14:24.481 INFO UrdfScene ready for 'arx_r5': 2 parts, 1 URDFs, 9 meshes 12:14:24.483 INFO Console web server: http://127.0.0.1:8080 12:14:24.483 INFO Console web server started on port 8080
For a remote robot, forward the port: ssh -L 8080:localhost:8080 you@robot-host. Full options: CLI reference.
Building blocks
Every config wires four pluggable pieces, each selected by a short name:
- Transports —
ros1,ros2,zmq,dataset(offline replay source). - Policy backends —
openpi/openpi_rtc,starvla,gr00t;mockreturns synthetic actions andreplayreplays recorded ones for offline work. - Inference strategies —
sync,async,naive,act,rtc; switchable live from the console. See Strategies for trade-offs. - Action spaces —
JointStateorEEFPose. EVA runs IK to convert EEF targets to joint commands.
Bundled robots: agibot_g2, agilex_piper, arx_r5, arx_x5, dual_franka, dual_yam, r1_lite, and ur5e. The PICO-based WebXR teleoperation path is documented separately. Add your own robot.
Where to go next
- Installation — Python 3.10+,
uv, editable install. - Quickstart — launch the console and run first inference.
- Configuration — the
.pyconfig model and_base_inheritance. - PICO-based WebXR teleoperation — the new browser-based human-control path.
- Data formats — QC-aware export to LeRobot v2.1/v3.0, HDF5, and MCAP.