Prepare a G1 policy for robot runners
Package your G1 policy, run the checks and resolve feedback before a supervised robot test.
Start here: package → test → submit
For a G1 robot run, ship one linux/arm64 Docker image with all dependencies installed and one ENTRYPOINT. A source ZIP, an ONNX model or run.sh alone is not a runnable robot package. Robot setup is handled by the runner; your submission needs its own container entrypoint.
- Build and save your complete controller as submission.tar. Keep your training framework and model format; ONNX is not a container requirement.
- Run that same image in the builder kit’s simulator with safety checks enabled, including counterfactual starts. Use your actual task scene and retain reports and traces.
- Publish a Unitree G1 policy ZIP and MP4. Include submission.tar if it fits; for a large image use the public archive reference below. Include source, required sensor details and evidence. New uploads receive packaging checks; owners can rerun latest checks.
Connect the controller to the safety interface
| Requirement | What to implement |
|---|---|
| Inputs | Read /safety/policy_observation, /safety/policy_state and read-only rt/lowstate. Preserve the kit’s exact joint order and units. |
| Outputs | Publish all 29 q, dq, kp, kd and tau slots to /safety/precheck. Explicitly hold joints outside your policy output. Host-approved gains apply. |
| Session and timing | Use checker-issued session_id and observation_id with increasing sequence. Observation freshness and next-command deadlines: 0.2 s. First simulation command: within 30 s. |
| Stop | Subscribe to /safety/abort and stop publishing. Never publish rt/lowcmd or rt/arm_sdk or control g1-safety-stops. |
| Sensors | Joints and IMU are standard. No camera images or lidar. Base state needs a configured qualified source. Declare extra dependencies; do not substitute simulated object state as proof of perception. |
If your policy needs additional sensors, include SENSOR_CONTRACT.md with the input format, rate, calibration, timestamps, coordinate frame, units, latency and behavior when input is lost. Package the required processing code and dependencies. The runner must connect and qualify these inputs before hardware testing.
Build and test the same image
docker buildx build --platform linux/arm64 --load -f template/Dockerfile -t g1-submission:local .
docker image inspect g1-submission:local --format '{{.Os}}/{{.Architecture}} {{json .Config.Entrypoint}}'
docker save g1-submission:local -o submission.tarDownload the builder kit above. Replace template/policy.py with your full controller and install its dependencies in template/Dockerfile. Copy submission.tar to containers/upload/submission.tar. Run from the kit root. Add --scene containers/upload/environment/scene.xml to every run for a custom scene and include all its assets.
bash sim.sh --seconds 60
bash sim.sh --seconds 60 --counterfactualsThe kit uses Docker Compose on Linux, macOS and Windows. The kit rejects startup-only reports and requires at least 10 simulated seconds after policy handoff; increase --seconds if needed. Keep containers/sim/output/, exact commands, repository commit and image SHA-256.
| Result | Next step |
|---|---|
| within_limits | Also require builder-check.json = simulation_checks_complete, control_ready = true, a recorded policy handoff and at least 10 simulated seconds afterward. Verify control_path, scene and per-check flags. Hardware qualification is still separate. |
| completed | Not a safety pass. Check whether safety was disabled or a direct/example controller ran. |
| no_command | Check installed dependencies, entrypoint, ROS setup, session exchange and first-command timing. |
| violation | Use the first failed check’s joint, measurement, limit and timestamp. Fix the cause; keep checks enabled. |
| error | Fix the runtime/protocol error. Compare simulator setup before attributing findings to the policy. |
Submit an image larger than the upload limit
ZIP + MP4 must stay under 100 MB, with video at most 50 MB. If submission.tar fits, store it in the ZIP without compression (zip -0); a wrapper directory is fine. For a larger image, host it at a permanent public HTTPS URL and put one g1-runner.json in the source ZIP. Do not include both forms. Never include credentials, signed URLs or private files.
{
"schema_version": 1,
"repository_commit": "e93c49267a7b6b905c6666c8c70668f8ee7ac397",
"image": {
"archive_url": "https://YOUR-PUBLIC-HOST/submission.tar",
"sha256": "REPLACE_WITH_64_LOWERCASE_HEX_DIGITS"
},
"required_sensors": [
"joint_state",
"imu"
]
}Compute the tar digest with sha256sum submission.tar (Linux) or shasum -a 256 submission.tar (macOS). Add camera, lidar or base_state to required_sensors if needed. Arena records this reference; it does not fetch the URL or verify the image’s bytes, startup or safety. Runners must verify its digest and test that exact image.
Optional: automatic model screening
- Choose the supported controller interface that matches your policy. Export the complete inference path, including normalization and command limits.
- Put arena-policy.json, the model files and required assets in one ZIP. Publish it as a Unitree G1 policy with a simulation video.
- Arena validates the archive, prepares supported controllers, runs the current G1 safety checks, and publishes the results automatically.
- Fix any listed requirements and upload a corrected version. You can also use Rerun latest checks on your own existing project after an evaluator update or an interrupted check. Results update on the page.
Preferred format describes the model files only. Simulation findings and a recorded physical robot test are separate stages. An unsupported export has not run safety simulation; it has neither passed nor failed safety.
Complete checklist for your coding agent
# Prepare your G1 policy for robot runners
Public builder kit: https://arena.himrobotics.com/policy-contracts/g1-builder-kit-e93c492-v1.zip
Guide: https://arena.himrobotics.com/docs/g1-policy-checks
Revision: e93c49267a7b6b905c6666c8c70668f8ee7ac397
1. Build one linux/arm64 Docker image with every dependency, model and controller installed and one ENTRYPOINT. Use the public kit's container template and ROS 2 Foxy interface. ONNX is optional inside the image. Do not install packages at startup.
2. Read /safety/policy_observation and /safety/policy_state; rt/lowstate is read-only. Publish all 29 slots of JointCommand (q, dq, kp, kd, tau) to /safety/precheck. Preserve the kit's joint order. Use the checker-issued session_id and observation_id and an increasing sequence. Stop publishing on /safety/abort. Never publish rt/lowcmd or rt/arm_sdk or manage g1-safety-stops. The host owns motor output and approved gains.
3. Fresh observation and next-command deadlines are both 0.2 seconds. The first command must arrive within 30 seconds in simulation. Include an explicit hold for joints your policy does not control.
4. The standard interface supplies joints and IMU, not camera images or lidar. Base position/velocity needs a qualified configured source. If your policy needs a camera, lidar or extra base state, declare it and resolve that input before claiming the policy can run. Simulated object state does not verify real sensor input.
5. Robot setup is handled by the runner. Do not add a dummy setup.sh to your package. Your image needs its own entrypoint. Builders test in simulation; hardware setup and qualification remain with the supervised runner.
## Build and test the SAME image
Download and unzip the public builder kit above. It includes the exact message definitions, simulation dependencies, a Docker template and local safety checks. No private repository access is required. Do not disable safety checks.
Replace template/policy.py with your full controller and add its installed dependencies to template/Dockerfile. From the kit root:
~~~sh
docker buildx build --platform linux/arm64 --load -f template/Dockerfile -t g1-submission:local .
docker image inspect g1-submission:local --format '{{.Os}}/{{.Architecture}} {{json .Config.Entrypoint}}'
docker save g1-submission:local -o submission.tar
~~~
The inspection must show linux/arm64 and a non-empty entrypoint. Copy submission.tar to containers/upload/submission.tar in the kit. Copy any complete custom environment/ directory beside it. Include every referenced asset; retain the floating G1, named joints/actuators, pelvis IMU and stand keyframe. Test your actual task scene.
From the kit root (Docker Compose and Python 3 required):
~~~sh
bash sim.sh --seconds 60
bash sim.sh --seconds 60 --counterfactuals
~~~
For a custom scene, add --scene containers/upload/environment/scene.xml to each command. The kit uses isolated Docker Compose on Linux/macOS/Windows. Host battery, circle and local examples are not submitted-container tests. The launcher requires policy handoff and at least 10 simulated seconds under submitted control; increase --seconds if coverage is incomplete.
Save containers/sim/output/ (reports and traces), the exact command, repository commit and image SHA-256. within_limits alone is insufficient: require builder-check.json to report simulation_checks_complete, with checking enabled, accepted commands, control_ready=true, a non-null policy_handoff_at_secs and at least 10 simulated seconds after handoff. completed, error, violation and no_command are not passes. Inspect safety_checks, control_path, scene and per-check flags. Local reports are builder-provided evidence, not Arena-verified results or hardware approval.
## Submit to Arena
Arena accepts a source ZIP plus MP4 with a combined 100 MB limit (video at most 50 MB). Keep secrets and private data out.
- If it fits: include one submission.tar in the ZIP, alongside source and evidence/. Store the tar without ZIP compression (zip -0) for bounded metadata inspection. A normal wrapper directory is allowed.
- Large image: host submission.tar at a permanent public HTTPS download URL; put g1-runner.json below in your source ZIP. Never put a signed/private URL or credentials in the manifest. Compute the digest of the tar with sha256sum (Linux) or shasum -a 256 (macOS). Arena records the reference but does not fetch or execute it automatically.
~~~json
{
"schema_version": 1,
"repository_commit": "e93c49267a7b6b905c6666c8c70668f8ee7ac397",
"image": {
"archive_url": "https://YOUR-PUBLIC-HOST/submission.tar",
"sha256": "REPLACE_WITH_64_LOWERCASE_HEX_DIGITS"
},
"required_sensors": ["joint_state", "imu"]
}
~~~
Declare camera, lidar or base_state if required; do not remove a dependency just to pass a check. For additional sensor inputs, include SENSOR_CONTRACT.md with camera/stream format and rate, calibration, timestamps, coordinate frame, units, latency and lost-track behavior. No camera or object-state topic exists in the standard runner; package the required processing code but keep hardware eligibility blocked until that input is connected and qualified. For small embedded images, describe required sensors in your README.
Publish as a Unitree G1 policy. New uploads receive packaging checks automatically; owners can Rerun latest checks. Keep arena-policy.json and supported model files if you also want Arena's existing model screening. That screening does NOT execute or verify your submitted container, startup, ROS protocol or perception. Container metadata or a download reference alone never means ready to run.
## If it fails
Missing container: provide submission.tar or g1-runner.json. Wrong architecture/entrypoint: rebuild linux/arm64 with the controller as ENTRYPOINT. no_command: inspect entrypoint, ROS setup, arm/session exchange and first-command timing. violation: use the first failed check's measurement, limit, joint and timestamp. error: fix the runtime/protocol failure before changing policy behavior. Simulator mismatch: compare scene, gains, initial pose, physics and observation/action timing before retuning. Re-upload the corrected package with the original Arena link; preserve earlier reports.
The same image must pass the builder kit’s container simulation and separate hardware qualification before a supervised robot run. Current Arena model checks do not grant that approval.
Model-screening examples
| Interface | Files | What runs |
|---|---|---|
| g1-walker-99-v1 | policy.onnx plus any external weights | 99 inputs → 29 actions; neural locomotion in the reference G1 scene |
| nvidia-decoupled-wbc-516-v1 | walker.onnx and balance.onnx | 516 inputs → 15 actions; locomotion and balance with neutral upper-body hold |
{
"policy_type": "trained",
"model": "policy.onnx",
"safety_adapter": "g1-walker-99-v1"
}For NVIDIA, set model to walker.onnx and safety_adapter to nvidia-decoupled-wbc-516-v1. Keep balance.onnx beside walker.onnx. Each frame contains: velocity command × [2,2,0.5], height 0.74, torso roll/pitch/yaw zeros, body gyro × 0.5, projected gravity, 29 joint offsets, 29 joint velocities × 0.05, and 15 previous actions. Six frames run oldest to newest, initially zero.
Reproduce and review your results
- Download the full report and traces from your submission. Check which stage ran: packaging, model screening or container simulation.
- Match the recorded controller interface, simulator version, scene, starting conditions, seeds, sensor noise and timing. Use the matching test tools in the builder kit; a different setup is a different test.
- Start with the earliest finding. Compare the joint, measured value, limit and timestamp with your controller output. Evaluation errors and incomplete tests need investigation before a result can be assessed.
- Fix the cause, rerun locally and upload the corrected package. Use Rerun latest checks on your existing submission when you need to repeat Arena’s current checks.
Resolve a blocked check
| Blocker | Fix |
|---|---|
| No controller contract | Export for a supported interface and declare the matching safety_adapter. Include the full controller, not just one checkpoint. |
| Reference assets differ | Use the latest reviewed reference for the standard task. For a scene bug, keep the corrected files and include a diff and reproduction; HIM must review and version the reference. Do not restore a known-broken scene. |
| Missing models or weights | Include every referenced ONNX file and external weight file inside the ZIP. |
| Partial-body or composite controller | Include balance and every control stage needed for the behavior. Do not submit gait-only evidence as a full-task test. |
| Artificial body support | Use a free-standing simulation driven by the joint controller. A welded or scripted pelvis does not establish balance. |
| Worker error | Rerun the existing upload. A worker error is not a confirmed policy defect. |
Use Copy fix instructions beside the result to bring the exact requirements into your editor or coding agent. Keep existing evidence; corrected uploads and rechecks produce new records. Physical-test claims and result publication still require a robot runner.
