diff --git a/.gitignore b/.gitignore index 4f8a78e..751c5e6 100644 --- a/.gitignore +++ b/.gitignore @@ -14,7 +14,7 @@ wheels/ .venv/ # Onshape export intermediates (transient; the committed urdf/.urdf hub -# is what --from-cache reuses). +# is what the generator reuses instead of re-exporting). robots/*/cad/assets/ robots/*/cad/robot.pkl diff --git a/README.md b/README.md index c6a8d94..bd3b4eb 100644 --- a/README.md +++ b/README.md @@ -4,43 +4,62 @@ [![ROS 2](https://img.shields.io/badge/ROS_2-Jazzy-22314E.svg)](https://docs.ros.org/en/jazzy/) [![License](https://img.shields.io/badge/license-MIT-yellow.svg)](LICENSE) -Robot description for the **Berkeley Humanoid Lite V2** — a low-cost, open-source -humanoid built on [Robstride](https://robstride.com) actuators. This repository is the -single source of truth for the robot's geometry: it holds the **URDF**, **MJCF**, and -**xacro** (with a `ros2_control` block) descriptions and meshes, all generated from the -Onshape CAD. +Robot description for the Berkeley Humanoid Lite V2, an open-source humanoid built on +[Robstride](https://robstride.com) actuators. This repository is the single source of +truth for the robot's geometry. It holds the URDF, MJCF and xacro descriptions and the +meshes, all generated from the Onshape CAD. The same source serves both worlds: -- **Simulation / RL** — Mujoco Lab and Isaac Lab, via the `robot_assets` Python loader. -- **ROS 2** — `ros2_control` + `robot_state_publisher`, as the `lite_description` +- Simulation and RL, through the `robot_assets` Python loader, for Mujoco Lab and Isaac Lab. +- ROS 2, through `ros2_control` and `robot_state_publisher`, as the `lite_description` ament package. ## Variants | Variant | Description | DoF | Root | `ros2_control` | |---|---|---|---|---| -| `lite` | full-body Lite humanoid (legs, 1-DoF waist yaw, arms, neck, 5-finger hands) | 72 | `pelvis` | model-only | -| `lite_pro` | full-body Lite **Pro** humanoid (legs, 3-DoF waist, arms, neck, 5-finger hands) | 74 | `pelvis` | model-only | -| `lite_dummy` | V1 bimanual upper body (arms + neck) — the configuration `Humanoid Control` deploys | 17 | `chest` | yes — Robstride on two CAN buses | -| `lite_bimanual` | V2 bimanual arms (no neck) | 14 | `chest` | yes — Robstride on two CAN buses | -| `lite_biped` | V2 legs (hip ×3 / knee / ankle ×3 per leg) | 14 | `pelvis` | model-only | +| `lite` | full body (legs, 1-DoF waist yaw, arms, neck, 5-finger hands) | 72 | `pelvis` | model-only | +| `lite_pro` | full body **Pro** (legs, 3-DoF waist, arms, neck, 5-finger hands) | 74 | `pelvis` | model-only | +| `lite_dummy` | V1 bimanual upper body (arms + neck), the configuration `Humanoid Control` deploys | 17 | `chest` | Robstride on two CAN buses | +| `lite_bimanual` | V2 bimanual arms, no neck | 14 | `chest` | Robstride on two CAN buses | +| `lite_biped` | V2 legs (hip x3, knee, ankle x3 per leg), floating base | 14 | `pelvis` | Robstride on two CAN buses + base IMU | +| `lite_biped_debug` | `lite_biped` with the flat debug foot instead of the rockered sole | 14 | `pelvis` | Robstride on two CAN buses + base IMU | -All variants are generated from the same Onshape document (different `Configuration=…`); the -`.urdf.xacro` of a `ros2_control` variant selects sim / mock / real hardware via xacro args. +Every variant comes from the same Onshape document with a different `Configuration=`. + +## Hardware backends + +A variant with a `ros2_control` block selects its backend through two xacro args, the +convention the [Universal Robots description](https://github.com/UniversalRobots/Universal_Robots_ROS2_Description/blob/ros2/urdf/ur.ros2_control.xacro) +uses: one boolean per non-real backend, with real hardware as the fallback. + +| `sim_mujoco` | `use_mock_hardware` | Backend | +|---|---|---| +| `false` | `false` | `humanoid_devices_robstride/RobstrideSystem`, one block per CAN bus | +| `false` | `true` | `mock_components/GenericSystem` | +| `true` | any | `mujoco_ros2_control/MujocoSystem` | + +`sim_mujoco` wins over `use_mock_hardware`. Note that `sim_mujoco` is unrelated to the +`use_sim_time` node parameter, which controls the clock. + +The switches choose a plugin and nothing else. The joint macros are backend-agnostic and +always emit their hardware params, because every backend ignores the params it does not +know. Real hardware needs one `` block per physical CAN bus, so the real +path emits several blocks while the mock and MuJoCo paths share one combined block. ## CAD source Every description is generated from an Onshape assembly (document -`e9ee61a2e2678af2088d9f31`) by the `robot_assets` tool — see -[Re-generating from CAD](#re-generating-from-cad). The files under `robots//` -are build artifacts: **do not hand-edit them**; change the `cad/` inputs and regenerate. +`e9ee61a2e2678af2088d9f31`) by the `robot_assets` tool. See +[Re-generating from CAD](#re-generating-from-cad). The files under `robots//` are +build artifacts. Do not hand-edit them. Change the `cad/` inputs and regenerate. ## Usage -### Simulation / RL (Python, no ROS toolchain) +### Simulation and RL (Python, no ROS toolchain) ```bash uv add git+https://github.com/Berkeley-Humanoids/Lite-Description.git @@ -53,48 +72,49 @@ urdf_path = load("robots/lite/urdf/lite.urdf") # Isaac Lab mjcf_path = load("robots/lite_dummy/mjcf/lite_dummy.xml") # MuJoCo ``` -`load()` fetches and caches the requested variant's subtree from this GitHub repo; no ROS -install required. +`load()` fetches the requested variant's subtree from this GitHub repo and caches it. No +ROS install is required. ### ROS 2 -`lite_description` is a standard `ament_cmake` package (its `package.xml` is at the repo -root). Build it in a ROS 2 workspace — or pull it via `vcs` / `humanoid_control.repos` from `Humanoid Control` -— and `colcon build`. Downstream, `robot_state_publisher` runs xacro on +`lite_description` is a standard `ament_cmake` package whose `package.xml` sits at the +repo root. Build it in a ROS 2 workspace, or pull it with `vcs` or +`humanoid_control.repos` from `Humanoid Control`, then run `colcon build`. Downstream, +`robot_state_publisher` runs xacro on `robots//xacro/.urdf.xacro`, and `package://lite_description/robots//meshes/visual/...` resolves after install. -The `` block selects the hardware backend via xacro args -(`use_sim` / `use_fake_hardware`), following the `franka_ros2` / Universal Robots -convention. ## Repository layout ``` -Lite-Description/ # repo root == ament package "lite_description" +Lite-Description/ # repo root == ament package "lite_description" package.xml CMakeLists.txt # ament (colcon); installs robots//... pyproject.toml # pip/uv: builds the robot_assets Python module - robot_assets/ # Python module: the CAD->assets generator + load() + robot_assets/ # Python module: load() and the CAD->assets generator + actuators/ # actuator spec tables (velocity/effort/armature) + workflow/ # the generator stages robots/ # per-variant assets (franka_description-style subdir) / xacro/ # ROS entry (GENERATED) - .urdf.xacro # top assembly: args + includes + instantiation - .description.xacro # model: kinematics, ${mesh_root}, base_link - .ros2_control.xacro # hardware macros: sim / mock / real, MIT interfaces, CAN ids - urdf/.urdf # flat URDF (GENERATED; the kinematic HUB; base_link-free) + .urdf.xacro # assembly: args, includes, instantiation + .description.xacro # model macro: kinematics, ${mesh_root}, base_link + .ros2_control.xacro # hardware macros: joints, groups, backends + urdf/.urdf # flat URDF (GENERATED; the kinematic HUB) mjcf/.xml # MJCF (GENERATED; MuJoCo training + deployment sim) meshes/visual/*.stl # one shared mesh copy cad/ # generation INPUTS (not installed): config.json # Onshape document + export options joint_properties.json # sim tuning: armature / friction / effort_limit - physics.json # MJCF