packages/robot/docs/SSD_PORT_ASSESSMENT.md
Scope: /media/shaw/Extreme SSD/hyperscape-robot-workspace/ and sibling directories.
Target: Porting to /home/shaw/milady/eliza/packages/robot/ (Python) and /home/shaw/milady/eliza/plugins/plugin-ainex/ (TypeScript).
Assessment Date: 2025-05-18
Total SSD Codebase Size: 14G
| Directory | Purpose | Port Verdict | Notes |
|---|---|---|---|
ainex-robot-code/ | Main robot codebase (training, bridge, perception) | DIRECT | 26 subdirs, 14G total; core training+bridge portable |
training/ | Parallel to ainex-robot-code, RL training scripts & exports | REFACTOR | Appears to be duplicate/sibling; consolidate with ainex-robot-code/training |
data-capture/, data-pipeline/ | Data processing for training datasets | REFERENCE-ONLY | Specialized data ingestion; defer to v2 |
huggingface/ | HuggingFace models, probably fine-tuning or inference | SKIP | Model hosting; separate MLOps problem |
paper/ | ICLR 2025 submission (TeX, PDF, figures) | REFERENCE-ONLY | Architecture decisions documented; read for constraints |
hyperscape/ | Hyperscape game engine integration | SKIP | Game logic; already in main eliza repo |
printables/ | STL/printable parts for physical assembly | SKIP | Hardware CAD; separate CAM process |
fleet/ | Multi-robot orchestration (if any) | SKIP | Not in core path for single-robot MVP |
turboquant/ | KV-cache compression library (PyTorch) | REFERENCE-ONLY | Optional optimization; document as future enhancement |
eliza/ | Parallel Hyperscape-fork eliza repo | SKIP | Use main /home/shaw/milady/eliza instead |
GAIT_SOURCE_CODE.py | Root file: Hiwonder gait primitives (Bezier, cubic spline) | DIRECT | Self-contained numpy; ~360 LOC; critical for gait baseline |
report.md | Architecture narrative + prior art analysis | REFERENCE-ONLY | Excellent framing; 200+ lines of design rationale |
Summary:
ainex-robot-code/ (bridge, training/mujoco, training/rl, perception, eliza Python plugin)training/ if separate; check for overlapPinned versions in source:
/media/shaw/Extreme SSD/hyperscape-robot-workspace/ainex-robot-code/requirements.txt: Exact pins: mujoco>=3.5.0, mujoco-mjx>=3.5.0, jax[cuda12]>=0.4.30, brax>=0.12.0/media/shaw/Extreme SSD/hyperscape-robot-workspace/ainex-robot-code/bridge/requirements.txt: websockets>=12.0,<14.0/media/shaw/Extreme SSD/hyperscape-robot-workspace/training/requirements.txt: Tight on torch, transformers, no upper bound on most JAX depsRisk: JAX+JAXlib version skew; numpy<2 constraint will bite if dependencies pull numpy2; mujoco-mjx versioning must track mujoco exactly.
Source: /media/shaw/Extreme SSD/hyperscape-robot-workspace/ainex-robot-code/bridge/protocol.py
CommandEnvelope (client → server):
{
"type": "command",
"request_id": str,
"timestamp": str (ISO 8601),
"command": str,
"payload": dict,
"preempt": bool = False
}
ResponseEnvelope (server → client):
{
"type": "response",
"request_id": str,
"timestamp": str,
"ok": bool,
"backend": str,
"message": str,
"data": dict
}
EventEnvelope (server → client, async):
{
"type": "event",
"event": str,
"timestamp": str,
"backend": str,
"data": dict
}
From protocol.py lines 93–104:
| Command | Payload | Purpose |
|---|---|---|
walk.set | {speed: 1-4, height: 0.015-0.06, x: -0.05-0.05, y: -0.05-0.05, yaw: -10-10} | Set walk parameters (velocity + height) |
walk.command | {action: "start"|"stop"|"enable"|"disable"|"enable_control"|"disable_control"} | Control walk state machine |
head.set | {pan: -1.5-1.5 rad, tilt: -1.0-1.0 rad, duration: 0-5 s} | Pan/tilt head |
action.play | {name: str} | Play predefined action/gesture |
servo.set | {duration: 0-5, positions: [{id: 1-24, position: 0-1000}]} | Direct servo PWM control |
policy.start | {task: str, hz?: 1-30, model?: str, max_steps?: 1-100000} | Launch RL policy |
policy.stop | {} | Stop active policy |
policy.tick | {} | Single step (used with external loop) |
policy.status | {} | Query policy state |
From protocol.py lines 106–116:
| Event | Data | Purpose |
|---|---|---|
session.hello | {backend: str, version: str, ...} | Server boot announcement |
telemetry.basic | {battery_mv, roll, pitch, walking: bool, ...} | IMU + battery snapshot |
telemetry.perception | {entities: [...], image_metadata: {...}} | Vision pipeline output |
telemetry.policy | {task, step, reward, observation, action} | RL policy telemetry |
safety.deadman_triggered | {reason: str} | Watchdog / rate-limit violation |
safety.policy_guard | {rejected: bool, reason: str} | Pre-execution action validation |
policy.status | {running: bool, task: str, step: int} | Async policy state update |
Source: /media/shaw/Extreme SSD/hyperscape-robot-workspace/ainex-robot-code/bridge/validation.py
[0.015, 0.06]; x,y must be [-0.05, 0.05]; yaw must be [-10, 10]; speed must be [1,2,3,4][-1.5, 1.5]; tilt [-1, 1]; duration (0, 5][0, 1000]; duration (0, 5][1, 30]; max_steps [1, 100000]Port notes:
policy.tick requires external control loop (useful for debugging)training/mujoco/Core Environments (all inherit from AiNexEnv or MjxEnv, JAX-compatible):
| Environment | File | Class | Obs Dims | Reward Terms | Status |
|---|---|---|---|---|---|
| Joystick | joystick.py | Joystick(AiNexEnv) | ~60 (gyro+gravity+joint+vel+action+history) | track_lin_vel (10), track_ang_vel (6), feet_phase (0.5), orientation, energy | Active (v23+v26 tuning) |
| Target Reaching | target.py | TargetReaching(AiNexEnv) | ~70 (+ target position) | reach_target (8), lin_vel_z (-2), orientation, stand_still, energy | Active |
| GetUp | getup.py | GetUp(AiNexEnv) | ~50 (gyro+gravity+joint+vel+last_action) | orientation (1.0), torso_height (5.0), posture (2.0), stand_still (2.0), action_rate, dof_limits | Active (recovery from falls) |
| Grasp | grasp.py | Grasp(MjxEnv) | ~80 (all dofs + object pose + gripper state) | reach_distance (8), grasp_contact (5), grasp_hold (20), stability | Active (needs scene XML) |
| Carry | carry.py | Carry(MjxEnv) | ~100 (grasp + locomotion + object tracking) | reach (5), grasp_contact (3), grasp_hold (10), target_distance (10), delivery (50) | Active (multi-phase) |
| Place | place.py | Place(MjxEnv) | ~80 (grasped object assumed, lower + release) | approach_target (8), lower_object (5), release_precision (15), placement_success (50) | Active |
| Wave | wave_env.py | WaveEnv(CompositionalEnv) | ~70 (upper-body focus) | gesture_tracking, action smoothness | Active (upper-body only) |
| Compositional | compositional_env.py | CompositionalEnv(AiNexEnv) | Configurable (multi-task) | Weighted sum of subgoal rewards | Experimental (meta-RL) |
| Demo | demo_env.py | DemoEnv (non-JAX) | Includes egocentric camera, red ball track | walk_to_ball reward | Demo-only (CPU inference) |
Source: /media/shaw/Extreme SSD/hyperscape-robot-workspace/ainex-robot-code/training/mujoco/base_env.py
AiNexEnv(MjxEnv) provides:
ainex_primitives.xml (pure-shape, no meshes, GPU-fast)Key asset files (in training/mujoco/):
ainex.xml — original mesh model (unused for training)ainex_primitives.xml — training model (capsules, boxes, no meshes)ainex_primitives_realistic.xml — corrected mass/forceainex_grasp_scene.xml — extends primitives + graspable object + contactsainex_mjx.xml — MJX variant (if different)ainex_constants.py — DOF counts, body names, site namesShared reward scales (from joystick.py default config):
tracking_lin_vel: 10.0
tracking_ang_vel: 6.0
orientation: -1.5
torques: -0.0001
action_rate: -0.01
feet_phase: 0.5 # Bezier gait tracking
Notable observations:
GAIT_SOURCE_CODE.pyenable_entity_slots=TrueCount: 9 test files in training/mujoco/tests/:
test_joystick_env.py — basic env init + steptest_target_env.py — target spawn + distance rewardtest_sensors.py — IMU/contact sensor accesstest_inference.py — checkpoint loading + inferencetest_domain_randomization.py — DR curriculumtest_train.py — training looptest_compositional_env.py — multi-tasktest_entity_slot_training.py — perception encodingtest_arm_control.py — arm trajectory trackingAll use JAX_PLATFORMS=cpu pytest (no GPU required for unit tests).
Path: /media/shaw/Extreme SSD/hyperscape-robot-workspace/ainex-robot-code/checkpoints/
Total: 2.2G across 20 directories
mujoco_locomotion_v1-v7 ~1.0M each (early iterations)
mujoco_locomotion_v10-v20 ~1.0M each (20 latest iterations)
mujoco_locomotion_v13_flat_feet ~1.0M (special: flat-footed variant)
mujoco_locomotion_v14-v20 ~1.0M each (recent; v20 is latest)
Total files per checkpoint: config.json (~1.7K), metrics.json (~1.3K)
(Very lightweight—actual weights likely stored in separate neural-net checkpoints)
Best candidate: mujoco_locomotion_v20/ (latest, ~2.0M)
config.json, metrics.jsonAlternative: Create a minimal 10-step policy checkpoint (~5MB) for unit test
Risk: If weights are stored elsewhere (S3, HuggingFace), CI script must fetch them; current checkpoint dirs contain only JSON metadata.
/media/shaw/Extreme SSD/hyperscape-robot-workspace/GAIT_SOURCE_CODE.py
~360 lines, pure NumPy, self-contained
get_rz(phi, swing_height=0.08) (lines 18–86)
x³ + 3(x²(1-x)) creates smooth stance→swing→stance phaseinitialize_gait_phase(rng, dt, gait_freq_range, foot_height_range) (lines 92–150)
phase, phase_dt, gait_freq, foot_heightget_rz() + initialize_gait_phase() to packages/robot/gait.pySelf-contained: Yes (only numpy)
Missing:
Port verdict: DIRECT with minor integration glue
/media/shaw/Extreme SSD/hyperscape-robot-workspace/ainex-robot-code/eliza/packages/python/elizaos_plugin_ainex/
| File | Role | Actions/Providers |
|---|---|---|
plugin.py | Plugin registration | Registers all actions + providers to ElizaOS runtime |
actions.py | Command handlers | walk_command, walk_set, policy_start, policy_stop, policy_tick, policy_status, action_play, head_set, servo_set |
providers.py | Scene state suppliers | get_robot_state, get_environment_state, get_available_actions |
bridge_client.py | WebSocket client | AinexBridgeClient with async command/event methods |
execution_service.py | Intent executor | Maps LLM output → RL policy invocation + monitoring |
replanner.py | Failure recovery | Re-plans if action fails or timeout |
agent.py | Agent lifecycle | Wraps ElizaOS agent with robot-specific context |
cli.py | Command-line entry | Start agent, list plugins, etc. |
actions.py)walk_command_handler:
action ∈ {start, stop, enable, disable, enable_control, disable_control}client.walk_command(action)walk_set_handler:
x, y, yaw, speed, heightclient.walk_set(...)policy_start_handler:
task, hz?, max_steps?client.policy_start(task, ...)(Other actions): head_set, servo_set, action_play, policy_stop, policy_tick, policy_status — similar pattern
providers.py)get_robot_state():
_battery_percentage() and _imu_stability() helper functionsget_environment_state():
_bearing_description(x, y, z):
Current: Python ElizaOS plugin (elizaos Python interop)
Target: Rewrite as TypeScript plugin in /home/shaw/milady/eliza/plugins/plugin-ainex/
Feature parity needed:
Risk: Python plugin currently depends on bridgeClient instance injected at runtime; TypeScript port must establish similar injection or DI pattern.
Source: /media/shaw/Extreme SSD/hyperscape-robot-workspace/ainex-robot-code/bridge/openpi_adapter.py
build_observation(perception: AinexPerceptionObservation) → OpenPIObservationPayload
Translates robot perception into OpenPI VLA wire format:
Action decoding (reverse direction):
decode_action(response) → dict with arm/leg joint targetsSource: /media/shaw/Extreme SSD/hyperscape-robot-workspace/ainex-robot-code/bridge/openpi_loop.py
OpenPIPolicyLoop class:
Manages:
Methods:
start_perception(frame_source) — Launch perception threadupdate_telemetry(data) — Inject robot statestep() — Query policy, dispatch actionEnv vars / Endpoints:
--policy-url http://localhost:8000/infer (default)--camera-device 0 (default)--hz 10.0 (default)Risk:
/infer endpointTotal: 259 test files across entire ainex-robot-code
| Directory | Count | Key Tests |
|---|---|---|
bridge/tests/ | 27 | protocol parsing, command validation, backend parity, safety |
training/mujoco/tests/ | 9 | env init, inference, domain randomization, entity slots |
training/rl/tests/ | 6 | skill registry, command parser, Brax policy deployment |
training/schema/tests/ | 2 | embodied context, hyperscape adapter |
training/demo/tests/ | 1 | demo env |
training/trajectory_db/tests/ | 1 | trajectory database |
training/datasets/tests/ | 1 | fine-tuning data formatting |
perception/tests/ | 20 | multicam fusion, ArUco, YOLO, entity slot encoding |
benchmarks/ | 160+ | (OSWorld, GAIA, SWE-bench, etc.; not robot-specific) |
| Other eliza/examples | 20+ | (agent-bench, LLM integration, etc.) |
High priority (must port):
training/mujoco/tests/test_joystick_env.py — Joystick env + Bezier gaittraining/mujoco/tests/test_inference.py — Checkpoint loading + inferencebridge/tests/test_protocol.py (if exists) — Protocol validationtraining/rl/tests/test_brax_target_skill.py — Skill deploymentMedium priority (port or mock):
perception/tests/ — Detector init (may require YOLO weights)training/trajectory_db/tests/ — DB schema (pure Python, no GPU)Low priority (skip or defer):
JAX_PLATFORMS=cpu python -m pytest training/trajectory_db/tests/ \
perception/multicam/tests/ training/rl/tests/ \
training/schema/tests/ training/datasets/tests/ \
training/demo/tests/ -q
No critical TODOs found in main robot code (training/, bridge/, perception/).
Scattered DEBUG logging pragmas:
run_visualizer.py: logging.DEBUG if args.verbose else logging.INFOtraining/finetune/*.py: Same logging guard (not a blocker)Labeling tool TODO:
software/labelImg/libs/canvas.py line ~800: # go outside of the shape's area for some reason. XXX (not robot-critical)ainex_grasp_scene.xml which extends primitives model; collision geometry untestedcompositional_env.py uses multi-phase reward; limited test coverageNo explicit [NOT STARTED] sections found. Code appears actively maintained (latest checkpoint is v20, March 26).
report.md (17KB) — Shaw's framing of the problempaper/llm_agents_rpg_robots_v2.tex (35KB) — ICLR 2025 draftpaper/llm_agents_rpg_robots_v2.pdf (75MB) — Rendered versionFrom report.md (lines 39–92):
EmbodiedContext abstraction:
type EmbodiedContext = {
episodeId, stepId, t,
instruction, dialogue, memorySummary,
cameras: {egoRgb, egoDepth, overheadRgb, overheadDepth},
transforms: {worldFromRobot, worldFromEgoCam, worldFromOverheadCam},
entities: [{id, type, slot, pose, velocity, affordances, relations, confidence, provenance}],
agent: {basePose, joints, contacts, heldEntityIds, locomotionState, manipulationState},
task: {phase, constraints, successCriteria}
}
GroundedIntent output from planner:
type GroundedIntent = {
verb: "navigate_to" | "face_entity" | "reach_to" | "grasp" | "carry_to" | "place",
targetEntityId?, targetPose?, parameters, constraints, success
}
Critical constraints:
Port bridge protocol → packages/robot/bridge_protocol.py
Port WebSocket bridge client → packages/robot/bridge_client.py
Port GAIT_SOURCE_CODE → packages/robot/gait.py
get_rz(), initialize_gait_phase()Port MuJoCo environments → packages/robot/mujoco_env.py
Port RL skills → packages/robot/rl_skills/
TypeScript plugin stub → plugins/plugin-ainex/
Execution service → packages/robot/execution_service.ts
Port perception pipeline → packages/robot/perception/
OpenPI adapter → packages/robot/openpi_adapter.py
Canonical schema → packages/robot/canonical_schema.py
End-to-end demo → examples/robot_walk_to_target/
gait.py (independent)
↓
canonical_schema.py (independent)
↓
mujoco_env.py ← (gait.py, canonical_schema.py)
↓
rl_skills/ ← (mujoco_env.py)
↓
bridge_protocol.py (independent)
↓
bridge_client.py ← (bridge_protocol.py)
↓
perception/ ← (canonical_schema.py)
↓
openpi_adapter.py ← (perception/, canonical_schema.py)
↓
execution_service.ts ← (bridge_client.py, rl_skills/, openpi_adapter.py)
↓
plugin-ainex/ ← (execution_service.ts, bridge_client.py)
| Risk | Impact | Likelihood | Mitigation |
|---|---|---|---|
| JAX+JAXlib version skew | Training fails | Medium | Pin all JAX ecosystem versions; test in CI on fresh venv |
| numpy<2 constraint breaks | Training fails | Medium | Upgrade numpy constraint in requirements, test with numpy 1.26.x + 2.x |
| Checkpoint weights location unclear | Inference fails | High | Audit checkpoint dirs; create S3 download script if needed |
| Grasp scene XML untested | Sim crashes | Medium | Add unit test for grasp_scene.xml XML parsing + MuJoCo load |
| OpenPI server unavailable | Policy loop hangs | Medium | Add timeout + fallback to Joystick behavior; document setup |
| Entity slot encoder dimension change | Obs shape mismatch | Low | Test perception pipeline initialization; log dim on startup |
| Bridge protocol in-the-wild | Clients diverge | Low | Publish protocol spec as JSON schema; enforce in CI |
| Perception not real-time | Plugin latency | Medium | Profile perception pipeline; consider HW acceleration (TensorRT) |
| Multi-foot gait phase sync | Broken walking | Medium | Test Bezier gait with all 4 legs; verify phase offsets |
| TypeScript plugin feature parity | Reduced capabilities | Medium | Maintain feature checklist; automated parity tests |
| Component | Size | Verdict | Effort | Notes |
|---|---|---|---|---|
| Bridge protocol + client | 400 LOC | DIRECT | 1 day | JSON envelopes, async WebSocket |
| GAIT_SOURCE_CODE | 360 LOC | DIRECT | 0.5 day | Pure numpy, no deps |
| MuJoCo environments (joystick + target + getup) | ~2500 LOC | DIRECT | 2 days | JAX+MuJoCo standard patterns |
| RL skills (walk, target, composite) | ~1500 LOC | DIRECT | 1.5 days | Checkpoint loading, inference |
| Perception pipeline | ~3000 LOC | REFACTOR | 3 days | Extract core; defer YOLO/ArUco tuning |
| OpenPI adapter | 400 LOC | DIRECT | 1 day | Pure schema translation |
| Trajectory DB | 800 LOC | DIRECT | 1 day | SQLite + Pydantic models |
| Eliza Python plugin | 800 LOC | REFACTOR | 2 days | Rewrite as TypeScript; adapt bridge client pattern |
| Tests (robot-critical) | 259 tests (20 core) | DIRECT | 2 days | Adapt to new package structure |
| Assets (XMLs, URDFs) | 6 files (~200KB) | DIRECT | 0.5 day | Copy verbatim; check paths |
Total estimated porting effort: 14–16 engineer-days for foundational MVP
Critical path: Bridge → Env → Skills → Plugin → Demo (6–8 days)
Bridge:
/media/shaw/Extreme SSD/hyperscape-robot-workspace/ainex-robot-code/bridge/protocol.py/media/shaw/Extreme SSD/hyperscape-robot-workspace/ainex-robot-code/bridge/validation.py/media/shaw/Extreme SSD/hyperscape-robot-workspace/ainex-robot-code/bridge/server.py/media/shaw/Extreme SSD/hyperscape-robot-workspace/ainex-robot-code/bridge/openpi_adapter.py, openpi_loop.pyTraining:
/media/shaw/Extreme SSD/hyperscape-robot-workspace/ainex-robot-code/training/mujoco/{joystick,target,getup,grasp,carry,place,compositional_env}.py/media/shaw/Extreme SSD/hyperscape-robot-workspace/ainex-robot-code/training/mujoco/base_env.py/media/shaw/Extreme SSD/hyperscape-robot-workspace/ainex-robot-code/training/rl/skills/{brax_walk_skill,brax_target_skill,composite_skill}.py/media/shaw/Extreme SSD/hyperscape-robot-workspace/ainex-robot-code/training/trajectory_db/{db,schema,models}.py/media/shaw/Extreme SSD/hyperscape-robot-workspace/ainex-robot-code/training/schema/canonical.pyGait:
/media/shaw/Extreme SSD/hyperscape-robot-workspace/GAIT_SOURCE_CODE.pyPerception:
/media/shaw/Extreme SSD/hyperscape-robot-workspace/ainex-robot-code/perception/pipeline.py/media/shaw/Extreme SSD/hyperscape-robot-workspace/ainex-robot-code/perception/entity_slots/sim_provider.pyPlugin (Eliza):
/media/shaw/Extreme SSD/hyperscape-robot-workspace/ainex-robot-code/eliza/packages/python/elizaos_plugin_ainex/{actions,providers,execution_service,bridge_client}.pyDocumentation:
/media/shaw/Extreme SSD/hyperscape-robot-workspace/report.md/media/shaw/Extreme SSD/hyperscape-robot-workspace/ainex-robot-code/README.md/media/shaw/Extreme SSD/hyperscape-robot-workspace/paper/llm_agents_rpg_robots_v2.{tex,pdf}End of Assessment