DEBUG
Default console tab. Four-step left column — prompt → config → setup → control — drives one closed-loop policy run; right side streams the live 3D arm, cameras, and action/state charts. Run modes: REAL, SIM, STEP.
Prerequisites
- Policy server running on a reachable IP/port (default
127.0.0.1:9000). It does not start with EVA. - Robot or simulator ready. REAL needs the arm powered and reachable; SIM does not.
- Config file (
.py, passed via--config) selecting robot, policy server, and prompt list. See Config for the DEBUG for a skeleton.
eva --config <path-to-your-config> --web-port 8080 # then open http://localhost:8080
Overview
DEBUG is the first of six console tabs (DEBUG·MANUAL·COLLECT·REPLAY·EVAL·RESULT) and runs one closed-loop inference: connect to the policy server, request actions, dispatch to robot or sim, and stream telemetry back.
Four-step workflow
Four numbered panels in the left column, top to bottom. The guide bar shows STEP n/4. Each step unlocks the next.
| # | Panel | Action |
|---|---|---|
| 1 | PROMPT | Pick a task prompt from the config-provided list. |
| 2 | CONFIG | Pick run mode (REAL / SIM / STEP) and strategy (see Strategies). |
| 3 | SETUP | Runs automatically after steps 1–2. Connects the policy, resets the arm to home, validates with one inference. |
| 4 | CONTROL | RUN / STOP / RESET (continuous) or SIM ↻ / REAL ▶ / STOP / RESET (STEP). Enabled only after Setup succeeds. |
Reading Setup status
| UI state | Meaning | Action |
|---|---|---|
| Spinner with sub-stages (connect, reset, validate) | In progress | Wait. |
| CONTROL unlocked; policy indicator LINKED | Success | Proceed to Control. |
| Policy indicator DOWN; RETRY visible | Policy server unreachable | Verify server + IP/port, click RETRY. |
The LINKED / DOWN indicator also sits permanently in the right-hand status bar.
Run modes
Three modes in step 2, SIM by default. MANUAL has its own top-level tab.
| Mode | Behavior |
|---|---|
| REAL | Dispatches actions to the real robot, mirrored to the sim preview, and records executed actions. Resets the arm to home first. |
| SIM | Simulation only — 3D arm moves, real robot does not. Setup skips the reset. |
| STEP | Breakpoint single-step: infer and execute one chunk at a time, previewed in sim, dispatched to the real robot on confirm. See next section. |
A stopped REAL or SIM run resumes from the arm's current actual pose, not from the start.
STEP: breakpoint single-stepping
STEP replaces continuous RUN/STOP with a preview-then-commit flow. After Setup succeeds:
- SIM ↻ — infer one chunk and animate it on the sim arm; the chunk is staged.
- Inspect the sim preview. Banner reads "SIM preview done · N actions · press REAL ▶ to dispatch".
- REAL ▶ — dispatch the staged chunk to the real robot; staging clears. The 3D view stays on the sim result.
- STOP ■ / RESET ⟲ behave as in continuous mode.
The preview always runs in sim first; there is no skip-sim path.
Live stage
Right side, three auto-refreshed regions, nothing to operate.
- 3D arm — drawn live from current joint positions, with step and chunk counters. Rendered in-process; no external viewer.
- Camera strip — one live feed per camera; unchanged frames are not re-sent.
- ACTION / STATE charts — each action and state dimension plotted over time; click to enlarge. After the run stops, a scrub bar unlocks for history review.
Below the stage: transport online, policy LINKED/DOWN, session state, last inference time, step count, elapsed time.
Gripper control and tuning
The GRIPPER panel exposes one open/close switch per gripper: GRIPPER for single-arm, LEFT / RIGHT for dual-arm.
Each switch has a force lock:
- On — your setting holds for the whole run, overriding the policy.
- Off — your setting is sent once, then control returns to the policy.
TUNING adjusts inference parameters live without restart: inference rate (Hz), publish rate (Hz), and the active strategy's tunable fields. APPLY takes effect on the next cycle; a running strategy updates in place.
Config for the DEBUG
DEBUG shares the console's .py config — no DEBUG-only file. The prompt list, selectable strategies, and tuning defaults all come from this file. Fields first, then a minimal skeleton.
| Field | Sets | Notes |
|---|---|---|
policy.type | Policy backend | e.g. openpi. See Backends. |
policy.host / policy.port | Policy server address | Must match the running policy server. |
inference_cfg.debug_tasks | Prompt list (step 1) | List of prompt strings shown in PROMPT. |
inference_strategies | Strategy options (step 2) | Each key is one option. See Strategies. |
inference_cfg.inference_rate | TUNING "inference rate" default (Hz) | Live-tunable. |
inference_cfg.publish_rate | TUNING "publish rate" default (Hz) | Live-tunable. |
inference_cfg.action_space / obs_space | Action / observation space | JointState or EEFPose; sets chart dimensions. See Action spaces. |
Minimal DEBUG config skeleton. _base_ inherits a parent that already sets robot and transport; only DEBUG-related fields are overridden here. "← fill in" / "← change" mark required edits.
_base_ = ['_base.py'] # inherit parent (robot + transport) policy = dict( type='openpi', # backend: openpi / starvla / gr00t / ... host='<policy-server-IP>', # ← fill in (127.0.0.1 for local) port=<port>, # ← fill in (default 9000) ) inference_cfg = dict( debug_tasks=[ # PROMPT panel list (step 1) '<task prompt>', # ← match the policy's training tasks ], inference_rate=3.0, # Hz; live-tunable in TUNING publish_rate=30, # Hz; live-tunable in TUNING ) inference_strategies = { # STRATEGY picker (step 2) 'sync': dict(type='BaseInferStrategy', args=dict(execute_horizon=5)), 'async': dict(type='AsyncLinearOverlapInferStrategy', args={}), }
.py under configs/01_deploy/ for your robot and edit only the "←" spots. Full field list and _base_ rules in Configuration.Customizing prompts and strategies
- Prompt list — set
inference_cfg.debug_tasksto strings matching the policy's training tasks. An override replaces the parent's list wholesale; restate every prompt you want. - Strategy list — add or drop entries in
inference_strategies. To tweak one strategy's args, write only the changed part; the rest is inherited:
inference_strategies = { 'async': dict(args=dict(latency_k=8)), # change only this arg of async; rest inherited 'act': dict(args=dict(exp_weight_m=0.01)), }