Skip to content

feat: add reBot DevArm RobStride support - #17

Draft
johnnynunez wants to merge 6 commits into
RLinf:mainfrom
johnnynunez:feat/rebot-robstride-support
Draft

feat: add reBot DevArm RobStride support#17
johnnynunez wants to merge 6 commits into
RLinf:mainfrom
johnnynunez:feat/rebot-robstride-support

Conversation

@johnnynunez

@johnnynunez johnnynunez commented Jul 20, 2026

Copy link
Copy Markdown

Summary

  • add a generic EnvRuntime lifecycle contract so robot-specific server/client wiring no longer lives in rpent/cli/main.py
  • preserve LIBERO behavior behind robots/libero/runtime.py, including early --suite / --task validation and nonzero startup errors
  • add a native, self-contained reBot DevArm B601-RS backend using motorbridge and SocketCAN; there is no wrc_demo dependency
  • expose guarded RPent tools for state, explicit arm enable, joint trajectories, calibrated gripper control, soft stop, reset, heartbeat, and emergency stop
  • package both robot backends and the reBot example YAML in the wheel

Safety behavior

  • startup registers IDs 1–7, enables active fault reporting, and reads RobStride mechPos (0x7019) plus status/fault telemetry without clearing faults, selecting a control mode, enabling torque, or sending a target; close confirms disable_all before releasing CAN
  • velocities are estimated from consecutive position samples rather than publishing the firmware-dependent mechVel scale
  • every admitted enable/motion captures a monotonic stop generation; stop/e-stop invalidates it permanently, so a later reset_stop cannot resurrect an older operation
  • reset_stop is rejected while any stop/disable transition is in progress and while disable_failed=true
  • enable_arm validates startup position, finite-difference velocity, and operation/fault status before selecting MIT mode; it enables only the six arm joints and holds the observed pose
  • repeated enable_arm is idempotent and preserves a physically enabled gripper state
  • the gripper remains disabled until calibrated and is enabled lazily only after travel/fault validation
  • stop_motion, emergency_stop, and shutdown use a priority RPC path that bypasses normal command serialization; feedback/command batches release the I/O lock between motors, so e-stop waits behind at most one motorbridge call before disable starts
  • every motion tick sends a waypoint or hold to every physically enabled motor, including the non-moving subsystem, before validating operation status and the actively reported raw fault/warning cache
  • joint and gripper trajectories abort fail-closed on transport errors, missing/nonzero status, faults/warnings, tracking error, excessive observed velocity, settlement timeout, or the server deadline
  • trajectory progress uses elapsed wall-clock time, so slow feedback can skip intermediate samples but cannot create catch-up command bursts
  • settlement requires consecutive in-tolerance samples below the configured velocity threshold
  • soft stop holds both the six arm joints and an enabled gripper at freshly measured positions and persists those fresh holds across reset
  • minimum-jerk duration uses the correct 1.875 peak-velocity factor
  • parameter reads are capped at 100 ms; nominal motion plus settlement is capped at 65 s, a hard server deadline fires at 68 s, and the client motion RPC timeout is 75 s
  • normal close always calls disable_all; if disable fails, it retains the controller and physically uncertain enabled/disable_failed state for retry instead of erasing it
  • an independent runtime heartbeat disables enabled motors if the RPent client disappears while the environment server remains alive
  • the pickle RPC server for physical hardware accepts loopback binds only
  • safety-critical rates, timeouts, gains, limits, and velocities have hard ceilings

Safety boundary

RobStride 0x7028 canTimeout exists on the tested B601 firmware but defaults to 0. Real-hardware tests on motor 7 found no post-enable mode_state 2 -> 0 transition after 21.5 seconds of host silence with raw 20000, either as a runtime write or after saving parameters in MIT mode. A manual disable was still required. Therefore neither 0x7028 nor motorbridge.set_can_timeout_ms() is treated as a verified watchdog, and a hard crash or SIGKILL of the environment-server process cannot be guaranteed fail-safe by Python. Real-hardware operation must remain attended with the arm supported and a physical emergency stop reachable. The PR remains draft for this reason.

Validation at 9bcaad87031e754dce7dc826e10b2d22f9c8543c

  • 77 passed with the complete test suite
  • deterministic concurrency tests cover e-stop during trajectory, enable, and lazy gripper enable; reset during disable; priority RPC dispatch; and heartbeat deadman expiration
  • failure tests cover transport errors, missing/persistent/in-motion status and faults across both enabled subsystems, stalled feedback, settlement/deadline timeout, failed shutdown disable and retry, NaN/Inf, unknown/nonnumeric config, loopback rejection, and process cleanup
  • Ruff lint and format checks pass on all backend/script/test Python files
  • compileall, git diff --check, and uv lock --check pass under the project Python 3.11.14 resolution
  • English and Chinese Sphinx documentation both build with -W --keep-going
  • a real wheel was built, inspected, installed without dependencies in a clean Python 3.11.14 venv, and verified to contain/import robots.rebot_robstride plus config/rebot_robstride.example.yaml
  • two passive hardware checks on can0 at 1 Mbit/s detected IDs 1–7; every motor reported status_available=true, status_code=0, fault_raw=0, and warning_raw=0; torque remained disabled and CAN remained ERROR-ACTIVE with zero error counters
  • no physical joint or gripper movement was performed; the hardware checks were limited to active fault reporting, passive telemetry/status reads, and confirmed disable_all on close

Dependencies

The optional Linux-only rebot-robstride extra adds motorbridge>=0.4.9 (MIT) and PyYAML>=6.0.

Add a generic environment runtime lifecycle, a guarded motorbridge SocketCAN backend for the seven-motor B601-RS arm, passive hardware validation, documentation, and unit tests.
@johnnynunez
johnnynunez marked this pull request as draft July 20, 2026 01:54
@johnnynunez

Copy link
Copy Markdown
Author

Independent safety review found blocking issues in preemptive e-stop, in-motion feedback/deadman behavior, startup validation, shutdown policy, minimum-jerk velocity bounds, config validation, loopback-only RPC exposure, LIBERO CLI failure handling, gripper settlement evidence, and package discovery. Marking this PR draft while these are corrected and covered by regression tests. No physical motion testing will be performed during the fixes.

Add preemptive stop RPCs, monitored fail-closed trajectories, startup guards, an agent heartbeat deadman, strict configuration validation, and safe shutdown behavior.

Also fix LIBERO CLI validation, package robot backends and config data in wheels, and extend concurrency, lifecycle, packaging, and safety regression coverage.
@johnnynunez

Copy link
Copy Markdown
Author

Safety-review remediation is now pushed in c4b3572.

The PR body has been updated with the preemptive stop path, monitored fail-closed control, startup/deadman/shutdown guards, wheel/CLI fixes, 49-test result, passive hardware evidence, and the explicit hard-server-crash safety boundary.

The PR remains draft pending the independent re-review of the remediated code.

Publish arm and gripper enabled state only after a final cancellation check under the I/O and state locks, so a concurrent emergency stop always wins. Reject overlong gripper profiles before lazy enable.
@johnnynunez

Copy link
Copy Markdown
Author

Follow-up safety audit pushed in 7282f8d: a final cancellation check under the I/O + state locks closes the post-hold enable publication race, and overlong gripper profiles are now rejected before lazy enable. Full suite: 51 passed. The PR remains draft pending independent re-review.

Prevent motion entry from clearing concurrent stop requests, hold an enabled gripper during soft stop, and latch disable failures until a confirmed emergency-stop retry.

Use wall-clock trajectory progress to avoid feedback-latency catch-up bursts and enforce hard configuration ceilings within the 75-second RPC budget.
@johnnynunez

Copy link
Copy Markdown
Author

Second-review remediation is pushed in 0c46445:

  • stop requests are no longer cleared by joint/gripper motion entry;
  • soft stop holds an enabled gripper at fresh feedback;
  • failed disable_all latches disable_failed and blocks reset;
  • safety config has hard ceilings within the 75 s RPC budget;
  • wall-clock profiles avoid feedback-latency catch-up bursts.

Validation: 62 passed, Ruff/format, compile/lock/diff, Sphinx -W, clean wheel install, and passive seven-motor hardware state/fault check. The PR intentionally remains draft because a hard environment-server crash still lacks a confirmed motor-side watchdog.

@johnnynunez
johnnynunez marked this pull request as ready for review July 20, 2026 04:09
@johnnynunez
johnnynunez marked this pull request as draft July 20, 2026 04:58
@johnnynunez
johnnynunez marked this pull request as ready for review July 20, 2026 07:36
@johnnynunez
johnnynunez marked this pull request as draft July 20, 2026 07:45
@qurakchin

Copy link
Copy Markdown
Collaborator

please rebase to main and use the new classes such as RpcFacade Daemon EnvSpec

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.

2 participants