# Unitree G1 · visual research prototype

This browser asset derives from Unitree Robotics' own simulation description,
`g1_23dof_mode_10.urdf`, at commit
[`7d6075f7f58588b189b940130e3edab3c839b2df`](https://github.com/unitreerobotics/unitree_ros/tree/7d6075f7f58588b189b940130e3edab3c839b2df/robots/g1_description).
It represents that specific **23-DoF configuration with fixed rubber hands**.
It must not be presented as the geometry of every G1 generation/configuration.
Upstream's configuration table is retained in [SOURCE_README.md](SOURCE_README.md).

Original URDF and STL meshes: Unitree Robotics. Browser conversion and mesh
simplification: Roboryn. Upstream distributes these files in `unitree_ros` under
the **BSD 3-Clause license**, reproduced in full in [LICENSE](LICENSE). Retain this
notice and license when redistributing the derived asset. The asset does not imply
endorsement by Unitree Robotics.

## What the model does and does not represent

- `g1-23dof.glb` includes all 26 visual meshes and the original hierarchy of 23
  revolute joints, plus the source's fixed joints and empty sensor link frames.
- The original [URDF](g1_23dof_mode_10.urdf) is retained unchanged. Link origins,
  visual origins, axes and joint limits are copied from it. Source colors are kept;
  material roughness/metallicity and scene lighting are presentation choices.
- Triangles have been reduced from 480,933 to 187,588 for a 3.41 MB GLB. Smoothed
  normals and simplified mesh surfaces make this an approximate visual reference.
  It is not metrology, engineering CAD, a collision model or a safe control model.
- These meshes do not expose a verified complete internal assembly. Separating
  body parts is a visual organization aid, not a technical exploded diagram.
- Procedural motion is illustrative interface animation, not recorded movement,
  physics simulation or evidence of walking, balance, autonomy or task capability.
  A capability claim requires separate attributable evidence and editorial review.
- This asset does not create observations, preferred selections or canonical
  publication authority. Its role is a clearly labeled visual prototype.

## Rebuild

No Blender or application build dependency is needed. Use an isolated Python 3.12
environment, so optional asset tooling does not change the web application's stack:

```sh
python3.12 -m venv /tmp/roboryn-g1-tools
/tmp/roboryn-g1-tools/bin/pip install -r scripts/requirements-g1-model.txt
/tmp/roboryn-g1-tools/bin/python scripts/prepare-g1-model.py --source-dir /tmp/roboryn-g1-source --download
```

The download is approximately 24 MB of public source files from the pinned
revision. Every input must match its SHA-256 in [manifest.json](manifest.json).
Omit `--download` to rebuild from an already populated source directory offline.
The generated file and manifest output statistics are written to this directory.
Source metadata and retrieval time are retained unchanged during a rebuild.
Do not run this manually maintained asset pipeline on deployment or app startup.

The converter deduplicates vertices, applies quadric-error mesh simplification
with a conservative aggressiveness of 5, computes area-weighted smooth normals,
and writes indexed glTF 2.0 without external buffers, texture requests or decoders.
It preserves every visual component. Original STL source hashes and file names,
transformation details, output checksum and per-mesh triangle counts are recorded
in the manifest. Rebuilding with different tool versions can change mesh output.

## Scene and animation contract

The `Unitree_G1` root maps the URDF's Z-up frame to glTF Y-up with a -90° X rotation.
The robot's front is **+X**, its left is **-Z**, and its origin is the pelvis.
Units remain the URDF's metres. Derive the displayed floor offset from the whole
model's bounding box; do not infer verified body dimensions from the display mesh.

Original links and joints retain their exact URDF names. A mesh child is named
`<linkName>_visual_0`. Mesh and link `extras.linkName` identify the source component.
Each joint node carries these glTF extras, available as Three.js `userData`:

```json
{
  "kind": "joint",
  "jointType": "revolute",
  "parentLink": "pelvis",
  "childLink": "left_hip_pitch_link",
  "axis": [0, 1, 0],
  "lower": -2.5307,
  "upper": 2.8798
}
```

Fixed joints omit the axis and limits. For an illustrative pose, cache each joint's
initial quaternion and multiply `initialQuaternion * Quaternion(axis, angle)`;
axes are in the original local joint frame. Respect limits, and restore the cached
rest transform when resetting. Moving geometry does not imply motion feasibility.

Useful component nodes are `head_link`, `torso_link`, `pelvis`, and the symmetric
`left_`/`right_` limb links. Each hand is part of `left_wrist_roll_rubber_hand` or
`right_wrist_roll_rubber_hand`; it has no articulated fingers in this configuration.
