Skip to content

feat(robodojo): add robot backend with eval-fair Flash replay - #96

Open
littleZ05 wants to merge 26 commits into
RLinf:mainfrom
littleZ05:feat/robodojo-integration
Open

littleZ05 wants to merge 26 commits into
RLinf:mainfrom
littleZ05:feat/robodojo-integration

Conversation

@littleZ05

@littleZ05 littleZ05 commented Aug 23, 2026

Copy link
Copy Markdown

Summary

Add RoboDojo (Isaac Sim / IsaacLab, dual ARX-X5 arms) through rpent --robot robodojo, using RPent's existing robot, runtime, perception, planner and memory interfaces. Infrastructure only; no evidence, checkpoints or research memories are included.

  • Shared Pi0.5 server with rlinf / xpolicylab adapters; lazy backend dependencies, 14-DoF actions, three-camera WebSocket inputs and unchanged dual-arm pi0_pick monitoring.
  • Shared perception primitives, read-only annotations, general/privileged/mixed tool groups, explicit CLI paths and scoped task prompts without manual MCP/JSON-RPC instructions.
  • Native eval-fair Flash with version-2 symbolic mask-centroid anchors, waypoint offsets, bounded recovery, and observation/RPC/tool isolation. Dev retains privileged feedback; eval exposes zero reward and no official task predicates or ground-truth object poses.
  • Bilingual Adding a Robot Backend guide, checklist, installation and capability matrices.
  • Cancellable raw-fd parent watcher, joined at server teardown; parent-watch daemons receive EOF before signal fallback. RobotWin's launcher retains the same EOF exit semantics and now releases the shared watcher on model initialization errors and normal return.
  • RoboDojo teardown runs on the main thread after the close RPC response: video writers, camera annotators/render products, syntheticdata stale handles, Replicator, then stage/app. Headless teardown is guarded against worker-thread UI/event-loop access.
  • CLI transcripts include planner error; common run_diagnostics.json preserves final errors, including finalization failures, for dev and Flash.

Affected tasks

Task discovery uses the configured RoboDojo checkout. Integration targets include put_bottles_into_dustbin, fill_pen_holder, stack_bowls_random; these are not benchmark-success claims. place_in_bin remains dustbin-specific.

Test plan

P6, Python 3.11:

  • .venv/bin/ruff check --preview .: passed.
  • .venv/bin/ruff format --check .: passed (253 files).
  • .venv/bin/pre-commit run --all-files: passed.
  • .venv/bin/pytest tests/unit_tests -q: 658 passed, 3 skipped, one Starlette dependency deprecation warning, 29.14s.
  • make -C docs html LANG=en SPHINXBUILD=<repo-checkout>/.venv/bin/sphinx-build SPHINXOPTS='-W --keep-going -E -q': passed; same command with LANG=zh: passed.
  • Regression coverage includes real subprocess EOF/cancellation exits, graceful ProcessDaemon stop, RobotWin normal/model-failure cleanup, deferred/idempotent camera teardown, stale syntheticdata graph handles before ticking, and CLI error artifacts for both planner modes.

P6 real smoke

bash evidence/pr96-p6-20260918/run-dev.sh

Single simulator, only PRO 6000 GPU0, layout 1; worktree PYTHONPATH and RPENT_REPO_ROOT. Codex gpt-6-astra, low effort, --planner-timeout-s 1500 --max-turns 40, outer timeout --signal=INT --kill-after=20s 1700s. This leaves startup/cleanup room below 30 minutes. These are smoke overrides, not defaults; the bilingual guide documents the same bounded policy for fill_pen_holder.

The evidence-only wrapper narrows the dev request to a real single-target grasp-and-hold demonstration with at most three attempts and no resets, runs the existing hold predicate on actual returned state/perception, records server return codes and fully decodes three videos. It never changes tool return values or creates a synthetic plan. Required shutdown checks reject fatal errors, tracebacks and [Error] after the shutdown marker; headless GLFW startup warnings are expected noise.

990.66s outer wall time, CLI/smoke exit 1 (audit timer 990.26s; CLI loop 950.4s). Planner entered and executed one 10-chunk pick. Actual pi0_pick.success=false, its step-limit terminated=false, both final grippers approximately open (0.998/0.999), and the unchanged hold predicate returned false. The environment's subsequent recorded terminated=true is preserved separately; it does not establish a held object or official benchmark success. The planner stopped motion rather than resetting the ended episode. No approach waypoint or passing plan was fabricated.

The provider then disconnected five times and failed with stream disconnected before completion: stream closed before response.completed. Both dev/transcript_put_bottles_into_dustbin_l1.json and dev/run_diagnostics.json contain that exact error. This attempt did not report HTTP 503; the earlier interrupted run did.

Shutdown acceptance passed: env/VLA/SAM3 each exited 0; no Fatal Python error; env shutdown interval contained no [Error], traceback, stale Py_Graph, or worker-thread event-loop error. Headless GLFW initialization/plugin warnings were the only closing warnings and are explicitly allowed noise. All three videos fully decoded 513/513 frames each. All owned services/policy children exited without manual intervention; GPU0 returned to 20 MiB / 0%, no compute processes.

Hold gate failed, so the batch stopped. No version-2 plan was exported and no P6 Flash or fill run was started. P6 eval-fair runtime isolation and successful replay remain unverified; offline Flash contracts pass, and historical P5f isolation evidence is below. Next step: investigate the real policy/scene grasp mismatch and obtain a genuine hold-accepted dev demonstration with a stable provider before evaluating it. Do not relax the hold gate.

Detailed evidence: evidence/pr96-p6-20260918/results.md, dev-audit.json, dev.console.log, and dev/ (service logs, states, trace, transcript and videos). Smoke instrumentation remains outside git; the PR contains only code/tests/documentation.

P7 hold follow-up (local fix, not pushed)

Local 3f126b2 stops policy chunks immediately on the unchanged pick heuristic and adds aperture/action diagnostics; 659 passed / 3 skipped, Ruff/format/pre-commit and EN/ZH strict Sphinx passed. PR code remains c8bd725 pending a green smoke.

Command: bash evidence/pr96-p7-20260918/run-dev.sh (single PRO6000 GPU0, layout1, planner1500s/40 turns, outer1700s+20s). 962.48s, CLI0 but smoke1: approach reached within3mm in8 steps; same white-cap query switched to a different horizontal bottle (~22.3cm anchor jump) twice. Planner finished stuck before any pick (0 chunks); hold not established, native task success=false. No provider disconnect.

Infrastructure passed: env/VLA/SAM3 exit0, clean shutdown, all three videos20/20 decoded frames, no residual services, GPU20MiB/0%. No export or Flash run after this failure; runtime isolation/replay and early-stop hold remain unverified at the local revision. Next check distinctive target identity and approach visibility on saved RGB-D before another bounded trial; same query/confidence alone is not persistent identity. Evidence and exact commands: evidence/pr96-p7-20260918/results.md (outside git).

P8 identity follow-up (local, not pushed)

Local commits 3f126b2 and 963a30d are not pushed because the real hold gate remains red.

  • Added shared AnchorTracker and locate_anchor: fixed 5cm world-centroid consistency against the first head observation, fresh accepted localization before every motion, and post-approach/pre-pick confirmation. Flash/export use the same guard; identity jumps revoke motion and are rejected. Added EN/ZH guidance and contracts.
  • Offline checks: 662 passed / 3 skipped, Ruff check/format, pre-commit and EN/ZH strict Sphinx passed (Python3.11).
  • Real dev command: bash /home/admin/robodojo_runtime/evidence/pr96-p8-20260918/run-dev.sh, single PRO6000 GPU0/sim, gpt-6-astra low, planner1500s/40 turns. 1028.65s, CLI0 / smoke1. Identity passed: centroid [169,167] -> [170,167], 2.249mm; approach error 2.4mm. Pick executed 1 chunk/36 actions and original gate returned pick_success=true, but wrist/head evidence showed the requested blue target still on table and a different white bottle in the gripper; held=false, native success=false. Planner stopped without retry.
  • Cleanup passed: env/VLA/SAM3 0/0/0, videos 49/49 decoded each, no residual processes, GPU20MiB/0%; no provider disconnect.
  • No plan export or Flash run after the failed target hold. Remaining blocker is checkpoint target selection, not pre-pick identity; inspect checkpoint language conditioning before another bounded trial. Evidence: /home/admin/robodojo_runtime/evidence/pr96-p8-20260918/results.md (outside git).

P9 official task language (local, not pushed)

Local 3864c6a fixes raw-template task-language RPC: prefer official description manager, otherwise fill every label from public layout descriptions, fail explicitly on unresolved/empty text; observations use the same resolver. pi0_pick now defaults to official language if prompt is omitted; explicit identity overrides remain supported and template markers are rejected. EN/ZH docs and contracts included. 676 passed /3 skipped, Ruff/format/pre-commit/strict bilingual Sphinx passed.

Before-fix CPU execution of actual original methods returns Pick up the <target> by 10 cm. Official HDF5 at the supplied location has root /instruction (not additional_info/instruction), value Pick up the lavender plastic shovel by 10 cm. However, official observations already used resolved descriptions, and P8's dustbin pick had an explicit blue-target override; that template defect is not established as P8's cause.

Same-P8 smoke command: bash /home/admin/robodojo_runtime/evidence/pr96-p9-20260918/run-dev.sh. Same dustbin/layout1/blue anchor/staging/arm/chunks/budgets; only omitted pick prompt to test official default. Actual RPC and VLA strings both: Pick up the bottles and throw them into the dustbin, using handover when needed. 810.99s, CLI0/smoke1; 1chunk/33 policy actions (35 total), pick_success=true but held=false: white bottle grasped, designated blue target remains on table. Native success=false. No provider disconnect. Services0/0/0, videos46/46 decoded each, clean shutdown/no residual processes, GPU20MiB/0%.

No export/Flash after failed target hold. Current Flash isolation/replay and real general_pickup scene remain unverified. No push or pull-rebase: 3f126b2, 963a30d, 3864c6a remain local pending green smoke; authenticated user littleZ05. Next investigate checkpoint instance-selection support, not lower gates. Evidence: /home/admin/robodojo_runtime/evidence/pr96-p9-20260918/results.md and language_probe.py (outside git).

Prior runtime evidence (different revisions)

  • P5e dustbin dev: 570.71s, exit 0, one 12-chunk pick, three videos 615 frames each, automatic cleanup to 20 MiB / 0%. Grasp hold was not established.
  • P5f fill: 1859.01s, exit 1, 1800s planner timeout, four picks (12/2/2/1 chunks), three videos 873 frames each, resources reclaimed. That budget also did not complete the task.
  • P5f Flash: 133.69s, exit 1, 12 chunks / 600 steps, stopped at the grasp-hold gate; three videos 615 frames each. Runtime isolation passed (six allowed tools, all 600 rewards zero, 615 public observations, no predicate/GT feedback, model=null). This is historical isolation evidence, not successful replay completion.
  • The interrupted pre-P6 dev attempt encountered provider HTTP 503 before picking. It is not policy evidence; its shutdown log helped identify stale syntheticdata callbacks.

Local evidence directories: evidence/pr96-p6-20260918/, pr96-p5f-20260918/, pr96-p5e-20260918/, and pr96-p5g-20260918/. They are host-local artifacts, not committed files.

Environment note

The installed Codex CLI model-catalog schema requires supports_parallel_tool_calls in every configured entry. The environment owner previously fixed ~/.codex/codex-models.json (backup suffix (local backup)). No global model configuration changed here. Provider stream errors and HTTP 503 must be reported separately from robot/runtime defects.

Known limitations

  • Handover is not implemented; low-Z tabletop scripted IK has reachability limits.
  • Flash export supports only move_to, set_gripper, pi0_pick; unsupported/failed/unanchored records are rejected. No task plans are bundled.
  • Recording/replay use version-2 sam3_mask_centroid_floor_v1; old box-center/version-1 plans require rerecording.
  • Export validity, grasp-hold acceptance, replay completion and official task success are distinct. Official scoring stays outside eval context; pi0_pick.success is a proprioceptive heuristic, not the official task predicate.
  • Planner budgets depend on recovery steps and provider latency. Timeout or failed gate stops the batch; it does not justify silently raising defaults or fabricating a plan.
  • Real RobotWin/LingBot GPU execution, Molmo GPU execution, physical hardware, other Python matrix legs and broad benchmark success remain unverified in this phase.
  • A hold-accepted dustbin demonstration and successful Flash replay are still missing; P6 stopped on the dev gate. The new bounded fill budget is documented but not rerun after that failure.

@qurakchin

Copy link
Copy Markdown
Collaborator

Thanks for the pr. We will soon review it.

Comment thread docs/ROBODOJO_AB_PROTOCOL.md Outdated
Comment thread robots/robodojo/__init__.py Outdated
Comment thread robots/robodojo/env_client.py Outdated
Comment thread robots/robodojo/env_server.py
Comment thread robots/robodojo/vla_client.py Outdated
@littleZ05
littleZ05 force-pushed the feat/robodojo-integration branch from 0f49c70 to 42018d1 Compare August 28, 2026 10:31
Comment thread robots/robodojo/env_client.py Outdated
Comment thread robots/robodojo/env_client.py Outdated
Comment thread robots/robodojo/env_client.py Outdated
Comment thread robots/robodojo/env_server.py Outdated
Comment thread robots/robodojo/env_server.py Outdated
"""Return (pos, rot) of a bottle in world-ish coords (env 0 at origin)."""
import torch

pos, rot = env.scene_manager.layout_manager.get_instance_pose(env_idx, label=label)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this expose simulator object positions to the agent? Since the RoboDojo prompt defines the setup as perception-isolated, should object locations only come from camera or depth observations instead?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch ??these outputs are now grouped as privileged tools and can be removed through allowed_tool_groups (e05e361). We will wire that into the two modes: dev keeps full feedback for self-evolution, eval-fair excludes privileged groups (mirroring LIBERO's evaluation-only Flash planner). The mode switch + contract tests land in the next stage.

Comment thread robots/robodojo/guides/interface.md Outdated
## 13. Reward/Score 明细(2026-08-20 补)

- 新增 RPC `get_reward_details`:返回逐项判定——每个 bottle 的
`is_A_on_B_bottom`(底部贴合 dustbin 底部平面)、`grippers_open`、

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it intended to expose these per-object success predicates to the agent? I would expect the environment to use them internally for success computation, while the agent only observes the normal reward or final success signal.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same handling as the object-position thread: get_reward_details is marked privileged and is excluded when the eval-fair group filter is active. A contract test proving eval runs cannot read predicates is part of the next stage.

Comment thread robots/robodojo/prompts/system.py Outdated
Comment thread robots/robodojo/robot_spec.py Outdated
name="sam3_server",
cmd=[
sys.executable,
str(get_repo_root() / "robots" / "libero" / "sam3_server.py"),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we use the shared rpent/robots/components/sam3_server.py here instead of the LIBERO-specific path?

Comment thread robots/robodojo/robot_spec.py Outdated
"""Initialize every RoboDojo component, or only ``components`` when given."""
from robots.robodojo.env_client import RoboDojoEnvClient
from robots.robodojo.vla_client import RoboDojoVLAClient
from rpent.utils.sam3_client import Sam3Client

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we use rpent.robots.components.sam3_client.Sam3Client here to stay consistent with the latest main?

Comment thread robots/robodojo/robot_spec.py Outdated
owned_daemons: dict[str, ProcessDaemon] = {}
primitives_kwargs: dict[str, Any] = {}

if "env" in selected:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we follow the starters and connectors pattern used in robots/libero/robot_spec.py here? The env, SAM3, and VLA lifecycle looks quite similar, and this could avoid duplicating the spawn and wait logic for each component.

Comment thread robots/robodojo/robot_spec.py Outdated
from rpent.utils.daemon import ProcessDaemon


DEFAULT_WORKSPACE = "/home/admin/robodojo_pro6000_ws"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we avoid using a developer-specific /home/admin/... path as the default workspace?


.. code-block:: bash

uv pip install -e ".[rlinf,openpi,libero-pro,sam3]" # full install

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This installation command seems out of sync with the latest main after #114: openpi is no longer a standalone extra. Could we align the RoboDojo installation with the new per-environment packaging structure?

RPent x RoboDojo Integration Log
================================

Record period: 2026-08-20 ~ 2026-08-21. Workspace:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to keep this integration log in the user-facing documentation? It contains local workspace paths and historical experiment notes that are likely to become stale.

Comment thread robots/robodojo/prompts/system.py Outdated
call `stabilize` first — place the nearest arm's open gripper in the bottle's
path at table height to stop it before it falls off the table (a lost bottle
is unrecoverable). Only resume the task after the alarm clears.
- To place a held object into the dustbin, use `place_in_bin` (carry to the

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this task-specific dustbin guidance live in the generic RoboDojo system prompt? It seems better suited to task-specific context or memory so unrelated RoboDojo tasks do not receive put_bottles instructions.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in e05e361: the dustbin/placement, bottle-alarm and score guidance moved out of the generic system prompt into task-specific context, so unrelated RoboDojo tasks no longer receive it.

- env_cfg: {{env_cfg_type}}
- action_type: {{action_type}}
- output_dir: {{output_dir}}
- scene (static hint): {{task_summary}}"""

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean the agent knows which objects are in the task before looking at the camera? Should it discover them from the observations instead?

)


def get_toolkit(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we align get_toolkit with the current robot interface and pass config and MemoryManager here, as LIBERO, RoboCasa, and RoboTwin do?

Comment thread robots/robodojo/toolkit.py Outdated
dashboard_events: DashboardEventSink,
) -> None:
state = EnvState(get_output_dir())
super().__init__(dashboard_events=dashboard_events, state=state)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the current Toolkit constructor requires memory. Could we pass the MemoryManager through here, consistent with the other robot toolkits?

Comment thread robots/robodojo/robot_spec.py Outdated
"--enable isaacsim.sensors.camera",
]
+ (["--random"] if getattr(args, "random", False) else []),
env=_subprocess_env({"CUDA_VISIBLE_DEVICES": str(args.sim_device)}),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ProcessDaemon currently takes env_overrides rather than env.

Comment thread robots/robodojo/robot_spec.py Outdated
else:
from rpent.utils.rpc import parse_endpoint

_, host, port = parse_endpoint(args.env_endpoint)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we use make_rpc_client() here like libero/robocasa/robotwin?
The CLI accepts [protocol://]host:port, but the current code discards the parsed protocol and always creates an HttpRpcClient.

Comment thread robots/robodojo/env_server.py Outdated
vision = obs.get("vision") or {}
return {name: {"width": 640, "height": 480} for name in vision}

def render_camera(self, camera_name: str | None = None) -> dict[str, Any]:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could get_camera_meta follow the common camera_name-based interface? BaseEnvClient sends camera_name

raise ValueError(f"unknown camera: {camera_name!r}")
return vision

def reset(self) -> dict[str, Any]:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we follow the current BaseEnvFacade contract here? New backends should preferably return reset=(obs, info) and step=(obs, reward, terminated, truncated, info), as LIBERO and RoboTwin do.

}
return obs, reward, done, info

def chunk_step(self, flat_actions, *, return_all_frames: bool = False):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the RoboDojo Pi_05 backend already produces action chunks, could we implement the shared chunk_step contract here, similar to LIBERO and RoboTwin, instead of issuing one RPC step per policy action?

Comment thread robots/robodojo/env_server.py Outdated
return env_cfg

env = create_collect_env(_build_env_cfg(), simulation_app)
if _args.random:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this initial reset in the server? BaseEnvClient performs reset when the client connects, so RoboDojo currently appears to reset twice on startup. LIBERO and RoboTwin leave the episode reset to the normal client lifecycle, which seems especially important for --random reproducibility.

Comment thread robots/robodojo/tools.py
return out


def back_project(primitives, state, row, col, camera="cam_head") -> dict:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could back_project and segment be marked @readonly, consistent with LIBERO?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same change as the newer thread: @readonly added in adb621d with a contract test covering it.

Comment thread robots/robodojo/prompts/system.py Outdated
- The robot tools are exposed as an MCP HTTP server. Find its URL in this
session's startup log: a line like `I [mcp_http] HttpMcpServer ready at
http://127.0.0.1:<port>/mcp/`.
- Call tools with JSON-RPC over HTTP: `initialize` (stateless=true),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we remove the manual MCP URL / JSON-RPC workflow here? LIBERO, RoboCasa, and RoboTwin prompts simply instruct the planner to call the registered RPent tools, leaving MCP details to the runtime. This seems cleaner and less coupled to the current implementation.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in e05e361: the prompt assumes planner-injected tools and calls them by name; the MCP URL / JSON-RPC discovery instructions were removed from system/user prompts and guides (zh/en).

Comment thread robots/robodojo/prompts/system.py Outdated
`success` heuristic is provisional; confirm holds from the wrist camera.
- Gripper semantics: 1 = close/hold, -1 = open. Keep the gripper closed while
carrying an object.
- `get_status` reports the step counter and step limit; the environment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The prompt refers to get_status, but I don't see get_status registered in RoboDojo's TOOLS_SPEC.

Comment thread robots/robodojo/prompts/system.py Outdated
the URL port) instead of writing a new client.
- Do NOT read the environment/rpent source code to understand the tools;
use `tools/list` for schemas and get on with the task.
- You are a text-only model: camera images are NOT visible to you. Trust

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the shared RoboDojo prompt assume that every planner is text-only? The other robot prompts are planner-agnostic, and view_env_state already carries image data.

Comment thread robots/robodojo/vla_server.py Outdated
"localhost",
]
_log("spawning policy server: " + " ".join(cmd))
proc = subprocess.Popen(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should RoboDojoVLAFacade retain ownership of the spawned policy process and terminate it on close? RPent's other runtime components follow a clear spawn/own/cleanup lifecycle, while this Popen handle is currently discarded and may leave the nested policy server running.

@littleZ05

Copy link
Copy Markdown
Author

P3 implemented in 8f96df3 (feat(robodojo): add eval-fair frozen Flash replay).

  • Reuses native --planner flash / RobotSpec.run_flash and robot memory flash/_plan.json; no LLM calls during replay.
  • Dev records perception/action traces. Strict export freezes symbolic SAM3 queries, thresholds, relative XYZ offsets and ordered move_to/set_gripper/pi0_pick actions. Unsupported or unanchored traces fail closed.
  • Replay uses opening-frame head grounding, optional wrist refinement with 5 cm agreement checks, and at most three pick attempts with visual/proprioceptive hold checks. pi0_pick semantics are unchanged.
  • Eval service filters observations to RGB-D/calibration/proprioception, returns zero reward without task verdicts, disables privileged diagnostic/reset RPCs and truth-based bottle alarms. Toolkit removes privileged/file tools; dev remains the default. Mode metadata rejects borrowed dev services.
  • Validation: focused 32 passed; full offline unit suite 633 passed, 3 skipped; Ruff check/format, pre-commit and strict EN/ZH Sphinx builds passed. Includes synthetic native FlashPlanner + memory replay and actual toolkit trace/export smoke tests.
  • Limitations: no real historical-trace replay, GPU, real policy service or simulator E2E was run. Plan completion is not official task success; scoring must remain outside replay. Export currently rejects place_in_bin/stabilize composites; record supported basic actions instead. Safety stops are not a collision-safety guarantee.

@littleZ05

Copy link
Copy Markdown
Author

P4 documentation update in 2b205e8: rewrote the English/Chinese RoboDojo guide as an Adding a Robot Backend worked example covering registration/runtime ownership, Env contracts and main-thread dispatch, tool information groups, prompts/tasks, shared policy backends, Flash isolation, and an implementation/test checklist. Preserved the frozen-replay instructions. Filled RoboDojo entries in both README feature matrices and Sphinx overviews as experimental, with task-scope caveats, no handover, and limited low-Z scripted IK. No runtime code changed.

Validation: ruff check --preview ., ruff format --check ., pre-commit run --all-files, and both make -C docs html LANG=en/zh builds with -W --keep-going -E passed. Python 3.11 full unit suite: 633 passed, 3 skipped, one dependency deprecation warning. GPU, real policy services, hardware, simulator E2E, and the other CI Python versions were not validated; no task-success claim is made.

@littleZ05 littleZ05 changed the title feat(robodojo): integrate RoboDojo (Isaac Sim, dual ARX-X5) as a new RPent environment backend feat(robodojo): add robot backend with eval-fair Flash replay Sep 17, 2026
@littleZ05

littleZ05 commented Sep 17, 2026

Copy link
Copy Markdown
Author

P5 smoke result: failed at VLA startup

  • Revision: 2b205e8ac3eb36d9dfca6cc0ea3e6843083c9d6e.
  • Command: bash evidence/pr96-p5-20260918/run-dev.sh put_bottles_into_dustbin.
  • Exact environment and expanded CLI are in run-dev.sh and put_bottles_into_dustbin/console.log in this directory.
  • Date: 2026-09-18, Asia/Shanghai. Wall time: 52.66 seconds (/usr/bin/time -p); exit code 1. No timeout or manual kill was required.
  • Device: GPU0, NVIDIA RTX PRO 6000 Blackwell Workstation Edition. Single simulator, no 4090 access.
  • Environment RPC listened on http://127.0.0.1:48081; SAM3 loaded its checkpoint and listened on http://127.0.0.1:37715.
  • VLA failed before health check: ModuleNotFoundError: No module named 'omegaconf' at rpent/robots/components/pi05_vla_server.py:41, under <pi05-venv>/bin/python.
  • The shared entry point imports OmegaConf before selecting the XPolicyLab backend. The only actual OmegaConf use in that module builds RLinf configuration. This is an observed import-boundary/dependency blocker; no dependency install, source fix or retry was attempted after failure.
  • Planner never entered; no pi0_pick, completed policy request or task-success result. No flash_trace.json was produced.
  • Videos: put_bottles_into_dustbin/videos/episode_2026-09-18_00-04-49_{cam_head,cam_left_wrist,cam_right_wrist}.mp4, each 44 bytes. All fail OpenCV/FFmpeg-backed decoding with moov atom not found, opened=False, zero frames. System ffmpeg/ffprobe commands were unavailable; decoding was checked using <venv>/bin/python and cv2.VideoCapture.
  • Cleanup: runtime detected VLA exit and cleaned up. Main PID 957185 and service PIDs 957217/957218/957219 no longer exist. nvidia-smi --query-compute-apps=pid,process_name,used_gpu_memory --format=csv,noheader returned no processes; GPU returned to 20 MiB / 0%.
  • fill_pen_holder: NOT RUN under stop-on-first-failure rule.
  • Flash export/eval-fair: BLOCKED / NOT RUN; no dev trace or valid frozen plan. Runtime privilege/reward/predicate checks remain unverified, distinct from existing offline contract coverage.
  • No repository changes; no new commit or push needed. Worktree clean, research main clean and unchanged at 567e404. Evidence remains outside git.

Logs

  • evidence/pr96-p5-20260918/put_bottles_into_dustbin/console.log
  • evidence/pr96-p5-20260918/put_bottles_into_dustbin/robodojo_env_server.log
  • evidence/pr96-p5-20260918/put_bottles_into_dustbin/robodojo_vla_server.log
  • evidence/pr96-p5-20260918/put_bottles_into_dustbin/sam3_server.log

PR metadata

Updated title to the repository's Conventional Commit style (under 70 characters): feat(robodojo): add robot backend with eval-fair Flash replay.
gh pr edit failed because this installed gh version requests deprecated Projects classic GraphQL fields. The same authorized update succeeded through gh api --method PATCH repos/RLinf/RPent/pulls/96.
Replaced stale research-result claims and obsolete CLI/server references with current P0-P4 infrastructure scope, validation and limitations.

@littleZ05

littleZ05 commented Sep 17, 2026

Copy link
Copy Markdown
Author

P5 lazy-import regression fix and rerun

Local commit: cd24e20 (fix(vla): defer RLinf configuration dependency imports). Not pushed: the requested all-green smoke gate was not met.

OmegaConf is imported only when building RLinf model configuration; missing installation raises a backend-specific error identifying the policy Python environment. Torch and RLinf imports were already lazy. New contracts execute the XPolicyLab CLI with OmegaConf/RLinf/Torch blocked and verify the RLinf missing-OmegaConf error.

Offline validation

  • PYTHONPATH=<repo-checkout> <pi05-venv>/bin/python -c 'import rpent.robots.components.pi05_vla_server': passed without installing OmegaConf.
  • .venv/bin/ruff check --preview .: passed.
  • .venv/bin/ruff format --check .: passed after formatting the new test.
  • .venv/bin/pytest tests/unit_tests/rpent/robots/components/test_pi05_vla_server_contracts.py -q: 14 passed.
  • .venv/bin/pytest tests/unit_tests -q: 635 passed, 3 skipped, one dependency deprecation warning (28.52 seconds).
  • .venv/bin/pre-commit run --all-files: passed.
  • make -C docs html LANG=en SPHINXBUILD=<repo-checkout>/.venv/bin/sphinx-build SPHINXOPTS='-W --keep-going -E -q': passed; same command with LANG=zh passed.

Real smoke: failed at toolkit construction

Command: bash evidence/pr96-p5-lazy-import-20260918/run-dev.sh put_bottles_into_dustbin.

The script records the full environment and exact CLI: worktree imports, gpt-6-astra/low, layout 1, GPU0, single sim, 1780-second timeout with 20-second kill grace, explicit source/Python/checkpoint paths, isolated memory and output paths. No research-main files were changed.

Wall time: 55.93 seconds, exit code 1. No retry after failure.

  • Env listener: http://127.0.0.1:35387.
  • SAM3 loaded checkpoint and listened at http://127.0.0.1:48207.
  • XPolicyLab connected at ws://localhost:37693; shared VLA RPC listened at http://127.0.0.1:34295. The original import regression no longer blocks startup.
  • Next blocker: TypeError: get_toolkit() got an unexpected keyword argument 'runtime_kwargs'. CLI callers at rpent/cli/main.py:557 and :574 pass runtime_kwargs, while robots/robodojo/robot_spec.py:141 accepts primitives_kwargs.
  • Planner did not enter and no pi0_pick call occurred. No usable dev action trace/frozen plan was produced.
  • Three files in put_bottles_into_dustbin/videos/, named episode_2026-09-18_00-18-33_{cam_head,cam_left_wrist,cam_right_wrist}.mp4, are each 44 bytes. OpenCV decoding fails for all three with moov atom not found, zero frames.
  • Main env/VLA/SAM3 service PIDs 959848/959849/959850 exited, but policy child PID 959944 survived and held 29750 MiB. Verified its task/port against this run and sent kill -TERM 959944. This is an automatic-cleanup failure, not a clean-shutdown pass.
  • After manual cleanup, PID 959944 disappeared; GPU0 returned to 20 MiB / 0%, with no compute processes. No 4090 was used.
  • fill_pen_holder and Flash: not run, per stop-on-first-failure instruction. Flash export is blocked before any dev action trace exists; no synthetic plan was created. Runtime privilege/zero-reward/no-predicate checks remain unverified.

Evidence (outside git)

  • evidence/pr96-p5-lazy-import-20260918/run-dev.sh
  • evidence/pr96-p5-lazy-import-20260918/put_bottles_into_dustbin.console.log
  • evidence/pr96-p5-lazy-import-20260918/put_bottles_into_dustbin/robodojo_env_server.log
  • evidence/pr96-p5-lazy-import-20260918/put_bottles_into_dustbin/robodojo_vla_server.log
  • evidence/pr96-p5-lazy-import-20260918/put_bottles_into_dustbin/sam3_server.log
  • evidence/pr96-p5-lazy-import-20260918/put_bottles_into_dustbin/transcript_put_bottles_into_dustbin_l1.json

The factory keyword mismatch and failure-path policy/video cleanup need separate fixes before the smoke sequence can pass. The import fix is committed locally but remains unpublished because the requested smoke gate failed.

@littleZ05

littleZ05 commented Sep 17, 2026

Copy link
Copy Markdown
Author

P5 toolkit interface fix and smoke rerun

Local commit: 0d883f7 (fix(robodojo): align toolkit factory with runtime interface), on top of cd24e20. Both remain local because the requested all-green smoke gate was not met.

Fix

RoboDojo's factory now accepts the same required keyword arguments as LIBERO/RoboCasa/RoboTwin: runtime_kwargs, dashboard_events, config. It creates MemoryManager from config and explicitly forwards runtime values to its internal toolkit; no catch-all kwargs or alternate public alias. Existing tool-group filtering and eval-fair behavior are preserved. Bilingual guides now distinguish the public factory argument from the internal toolkit argument.

The existing task/group tests now construct the real toolkit through the registry, checking memory and actual dispatch. New cases check all three missing required arguments and rejection of the obsolete keyword.

Validation

  • .venv/bin/ruff check --preview .: passed.
  • .venv/bin/ruff format --check .: passed after formatting the new test.
  • .venv/bin/pytest tests/unit_tests/robots/test_robodojo_runtime_contracts.py tests/unit_tests/robots/robodojo -q: 36 passed.
  • .venv/bin/pytest tests/unit_tests -q: 639 passed, 3 skipped, one dependency deprecation warning; 28.49 seconds, Python 3.11.
  • .venv/bin/pre-commit run --all-files: passed.
  • make -C docs html LANG=en SPHINXBUILD=<repo-checkout>/.venv/bin/sphinx-build SPHINXOPTS='-W --keep-going -E -q': passed; same command with LANG=zh passed.

Smoke: stopped at the first failure

Command: bash evidence/pr96-p5-toolkit-20260918/run-dev.sh put_bottles_into_dustbin.

The script contains the exact environment/CLI (worktree PYTHONPATH/RPENT_REPO_ROOT, gpt-6-astra/low, layout 1, GPU0, single sim, explicit interpreter/source/checkpoint paths, isolated local memory, 1780-second timeout plus 20-second kill grace). Wall time 55.72 seconds, exit code 1.

  • Env/VLA/SAM3 started. The toolkit factory succeeded and the MCP server listened at http://127.0.0.1:37913/mcp/.
  • Codex SDK was invoked, but failed before a model turn: InvalidRequestError: JSON-RPC error -32600: failed to load configuration: failed to parse model_catalog_json path ~/.codex/codex-models.json as JSON: missing field supports_parallel_tool_calls at line 1 column 23318.
  • No model tool calls or pi0_pick; no dev action trace. The global Codex configuration was not modified and no retry was attempted.
  • All three videos were finalized and decoded using OpenCV, 2/2 frames each: episode_2026-09-18_00-27-57_cam_head.mp4 (38092 bytes), cam_left_wrist.mp4 (32201 bytes), cam_right_wrist.mp4 (26103 bytes). This validates startup video decoding, not policy execution.
  • Env/VLA/SAM3 PIDs 962309/962310/962311 exited. XPolicyLab child PID 962405 survived holding 29750 MiB. Its task and port 37483 matched this run; sent kill -TERM 962405. Automatic cleanup is therefore still not a pass.
  • Final cleanup check: PID 962405 no longer exists; GPU0 is back to 20 MiB / 0%, with no compute processes.
  • fill_pen_holder: not run under stop-on-first-failure.
  • Flash: blocked/not run because no dev action trace exists. No plan was fabricated. Runtime privilege isolation, zero reward and predicate exclusion remain unverified.

Evidence outside git

  • evidence/pr96-p5-toolkit-20260918/run-dev.sh
  • evidence/pr96-p5-toolkit-20260918/put_bottles_into_dustbin.console.log
  • evidence/pr96-p5-toolkit-20260918/put_bottles_into_dustbin/{robodojo_env_server,robodojo_vla_server,sam3_server}.log
  • evidence/pr96-p5-toolkit-20260918/put_bottles_into_dustbin/codex_put_bottles_into_dustbin_l1.txt.stream.jsonl
  • evidence/pr96-p5-toolkit-20260918/put_bottles_into_dustbin/transcript_put_bottles_into_dustbin_l1.json
  • evidence/pr96-p5-toolkit-20260918/put_bottles_into_dustbin/videos/

Remaining blockers are the installed Codex SDK/model-catalog compatibility and policy child cleanup on failure. Research main and the 4090 were not touched; no evidence was committed.

@littleZ05

littleZ05 commented Sep 17, 2026

Copy link
Copy Markdown
Author

P5d rerun at local 0d883f7 (+ cd24e20), not pushed: bash evidence/pr96-p5d-20260918/run-dev.sh put_bottles_into_dustbin completed in 526.86s, exit 0. Env/VLA/SAM3 and the model loop worked; one pi0_pick executed 12 policy chunks. All three videos finalized and decoded 615/615 frames.

Smoke still FAILED its cleanup gate: the XPolicyLab child survived parent shutdown holding 29772 MiB. After verifying this run?s task/port, manually terminated PID 964708; GPU0 returned to 20 MiB / 0%, no compute processes. Per stop-on-first-failure, fill_pen_holder and Flash replay were not run; no push.

Offline validation of the actual 14-entry dev trace also blocks Flash export: Depth pixel must be the segmentation box center. Entry 6 back-projects (row=259,col=76) after a segmentation whose integer center is (223,293). No trace rewriting or synthetic plan. Next: fix owned policy-child cleanup and test normal/error shutdown; then record fresh segment -> exact center depth -> action sequences before export/replay. pi0_pick heuristic success was false; planner finish success is not an official benchmark result.

Reproduction note: this installed Codex CLI requires supports_parallel_tool_calls in every model-catalog entry. The environment owner fixed the catalog before P5d (backup suffix (local backup)); no PR source/global configuration change was needed for that issue.

Exact command/environment: evidence/pr96-p5d-20260918/run-dev.sh. Console/wall time: .../put_bottles_into_dustbin.console.log. Logs, states.json, flash_trace.json, transcript and videos: .../put_bottles_into_dustbin/. Detailed local report: evidence/pr96-p5d-20260918/results.md. Evidence remains outside git.

@littleZ05

littleZ05 commented Sep 17, 2026

Copy link
Copy Markdown
Author

P5e local fixes: 181950c adds idempotent owned-policy cleanup, atexit and SIGTERM unwinding through ProcessDaemon; 88b32a7 unifies recording/replay mask-centroid derivation with strict version-2 plans and tamper rejection. Prior cd24e20/0d883f7 remain local too. Offline validation: 647 passed / 3 skipped; focused 35 passed; Ruff, pre-commit and both strict Sphinx builds passed.

Commands: bash evidence/pr96-p5e-20260918/run-dev.sh put_bottles_into_dustbin and the same script with fill_pen_holder (serial, one sim, PRO 6000 GPU0, gpt-6-astra/low).

  • Dustbin: 570.71s, exit 0, one pi0_pick / 12 chunks, all 3 videos decoded 615/615 frames. Automatic cleanup passed: no policy/compute processes, GPU 20MiB/0%, no manual kill.
  • Fill pen holder: 960.19s, exit 1: Codex SDK timed out after the unchanged 900s planner cap. Three pi0_pick calls (12/1/1 chunks), all 3 videos decoded 719/719 frames. Timeout cleanup also passed automatically, GPU 20MiB/0%.
  • Per stop-on-first-failure, Flash simulator was not run. Offline export of the untouched dustbin trace passed in 0.10s (exit 0), producing memory/robodojo/flash/put_bottles_into_dustbin_plan.json with version 2. No fabricated/edited trace; replay privilege/reward/predicate checks remain unverified.

No push because the complete smoke gate is not green. Next: bound the pen-holder smoke completion or agree a planner budget within the 30-minute cap, then run the remaining Flash checks. Old box-center plans must be rerecorded, not silently converted.

Evidence root: evidence/pr96-p5e-20260918/ (run-dev.sh, task.console.log, task/videos, states.json, flash_trace.json, service logs). Full commands/results: results.md there; all outside git. Reproduction note: the installed Codex CLI model catalog requires supports_parallel_tool_calls on every entry; the environment owner supplied it before this batch, and no global configuration was changed here.

@littleZ05

littleZ05 commented Sep 17, 2026

Copy link
Copy Markdown
Author

P5f closeout at 88b32a7: both remaining runtime smokes were executed serially on PRO 6000 GPU0, one simulator. Overall not green; no source changes or new push. The PR description now reflects current evidence rather than the superseded P5 startup failure.

bash evidence/pr96-p5f-20260918/run-dev.sh fill_pen_holder
bash evidence/pr96-p5f-20260918/run-flash.sh
  • Fill: 1859.01s, exit 1, Codex SDK timed out after 1800s; turn 4/40, 18 tool calls, four pi0_pick calls (12/2/2/1 chunks). --planner-timeout-s 1800 --max-turns 40 are smoke-specific overrides, not defaults. It was recovering remaining/dropped writing tools; final pick returned at 02:16:08 CST, timeout at 02:17:08 while awaiting the next planner decision. This is a task/recovery/planner-duration budget shortfall, with no new startup/interface failure observed. All three videos: 873/873 frames fully decoded.
  • Flash: 133.69s, exit 1. Used the untouched P5e memory plan at evidence/pr96-p5e-20260918/memory/robodojo/flash/put_bottles_into_dustbin_plan.json via native --planner flash. Anchor grounding worked; pi0_pick ran 12 chunks/600 steps but returned grasp heuristic false, both grippers 0.999. The one-action plan has no preceding same-anchor approach move, so the existing hold/retry logic stops at Grasp not held; replay stopped. That exact branch is diagnosed from recorded output and code; the shared CLI does not serialize PlannerResult.error in its transcript. No second eval or modified plan. All three videos: 615/615 frames fully decoded.
  • Eval isolation passed: six allowed tools, no privileged tools/RPC calls; all 600 rewards were 0.0, done flags false, 615 observations obeyed the RGB-D/proprioception allowlist; no task predicates/GT object poses. Reward-free prompts, model=null, no LLM messages. flash-audit.json records the evidence-only, non-mutating audit.
  • Automatic resource cleanup passed for both: all owned services/policy child gone, no GPU0 compute processes, baseline 20 MiB / 0%, no manual kill. Shutdown was not error-free: both VLA logs report stdin _enter_buffered_busy at interpreter finalization; Flash renderer also logged a Hydra shutdown error. Shared parent-watch shutdown deserves a follow-up.

Next: profile fill planner/tool latency before selecting another bounded completion budget; record a genuinely held dev grasp (and a real same-anchor approach if retry is needed), then re-export. Do not weaken the Flash hold gate or synthesize a passing plan. Replay completion is not official task success.

Same-revision prior validation remains 647 passed / 3 skipped, Ruff check/format, pre-commit, EN/ZH strict Sphinx passed; no source changes, so not rerun in P5f. Prior dustbin dev: 570.71s, exit 0, 615 frames/camera, cleanup passed. Reproduction prerequisite: installed Codex model-catalog entries must declare supports_parallel_tool_calls (environment owner fixed this before these runs).

Exact runners/paths, timings, video frame reports and caveats: evidence/pr96-p5f-20260918/results.md, fill_pen_holder.console.log, flash.console.log, *.video-check.json, flash-audit.json; per-run logs/states/videos in fill_pen_holder/ and flash/. Evidence remains outside git; research main untouched.

@littleZ05

littleZ05 commented Sep 18, 2026

Copy link
Copy Markdown
Author

P6 fixes and bounded smoke results:

  • ac6fd66 ? raw-fd/select parent watcher with explicit cancellation/join, EOF-first shutdown for --parent-watch services and signal fallback. RobotWin's direct watcher consumer now also cleans up on model initialization failure; its policy contract is unchanged.
  • 656650c ? main-thread RoboDojo teardown: writer, camera annotators/render products, stale syntheticdata graph handles, Replicator, stage/app. Removes the asynchronous UI/event-loop teardown path.
  • c8bd725 ? preserve planner errors in transcript and final errors in run_diagnostics.json; bilingual bounded smoke guidance.

Validation: 658 passed / 3 skipped, Ruff check/format, pre-commit and EN/ZH strict Sphinx passed (Python 3.11). Includes real subprocess EOF/cancel/exit-0 tests, RobotWin lifecycle fakes, stale graph tick regression and dev/Flash error-artifact contracts.

bash evidence/pr96-p6-20260918/run-dev.sh

Dustbin layout 1, single sim, PRO 6000 GPU0 only; gpt-6-astra/low. Planner timeout 1500s/40 turns; outer timeout 1700s plus 20s grace (<30 min). These are smoke overrides, not defaults; the same bounded strategy is documented for fill.

990.66s, CLI/smoke exit 1. Planner ran one 10-chunk pi0_pick after symbolic mask-centroid grounding. Actual grasp heuristic and existing hold predicate were false; both grippers remained approximately open. The separate environment state reported terminated=true, retained as-is; that is not a held-grasp claim. No motion/reset followed. The provider then exhausted five reconnects with stream disconnected before completion: stream closed before response.completed, now serialized verbatim in both error artifacts. This attempt had stream failures, not the earlier HTTP 503.

Lifecycle acceptance passed: env/VLA/SAM3 exits 0/0/0, no fatal errors, no [Error]/traceback/stale graph/UI-loop error in env shutdown; only allowed headless GLFW warnings. Three MP4s finalized and fully decoded at 513 frames each. All owned/policy processes gone, GPU0 20 MiB / 0%, no manual cleanup.

Overall hold gate failed, so no plan export, Flash eval, or fill rerun. Successful replay on this revision remains unverified. No synthetic plan, weakened hold gate or replacement evaluation. Next: diagnose actual policy/scene grasp behavior and obtain a hold-accepted dev demonstration before export/eval. RobotWin/LingBot and Molmo GPU runs, hardware and other Python matrix legs were not tested here.

Evidence (outside git): evidence/pr96-p6-20260918/{results.md,dev-audit.json,dev.console.log} and dev/ (states/trace/transcript/service logs/videos). Scripts contain exact runtime paths and gate assertions. Research main remains untouched at 567e404.

Environment reminder: installed Codex catalog entries require supports_parallel_tool_calls; the owner applied that prior fix. No global configuration changes in this phase. PR description updated with current checks, historical evidence and remaining limitations.

@littleZ05

littleZ05 commented Sep 18, 2026

Copy link
Copy Markdown
Author

P7 hold follow-up: not green; local fix 3f126b2 is not pushed (PR remains c8bd725).

  • P6 videos show bottles were grasped/carried and then placed/released. Neither arm met the existing 6cm descent gate (2.67cm / 0.38cm). A separate code bug allowed remaining chunk actions after detecting a pick; the local fix stops immediately, retains both-arm monitoring/thresholds, and reports minimum aperture/action count. Contracts cover the release regression and recorded approach/bounded recovery. held is proprioception + wrist perception, not a native task-success predicate.
  • Offline: 659 passed / 3 skipped; Ruff check/format, pre-commit, EN/ZH strict Sphinx passed. Python3.11 only.
  • Real command: bash evidence/pr96-p7-20260918/run-dev.sh (worktree PYTHONPATH/RPENT_REPO_ROOT, GPU0/single sim, layout1, gpt-6-astra/low, planner1500s/40 turns, outer1700s+20s).
  • 962.48s, CLI0 / finish(stuck), smoke1. Explicit approach reached within3mm in8 steps. The white-cap query then switched from the upright bottle to a different horizontal white bottle (centroid [249,174]?[223,292], ~22.3cm world anchor jump), repeated identically on recheck. Planner stopped before pick: 0 chunks, hold not established, native task success=false. No provider disconnect this time.
  • Cleanup passed: env/VLA/SAM3 0/0/0, clean shutdown (headless GLFW warnings only), three videos 20/20 decoded frames each, no residual policy/services, GPU0 returned 20MiB/0%.
  • Per stop-on-failure: no export or Flash run; current runtime isolation and replay remain unverified. Next validate a distinctive symbolic target and visibility-preserving approach against saved before/after RGB-D; matching query/confidence alone does not establish persistent object identity. No gate relaxation or extra blind trial.

Full commands, raw paths and limitations: evidence/pr96-p7-20260918/results.md; audits/trace/videos in that directory, outside git. Environment reminder: this installed Codex catalog requires supports_parallel_tool_calls in every model entry; no global settings changed.

@littleZ05

Copy link
Copy Markdown
Author

P8 identity follow-up: not green; commits 3f126b2 and 963a30d remain local.

Added shared 5cm first-head-anchor consistency (AnchorTracker), opt-in dev locate_anchor, fresh pre-motion and post-approach/pre-pick checks, Flash/export reuse, and EN/ZH guidance/contracts. Offline: 662 passed / 3 skipped, Ruff/pre-commit/strict Sphinx all passed.

Real dev: bash /home/admin/robodojo_runtime/evidence/pr96-p8-20260918/run-dev.sh, 1028.65s, GPU0/single sim. Anchor identity passed (centroid [169,167] -> [170,167], 2.249mm); approach reached within2.4mm. Pi0 pick ran 1 chunk/36 actions and its unchanged heuristic returned pick_success=true, but head/wrist evidence showed the blue target still on the table and a different white bottle in the gripper. held=false, native success=false; planner stopped, no retry.

Infrastructure passed: env/VLA/SAM3 0/0/0, three videos 49/49 decoded, no residual processes, GPU20MiB/0%, no provider disconnect. No plan export or Flash run after failed target hold. Remaining blocker is checkpoint target selection; inspect language conditioning before another trial. Full report/raw paths: /home/admin/robodojo_runtime/evidence/pr96-p8-20260918/results.md (outside git). Environment note about supports_parallel_tool_calls remains applicable.

@littleZ05

Copy link
Copy Markdown
Author

P9 official task language (local, not pushed)

Local 3864c6a fixes raw-template task-language RPC: prefer official description manager, otherwise fill every label from public layout descriptions, fail explicitly on unresolved/empty text; observations use the same resolver. pi0_pick now defaults to official language if prompt is omitted; explicit identity overrides remain supported and template markers are rejected. EN/ZH docs and contracts included. 676 passed /3 skipped, Ruff/format/pre-commit/strict bilingual Sphinx passed.

Before-fix CPU execution of actual original methods returns Pick up the <target> by 10 cm. Official HDF5 at the supplied location has root /instruction (not additional_info/instruction), value Pick up the lavender plastic shovel by 10 cm. However, official observations already used resolved descriptions, and P8's dustbin pick had an explicit blue-target override; that template defect is not established as P8's cause.

Same-P8 smoke command: bash /home/admin/robodojo_runtime/evidence/pr96-p9-20260918/run-dev.sh. Same dustbin/layout1/blue anchor/staging/arm/chunks/budgets; only omitted pick prompt to test official default. Actual RPC and VLA strings both: Pick up the bottles and throw them into the dustbin, using handover when needed. 810.99s, CLI0/smoke1; 1chunk/33 policy actions (35 total), pick_success=true but held=false: white bottle grasped, designated blue target remains on table. Native success=false. No provider disconnect. Services0/0/0, videos46/46 decoded each, clean shutdown/no residual processes, GPU20MiB/0%.

No export/Flash after failed target hold. Current Flash isolation/replay and real general_pickup scene remain unverified. No push or pull-rebase: 3f126b2, 963a30d, 3864c6a remain local pending green smoke; authenticated user littleZ05. Next investigate checkpoint instance-selection support, not lower gates. Evidence: /home/admin/robodojo_runtime/evidence/pr96-p9-20260918/results.md and language_probe.py (outside git).

get_task_language returned the raw general_pickup template, so callers could
receive the literal placeholder instead of the description the environment
publishes. Resolve language through RoboDojo's description manager, fall back
to expanding labels from the layout descriptions, and reject empty or
unresolved strings at the boundary. Observations expose the same resolved
value, and pi0_pick defaults to it while still rejecting template markers in
explicit overrides.
@littleZ05

Copy link
Copy Markdown
Author

Pushed 2eaad5e.

get_task_language returned the raw general_pickup template, so a caller could
receive the literal placeholder Pick up the <target> by 10 cm. instead of the
description the environment itself publishes. The recorded official traces show
the expected form, e.g. Pick up the lavender plastic shovel by 10 cm.
(additional_info/instruction in the released episodes).

The RPC and the public observations now resolve language through RoboDojo's
description manager, fall back to expanding each <label> from
layout_manager.get_label_descriptions(label=..., env_idx=0), and raise on empty
language or leftover template markers instead of substituting the task name.
pi0_pick.prompt is now optional and defaults to the resolved language; explicit
overrides stay supported but are rejected before inference if they still contain
template markers.

Verified on this branch: 672 passed, 3 skipped (offline unit scope), ruff check
and format, pre-commit, and strict EN/ZH Sphinx (-W --keep-going -E).

@@ -0,0 +1,297 @@
Adding a Robot Backend

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove the Adding a Robot Backend section, it's already in add_robot doc

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed in 541a25f. The duplicated backend-integration steps ("register the backend", "define the environment contract", "assemble tools", "reuse the policy service") are gone from both index files, which now keep only what is specific to RoboDojo: the module list, capability scope and limitations, and the installation pointer, plus a pointer to development/add_robot.

Comment thread rpent/robots/components/xpolicylab_vla_server.py Outdated
Comment thread robots/robodojo/env_server.py Outdated
pi05_root = args.policy_root
if not pi05_root:
raise ValueError("--policy-root is required for a local XPolicyLab server")
launcher = os.path.join(pi05_root, "setup_eval_policy_server.sh")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setup_eval_policy_server.sh, is this provided by upstream or your local script? if it is latter, please use a more standard method.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Upstream — the PR does not ship that script.

_spawn_policy_server resolves launcher = <policy-root>/setup_eval_policy_server.sh, and --policy-root points into RoboDojo's XPolicyLab submodule (XPolicyLab/policy/Pi_05/). RoboDojo tracks that submodule itself, e.g. 36bfcb7 [scripts] chore: bump XPolicyLab submodule to latest main. So this is the upstream-provided entry point; we only pass its arguments.

The /tmp log next to it was ours, and it is fixed in the follow-up commit on this branch: the policy server log now goes to <output-dir>/vla_server.log, and the RoboDojo launcher passes its run output directory down.

Comment thread rpent/robots/components/perception_tools.py Outdated
Comment thread robots/robodojo/tools.py
"general": frozenset(
{"back_project", "segment", "move_to", "pi0_pick", "stabilize"}
),
"privileged": frozenset({"get_reward_details", "get_safety_status"}),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just curious, what is the use of privileged tools?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is the eval-fair isolation gate.

TOOL_GROUPS classifies each RoboDojo tool as general, privileged or mixed, and get_toolkit(allowed_tool_groups=...) filters registration by group. In dev mode nothing is filtered, so the planner can read get_reward_details (reward breakdown, per-stage progress) and get_safety_status (rolling / off-table alarms) and use them to correct a failing run.

In Flash replay (--planner flash, mode eval-fair) robots/robodojo/toolkit.py intersects the allowed groups with {"general", "mixed"}, and env_server additionally drops env.get_reward_details, env.get_safety_status, env.is_success and env.reset from the RPC table. A replay therefore cannot consult reward, and cannot reset the episode. mixed covers tools such as view_env_state / set_gripper / place_in_bin that are needed on both paths, which is why they are not in general.

@littleZ05

Copy link
Copy Markdown
Author

Pushed 541a25f (fast-forward on top of the main merge). All findings from the latest review round:

Finding Resolution
guides/interface.md looks generated; fold useful parts into the docs File removed; RoboDojo-specific content merged into docs/source-{en,zh}/rst_source/usage/robodojo/index.rst
"Adding a Robot Backend" duplicates development/add_robot Duplicated steps removed from both index files; a pointer to development/add_robot remains
/tmp log in the policy server Log moved to <output-dir>/vla_server.log; pi05_vla_server gained --output-dir, passed down by the RoboDojo launcher
/tmp save_dir in env_server Replaced by an explicit --save-dir, passed from the run output directory
Shared perception abstraction Reverted: RoboDojo keeps local view_env_state / back_project, robots/libero/tools.py matches upstream/main exactly, and rpent/robots/components/perception_tools.py plus its test are gone
Is setup_eval_policy_server.sh ours? Upstream — it lives in RoboDojo's XPolicyLab submodule, resolved from --policy-root
What are privileged tools for? Eval-fair isolation: get_reward_details / get_safety_status are readable in dev and excluded from the Flash replay allowlist

Verification on this commit: 669 passed, 3 skipped (offline unit scope; the three removed cases are the deleted perception contract tests), ruff check and format, pre-commit, and strict EN/ZH Sphinx (-W --keep-going -E). The only GPU/simulator-backed checks remain the ones already recorded in this thread; no new smoke was run for this round.

The installation page deferred the whole environment build to upstream and
never mentioned the pieces this integration actually depends on. Add a Python
environments section that states why the RoboDojo simulator, Pi_05 and RPent
interpreters have to stay separate, which upstream installer builds each one,
the versions this backend is validated against, and that RPent reaches the
child services through PYTHONPATH rather than being installed into the policy
environment.

Also record the placement settling budget the backend needs in official mode,
note that each service writes into the run output directory, and add a
verification section with one bounded development run, the files and logs it
should leave behind, and the expected observation keys.
@littleZ05

Copy link
Copy Markdown
Author

Pushed dd4318a. The installation page no longer only defers to upstream:

New "Python environments" section. States why the RoboDojo simulator, Pi_05 and RPent interpreters must stay separate (Isaac Sim pins websockets==12.0, numpy==1.26.0, packaging==23.0, filelock==3.13.1, typing_extensions==4.12.2), which upstream installer builds each one (RoboDojo/scripts/install.sh, XPolicyLab/policy/Pi_05/install.sh), the versions this backend is validated against (isaacsim 5.1.0.0, torch 2.7.0+cu128, viser 0.1.34, tyro 0.9.0, warp-lang 1.11.0, CuRobo from third_party/curobo), and that RPent is deliberately not installed into the policy environment: the CLI composes PYTHONPATH for every child service from the repo root, --source-root and --xpolicylab-root.

ROBODOJO_PLACEMENT_SETTLE_STEPS is now documented. It is read by the RoboDojo checkout rather than by RPent, and the default of 20 leaves placements unstable in official mode.

New "Verify the installation" section. One bounded development run, the logs it should leave (robodojo_env_server.log, sam3_server.log, robodojo_vla_server.log, and vla_server.log once the policy server is spawned), the observation keys and cameras, and the per-camera MP4s. It also notes the run-output-directory convention added in 541a25f.

The page still delegates the Isaac Sim build itself to the upstream installer, since duplicating it would drift.

Verified on this commit: strict EN/ZH Sphinx (-W --keep-going -E), 669 passed, 3 skipped, ruff check/format and pre-commit clean.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants