diff --git a/README.md b/README.md index 887c94c..5f11a39 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# bar_ros2_docs +# Humanoid-Control-Website -Documentation site for [`bar_ros2`](https://github.com/T-K-233/bar_ros2) — the +Documentation site for [`humanoid_control`](https://github.com/Berkeley-Humanoids/humanoid_control) — the Berkeley Architecture Research (BAR) humanoid low-level control stack. Built with [Docusaurus 3](https://docusaurus.io/) + `@docusaurus/theme-mermaid` @@ -26,7 +26,7 @@ npm run serve # serve the built dist locally The `build/` directory is a fully static site — drop it on Netlify, Cloudflare Pages, or GitHub Pages. For GitHub Pages, configure the workflow to publish `build/`; the bundled `docusaurus.config.ts` already sets -`organizationName` and `projectName` for a `T-K-233/bar_ros2_docs` repo. +`organizationName` and `projectName` for a `Berkeley-Humanoids/Humanoid-Control-Website` repo. ## Layout diff --git a/docs/concepts/architecture.md b/docs/concepts/architecture.md index d44c2f4..bd23446 100644 --- a/docs/concepts/architecture.md +++ b/docs/concepts/architecture.md @@ -15,7 +15,7 @@ build against which: ![Module dependency graph](/img/diagrams/concepts__architecture__03_module_deps.svg) -Notice that `bar_controllers` does **not** `find_package(bar_robstride)`. +Notice that `humanoid_controllers` does **not** `find_package(humanoid_control_robstride)`. The plugin is loaded by `controller_manager` at launch via `pluginlib` — a runtime dep that doesn't appear in the static graph but is just as binding. The same applies to every `` entry in a controller-manager YAML. @@ -36,7 +36,7 @@ MuJoCo — it performs three steps: | `update()` | read state_interfaces_, write command_interfaces_, lock-free trylock for diag publishers | allocations, blocking, exceptions across the RT boundary | | `write()` | stage frames into the bus library's outgoing queue | the actual CAN/EtherCAT syscall (that's the I/O thread's job) | -The I/O thread in each hardware plugin (`bar_socketcan::SocketCanBus`, +The I/O thread in each hardware plugin (`humanoid_control_socketcan::SocketCanBus`, `ethercat_driver_ros2`'s EtherLAB master thread) is **separate** from the controller-manager thread. RT-safety is preserved by making `read()` / `write()` allocation-free buffer swaps. @@ -80,11 +80,11 @@ Behavior per state: | State | Plugin | What it writes | |---|---|---| -| **ZERO_TORQUE** | `bar/ZeroTorqueController` | 0 to all 5 cmd interfaces. Startup default, fault fallback. | -| **DAMPING** | `bar/DampingController` | `K=0`, `D=damping value`, `q_cmd=q_captured` — soft under gravity, resists velocity. | -| **STANDBY** | `bar/StandbyController` | Linear pose interpolation through a YAML sequence; ramps `K_p / K_d` on first segment. Publishes `StandbyState` with `is_finished`. | -| **LOCOMOTION** | `bar/RLPolicyController` | In-process ONNX inference (System 0): packs observations, replays the `.mcap` motion reference, decodes + writes commands — all in the RT `update()`. Runs every learned policy (tracking / piano / locomotion); they differ only by the loaded `.onnx` + `.mcap`. | -| **REMOTE** | `bar/RemotePolicyController` | System 1/2 external-command ingress: subscribes `~/command` (`MITCommand` over DDS) from a *non*-real-time source (gravity-comp today, VLA / manipulation later) with arrival-time stale-command gating. | +| **ZERO_TORQUE** | `humanoid_control/ZeroTorqueController` | 0 to all 5 cmd interfaces. Startup default, fault fallback. | +| **DAMPING** | `humanoid_control/DampingController` | `K=0`, `D=damping value`, `q_cmd=q_captured` — soft under gravity, resists velocity. | +| **STANDBY** | `humanoid_control/StandbyController` | Linear pose interpolation through a YAML sequence; ramps `K_p / K_d` on first segment. Publishes `StandbyState` with `is_finished`. | +| **LOCOMOTION** | `humanoid_control/RLPolicyController` | In-process ONNX inference (System 0): packs observations, replays the `.mcap` motion reference, decodes + writes commands — all in the RT `update()`. Runs every learned policy (tracking / piano / locomotion); they differ only by the loaded `.onnx` + `.mcap`. | +| **REMOTE** | `humanoid_control/RemotePolicyController` | System 1/2 external-command ingress: subscribes `~/command` (`MITCommand` over DDS) from a *non*-real-time source (gravity-comp today, VLA / manipulation later) with arrival-time stale-command gating. | ### Transition mechanics @@ -100,8 +100,8 @@ plain `rclcpp::Node` that subscribes: …and exposes five `std_srvs/Trigger` services so transitions can also be driven from the command line: -- `/bar/mode/damp`, `/bar/mode/load`, `/bar/mode/start_remote`, - `/bar/mode/start_locomotion`, `/bar/mode/quit` +- `/humanoid_control/mode/damp`, `/humanoid_control/mode/load`, `/humanoid_control/mode/start_remote`, + `/humanoid_control/mode/start_locomotion`, `/humanoid_control/mode/quit` `/control_mode` is published at 50 Hz. The manager polls `list_controllers` periodically (every 25 ticks = 500 ms) so controllers @@ -141,7 +141,7 @@ rather than the **inference**. ### Launch-time `prepare`, then in-process replay The heavy, non-real-time work runs **once at launch**, never per tick. -`bar_policy prepare` (and `pianist_policy prepare`) resolves the ONNX +`humanoid_control_policy prepare` (and `pianist_policy prepare`) resolves the ONNX checkpoint (local file or W&B run) and converts the policy's LeRobot motion dataset into a single-episode rosbag2 **`.mcap`** bag, then emits an `rl_policy_controller` parameter overlay. The launch runs `prepare` @@ -179,10 +179,10 @@ the hot loop), resolving each term as one of: :::tip[Why a *generic* topic for the live key state] Routing live key state through a plain float array — rather than -`pianist_msgs/PianoKeyState` — keeps `bar_controllers` free of any +`pianist_msgs/PianoKeyState` — keeps `humanoid_controllers` free of any task-package dependency. The core controller package never learns the piano task exists; it just packs a named extern vector. New tasks add -their own publisher on their own topic without touching `bar_controllers`. +their own publisher on their own topic without touching `humanoid_controllers`. ::: `reset()` (on activation) and `record_action()` (once per tick, after @@ -196,15 +196,15 @@ sources that *should* live out-of-process: it subscribes to `MITCommand` over DDS and writes the bus, with arrival-time staleness gating. Today that is the gravity-compensation runner (`Lite-Gravity-Compensation` — raw CycloneDDS, no `rclpy`); next it is VLA / manipulation. Such a client -does not hand-write the message types: [`bar_msgs_dds`](../reference/packages.md#bar_msgs_dds) -generates wire-compatible `cyclonedds` types from `bar_msgs/msg/*.msg`, and +does not hand-write the message types: [`humanoid_control_msgs_dds`](../reference/packages.md#humanoid_control_msgs_dds) +generates wire-compatible `cyclonedds` types from `humanoid_control_msgs/msg/*.msg`, and the `lite_sdk2` SDK wraps them in a publisher/subscriber layer — see -[Talk to bar_ros2 from Python](../how_to/talk_to_bar_ros2_from_python.md). +[Talk to humanoid_control from Python](../how_to/talk_to_humanoid_control_from_python.md). These are System 1/2: slower, deliberative, and tolerant of the latency the DDS hop adds. -`MITState` is a **code-level** schema (a `bar::MITState` POD in -`bar_common`) — not a published topic. Observations are assembled +`MITState` is a **code-level** schema (a `humanoid_control::MITState` POD in +`humanoid_control_common`) — not a published topic. Observations are assembled in-process from `/lite/joint_states` (the always-on broadcaster) and `/imu/data` (the IMU driver). See [Policy runner](../reference/policy_runner.md). @@ -214,8 +214,8 @@ A handful of artifacts are **frozen once a trained policy depends on them**: | Artifact | Frozen because | |---|---| -| `bar_msgs/MITCommand` | trained policies emit this field-by-field over DDS | -| Joint order in `bar_*_controllers.yaml` | trained policies index into this order | +| `humanoid_control_msgs/MITCommand` | trained policies emit this field-by-field over DDS | +| Joint order in `humanoid_control_*_controllers.yaml` | trained policies index into this order | | `MITState` struct + Python dataclass | both sides agree on `joint_position`/`joint_velocity`/IMU layout | | Observation term scale + default vectors | shifts mean retraining | @@ -229,8 +229,8 @@ system: Concrete examples: -- A Robstride bus-off → `bar_robstride` publishes `SafetyStatus{level=FAULT, - source="bar_robstride/can0", flags=BUS_OFF}` → `mode_manager` requests a +- A Robstride bus-off → `humanoid_control_robstride` publishes `SafetyStatus{level=FAULT, + source="humanoid_control_robstride/can0", flags=BUS_OFF}` → `mode_manager` requests a STRICT switch to DAMPING. If DAMPING fails (e.g. command interfaces unavailable), `mode_manager` falls back to ZERO_TORQUE. - A `RemotePolicyController` whose Python publisher stalls for >100 ms @@ -240,7 +240,7 @@ Concrete examples: **arrival time at the subscription callback**, not against `MITCommand.header.stamp`, so publisher clock skew is irrelevant. - An RL policy returning NaN in its action vector → `RLPolicyController` - detects via `bar::rt::all_finite(...)` and returns `return_type::ERROR`, + detects via `humanoid_control::rt::all_finite(...)` and returns `return_type::ERROR`, triggering `fallback_controllers` in the CM YAML. ## Deployment topology @@ -249,19 +249,19 @@ The shipping configuration is a **two-machine tethered split**. The same colcon workspace is installed (and built from the same pixi lock file) on both machines; each launch boots only the subset of nodes that belongs on its side. Single-machine sim/dev paths -(`bar_bringup_lite/mujoco.launch.py`, `bar_bringup_lite/view_lite.launch.py`, -`bar_bringup_lite/calibrate.launch.py`) are unaffected — they +(`humanoid_control_bringup_lite/mujoco.launch.py`, `humanoid_control_bringup_lite/view_lite.launch.py`, +`humanoid_control_bringup_lite/calibrate.launch.py`) are unaffected — they collapse both sides into one process tree. -Launches come from two sibling repos: `bar_ros2` ships every +Launches come from two sibling repos: `humanoid_control` ships every Lite/Prime control-plane and tracking-policy launch; `pianist_ros2` ships the piano-task-specific launches. | Side | Machine | Launch | What lives here | |---|---|---|---| -| **Robot** | Onboard computer (RT kernel, wired tether) | `bar_bringup_lite/launch/real.launch.py` (bar_ros2) | `ros2_control_node`, `bar_robstride` / `bar_sito` hardware plugins, `joint_state_broadcaster`, the five FSM controllers (`zero_torque` / `damping` / `standby` / `rl_policy` / `remote_policy`), `mode_manager`, `joy_node`, `robot_state_publisher`, IMU driver | -| **Host** | Operator workstation | `bar_bringup_lite/launch/viz.launch.py` (bar_ros2) | `viser_viz` *or* `rerun_viz` (selected by `viewer:=`) | -| **Robot** | Onboard computer | `bar_policy/launch/lite_policy.launch.py` (bar_ros2) / `pianist_policy/launch/piano_policy.launch.py` (pianist_ros2) | Runs `prepare` (resolve ONNX, convert motion → `.mcap` + overlay) then loads `rl_policy_controller` into the local CM. Inference is in-process, so the `.onnx` / `.mcap` artifacts **and** the W&B / HF Hub / `onnxruntime` *prepare-time* deps live here. The RT path itself pulls none of them. | +| **Robot** | Onboard computer (RT kernel, wired tether) | `humanoid_control_bringup_lite/launch/real.launch.py` (humanoid_control) | `ros2_control_node`, `humanoid_control_robstride` / `humanoid_control_sito` hardware plugins, `joint_state_broadcaster`, the five FSM controllers (`zero_torque` / `damping` / `standby` / `rl_policy` / `remote_policy`), `mode_manager`, `joy_node`, `robot_state_publisher`, IMU driver | +| **Host** | Operator workstation | `humanoid_control_bringup_lite/launch/viz.launch.py` (humanoid_control) | `viser_viz` *or* `rerun_viz` (selected by `viewer:=`) | +| **Robot** | Onboard computer | `humanoid_control_policy/launch/lite_policy.launch.py` (humanoid_control) / `pianist_policy/launch/piano_policy.launch.py` (pianist_ros2) | Runs `prepare` (resolve ONNX, convert motion → `.mcap` + overlay) then loads `rl_policy_controller` into the local CM. Inference is in-process, so the `.onnx` / `.mcap` artifacts **and** the W&B / HF Hub / `onnxruntime` *prepare-time* deps live here. The RT path itself pulls none of them. | | **Robot** | Onboard computer | `pianist_policy/launch/midi_keyboard_driver.launch.py` (pianist_ros2) | USB-MIDI keyboard driver → `/piano/key_state` (`std_msgs/Float32MultiArray`); feeds the on-robot controller's `key_pressed` extern term locally (loopback, does **not** cross the tether). | :::tip[The deployment trade the in-process move makes] @@ -332,7 +332,7 @@ deployed surface. ## Next -- [`mode_manager` source](https://github.com/T-K-233/bar_ros2/blob/main/bar_controllers/src/mode_manager.cpp) +- [`mode_manager` source](https://github.com/Berkeley-Humanoids/humanoid_control/blob/main/humanoid_controllers/src/mode_manager.cpp) — the FSM is ~150 lines of C++; readable in one sitting. - [Lite 101](../getting_started/lite_101.md) — see all of this run end-to-end against mock hardware and MuJoCo. diff --git a/docs/concepts/calibration_math.md b/docs/concepts/calibration_math.md index 14e897e..7756993 100644 --- a/docs/concepts/calibration_math.md +++ b/docs/concepts/calibration_math.md @@ -4,7 +4,7 @@ title: Calibration math # Calibration math -How `bar_robstride` maps between the raw encoder reading and the +How `humanoid_control_robstride` maps between the raw encoder reading and the URDF joint frame, where the per-joint constants live, and why the calibration is split across two files. @@ -37,7 +37,7 @@ is in the joint frame — controllers never see the raw encoder. | Parameter | Per | Where it lives | What it captures | |---|---|---|---| | `direction` | joint | URDF `` inside the `` block | Wiring sign — does the motor's positive direction match the URDF's positive joint direction? | -| `homing_offset` | joint | `bar_bringup_lite/config/calibration.yaml` | Per-physical-robot encoder zero offset (motor frame, rad). | +| `homing_offset` | joint | `humanoid_control_bringup_lite/config/calibration.yaml` | Per-physical-robot encoder zero offset (motor frame, rad). | The split is deliberate: @@ -53,7 +53,7 @@ The split is deliberate: ## Deriving the offset -The calibration tool (`bar_bringup_lite/scripts/calibrate_robot.py`) +The calibration tool (`humanoid_control_bringup_lite/scripts/calibrate_robot.py`) runs the plugin with `calibration_file:=''` — identity calibration — so `/lite/joint_states` reports `direction · raw_motor_pos` (the direction-applied-but-not-offset frame). The operator hand-sweeps each @@ -141,6 +141,6 @@ URDF. The cost is that hand-edits to `id` / `direction` in ## See also - [How-to → Calibrate the zero pose](../how_to/calibrate_zero_pose.md) — the recipe. -- [`RobstrideSystem` source](https://github.com/T-K-233/bar_ros2/blob/main/bar_devices/bar_robstride/src/robstride_system.cpp#:~:text=load_calibration) +- [`RobstrideSystem` source](https://github.com/Berkeley-Humanoids/humanoid_control/blob/main/humanoid_control_devices/humanoid_control_robstride/src/robstride_system.cpp#:~:text=load_calibration) — the loader + apply. -- `bar_bringup_lite/scripts/calibrate_robot.py` — the formula in code. +- `humanoid_control_bringup_lite/scripts/calibrate_robot.py` — the formula in code. diff --git a/docs/concepts/five_mode_fsm.md b/docs/concepts/five_mode_fsm.md index 798a98b..16d72e1 100644 --- a/docs/concepts/five_mode_fsm.md +++ b/docs/concepts/five_mode_fsm.md @@ -32,18 +32,18 @@ property. | Mode | Plugin | What it writes per tick | Use it for | |---|---|---|---| -| **ZERO_TORQUE** | `bar::ZeroTorqueController` | `0` to all 5 MIT interfaces on every joint | Startup default. Fault fallback when DAMPING can't be applied (e.g. state not yet valid). Robot is alive but inert. | -| **DAMPING** | `bar::DampingController` | `stiffness=0`, `damping=damping_value`, `position=captured`, `velocity=0`, `effort=0` | Compliant fail-safe. Robot stays soft under gravity but resists velocity. The state you pass through between operator-driven transitions. | -| **STANDBY** | `bar::StandbyController` | Interpolated `position` along a YAML pose sequence; `K_p`/`K_d` ramped 0→target during segment 0 | Animate the arms to the piano-ready pose with gain ramp-in. Publishes `~/state.is_finished` so transitions out are gated correctly. | -| **LOCOMOTION** | `bar::RLPolicyController` | In-process ONNX inference (low-latency, C++): packs obs, replays the `.mcap` motion reference, writes commands | **Every learned policy** — tracking, piano, locomotion. They differ only by the loaded `.onnx` + `.mcap`; the ONNX `task_type` selects the term set. This is the System 0 real-time path. | -| **REMOTE** | `bar::RemotePolicyController` | `MITCommand` consumed from `~/command` over DDS | System 1/2 external-command ingress: a *non*-real-time source publishes commands (gravity-comp today via `Lite-Gravity-Compensation`; VLA / manipulation later). Not used by the learned policies. | +| **ZERO_TORQUE** | `humanoid_control::ZeroTorqueController` | `0` to all 5 MIT interfaces on every joint | Startup default. Fault fallback when DAMPING can't be applied (e.g. state not yet valid). Robot is alive but inert. | +| **DAMPING** | `humanoid_control::DampingController` | `stiffness=0`, `damping=damping_value`, `position=captured`, `velocity=0`, `effort=0` | Compliant fail-safe. Robot stays soft under gravity but resists velocity. The state you pass through between operator-driven transitions. | +| **STANDBY** | `humanoid_control::StandbyController` | Interpolated `position` along a YAML pose sequence; `K_p`/`K_d` ramped 0→target during segment 0 | Animate the arms to the piano-ready pose with gain ramp-in. Publishes `~/state.is_finished` so transitions out are gated correctly. | +| **LOCOMOTION** | `humanoid_control::RLPolicyController` | In-process ONNX inference (low-latency, C++): packs obs, replays the `.mcap` motion reference, writes commands | **Every learned policy** — tracking, piano, locomotion. They differ only by the loaded `.onnx` + `.mcap`; the ONNX `task_type` selects the term set. This is the System 0 real-time path. | +| **REMOTE** | `humanoid_control::RemotePolicyController` | `MITCommand` consumed from `~/command` over DDS | System 1/2 external-command ingress: a *non*-real-time source publishes commands (gravity-comp today via `Lite-Gravity-Compensation`; VLA / manipulation later). Not used by the learned policies. | Full per-controller parameter tables live in [Reference → Controllers](../reference/controllers.md). ## Transition rules -Encoded in `bar_controllers/src/mode_manager.cpp`. The operator's +Encoded in `humanoid_controllers/src/mode_manager.cpp`. The operator's gamepad intent goes through `dispatch_intent`, which gates based on the current mode: @@ -58,10 +58,10 @@ QUIT (BACK) : ZERO_TORQUE or DAMPING → rclcpp::shutdown() ``` The same transitions are also exposed as `std_srvs/Trigger` services -under `/bar/mode/{damp,load,start_remote,start_locomotion,quit}`, so a +under `/humanoid_control/mode/{damp,load,start_remote,start_locomotion,quit}`, so a keyboardless lab box can drive the FSM with `ros2 service call …`. -`mode_manager` publishes `/control_mode` (`bar_msgs/ControlMode`) at +`mode_manager` publishes `/control_mode` (`humanoid_control_msgs/ControlMode`) at 50 Hz. When an intent is rejected, the rejection reason goes into `status_message` so operators see *why* a button didn't take effect. @@ -72,7 +72,7 @@ controllers become visible to `dispatch_intent` immediately. ## The auto-DAMP path (safety) -Every hardware plugin publishes `/safety_status` (`bar_msgs/SafetyStatus`) +Every hardware plugin publishes `/safety_status` (`humanoid_control_msgs/SafetyStatus`) on a TRANSIENT_LOCAL QoS, with a bitmask of `BUS_OFF`, `RX_TIMEOUT`, `TX_QUEUE_OVERRUN`, `MOTOR_FAULT`, `TEMPERATURE_LIMIT`, `INVALID_FRAME`. `mode_manager` subscribes. On any non-`OK` level it requests DAMPING @@ -128,4 +128,4 @@ runtime**, not by a launch arg. There's no `policy_mode` parameter on - [Reference → Controllers](../reference/controllers.md) — per-plugin parameter tables. - [Concepts → Safety pipeline](./safety_pipeline.md) — what triggers auto-DAMP. - [How-to → Switch controllers without the FSM](../how_to/switch_controllers_manually.md). -- [`mode_manager` source](https://github.com/T-K-233/bar_ros2/blob/main/bar_controllers/src/mode_manager.cpp). +- [`mode_manager` source](https://github.com/Berkeley-Humanoids/humanoid_control/blob/main/humanoid_controllers/src/mode_manager.cpp). diff --git a/docs/concepts/frozen_schemas.md b/docs/concepts/frozen_schemas.md index 0610c81..c1fa194 100644 --- a/docs/concepts/frozen_schemas.md +++ b/docs/concepts/frozen_schemas.md @@ -4,7 +4,7 @@ title: Frozen schemas # Frozen schemas -A few things in `bar_ros2` are described as **frozen**. This page +A few things in `humanoid_control` are described as **frozen**. This page explains which ones, why, and what to do when you want to change them. ![Frozen schemas and their consumers](/img/diagrams/concepts__frozen_schemas__01.svg) @@ -27,7 +27,7 @@ specific surfaces are not. ### 1. Canonical joint order -The order of joints in `bar_lite_controllers.yaml`'s `joints:` list +The order of joints in `humanoid_control_lite_controllers.yaml`'s `joints:` list is canonical: ```yaml @@ -57,7 +57,7 @@ work. Inserting or reordering is not safe. The Lite URDF supports this directly via `mode:=arms` (14 joints, default) and `mode:=arms_neck` (17 joints, requires neck silicon). -### 2. `bar_msgs/MITCommand` fields +### 2. `humanoid_control_msgs/MITCommand` fields The command schema the controllers write/consume — used internally by the in-process `RLPolicyController` and on the wire by any System 1/2 @@ -77,10 +77,10 @@ Five parallel arrays + names. The arrays are indexed in the same canonical joint order above. Adding a field breaks parsers; renaming a field breaks everything. -Off-ROS (Tier-3) clients don't hand-mirror this struct: `bar_msgs_dds` +Off-ROS (Tier-3) clients don't hand-mirror this struct: `humanoid_control_msgs_dds` **generates** the wire-compatible `cyclonedds` type from this `.msg` via `pixi run gen-dds`, so the wire form follows the schema automatically. That -makes `bar_msgs_dds` one more frozen-schema consumer to regenerate on any +makes `humanoid_control_msgs_dds` one more frozen-schema consumer to regenerate on any change (see [the change drill](#how-to-change-a-frozen-schema)). ### 3. The 5 MIT command interface names @@ -95,9 +95,9 @@ These names are not arbitrary — they match `stiffness` to e.g. `kp` would break the binding against the sim plugin while leaving the silicon plugin happy — silent skew. -### 4. The ONNX `custom_metadata_map` schema (`bar_policy`) +### 4. The ONNX `custom_metadata_map` schema (`humanoid_control_policy`) -`bar_policy/policy_metadata.py` parses 13 fields baked into every +`humanoid_control_policy/policy_metadata.py` parses 13 fields baked into every trained `.onnx`: ``` @@ -131,7 +131,7 @@ position); removing them is not. To draw the contrast: most of the rest of the project is free to refactor. -- **Per-joint default `K_p` / `K_d`** in `bar_lite_controllers.yaml` +- **Per-joint default `K_p` / `K_d`** in `humanoid_control_lite_controllers.yaml` are tuning numbers, not schema. Change at will. - **CAN ids in the URDF** are wiring facts; if the physical robot changes, the URDF changes. @@ -149,16 +149,16 @@ refactor. The drill, in order: 1. **Write down what depends on it.** Every trained policy, every - subscriber, every rosbag from the past — and, for `bar_msgs`, the - generated `bar_msgs_dds` mirror that every Tier-3 (non-`rclpy`) client + subscriber, every rosbag from the past — and, for `humanoid_control_msgs`, the + generated `humanoid_control_msgs_dds` mirror that every Tier-3 (non-`rclpy`) client consumes via `lite_sdk2`. 2. **Stage the change** — branch + commit + describe in the PR exactly which schemas move and why. -3. **Bump a version**. For `bar_msgs`, that's the message's +3. **Bump a version**. For `humanoid_control_msgs`, that's the message's `package.xml` version + a deprecation period (parallel old + new field, or a v2 message type, for at least one release). 4. **Regenerate the Tier-3 mirror.** Run `pixi run gen-dds` to re-emit - `bar_msgs_dds/_generated.py` from the new `.msg`, and commit it. CI + `humanoid_control_msgs_dds/_generated.py` from the new `.msg`, and commit it. CI re-runs the emitter (`pixi run test-dds`) plus a CDR wire round-trip test, failing on an uncommitted diff or a changed field layout. 5. **Retrain every trained policy** against the new schema. diff --git a/docs/concepts/index.md b/docs/concepts/index.md index a8ae0c6..d747c61 100644 --- a/docs/concepts/index.md +++ b/docs/concepts/index.md @@ -6,7 +6,7 @@ sidebar_label: Overview # Concepts -Background reading. These pages discuss the *design* of `bar_ros2` — +Background reading. These pages discuss the *design* of `humanoid_control` — the architecture, the conventions, the trade-offs that decided which abstractions live where. Read these when you want to understand the project well enough to extend it (or argue with it). diff --git a/docs/concepts/mit_command_surface.md b/docs/concepts/mit_command_surface.md index 24ad140..97efc28 100644 --- a/docs/concepts/mit_command_surface.md +++ b/docs/concepts/mit_command_surface.md @@ -66,7 +66,7 @@ projects. Three properties make it the right primitive: 1. **One formula across silicon and sim.** Robstride firmware computes it on the motor MCU; `mujoco_ros2_control::MujocoSystem` computes the same expression and applies it via `qfrc_applied`; our - `bar_robstride/RobstrideSystem` encodes the five fields straight + `humanoid_control_robstride/RobstrideSystem` encodes the five fields straight into a wire frame. A controller written against this surface runs unchanged on silicon, MuJoCo, and `mock_components`. 2. **No mode-switching at the actuator.** "Switch from position control @@ -120,8 +120,8 @@ kd : 16 bits, unsigned, scaled to [0, kd_max] ``` Limits are model-specific (rs-00..rs-06); see -`bar_devices/bar_robstride/include/bar_robstride/robstride_protocol.hpp`. -`bar_robstride/RobstrideSystem::write` does the scale-and-pack; +`humanoid_control_devices/humanoid_control_robstride/include/humanoid_control_robstride/robstride_protocol.hpp`. +`humanoid_control_robstride/RobstrideSystem::write` does the scale-and-pack; `read` reverses it. ## See also @@ -131,5 +131,5 @@ Limits are model-specific (rs-00..rs-06); see - [Reference → Hardware specs → MIT-mode command convention](../reference/hardware_specs.md#mit-mode-command-convention) — short-form repeat of the formula. - The protocol header in - [`bar_robstride/robstride_protocol.hpp`](https://github.com/T-K-233/bar_ros2/blob/main/bar_devices/bar_robstride/include/bar_robstride/robstride_protocol.hpp) + [`humanoid_control_robstride/robstride_protocol.hpp`](https://github.com/Berkeley-Humanoids/humanoid_control/blob/main/humanoid_control_devices/humanoid_control_robstride/include/humanoid_control_robstride/robstride_protocol.hpp) is the source-of-truth for the wire encoding. diff --git a/docs/concepts/prime_hybrid_actuation.md b/docs/concepts/prime_hybrid_actuation.md index 49ba085..7f8cd37 100644 --- a/docs/concepts/prime_hybrid_actuation.md +++ b/docs/concepts/prime_hybrid_actuation.md @@ -33,7 +33,7 @@ EtherCAT, through the IgH master); two — the distal wrist roll/pitch — are So the EtherCAT ring carries **10 eRob** (positions 0-9, left arm 0-4, right arm 5-9) and the CAN bus carries **4 Sito** wrists (ids `0x16/0x17/0x26/0x27`). All Prime eRob are **50:1** gear. The single source of truth for this mapping -is `bar_bringup_prime/config/prime_hardware.yaml` (`buses`, `joints.all_joints`, +is `humanoid_control_bringup_prime/config/prime_hardware.yaml` (`buses`, `joints.all_joints`, `joints.erob_slaves`, `joints.mit_joints`); the per-joint bus assignment is emitted by `prime_description` (`robots/prime_dummy/xacro/prime_dummy.ros2_control.xacro`). @@ -54,7 +54,7 @@ constant (read each joint's model off its label; see the eRob manual §25.2): The 1.5% `Kt` difference is negligible in practice; the **gear ratio** would be the real lever, but every Prime eRob is 50:1, so a single conversion -serves all of them. `bar_bringup_prime/config/prime_hardware.yaml` can still +serves all of them. `humanoid_control_bringup_prime/config/prime_hardware.yaml` can still override `Kt`/gear per joint (`joints.erob_kt` / `joints.erob_gear`) if a model ever differs. @@ -63,7 +63,7 @@ ever differs. `real.launch.py` expands the xacro with `use_fake_hardware:=false use_sim:=false`, which emits **two concurrent `ros2_control` blocks** — `PrimeEtherCATSide` (`ethercat_driver/EthercatDriver`, the 10 eRob) and `PrimeSitoCAN` -(`bar_sito/SitoSystem`, the 4 Sito wrists). One `controller_manager` runs them +(`humanoid_control_sito/SitoSystem`, the 4 Sito wrists). One `controller_manager` runs them together and exposes a flat 14-joint list to the mode controllers. The sim path (`mujoco.launch.py`) collapses both into one `MujocoSystem` block but presents the identical 14 joints, so the shared controllers run unchanged. @@ -96,7 +96,7 @@ differently — and that difference is the heart of the Prime control story. The Sito firmware runs the MIT law directly. The host sends the desired position, velocity, and feedforward torque in a command frame, and `Kp`/`Kd` in a separate gains frame. Conversions (in -`bar_devices/bar_sito/include/bar_sito/sito_protocol.hpp`, TA40-50): +`humanoid_control_devices/humanoid_control_sito/include/humanoid_control_sito/sito_protocol.hpp`, TA40-50): ``` position_counts = q_cmd · 65536 / (2π) # 16-bit encoder, MOTOR side @@ -132,7 +132,7 @@ are not PDO-mappable, so they cannot be a per-tick command interface): | `0x2381:02` | velocity loop integral (held at 0 for clean impedance) | | `0x2383` | "Bus Regulation of PID" gate — `1` = use bus-written gains, `0` = factory | -The SI-to-register conversion (`bar_bringup_prime/scripts/erob_impedance_manager.py`, +The SI-to-register conversion (`humanoid_control_bringup_prime/scripts/erob_impedance_manager.py`, `erob_gains()`), validated exactly against the ZeroErr derivation: ``` @@ -186,7 +186,7 @@ fixed mode impedance and track position in CSP. ## The eRob impedance manager -`bar_bringup_prime/scripts/erob_impedance_manager.py` is the bridge between the +`humanoid_control_bringup_prime/scripts/erob_impedance_manager.py` is the bridge between the mode FSM and the eRob loop gains. It subscribes to `/control_mode` and, on each transition, converts that mode's `(kp, kd)` to loop-gain registers and writes them over the EtherLab `ethercat download` CLI. (It uses the CLI, not the diff --git a/docs/concepts/safety_pipeline.md b/docs/concepts/safety_pipeline.md index 6f0deab..6609502 100644 --- a/docs/concepts/safety_pipeline.md +++ b/docs/concepts/safety_pipeline.md @@ -4,7 +4,7 @@ title: Safety pipeline # Safety pipeline -`bar_ros2`'s safety layer is **layered** rather than concentrated. +`humanoid_control`'s safety layer is **layered** rather than concentrated. Three subsystems each enforce one piece of the contract; together they make sure that "the robot is in DAMPING within a tick of a fault" is the worst case, never "the robot is doing something @@ -26,11 +26,11 @@ unexpected and we didn't notice". | `TEMPERATURE_LIMIT` | A specific overtemperature bit was set in a motor's fault frame. | | `INVALID_FRAME` | A frame on the bus had the wrong comm-type code or DLC for the protocol. | -The plugin publishes `bar_msgs/SafetyStatus` on `/safety_status` — +The plugin publishes `humanoid_control_msgs/SafetyStatus` on `/safety_status` — TRANSIENT_LOCAL durability so late-joining subscribers (like rqt or a freshly-started `mode_manager`) immediately see the most recent value. The `source` field carries the bus interface name -(`bar_robstride/can0`, etc.), so an operator can tell which bus +(`humanoid_control_robstride/can0`, etc.), so an operator can tell which bus flagged. Each tick, the plugin rebuilds `flags` from **currently observed** @@ -84,7 +84,7 @@ against bad *output* instead: a NaN / non-finite action returns Every active-policy controller is configured with `fallback_controllers: [damping_controller]` in -`bar_lite_controllers.yaml`. The controller_manager interprets this +`humanoid_control_lite_controllers.yaml`. The controller_manager interprets this as "if this controller returns ERROR, automatically deactivate it and activate the fallback". diff --git a/docs/concepts/workspace_and_environment.md b/docs/concepts/workspace_and_environment.md index e2937a5..314876f 100644 --- a/docs/concepts/workspace_and_environment.md +++ b/docs/concepts/workspace_and_environment.md @@ -17,13 +17,13 @@ it into one environment and one repository creates dependency conflicts (CUDA versions, PyTorch wheels vs. the ROS conda packages), build-system mismatches (colcon vs. uv), and release-cadence mismatches. -`bar_ros2` separates code by **what it needs to talk to**, not by language +`humanoid_control` separates code by **what it needs to talk to**, not by language or topic: | | **Tier 1 — ROS native** | **Tier 2 — workspace tooling** | **Tier 3 — separate project** | |---|---|---|---| -| Location | `src//` | per-package `scripts/`, the `bar` CLI, a future top-level `scripts/` | its own git repo, outside the workspace | -| Examples | `bar_controllers`, `bar_robstride`, `bar_socketcan` | `robstride_probe`, calibration helpers, `bar bus ping` | `Lite-SDK2`, `Lite-Gravity-Compensation` | +| Location | `src//` | per-package `scripts/`, the `hc` CLI, a future top-level `scripts/` | its own git repo, outside the workspace | +| Examples | `humanoid_controllers`, `humanoid_control_robstride`, `humanoid_control_socketcan` | `robstride_probe`, calibration helpers, `hc bus ping` | `Lite-SDK2`, `Lite-Gravity-Compensation` | | Build / run | `colcon` + `ros2 run` | `pixi run …` | own toolchain (`uv run …`) | | Imports `rclpy`? | **yes** | no | **no** | | Talks to ROS via | native pub / sub / service / action | doesn't talk to running nodes | **DDS (CycloneDDS)** + file handoff | @@ -39,18 +39,18 @@ follows: a process with no ROS deps participating in the robot's DDS network. The catch with "just speak DDS directly" is usually that you have to -hand-mirror the message types, and they drift. `bar_ros2` avoids that by +hand-mirror the message types, and they drift. `humanoid_control` avoids that by **generating** them: -- [`bar_msgs_dds`](../reference/packages.md) generates wire-compatible - `cyclonedds` types from `bar_msgs/msg/*.msg` (`pixi run gen-dds`), +- [`humanoid_control_msgs_dds`](../reference/packages.md) generates wire-compatible + `cyclonedds` types from `humanoid_control_msgs/msg/*.msg` (`pixi run gen-dds`), including the RMW type-name mangling and `rt/` topic conventions. A CI drift test + a CDR wire round-trip test keep it honest. -- [`lite_sdk2`](../how_to/talk_to_bar_ros2_from_python.md) layers a +- [`lite_sdk2`](../how_to/talk_to_humanoid_control_from_python.md) layers a publisher/subscriber API (topic + QoS registry) on top of those types. - [`Lite-Gravity-Compensation`](../tutorials/run_gravity_compensation.md) is the reference Tier-3 project: it depends on `lite_sdk2`, computes - gravity torques in MuJoCo, and publishes `bar_msgs/MITCommand` onto + gravity torques in MuJoCo, and publishes `humanoid_control_msgs/MITCommand` onto `/remote_policy_controller/command` (consumed by the `RemotePolicyController`) over raw CycloneDDS — no `rclpy`, no colcon sourcing. @@ -60,7 +60,7 @@ with the ROS schema. ### When to promote a tier -- **Tier 2 → a new `bar_*` package** when a script grows into a real ROS +- **Tier 2 → a new `humanoid_control_*` package** when a script grows into a real ROS node (it needs to publish/subscribe, claim interfaces, or run inside the controller_manager process). - **Tier 2 → Tier 3** when it (a) needs dependencies that conflict with @@ -76,12 +76,12 @@ with the ROS schema. The environment — ROS 2 Jazzy, the compiler toolchain, every Python and native dependency — is managed by [pixi](https://pixi.sh) against the [RoboStack](https://robostack.github.io) conda channel, pinned by -`bar_ws/pixi.toml` + `pixi.lock`. +`humanoid_control_ws/pixi.toml` + `pixi.lock`. - **Reproducible.** `pixi.lock` pins exact versions and hashes; the same lockfile resolves the same environment on every developer machine and on the Jetson (`linux-64` + `linux-aarch64`). -- **No sudo, no system pollution.** Everything lives under `bar_ws/.pixi/`. +- **No sudo, no system pollution.** Everything lives under `humanoid_control_ws/.pixi/`. No host Ubuntu-version dependency, no system-wide `ros-jazzy-desktop`. - **One tool for conda *and* PyPI.** pixi drives `uv` internally for the PyPI side (`onnxruntime`, `huggingface-hub`, the visualisers), so there @@ -117,22 +117,22 @@ before deployment; see [Architecture → deployment topology](./architecture.md) The repository layout is a deliberate split: -- **`bar_ws` is a thin, config-only git repo.** It tracks only the +- **`humanoid_control_ws` is a thin, config-only git repo.** It tracks only the environment and tooling — `pixi.toml`, `pixi.lock`, `.gitattributes` (which marks `pixi.lock` as generated), `canup.sh`, and the task definitions — and **gitignores all of `src/`** (keeping a `.gitkeep`). -- **First-party code lives in the `bar_ros2` monorepo.** All the `bar_*` +- **First-party code lives in the `humanoid_control` monorepo.** All the `humanoid_control_*` packages are co-developed and released together, so they share one repo - (its own git history) checked out under `src/bar_ros2/`, rather than the + (its own git history) checked out under `src/humanoid_control/`, rather than the strict `ros2/ros2` one-repo-per-package convention. The piano task is the sibling `pianist_ros2` repo under `src/pianist_ros2/`. - **Third-party dependencies are pinned, not vendored.** - `src/bar_ros2/bar.repos` lists `ethercat_driver_ros2` and the three + `src/humanoid_control/bar.repos` lists `ethercat_driver_ros2` and the three `mujoco_*` packages; `vcs import` (`pixi run setup`) pulls them into `src/`. Pin to commit SHAs for releases. -This keeps the *environment* history (`bar_ws` / `pixi.lock`) on a separate -track from the *code* history (`bar_ros2`), while still letting `bar_ros2` +This keeps the *environment* history (`humanoid_control_ws` / `pixi.lock`) on a separate +track from the *code* history (`humanoid_control`), while still letting `humanoid_control` be tagged and reused on its own. ### The reproducibility chain @@ -140,14 +140,14 @@ be tagged and reused on its own. Three independent pins compose into a deterministic rebuild: ```sh -git clone && cd bar_ws -git clone …/bar_ros2.git src/bar_ros2 # + pianist_ros2 for the piano task +git clone && cd humanoid_control_ws +git clone …/humanoid_control.git src/humanoid_control # + pianist_ros2 for the piano task pixi install # exact env from pixi.lock pixi run setup # vcs import third-party deps into src/ pixi run build # colcon build ``` -`pixi.lock` pins the environment; the `bar_ros2` / `pianist_ros2` +`pixi.lock` pins the environment; the `humanoid_control` / `pianist_ros2` checkouts pin the first-party tree; `bar.repos` pins the third-party tree. Together they reproduce the workspace bit-for-bit. @@ -157,6 +157,6 @@ Together they reproduce the workspace bit-for-bit. setup. - [Workspace shortcuts with pixi](../how_to/use_pixi_tasks.md) — what each `pixi run …` alias does. -- [Talk to bar_ros2 from Python](../how_to/talk_to_bar_ros2_from_python.md) +- [Talk to humanoid_control from Python](../how_to/talk_to_humanoid_control_from_python.md) — building a Tier-3 client over DDS. - [Packages reference](../reference/packages.md) — what each package ships. diff --git a/docs/getting_started/installation.md b/docs/getting_started/installation.md index 8b7db3b..8953a02 100644 --- a/docs/getting_started/installation.md +++ b/docs/getting_started/installation.md @@ -2,13 +2,13 @@ There are two ways to get BAR onto your machine: -- **Install the prebuilt packages (recommended)** — pull the `ros-jazzy-bar-*` - conda packages straight from the [`bar-robotics`](https://prefix.dev/channels/bar-robotics) +- **Install the prebuilt packages (recommended)** — pull the `ros-jazzy-humanoid-control-*` + conda packages straight from the [`berkeley-humanoids`](https://prefix.dev/channels/berkeley-humanoids) channel. No clone, no `colcon`, no compiler — ~2 minutes. Best for running the control stack, deploying to a robot or Jetson, or building your own packages on - top of `bar_msgs` / `bar_controllers`. + top of `humanoid_control_msgs` / `humanoid_controllers`. - **Build from source** — clone the repos into a pixi workspace and `colcon - build`. For contributors who modify `bar_ros2`, and for the parts not yet in + build`. For contributors who modify `humanoid_control`, and for the parts not yet in the channel (MuJoCo sim, the piano task, EtherCAT / Prime). Both use [pixi](https://pixi.sh); neither needs a system-wide `ros-jazzy-desktop` @@ -52,7 +52,7 @@ shell rc. Restart your shell (or `source ~/.bashrc`) so `pixi` resolves. ## Install the prebuilt packages (recommended) The BAR packages are published as conda packages on the -[`bar-robotics`](https://prefix.dev/channels/bar-robotics) channel and rebuilt by +[`berkeley-humanoids`](https://prefix.dev/channels/berkeley-humanoids) channel and rebuilt by the buildfarm on every release. You consume them like any other dependency. ### 1. Create a project and add the channel @@ -68,7 +68,7 @@ Open `bar-app/pixi.toml` and set the channels + the package(s) you want: [workspace] name = "bar-app" channels = [ - "https://prefix.dev/bar-robotics", + "https://prefix.dev/berkeley-humanoids", "https://prefix.dev/robostack-jazzy", "https://prefix.dev/conda-forge", ] @@ -80,22 +80,22 @@ platforms = ["linux-64", "linux-aarch64"] # yourself. Use ros-jazzy-desktop instead if you want the RViz-based # `view` / `viz` launches. ros-jazzy-ros-base = "*" -# The whole Lite bringup: bar_controllers (ONNX-enabled), bar_msgs, -# lite_description, bar_robstride, bar_socketcan, bar_common, bar_policy. -ros-jazzy-bar-bringup-lite = "*" -# Optional: the `bar` diagnostic CLI (run via `ros2 run bar_cli bar ...`). -ros-jazzy-bar-cli = "*" +# The whole Lite bringup: humanoid_controllers (ONNX-enabled), humanoid_control_msgs, +# lite_description, humanoid_control_robstride, humanoid_control_socketcan, humanoid_control_common, humanoid_control_policy. +ros-jazzy-humanoid-control-bringup-lite = "*" +# Optional: the `hc` diagnostic CLI (run via `ros2 run humanoid_control_cli hc ...`). +ros-jazzy-humanoid-control-cli = "*" ``` -`bar-robotics` is listed **first** so `ros-jazzy-bar-*` resolves from there, with +`berkeley-humanoids` is listed **first** so `ros-jazzy-humanoid-control-*` resolves from there, with RoboStack + conda-forge underneath for the ROS core and native libs. Add only -the packages you need — e.g. `ros-jazzy-bar-msgs` if you just want the message -definitions, or `ros-jazzy-bar-controllers` to build a node against the +the packages you need — e.g. `ros-jazzy-humanoid-control-msgs` if you just want the message +definitions, or `ros-jazzy-humanoid-controllers` to build a node against the controller interfaces. The full set is on the [Packages reference](../reference/packages.md). :::note[Pull a ROS base alongside the bar packages] -`ros-jazzy-bar-bringup-lite` pulls its own library dependencies, but **not** the +`ros-jazzy-humanoid-control-bringup-lite` pulls its own library dependencies, but **not** the `ros2 launch` / `ros2 run` / `ros2 pkg` command-line tooling — those live in `ros-jazzy-ros-base` (or `ros-jazzy-desktop`). Without a ROS base, `ros2 launch` fails with `invalid choice: 'launch'`. The from-source workspace gets this from @@ -106,25 +106,25 @@ fails with `invalid choice: 'launch'`. The from-source workspace gets this from ```sh pixi install -pixi run ros2 launch bar_bringup_lite real.launch.py +pixi run ros2 launch humanoid_control_bringup_lite real.launch.py ``` -`pixi install` downloads the prebuilt `ros-jazzy-bar-*` binaries plus the +`pixi install` downloads the prebuilt `ros-jazzy-humanoid-control-*` binaries plus the RoboStack ROS core — no build step. Everything the packages ship (launch files, URDFs, meshes, controller YAMLs, console executables) lands on the ament index, so `ros2 launch …` / `ros2 run …` work inside `pixi shell` (or via -`pixi run …`). The `bar` diagnostic CLI is a package executable — run it as -`ros2 run bar_cli bar …`. +`pixi run …`). The `hc` diagnostic CLI is a package executable — run it as +`ros2 run humanoid_control_cli hc …`. ```sh pixi shell -ros2 pkg list | grep '^bar_' # the bar_* packages you pulled in -ros2 launch bar_bringup_lite real.launch.py --show-args # dry-parse the launch (no hardware) -ros2 run bar_cli bar bus discover --iface can0 --scan-to 32 # read-only CAN scan, e.g. +ros2 pkg list | grep '^humanoid_control_' # the humanoid_control_* packages you pulled in +ros2 launch humanoid_control_bringup_lite real.launch.py --show-args # dry-parse the launch (no hardware) +ros2 run humanoid_control_cli hc bus discover --iface can0 --scan-to 32 # read-only CAN scan, e.g. ``` :::note[What the channel ships today] -`bar-robotics` carries the **11 `ros-jazzy-bar-*` packages** for both `linux-64` +`berkeley-humanoids` carries the **11 `ros-jazzy-humanoid-control-*` packages** for both `linux-64` and `linux-aarch64` (Jetson). That covers the full control stack and the real-hardware **Lite** bringup (`real.launch.py`). Not yet published: the MuJoCo simulation deps (`mujoco_*`), the piano task (`pianist_*`), and the EtherCAT / @@ -146,28 +146,28 @@ pixi add --pypi rerun-sdk viser yourdfpy "scipy>=1.13" ## Build from source -For contributors who modify `bar_ros2`, or to get the packages not yet in the +For contributors who modify `humanoid_control`, or to get the packages not yet in the channel (MuJoCo sim, piano task, EtherCAT / Prime). This builds everything with `colcon` inside the same pixi-managed environment. ### 1. Clone the workspace and sources -`bar_ws` is a thin, **config-only** repo (`bar-ros2-project`): it tracks the pixi +`humanoid_control_ws` is a thin, **config-only** repo (`bar-ros2-project`): it tracks the pixi environment and the workspace tasks, and gitignores `src/`. The first-party code lives in separate repos that you clone into `src/` yourself (third-party deps are pulled later, in step 3). ```sh # the config-only workspace -git clone https://github.com/T-K-233/bar-ros2-project.git bar_ws -cd bar_ws +git clone https://github.com/T-K-233/bar-ros2-project.git humanoid_control_ws +cd humanoid_control_ws -# first-party sources into src/ (gitignored by bar_ws) -git clone https://github.com/T-K-233/bar_ros2.git src/bar_ros2 +# first-party sources into src/ (gitignored by humanoid_control_ws) +git clone https://github.com/Berkeley-Humanoids/humanoid_control.git src/humanoid_control git clone https://github.com/T-K-233/pianist_ros2.git src/pianist_ros2 # optional: piano task ``` -`src/bar_ros2` is the package monorepo (required); `src/pianist_ros2` is the +`src/humanoid_control` is the package monorepo (required); `src/pianist_ros2` is the optional piano-task sibling — skip it if you don't need piano. Don't hand-clone the `mujoco_*` / `ethercat_driver_ros2` dependencies; `vcs import` pulls those in step 3. @@ -186,7 +186,7 @@ reproducible solve. ### 3. Pull third-party sources ```sh -vcs import --input src/bar_ros2/bar.repos src +vcs import --input src/humanoid_control/bar.repos src ``` This brings in the three `mujoco_*` packages and `ethercat_driver_ros2` under @@ -198,7 +198,7 @@ colcon build fails with a clear CMake error — add the dep to `pixi.toml`'s :::warning[Optional: skip the EtherCAT path] `ethercat_driver_ros2` links `libethercat`, which has no conda recipe. The -default build below skips `ethercat.*` and `bar_bringup_prime` so Lite bringup +default build below skips `ethercat.*` and `humanoid_control_bringup_prime` so Lite bringup works on any host. To enable Prime, install the IgH EtherLAB master from source on the host, then drop the `--packages-skip-regex` filter. ::: @@ -207,10 +207,10 @@ on the host, then drop the `--packages-skip-regex` filter. ```sh pixi shell -colcon build --symlink-install --packages-skip-regex 'ethercat.*|bar_bringup_prime' +colcon build --symlink-install --packages-skip-regex 'ethercat.*|humanoid_control_bringup_prime' ``` -`pixi shell` sources the conda env and `bar_ws/install/setup.bash` once it +`pixi shell` sources the conda env and `humanoid_control_ws/install/setup.bash` once it exists, so `ros2`, `colcon`, and every console script land on `PATH`. The build covers the Lite path (every BAR + Pianist package plus the three `mujoco_*` deps). `--symlink-install` means edits to launch / config / Python files are @@ -221,25 +221,25 @@ re-sources `install/setup.bash` whenever you enter `pixi shell`. ### 5. Sanity-check ```sh -ros2 pkg list | grep '^bar_' # 12 entries from bar_ros2 +ros2 pkg list | grep '^humanoid_control_' # 12 entries from humanoid_control ros2 pkg list | grep '^pianist_' # 4 entries from pianist_ros2 ros2 control list_hardware_interfaces 2>/dev/null \ || echo "(no controller_manager running yet — expected)" ``` -The 11 `bar_ros2` packages (Lite's `lite_description` comes separately, via `bar.repos`): +The 11 `humanoid_control` packages (Lite's `lite_description` comes separately, via `bar.repos`): ``` -bar_bringup_lite -bar_bringup_prime -bar_cli -bar_common -bar_controllers -bar_robstride -bar_sito -bar_socketcan -bar_msgs -bar_policy +humanoid_control_bringup_lite +humanoid_control_bringup_prime +humanoid_control_cli +humanoid_control_common +humanoid_controllers +humanoid_control_robstride +humanoid_control_sito +humanoid_control_socketcan +humanoid_control_msgs +humanoid_control_policy ``` The 4 `pianist_ros2` packages (present only if you cloned the piano-task sibling diff --git a/docs/getting_started/intro.md b/docs/getting_started/intro.md index 2703dac..3bb674f 100644 --- a/docs/getting_started/intro.md +++ b/docs/getting_started/intro.md @@ -1,13 +1,13 @@ # Introduction -`bar_ros2` is the unified low-level control stack for the **Berkeley Architecture +`humanoid_control` is the unified low-level control stack for the **Berkeley Architecture Research (BAR)** humanoid robots. It runs on **ROS 2 Jazzy under PREEMPT_RT** (shipped via the [RoboStack](https://robostack.github.io) conda channel and pixi, no system-wide ROS install required) and targets two robots with **as much shared code as possible**. Task-specific packages (piano playing, etc.) ship from sibling repos -that depend on `bar_ros2` — see [Packages reference](../reference/packages.md) +that depend on `humanoid_control` — see [Packages reference](../reference/packages.md) for the split. Throughout the rest of the docs, runtime commands are shown in canonical `ros2 launch …` / `ros2 run …` form; if you prefer shorter aliases, the workspace also ships a `pixi run …` shortcut @@ -35,7 +35,7 @@ hardware-by-hardware axis: separate plugins for each actuator family, separate launch files per task, separate observation pipelines for sim vs. silicon. The result is N × M code paths, where N is robots and M is tasks. -`bar_ros2` factors the axes orthogonally: +`humanoid_control` factors the axes orthogonally: | Axis | Where the variation lives | |---|---| @@ -61,14 +61,14 @@ controllers — they don't see the split. Prime adds a third path through ## How the project is organized -A single git repo at `T-K-233/bar_ros2`, a flat collection of ROS 2 packages +A single git repo at `Berkeley-Humanoids/humanoid_control`, a flat collection of ROS 2 packages (franka_ros2 / Universal_Robots_ROS2_Driver pattern): ![Package organization](/img/diagrams/getting_started__intro__02.svg) -Notice that **`bar_controllers`, `bar_msgs`, and `bar_policy` have no -robot-specific code** — everything robot-specific lives in `bar_description_*` -or `bar_bringup_*`. +Notice that **`humanoid_controllers`, `humanoid_control_msgs`, and `humanoid_control_policy` have no +robot-specific code** — everything robot-specific lives in `humanoid_control_description_*` +or `humanoid_control_bringup_*`. ## Design rationale (one-paragraph version) @@ -97,7 +97,7 @@ list; the most influential are: decomposition pattern and `industrial_ci` workflow. - **[legged_control2](https://qiayuanl.github.io/legged_control2_doc/overview.html)** — two-tier hardware factoring (bus library / per-actuator-family plugin) - that we mirror for `bar_socketcan` / `bar_robstride` / `bar_sito`. + that we mirror for `humanoid_control_socketcan` / `humanoid_control_robstride` / `humanoid_control_sito`. - **[mujoco_ros2_control](https://github.com/qiayuanl/mujoco_ros2_control)** — the MuJoCo ↔ ros2_control bridge whose `MujocoSystem` plugin we consume. - **[franka_ros2](https://github.com/frankarobotics/franka_ros2)** — the flat @@ -105,7 +105,7 @@ list; the most influential are: - **[Universal_Robots_ROS2_Driver](https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver)** — gold-standard `ros2_control` hardware integration. The `Universal_Robots_Client_Library` / `ur_robot_driver` split mirrors our - `bar_socketcan` / `bar_robstride` split. + `humanoid_control_socketcan` / `humanoid_control_robstride` split. ## Next @@ -114,4 +114,4 @@ list; the most influential are: - [Architecture](../concepts/architecture.md) — ros2_control flow, the 5-mode FSM, and the in-process System 0 policy tier. - [Installation](./installation.md) — install the prebuilt packages from the - `bar-robotics` channel in ~2 minutes, or build from source. \ No newline at end of file + `berkeley-humanoids` channel in ~2 minutes, or build from source. \ No newline at end of file diff --git a/docs/getting_started/lite_101.md b/docs/getting_started/lite_101.md index 3cfa8db..c7d2b2c 100644 --- a/docs/getting_started/lite_101.md +++ b/docs/getting_started/lite_101.md @@ -19,7 +19,7 @@ Every command on this page runs inside `pixi shell` (one-time per terminal, sources ROS 2 Jazzy + the workspace overlay): ```sh -cd bar_ws && pixi shell +cd humanoid_control_ws && pixi shell ``` Stay in that shell for the rest of the lesson. If you ever want @@ -35,7 +35,7 @@ The simplest possible launch: `robot_state_publisher` + a the kinematic chain. ```sh -ros2 launch bar_bringup_lite view_lite.launch.py +ros2 launch humanoid_control_bringup_lite view_lite.launch.py ``` What you'll see: @@ -66,7 +66,7 @@ hosted inside `mujoco_sim`, all five mode-FSM controllers loaded, the the Robstride firmware computes on silicon. ```sh -ros2 launch bar_bringup_lite mujoco.launch.py +ros2 launch humanoid_control_bringup_lite mujoco.launch.py ``` A **MuJoCo viewer window** opens with the Lite humanoid at zero pose. @@ -89,11 +89,11 @@ Expected output (give or take): ``` joint_state_broadcaster joint_state_broadcaster/JointStateBroadcaster active -zero_torque_controller bar/ZeroTorqueController active -damping_controller bar/DampingController inactive -standby_controller bar/StandbyController inactive -rl_policy_controller bar/RLPolicyController inactive -remote_policy_controller bar/RemotePolicyController inactive +zero_torque_controller humanoid_control/ZeroTorqueController active +damping_controller humanoid_control/DampingController inactive +standby_controller humanoid_control/StandbyController inactive +rl_policy_controller humanoid_control/RLPolicyController inactive +remote_policy_controller humanoid_control/RemotePolicyController inactive ``` ### What just happened @@ -142,13 +142,13 @@ ros2 topic echo --once /control_mode :::tip["See it move"] Two interchangeable live visualizers ride on `/lite/joint_states` + -`/robot_description`, both shipped by `bar_bringup_lite`. On the +`/robot_description`, both shipped by `humanoid_control_bringup_lite`. On the tethered deployment they live on the **operator workstation** (host side of the tether), spawned by `viz.launch.py`: ```sh -ros2 launch bar_bringup_lite viz.launch.py # viser, http://localhost:8080 -ros2 launch bar_bringup_lite viz.launch.py viewer:=rerun # native rerun window +ros2 launch humanoid_control_bringup_lite viz.launch.py # viser, http://localhost:8080 +ros2 launch humanoid_control_bringup_lite viz.launch.py viewer:=rerun # native rerun window ``` For a single-machine MuJoCo run, the standalone shortcuts work too — @@ -156,8 +156,8 @@ they auto-discover `/robot_description` and the joint-state topic on the local domain: ```sh -ros2 run bar_bringup_lite viser_viz -ros2 run bar_bringup_lite rerun_viz +ros2 run humanoid_control_bringup_lite viser_viz +ros2 run humanoid_control_bringup_lite rerun_viz ``` Visualiser dependencies (`rerun-sdk`, `viser`, `yourdfpy`, `scipy`) @@ -185,8 +185,8 @@ Verify: ```sh ros2 control list_controllers -# damping_controller bar/DampingController active -# zero_torque_controller bar/ZeroTorqueController inactive +# damping_controller humanoid_control/DampingController active +# zero_torque_controller humanoid_control/ZeroTorqueController inactive ``` :::tip[Why DAMPING is the "compliant fail-safe"] @@ -227,7 +227,7 @@ Four moving pieces, all worth recognising for the rest of the docs: |---|---| | **URDF** (`lite_description`) | Kinematic + dynamic description. Same file across mock / sim / real — the `` `` is the only difference. | | **`controller_manager`** | Hosts the hardware plugin + every controller. The "tick loop" of the system. Update rate 50 Hz here. | -| **Mode-FSM controllers** (`bar_controllers`) | Five plugins, one active at a time. `zero_torque` (safe default), `damping` (compliant fail-safe), `standby` (interpolate to a pose), `rl_policy` (in-process ONNX — the System 0 learned-policy tier), `remote_policy` (System 1/2 external-command ingress for non-real-time `MITCommand` sources). | +| **Mode-FSM controllers** (`humanoid_controllers`) | Five plugins, one active at a time. `zero_torque` (safe default), `damping` (compliant fail-safe), `standby` (interpolate to a pose), `rl_policy` (in-process ONNX — the System 0 learned-policy tier), `remote_policy` (System 1/2 external-command ingress for non-real-time `MITCommand` sources). | | **MuJoCo / Robstride** (the simulation / real backend) | Where the MIT torque actually gets applied. Same five command interfaces in both. | ## Next diff --git a/docs/how_to/add_new_joint.md b/docs/how_to/add_new_joint.md index e3d5575..e3e6f8e 100644 --- a/docs/how_to/add_new_joint.md +++ b/docs/how_to/add_new_joint.md @@ -18,8 +18,8 @@ Five files in three packages: | `lite_description/robots/lite_dummy/xacro/lite_dummy.urdf.xacro` | Kinematic chain: link, joint axis, limits, mass, mesh | | `lite_description/robots/lite_dummy/xacro/lite_dummy.ros2_control.xacro` | `` block — which CAN bus, model, direction, command/state interfaces | | `lite_description/robots/lite_dummy/mjcf/lite_dummy.xml` | MuJoCo model (if you want sim parity) | -| `bar_controllers/config/bar_lite_controllers.yaml` | `joints:` list for every controller + per-joint K/D / standby pose entries | -| `bar_bringup_lite/config/calibration.yaml` | `homing_offset` for the new joint (created via [Calibrate the zero pose](./calibrate_zero_pose.md)) | +| `humanoid_controllers/config/humanoid_control_lite_controllers.yaml` | `joints:` list for every controller + per-joint K/D / standby pose entries | +| `humanoid_control_bringup_lite/config/calibration.yaml` | `homing_offset` for the new joint (created via [Calibrate the zero pose](./calibrate_zero_pose.md)) | > **Heads-up — the Lite description is generated.** The three `lite_description` > files above are build artifacts of the external @@ -93,7 +93,7 @@ xacro $(ros2 pkg prefix lite_description)/share/lite_description/robots/lite_dum Open the file, confirm the new joints appear with the right `` children. -## Step 3 — Update `bar_lite_controllers.yaml` +## Step 3 — Update `humanoid_control_lite_controllers.yaml` For every controller's `joints:` list, append the new joint name(s). **Order matters** — this is the canonical joint order @@ -134,24 +134,24 @@ Once the URDF + YAML are updated and the build is clean, plug in the new motor and run: ```bash -ros2 launch bar_bringup_lite calibrate.launch.py +ros2 launch humanoid_control_bringup_lite calibrate.launch.py ``` Hand-sweep the new joint(s) through their full range. Old joints sit stationary — the tool's `sweep_threshold` will preserve their existing `homing_offset` entries. Move the resulting -`./calibration.yaml` over `bar_bringup_lite/config/calibration.yaml`. +`./calibration.yaml` over `humanoid_control_bringup_lite/config/calibration.yaml`. ## Step 5 — Verify ```bash -ros2 launch bar_bringup_lite real.launch.py mode:=arms_neck +ros2 launch humanoid_control_bringup_lite real.launch.py mode:=arms_neck ``` In a second terminal: ```bash -cd bar_ws && pixi shell +cd humanoid_control_ws && pixi shell # Should now see 14 + new joints in /lite/joint_states ros2 topic echo --once /lite/joint_states | grep -c " - " # name count ``` diff --git a/docs/how_to/calibrate_prime_erob.md b/docs/how_to/calibrate_prime_erob.md index 4e76200..44122f3 100644 --- a/docs/how_to/calibrate_prime_erob.md +++ b/docs/how_to/calibrate_prime_erob.md @@ -1,6 +1,6 @@ # Calibrate the Prime arms (eRob + Sito) -Per-physical-robot recipe: regenerate `bar_bringup_prime/config/prime_calibration.yaml` +Per-physical-robot recipe: regenerate `humanoid_control_bringup_prime/config/prime_calibration.yaml` so each joint's encoder zero maps to the URDF's joint zero. One file holds all 14 joints — the 10 eRob (ZeroErr, EtherCAT) arm joints and the 4 Sito (CAN) wrists — and the **same** `calibrate_erob` sweep tool calibrates both. Same idea as @@ -71,9 +71,9 @@ The launch also spawns the `joint_state_broadcaster` (so `/prime/joint_states` f and the `calibrate_erob` tracker: ```bash -ros2 launch bar_bringup_prime calibrate.launch.py backends:=ec \ +ros2 launch humanoid_control_bringup_prime calibrate.launch.py backends:=ec \ output:=~/prime_calibration.yaml \ - prior:=$(ros2 pkg prefix bar_bringup_prime)/share/bar_bringup_prime/config/prime_calibration.yaml + prior:=$(ros2 pkg prefix humanoid_control_bringup_prime)/share/humanoid_control_bringup_prime/config/prime_calibration.yaml ``` `prior:=...` carries already-calibrated joints (the Sito wrists, or the other arm) @@ -87,7 +87,7 @@ with a live readout. For each ring position, support the joint, then: ```bash -ros2 run bar_bringup_prime erob_limp_joint # e.g. 4 +ros2 run humanoid_control_bringup_prime erob_limp_joint # e.g. 4 ``` The joint goes damped-limp (the read-back prints `Kp=0`, confirming the `0x2383` gate @@ -102,7 +102,7 @@ joint with too small a sweep (skipped, prior kept) or `abs(homing_offset) > pi` ## Step 3 — Apply and verify -Copy the reviewed file over `bar_bringup_prime/config/prime_calibration.yaml`. +Copy the reviewed file over `humanoid_control_bringup_prime/config/prime_calibration.yaml`. `real.launch.py` folds it into per-joint configs automatically at launch. To verify the sign end-to-end, fold it, re-launch, and move one joint to a known stop — at the stop, `/joint_states` should read that joint's URDF limit. @@ -114,7 +114,7 @@ A good cross-check on a symmetric robot: the two arms' offsets should mirror eac The 4 Sito wrists (`left`/`right` `wrist_roll` + `wrist_pitch`) use the **same** `calibrate_erob` tool and the **same** `prime_calibration.yaml` — it discovers them from -the `bar_sito/SitoSystem` block (by `can_id`) alongside the eRob. Two differences: +the `humanoid_control_sito/SitoSystem` block (by `can_id`) alongside the eRob. Two differences: - **Limp is free.** A Sito is an MIT motor; with no command controller active its gains default to zero, so it is backdrivable out of the box — no gain-gate dance. @@ -124,13 +124,13 @@ the `bar_sito/SitoSystem` block (by `can_id`) alongside the eRob. Two difference single-bus run still writes a complete 14-joint file. ```bash -ros2 launch bar_bringup_prime calibrate.launch.py backends:=can \ +ros2 launch humanoid_control_bringup_prime calibrate.launch.py backends:=can \ output:=~/prime_calibration.yaml \ - prior:=$(ros2 pkg prefix bar_bringup_prime)/share/bar_bringup_prime/config/prime_calibration.yaml + prior:=$(ros2 pkg prefix humanoid_control_bringup_prime)/share/humanoid_control_bringup_prime/config/prime_calibration.yaml ``` Hand-sweep each wrist to both stops (the live readout tracks them), Ctrl-C, review, copy -over `prime_calibration.yaml`, and `colcon build --packages-select bar_bringup_prime`. +over `prime_calibration.yaml`, and `colcon build --packages-select humanoid_control_bringup_prime`. Unlike the eRob, the Sito read `direction` **and** `homing_offset` straight from this file (`SitoSystem::load_calibration`) — so a flipped wrist is a one-line edit. @@ -145,7 +145,7 @@ offset_new = offset + (lower + upper) For a symmetric joint (`lower = -upper`, e.g. the wrists) the offset is unchanged; for an asymmetric one (e.g. `shoulder_roll`, `elbow_pitch`) it shifts. Then -`colcon build --packages-select bar_bringup_prime` — no source rebuild; the eRob fold and +`colcon build --packages-select humanoid_control_bringup_prime` — no source rebuild; the eRob fold and `SitoSystem` both re-read the file at launch. This works for any joint, eRob or Sito. ## eRob bus-split (hardware-confirmed) diff --git a/docs/how_to/calibrate_zero_pose.md b/docs/how_to/calibrate_zero_pose.md index 5cdcf0a..5bc7e33 100644 --- a/docs/how_to/calibrate_zero_pose.md +++ b/docs/how_to/calibrate_zero_pose.md @@ -1,6 +1,6 @@ # Calibrate the zero pose -Per-physical-robot recipe: regenerate `bar_bringup_lite/config/calibration.yaml` +Per-physical-robot recipe: regenerate `humanoid_control_bringup_lite/config/calibration.yaml` so the URDF's joint zero matches your robot's encoder zero. Run this once per robot (after assembly, after a motor swap, or after a hard mechanical reset). @@ -37,9 +37,9 @@ Full math: [Concepts → Calibration math](../concepts/calibration_math.md). ## Step 1 — Launch the calibration tool ```bash -cd ~/bar_ws +cd ~/humanoid_control_ws pixi shell -ros2 launch bar_bringup_lite calibrate.launch.py +ros2 launch humanoid_control_bringup_lite calibrate.launch.py ``` `calibrate.launch.py` includes `real.launch.py` with three overrides: @@ -104,7 +104,7 @@ homing_offset = 0.5 * (lower_offset + upper_offset) * direction Then writes YAML to `./calibration.yaml` (cwd at launch time): ``` -Wrote calibration to /home/user/bar_ws/calibration.yaml +Wrote calibration to /home/user/humanoid_control_ws/calibration.yaml ``` If any joint had `sweep < 0.5 rad`, the tool **keeps its prior @@ -120,15 +120,15 @@ joint. That's a URDF bug, not a calibration one — fix the ## Step 4 — Promote the file ```bash -cp ./calibration.yaml src/bar_ros2/bar_bringup_lite/config/calibration.yaml +cp ./calibration.yaml src/humanoid_control/humanoid_control_bringup_lite/config/calibration.yaml ``` That copies into the source tree. Next `colcon build` will pick it up; or because the launch resolves the file via `FindPackageShare`, -just rebuild `bar_bringup_lite` to refresh the install share: +just rebuild `humanoid_control_bringup_lite` to refresh the install share: ```bash -colcon build --symlink-install --packages-select bar_bringup_lite +colcon build --symlink-install --packages-select humanoid_control_bringup_lite ``` ## Step 5 — Verify @@ -136,7 +136,7 @@ colcon build --symlink-install --packages-select bar_bringup_lite Relaunch the normal real bringup (without the calibration override): ```bash -ros2 launch bar_bringup_lite real.launch.py +ros2 launch humanoid_control_bringup_lite real.launch.py ``` Watch for the per-bus calibration-load log: @@ -145,7 +145,7 @@ Watch for the per-bus calibration-load log: [ros2_control_node-1] Loaded calibration_file '...' (7/7 joints matched). ``` -In a second terminal (inside the workspace env — `cd bar_ws && pixi shell`): +In a second terminal (inside the workspace env — `cd humanoid_control_ws && pixi shell`): ```bash ros2 topic echo --once /lite/joint_states @@ -169,14 +169,14 @@ Adjust the threshold if 0.5 rad is too generous (e.g. for joints with < 1 rad total range): ```bash -ros2 launch bar_bringup_lite calibrate.launch.py sweep_threshold:=0.2 +ros2 launch humanoid_control_bringup_lite calibrate.launch.py sweep_threshold:=0.2 ``` ## See also - [Concepts → Calibration math](../concepts/calibration_math.md) — the formula derivation and why it's split URDF + YAML. -- [Reference → Launch args](../reference/launch_args.md#bar_bringup_litelaunchcalibratelaunchpy) +- [Reference → Launch args](../reference/launch_args.md#humanoid_control_bringup_litelaunchcalibratelaunchpy) — the `output` and `sweep_threshold` args. - The `calibrate_robot` source is ~250 lines in - [`bar_bringup_lite/scripts/calibrate_robot.py`](https://github.com/T-K-233/bar_ros2/blob/main/bar_bringup_lite/scripts/calibrate_robot.py). + [`humanoid_control_bringup_lite/scripts/calibrate_robot.py`](https://github.com/Berkeley-Humanoids/humanoid_control/blob/main/humanoid_control_bringup_lite/scripts/calibrate_robot.py). diff --git a/docs/how_to/diagnose_enobufs.md b/docs/how_to/diagnose_enobufs.md index 9747a74..9982b2c 100644 --- a/docs/how_to/diagnose_enobufs.md +++ b/docs/how_to/diagnose_enobufs.md @@ -12,8 +12,8 @@ for finding and fixing the root cause. ## The symptom ``` -[bar_socketcan]: CAN write() returned -1 (errno=No buffer space available) for id=0x017FFF0B -[bar_socketcan]: CAN write() returned -1 (errno=No buffer space available) for id=0x017FFF15 +[humanoid_control_socketcan]: CAN write() returned -1 (errno=No buffer space available) for id=0x017FFF0B +[humanoid_control_socketcan]: CAN write() returned -1 (errno=No buffer space available) for id=0x017FFF15 ... ``` @@ -21,11 +21,11 @@ Plus a `/safety_status` message with `FLAG_TX_QUEUE_OVERRUN` set (open a `pixi shell` first so `ros2` is on PATH): ```bash -cd bar_ws && pixi shell +cd humanoid_control_ws && pixi shell ros2 topic echo /safety_status # level: 2 # FAULT # flags: 4 # FLAG_TX_QUEUE_OVERRUN = 1 << 2 -# source: bar_robstride/can0 +# source: humanoid_control_robstride/can0 ``` ## Why it happens @@ -52,12 +52,12 @@ each motor. ```bash # Quick read-only probe to confirm motors are responding -bar bus discover --iface can0 -bar bus discover --iface can1 +hc bus discover --iface can0 +hc bus discover --iface can1 # Should report 7 motors on each bus, no ENOBUFS warnings in the output. ``` -If `bar bus discover` itself reports `tx_dropped > 0`, motors are +If `hc bus discover` itself reports `tx_dropped > 0`, motors are still off the bus. Don't proceed until that scan is clean. ## Step 2 — Check the kernel CAN state @@ -126,7 +126,7 @@ and quiet afterwards, the Enable burst was the issue. If you've raised qdisc to 1000 and still hit ENOBUFS, the controller_manager might be writing too fast for the wire. Lower -the update rate in `bar_lite_controllers.yaml`: +the update rate in `humanoid_control_lite_controllers.yaml`: ```yaml controller_manager: @@ -157,8 +157,8 @@ bottleneck. Either drop the rate or upgrade the adapter. ``` ENOBUFS warnings observed -├── bar bus discover reports 0 motors → motor power off → fix power, relaunch -├── bar bus discover reports motors but ENOBUFS persists at activation only +├── hc bus discover reports 0 motors → motor power off → fix power, relaunch +├── hc bus discover reports motors but ENOBUFS persists at activation only │ └── Burst-on-Enable. Drop activate-time WriteParameter calls (already done │ in our plugin via write_firmware_limits=false default). If recurring, │ raise txqueuelen or stagger Enables. diff --git a/docs/how_to/first_real_bringup.md b/docs/how_to/first_real_bringup.md index 3795cc3..33ed97d 100644 --- a/docs/how_to/first_real_bringup.md +++ b/docs/how_to/first_real_bringup.md @@ -15,12 +15,12 @@ any pose. ## Prerequisites -- Workspace built (`colcon build --symlink-install` from `bar_ws/`, +- Workspace built (`colcon build --symlink-install` from `humanoid_control_ws/`, inside `pixi shell`). - USB-to-CAN adapters plugged into the workstation. Both arms' buses are visible at `can0` and `can1` (typical) or whatever the host assigned — `ip -br link show type can` to confirm. -- A pre-existing `bar_bringup_lite/config/calibration.yaml` for this +- A pre-existing `humanoid_control_bringup_lite/config/calibration.yaml` for this physical robot. The bundled file works for the development robot; if you're on a different unit, [calibrate first](./calibrate_zero_pose.md). - Robot **power is on** at the wall, but motors can be in any pose. @@ -49,12 +49,12 @@ acceptable; `BUS-OFF` means power-cycle the adapter.) A read-only scan before anything claims the bus: ```bash -cd bar_ws +cd humanoid_control_ws pixi shell -bar bus discover --iface can0 --scan-to 32 +hc bus discover --iface can0 --scan-to 32 # Expect 7 actuators at ids 11..17 -bar bus discover --iface can1 --scan-to 32 +hc bus discover --iface can1 --scan-to 32 # Expect 7 actuators at ids 21..27 ``` @@ -66,7 +66,7 @@ warnings**, the actuators aren't powered — see ## Step 3 — Launch the bringup ```bash -ros2 launch bar_bringup_lite real.launch.py +ros2 launch humanoid_control_bringup_lite real.launch.py ``` Default args: `mode:=arms hardware_config:= @@ -78,12 +78,12 @@ development robot). The default `enable_gamepad:=true` hard-fails if the resolved `joy_dev` path is missing; the error message lists any other `/dev/input/js*` devices it can see so you can override with `joy_dev:=/dev/input/jsN`. Pass `enable_gamepad:=false` on a -keyboardless lab box to use the `/bar/mode/*` services instead. +keyboardless lab box to use the `/humanoid_control/mode/*` services instead. `real.launch.py` boots the **onboard-computer side** of the tethered deployment split: hardware plugins, FSM controllers, `mode_manager`, -gamepad. Visualisers (`ros2 launch bar_bringup_lite viz.launch.py`) -and policy runners (`ros2 launch bar_policy lite_policy.launch.py …`) +gamepad. Visualisers (`ros2 launch humanoid_control_bringup_lite viz.launch.py`) +and policy runners (`ros2 launch humanoid_control_policy lite_policy.launch.py …`) live on the operator workstation — matching `ROS_DOMAIN_ID` is enough for them to see each other. See [Concepts → Architecture → Deployment topology](../concepts/architecture.md#deployment-topology). @@ -91,8 +91,8 @@ for them to see each other. See Watch the launch logs for: ``` -[ros2_control_node-1] Loaded hardware 'LiteLeftArm' from plugin 'bar_robstride/RobstrideSystem' -[ros2_control_node-1] Loaded hardware 'LiteRightArm' from plugin 'bar_robstride/RobstrideSystem' +[ros2_control_node-1] Loaded hardware 'LiteLeftArm' from plugin 'humanoid_control_robstride/RobstrideSystem' +[ros2_control_node-1] Loaded hardware 'LiteRightArm' from plugin 'humanoid_control_robstride/RobstrideSystem' [ros2_control_node-1] SocketCanBus opened on 'can0' [ros2_control_node-1] SocketCanBus opened on 'can1' @@ -110,7 +110,7 @@ holding zero torque — fully back-drivable by hand. ## Step 4 — Verify in a second terminal ```bash -cd bar_ws +cd humanoid_control_ws pixi shell # 14 joints reporting at the configured update rate @@ -125,7 +125,7 @@ ros2 topic echo --once /lite/joint_states | head -5 # header / 14 names / real-looking positions (NOT all 0.0 — that'd mean motors un-Enabled) ros2 topic echo --once /safety_status -# level: 0 flags: 0 source: bar_robstride/can0 (then a second one for can1) +# level: 0 flags: 0 source: humanoid_control_robstride/can0 (then a second one for can1) ``` The "all 0.0 positions" signal is the most useful early-warning: it diff --git a/docs/how_to/index.md b/docs/how_to/index.md index 2c15841..9c5bbf9 100644 --- a/docs/how_to/index.md +++ b/docs/how_to/index.md @@ -16,7 +16,7 @@ and now have a concrete task in mind. How-tos skip the pedagogy that | Guide | Use it when | |---|---| | [First real-hardware bringup](./first_real_bringup.md) | You have the physical Lite robot on the bench and a workspace built. You want `/lite/joint_states` to flow and `zero_torque_controller` active. | -| [Calibrate the zero pose](./calibrate_zero_pose.md) | The URDF "joint zero" doesn't match where the robot's encoders read zero. You want to regenerate `bar_bringup_lite/config/calibration.yaml`. | +| [Calibrate the zero pose](./calibrate_zero_pose.md) | The URDF "joint zero" doesn't match where the robot's encoders read zero. You want to regenerate `humanoid_control_bringup_lite/config/calibration.yaml`. | | [Probe actuators on a CAN bus](./probe_can_bus.md) | You suspect a wiring issue, a missing motor, or just want to scan all IDs on a bus before bringup. | | [Switch controllers without the FSM](./switch_controllers_manually.md) | The gamepad isn't in the loop. You want to call `switch_controller` directly to put the robot in DAMPING / STANDBY / REMOTE. | @@ -40,5 +40,5 @@ and now have a concrete task in mind. How-tos skip the pedagogy that | Guide | Use it when | |---|---| | [Run and extend an in-process policy](./promote_python_to_cpp.md) | You have a trained `.onnx` and want to ship it via the launch-time `prepare` step into the in-process C++ `RLPolicyController` (System 0) — or you need to add a new observation term or task. | -| [Talk to bar_ros2 from Python](./talk_to_bar_ros2_from_python.md) | You want a host-side Python process (gravity-comp, VLA, data tool) to publish/subscribe `bar_msgs` over DDS with no `rclpy` — via `lite_sdk2` + the generated `bar_msgs_dds` types. | +| [Talk to humanoid_control from Python](./talk_to_humanoid_control_from_python.md) | You want a host-side Python process (gravity-comp, VLA, data tool) to publish/subscribe `humanoid_control_msgs` over DDS with no `rclpy` — via `lite_sdk2` + the generated `humanoid_control_msgs_dds` types. | | [Add a new joint to the URDF](./add_new_joint.md) | A new actuator goes on the robot. You need to wire it into the URDF, controllers YAML, and `calibration.yaml`. | diff --git a/docs/how_to/live_viz.md b/docs/how_to/live_viz.md index 51b3bd1..2ed3f04 100644 --- a/docs/how_to/live_viz.md +++ b/docs/how_to/live_viz.md @@ -28,17 +28,17 @@ tethered split: it subscribes over DDS to the `/lite/joint_states` stream `real.launch.py` publishes from the onboard computer and renders the live pose on the operator workstation. -Inside the workspace env (`cd bar_ws && pixi shell`): +Inside the workspace env (`cd humanoid_control_ws && pixi shell`): ```bash # Default — viser, browser at http://localhost:8080 -ros2 launch bar_bringup_lite viz.launch.py +ros2 launch humanoid_control_bringup_lite viz.launch.py # Native rerun window instead -ros2 launch bar_bringup_lite viz.launch.py viewer:=rerun +ros2 launch humanoid_control_bringup_lite viz.launch.py viewer:=rerun # Multi-robot or non-Lite — override the topic -ros2 launch bar_bringup_lite viz.launch.py joint_state_topic:=//joint_states +ros2 launch humanoid_control_bringup_lite viz.launch.py joint_state_topic:=//joint_states ``` `viewer:=` mirrors mjlab's `--viewer` flag so the same vocabulary @@ -58,8 +58,8 @@ instead of the launch wrapper. `ROS_DOMAIN_ID` matching is on you — these talk to whatever's already on the local domain. ```bash -ros2 run bar_bringup_lite rerun_viz -ros2 run bar_bringup_lite viser_viz +ros2 run humanoid_control_bringup_lite rerun_viz +ros2 run humanoid_control_bringup_lite viser_viz ``` Both work against any bringup that publishes `/robot_description` @@ -102,16 +102,16 @@ per-`/lite/joint_states` callback + a tf update. | Symptom | Cause | |---|---| -| Window opens but robot is blank / collapsed | Mesh `package://` URLs not resolving. Make sure `lite_description`'s install is on `AMENT_PREFIX_PATH` (pixi activation does this automatically once you `pixi shell` into `bar_ws/`). | -| `rerun_viz` says `ModuleNotFoundError: No module named 'rerun'` | The pixi env wasn't entered — run `cd bar_ws && pixi shell` first, then `ros2 run bar_bringup_lite rerun_viz`. | +| Window opens but robot is blank / collapsed | Mesh `package://` URLs not resolving. Make sure `lite_description`'s install is on `AMENT_PREFIX_PATH` (pixi activation does this automatically once you `pixi shell` into `humanoid_control_ws/`). | +| `rerun_viz` says `ModuleNotFoundError: No module named 'rerun'` | The pixi env wasn't entered — run `cd humanoid_control_ws && pixi shell` first, then `ros2 run humanoid_control_bringup_lite rerun_viz`. | | `viser_viz` complains about a missing `scipy` symbol | Stale env. Re-run `pixi install` to resync against `pixi.lock`. | -| Browser at `:8080` shows "this site can't be reached" | `viser_viz` not running — start it via `ros2 launch bar_bringup_lite viz.launch.py` (default viewer is `viser`), or wrong host in the URL. | +| Browser at `:8080` shows "this site can't be reached" | `viser_viz` not running — start it via `ros2 launch humanoid_control_bringup_lite viz.launch.py` (default viewer is `viser`), or wrong host in the URL. | | Joints visible in `ros2 topic echo /lite/joint_states` but not moving in viewer | TF buffer staleness — restart the viewer; the URDF subscription may have been late to the latched message. | ## See also -- `rerun_viz` source: [`bar_bringup_lite/scripts/rerun_viz.py`](https://github.com/T-K-233/bar_ros2/blob/main/bar_bringup_lite/scripts/rerun_viz.py) -- `viser_viz` source: [`bar_bringup_lite/scripts/viser_viz.py`](https://github.com/T-K-233/bar_ros2/blob/main/bar_bringup_lite/scripts/viser_viz.py) -- `viz.launch.py` source: [`bar_bringup_lite/launch/viz.launch.py`](https://github.com/T-K-233/bar_ros2/blob/main/bar_bringup_lite/launch/viz.launch.py) +- `rerun_viz` source: [`humanoid_control_bringup_lite/scripts/rerun_viz.py`](https://github.com/Berkeley-Humanoids/humanoid_control/blob/main/humanoid_control_bringup_lite/scripts/rerun_viz.py) +- `viser_viz` source: [`humanoid_control_bringup_lite/scripts/viser_viz.py`](https://github.com/Berkeley-Humanoids/humanoid_control/blob/main/humanoid_control_bringup_lite/scripts/viser_viz.py) +- `viz.launch.py` source: [`humanoid_control_bringup_lite/launch/viz.launch.py`](https://github.com/Berkeley-Humanoids/humanoid_control/blob/main/humanoid_control_bringup_lite/launch/viz.launch.py) - [Reference → Launch args](../reference/launch_args.md) — the `viz.launch.py` arg table (`viewer`, `joint_state_topic`). diff --git a/docs/how_to/mit_slider_gui.md b/docs/how_to/mit_slider_gui.md index bfca2bb..cf1a36d 100644 --- a/docs/how_to/mit_slider_gui.md +++ b/docs/how_to/mit_slider_gui.md @@ -31,21 +31,21 @@ keep the workspace clear. - A `forward_command_controller/MultiInterfaceForwardCommandController` loaded in the controllers YAML, claiming all 5 MIT interfaces on the target joint. The single-actuator test config in - `bar_devices/bar_robstride/test/single_robstride_gui_controllers.yaml` + `humanoid_control_devices/humanoid_control_robstride/test/single_robstride_gui_controllers.yaml` is the canonical example. ## Step 1 — Launch the test stack For a single-motor sanity check there's a dedicated launch (inside -the workspace env — `cd bar_ws && pixi shell`): +the workspace env — `cd humanoid_control_ws && pixi shell`): ```bash -ros2 launch bar_robstride single_robstride_gui.launch.py +ros2 launch humanoid_control_robstride single_robstride_gui.launch.py ``` The launch composes a `controller_manager` and starts the `mit_slider_gui` executable; if you want the slider GUI alone against -an already-running controller manager, run `ros2 run bar_robstride +an already-running controller manager, run `ros2 run humanoid_control_robstride mit_slider_gui` directly. This brings up: @@ -57,7 +57,7 @@ This brings up: In a second terminal, open the slider GUI: ```bash -bar motor slider +hc motor slider ``` A Qt window appears with five sliders (position, velocity, effort, @@ -148,6 +148,6 @@ interactions. ## See also -- The GUI source: [`bar_robstride/scripts/mit_slider_gui.py`](https://github.com/T-K-233/bar_ros2/blob/main/bar_devices/bar_robstride/scripts/mit_slider_gui.py). +- The GUI source: [`humanoid_control_robstride/scripts/mit_slider_gui.py`](https://github.com/Berkeley-Humanoids/humanoid_control/blob/main/humanoid_control_devices/humanoid_control_robstride/scripts/mit_slider_gui.py). - [Concepts → MIT command surface](../concepts/mit_command_surface.md) — what each slider does. - [Switch controllers without the FSM](./switch_controllers_manually.md). diff --git a/docs/how_to/probe_can_bus.md b/docs/how_to/probe_can_bus.md index 8308b12..424a9ea 100644 --- a/docs/how_to/probe_can_bus.md +++ b/docs/how_to/probe_can_bus.md @@ -40,10 +40,10 @@ and the bus is acking. `ERROR-WARNING` is transient and self-recovers; ## Scan all IDs on a bus ```bash -cd bar_ws +cd humanoid_control_ws pixi shell -bar bus discover --iface can0 -bar bus discover --iface can1 +hc bus discover --iface can0 +hc bus discover --iface can1 ``` Default scan range: 1..32. Sends one `GetDeviceId` per ID with 8 ms @@ -68,11 +68,11 @@ on `can1` (right arm). ```bash # Default range is 1..32; widen if you suspect IDs outside that. -bar bus discover --iface can0 \ +hc bus discover --iface can0 \ --scan-from 1 --scan-to 127 # Tighter scan (faster) if you only want to check specific IDs: -bar bus discover --iface can0 \ +hc bus discover --iface can0 \ --scan-from 11 --scan-to 17 ``` @@ -81,7 +81,7 @@ bar bus discover --iface can0 \ If the bus is slow / cheap-USB-adapter, raise `--per-id-wait-ms`: ```bash -bar bus discover --iface can0 \ +hc bus discover --iface can0 \ --per-id-wait-ms 20 ``` @@ -90,7 +90,7 @@ bar bus discover --iface can0 \ When you know the ID and want a deeper status check: ```bash -bar bus ping --iface can0 --id 11 +hc bus ping --iface can0 --id 11 # TX GetDeviceId id=... # RX GetDeviceId reply device=11 uid=... # stats: rx=1 tx=1 rx_dropped=0 tx_failed=0 @@ -101,7 +101,7 @@ With `--read-status` the ping briefly Enables, prompts an responds with calibrated-looking values: ```bash -bar bus ping --iface can0 --id 11 --read-status +hc bus ping --iface can0 --id 11 --read-status # RX OperationStatus device=11 pos= 4.9200 rad vel= 0.0 torque= 0.0 temp=24.0 C fault_bits=0x00 ``` @@ -129,7 +129,7 @@ how you confirm `on_deactivate`'s Disable made it through. ## Common findings -| `bar bus discover` reports | Likely cause | +| `hc bus discover` reports | Likely cause | |---|---| | `found : 0 actuator(s)` | Bus down, adapter unplugged, or motors not powered. Check `ip -d link` and the bench power. | | `found : N < expected` | Some motors are off the bus. Trace the daisy-chain — usually a connector. | diff --git a/docs/how_to/promote_python_to_cpp.md b/docs/how_to/promote_python_to_cpp.md index 67fd735..d7aa971 100644 --- a/docs/how_to/promote_python_to_cpp.md +++ b/docs/how_to/promote_python_to_cpp.md @@ -5,7 +5,7 @@ title: Run and extend an in-process policy # Run and extend an in-process policy Every learned policy on this stack — tracking, piano, locomotion — -runs **in-process** in the C++ `bar::RLPolicyController` (FSM +runs **in-process** in the C++ `humanoid_control::RLPolicyController` (FSM `LOCOMOTION` mode). This is the **System 0** real-time layer: inference happens inside the `ros2_control` RT `update()`, with no allocation, no blocking, and no separate process that could stall. Policies differ only @@ -18,7 +18,7 @@ observation term or task**. :::note[The old Python-tier promotion workflow was removed] There used to be an out-of-process Python *inference* tier -(`bar_policy.remote_policy_runner` / `pianist_policy.PianoPolicyRunner`) +(`humanoid_control_policy.remote_policy_runner` / `pianist_policy.PianoPolicyRunner`) that published `MITCommand` over DDS, plus a "prototype in Python, then promote to C++" workflow. **That tier is gone.** There is no Python→C++ promotion step anymore — all inference is C++ in-process from the start. @@ -33,8 +33,8 @@ for the full rationale. The non-real-time work happens **once at launch** in a `prepare` step; the RT loop only ever integer-indexes preloaded data. -1. **Launch-time `prepare`.** `ros2 launch bar_policy lite_policy.launch.py` - runs `bar_policy prepare` synchronously. It resolves the ONNX +1. **Launch-time `prepare`.** `ros2 launch humanoid_control_policy lite_policy.launch.py` + runs `humanoid_control_policy prepare` synchronously. It resolves the ONNX checkpoint (a local file or a W&B run), converts the policy's LeRobot motion dataset into a single-episode rosbag2 **`.mcap`** motion bag, and emits an `rl_policy_controller` parameter overlay @@ -44,7 +44,7 @@ the RT loop only ever integer-indexes preloaded data. 2. **Inactive spawn.** The launch then spawns `rl_policy_controller` *inactive* into the running controller_manager with that overlay. 3. **FSM activation.** The operator's `START_LOCOMOTION` intent - (`/bar/mode/start_locomotion`, R1+A on the gamepad) activates it. + (`/humanoid_control/mode/start_locomotion`, R1+A on the gamepad) activates it. 4. **Per-tick, in-process.** Once active, each RT tick the controller packs the observation (`ObservationManager`), runs ONNX inference (`OnnxPolicy`), reads the motion reference from the preloaded `.mcap` @@ -72,14 +72,14 @@ Then, in a second terminal (inside `pixi shell`), prepare + load the policy. From a local ONNX file: ```bash -ros2 launch bar_policy lite_policy.launch.py \ +ros2 launch humanoid_control_policy lite_policy.launch.py \ checkpoint_file:=/path/to/policy.onnx ``` …or pull it straight from a W&B run: ```bash -ros2 launch bar_policy lite_policy.launch.py \ +ros2 launch humanoid_control_policy lite_policy.launch.py \ wandb_run_path:=entity/project/run_id ``` @@ -91,7 +91,7 @@ Useful extra arguments (all optional): | `motion_file:=` | Local LeRobot dataset dir override. | | `registry_name:=` | HuggingFace LeRobot repo id override (the ONNX `dataset_repo_id` wins otherwise). | | `episode_index:=` | Dataset episode to replay (default `0`). | -| `out_dir:=` | Artifact output dir (default `~/.cache/bar_policy/launch`). | +| `out_dir:=` | Artifact output dir (default `~/.cache/humanoid_control_policy/launch`). | For the piano task, use the equivalent `pianist_policy/launch/piano_policy.launch.py` from `pianist_ros2`; it @@ -100,10 +100,10 @@ runs the same prepare→inactive-spawn flow with the piano metadata. Finally, drive the FSM to activate (third terminal, inside `pixi shell`): ```bash -ros2 service call /bar/mode/damp std_srvs/srv/Trigger -ros2 service call /bar/mode/load std_srvs/srv/Trigger +ros2 service call /humanoid_control/mode/damp std_srvs/srv/Trigger +ros2 service call /humanoid_control/mode/load std_srvs/srv/Trigger # wait for /standby_controller/state.is_finished == true -ros2 service call /bar/mode/start_locomotion std_srvs/srv/Trigger +ros2 service call /humanoid_control/mode/start_locomotion std_srvs/srv/Trigger ``` :::tip[onnxruntime is opt-in] @@ -116,8 +116,8 @@ nothing. The startup log line tells you which backend is active. ## Add a new observation term or task -All term resolution lives in C++ now, in `bar::ObservationManager` -(`bar_controllers/include/bar_controllers/observation_manager.hpp`). At +All term resolution lives in C++ now, in `humanoid_control::ObservationManager` +(`humanoid_controllers/include/humanoid_controllers/observation_manager.hpp`). At `on_configure` it resolves the metadata-declared `observation_names` **in order** into a fixed list of term descriptors, then packs them into a preallocated buffer each tick — no allocation, no string work in the @@ -152,12 +152,12 @@ So the decision tree for a new term is: | A precomputed time-series from the motion dataset | the relevant `ReferenceProvider` | have `prepare` emit it into the `.mcap` bag | | A live sensor reading at runtime | a controller `register_extern` + subscription | publish it on a **generic** `Float32MultiArray` topic | -:::tip[Keep `bar_controllers` task-agnostic] +:::tip[Keep `humanoid_controllers` task-agnostic] Live sensor terms route through a plain `std_msgs/Float32MultiArray` rather than a task-specific message (no `pianist_msgs` dependency). The core controller package never learns a specific task exists — it just packs a named extern vector. A new task adds its own publisher on its -own topic without touching `bar_controllers`. +own topic without touching `humanoid_controllers`. ::: Make sure the new term name appears in the ONNX metadata's @@ -174,7 +174,7 @@ If you have a slow, deliberative, non-real-time source — gravity compensation today (`Lite-Gravity-Compensation`), VLA / manipulation later — that belongs in the **System 1/2 external-command ingress**, not here. Such a source runs out-of-process and publishes `MITCommand` over -DDS to `bar::RemotePolicyController` (FSM `REMOTE` mode), which validates +DDS to `humanoid_control::RemotePolicyController` (FSM `REMOTE` mode), which validates joint order, gates on arrival-time staleness, and falls back to damping. That controller is *not* used by learned policies. See [Switch controllers without the FSM](./switch_controllers_manually.md) @@ -188,8 +188,8 @@ and the architecture page below. metadata contract (`observation_names`, joint order, scales) the checkpoint freezes. - The C++ controller and modules: - [`bar_controllers/src/rl_policy_controller.cpp`](https://github.com/T-K-233/bar_ros2/blob/main/bar_controllers/src/rl_policy_controller.cpp), + [`humanoid_controllers/src/rl_policy_controller.cpp`](https://github.com/Berkeley-Humanoids/humanoid_control/blob/main/humanoid_controllers/src/rl_policy_controller.cpp), `observation_manager.hpp`, `reference_provider.hpp`, `action_mapper.hpp`, `onnx_policy.hpp`. - The launch: - [`bar_policy/launch/lite_policy.launch.py`](https://github.com/T-K-233/bar_ros2/blob/main/bar_policy/launch/lite_policy.launch.py). + [`humanoid_control_policy/launch/lite_policy.launch.py`](https://github.com/Berkeley-Humanoids/humanoid_control/blob/main/humanoid_control_policy/launch/lite_policy.launch.py). diff --git a/docs/how_to/record_experiments.md b/docs/how_to/record_experiments.md index ca0978f..74acaf2 100644 --- a/docs/how_to/record_experiments.md +++ b/docs/how_to/record_experiments.md @@ -45,7 +45,7 @@ ros2 bag record -s mcap -o tuning_$(date +%Y%m%d_%H%M%S) \ ``` For a System 1/2 ingress session (gravity-comp, VLA), also add the -command topic `/remote_policy_controller/command` (`bar_msgs/MITCommand`). +command topic `/remote_policy_controller/command` (`humanoid_control_msgs/MITCommand`). For piano runs, capture the live key state `/piano/key_state` (`std_msgs/Float32MultiArray`, 0/1 per key) — the source for offline F1 / precision / recall computed via `pianist_metrics` against the diff --git a/docs/how_to/recover_from_fault.md b/docs/how_to/recover_from_fault.md index a3b0bca..3aef454 100644 --- a/docs/how_to/recover_from_fault.md +++ b/docs/how_to/recover_from_fault.md @@ -13,12 +13,12 @@ runbook. Open a shell into the workspace so `ros2` is on PATH: ```bash -cd bar_ws +cd humanoid_control_ws pixi shell ros2 topic echo /safety_status # level: 2 # 0=OK, 1=WARNING, 2=FAULT, 3=CRITICAL # flags: 8 # bitmask -# source: bar_robstride/can0 +# source: humanoid_control_robstride/can0 # message: "" ``` @@ -60,7 +60,7 @@ from. **Recovery**: 1. Confirm motors are powered: - `bar bus discover --iface canN` + `hc bus discover --iface canN` 2. Confirm wiring — wiggle the daisy chain connector at each motor. 3. Restart the launch. `RX_TIMEOUT` clears on `on_activate` so a relaunch is sufficient; no power-cycle needed. @@ -90,7 +90,7 @@ generic flag. every joint. 2. If the fault persists, single-step diagnosis: ```bash - bar bus ping --iface canN --id --read-status + hc bus ping --iface canN --id --read-status ``` The reply's `fault_bits` byte tells you which specific sub-cause: - `bit 0` = overtemperature (also raised as `FLAG_TEMPERATURE_LIMIT`) @@ -145,8 +145,8 @@ walks back up: # R1+A → LOCOMOTION # R1+B → REMOTE # Or via the std_srvs/Trigger services: -ros2 service call /bar/mode/load std_srvs/srv/Trigger -ros2 service call /bar/mode/start_remote std_srvs/srv/Trigger +ros2 service call /humanoid_control/mode/load std_srvs/srv/Trigger +ros2 service call /humanoid_control/mode/start_remote std_srvs/srv/Trigger ``` Or via `ros2 control switch_controllers` directly. diff --git a/docs/how_to/switch_controllers_manually.md b/docs/how_to/switch_controllers_manually.md index 49a969c..8049f49 100644 --- a/docs/how_to/switch_controllers_manually.md +++ b/docs/how_to/switch_controllers_manually.md @@ -36,7 +36,7 @@ Easiest: pass `enable_mode_manager:=false` so `mode_manager` isn't spawned at all: ```bash -ros2 launch bar_bringup_lite real.launch.py enable_mode_manager:=false +ros2 launch humanoid_control_bringup_lite real.launch.py enable_mode_manager:=false ``` Now `zero_torque_controller` is active (the spawner set it active), @@ -51,7 +51,7 @@ calls — open a second terminal and `pixi shell` into the workspace so `ros2` is on PATH: ```bash -cd bar_ws +cd humanoid_control_ws pixi shell ``` @@ -94,7 +94,7 @@ ros2 control switch_controllers \ --activate remote_policy_controller ``` -`remote_policy_controller` (`bar/RemotePolicyController`) is the +`remote_policy_controller` (`humanoid_control/RemotePolicyController`) is the **System 1/2 external-command ingress**: it immediately starts looking for `MITCommand` on `/remote_policy_controller/command`. Without a publisher it'll trip its stale-command policy (`passive` by default @@ -104,10 +104,10 @@ non-real-time `MITCommand` source first — gravity compensation controller is **not** fed by any learned policy; learned policies run in-process in `rl_policy_controller`. -`rl_policy_controller` (`bar/RLPolicyController`) is **not** spawned by +`rl_policy_controller` (`humanoid_control/RLPolicyController`) is **not** spawned by `real.launch.py` — it is loaded *inactive* by the prepare→spawn [policy launch](./promote_python_to_cpp.md) -(`ros2 launch bar_policy lite_policy.launch.py checkpoint_file:=`), +(`ros2 launch humanoid_control_policy lite_policy.launch.py checkpoint_file:=`), which runs `prepare` to resolve the ONNX + `.mcap` motion bag and emit the parameter overlay. Once that launch has spawned it, you can activate it by hand the same way as below. @@ -132,11 +132,11 @@ shutdown. # Which controllers are loaded, and which are active? ros2 control list_controllers # Expected after first transition: -# damping_controller bar/DampingController active -# zero_torque_controller bar/ZeroTorqueController inactive +# damping_controller humanoid_control/DampingController active +# zero_torque_controller humanoid_control/ZeroTorqueController inactive # joint_state_broadcaster joint_state_broadcaster/... active -# standby_controller bar/StandbyController inactive -# remote_policy_controller bar/RemotePolicyController inactive +# standby_controller humanoid_control/StandbyController inactive +# remote_policy_controller humanoid_control/RemotePolicyController inactive # What hardware components are up? ros2 control list_hardware_components diff --git a/docs/how_to/talk_to_bar_ros2_from_python.md b/docs/how_to/talk_to_humanoid_control_from_python.md similarity index 87% rename from docs/how_to/talk_to_bar_ros2_from_python.md rename to docs/how_to/talk_to_humanoid_control_from_python.md index c926738..a136ad0 100755 --- a/docs/how_to/talk_to_bar_ros2_from_python.md +++ b/docs/how_to/talk_to_humanoid_control_from_python.md @@ -1,19 +1,19 @@ --- -title: Talk to bar_ros2 from Python +title: Talk to humanoid_control from Python --- -# Talk to bar_ros2 from Python +# Talk to humanoid_control from Python You have a host-side Python process — a gravity-comp runner, a VLA / manipulation -policy, a data tool — that needs to exchange messages with a running `bar_ros2` +policy, a data tool — that needs to exchange messages with a running `humanoid_control` bringup, but you **don't** want `rclpy`, a colcon overlay, or `--system-site-packages` in that environment. This is the **Tier-3** path: a pure-pip process that joins the same DDS network the ROS nodes use. You do not hand-write the message types. Two packages handle it: -- **`bar_msgs_dds`** — `cyclonedds` `IdlStruct` types **generated** from - `bar_msgs/msg/*.msg` (see [Packages → `bar_msgs_dds`](../reference/packages.md#bar_msgs_dds)). +- **`humanoid_control_msgs_dds`** — `cyclonedds` `IdlStruct` types **generated** from + `humanoid_control_msgs/msg/*.msg` (see [Packages → `humanoid_control_msgs_dds`](../reference/packages.md#humanoid_control_msgs_dds)). Wire-compatible with ROS 2: it bakes in the rmw type-name mangling (`pkg::msg::dds_::Name_`) and the `rt/` topic prefix. - **`lite_sdk2`** — a message-agnostic publisher/subscriber layer on top, with a @@ -21,7 +21,7 @@ You do not hand-write the message types. Two packages handle it: ## 1. Add the dependency -`lite_sdk2` pulls in `bar_msgs_dds` and `cyclonedds`: +`lite_sdk2` pulls in `humanoid_control_msgs_dds` and `cyclonedds`: ```toml # pyproject.toml @@ -101,8 +101,8 @@ lite-sdk2-control enp2s0 disable # zero-torque burst, then exit ## Changing a message -Messages live in `bar_ros2`, not in the SDK. Edit `bar_msgs/msg/*.msg`, run -`pixi run gen-dds` to regenerate `bar_msgs_dds`, and the new/changed type flows +Messages live in `humanoid_control`, not in the SDK. Edit `humanoid_control_msgs/msg/*.msg`, run +`pixi run gen-dds` to regenerate `humanoid_control_msgs_dds`, and the new/changed type flows through `lite_sdk2` automatically — there is no schema to mirror by hand. This is a [frozen-schema change](../concepts/frozen_schemas.md#how-to-change-a-frozen-schema); follow the full drill if a trained policy depends on it. diff --git a/docs/how_to/use_pixi_tasks.md b/docs/how_to/use_pixi_tasks.md index 24bbe57..57adbb0 100644 --- a/docs/how_to/use_pixi_tasks.md +++ b/docs/how_to/use_pixi_tasks.md @@ -10,20 +10,20 @@ The rest of this site documents commands in canonical `ros2 launch …` / `ros2 run …` form. Those work everywhere — Jetson, workstation, CI. The workspace also ships a thin **alias layer** in -`bar_ws/pixi.toml` so you can shorten the most common command lines +`humanoid_control_ws/pixi.toml` so you can shorten the most common command lines to `pixi run `. This page documents that layer end-to-end: what each alias maps to, when to reach for it, and how to add your own. -`pixi.toml` lives at the **workspace level** (`bar_ws/pixi.toml`), -*not* inside `bar_ros2` or `pianist_ros2`. That's intentional — the +`pixi.toml` lives at the **workspace level** (`humanoid_control_ws/pixi.toml`), +*not* inside `humanoid_control` or `pianist_ros2`. That's intentional — the file pins ROS 2 Jazzy, the colcon toolchain, every Python dep, and the activation script that auto-sources `install/setup.bash`. Those -are workspace concerns; both `bar_ros2` and `pianist_ros2` consume them. +are workspace concerns; both `humanoid_control` and `pianist_ros2` consume them. :::tip[Why have aliases at all] A single `pixi run launch-mujoco` is shorter than -`ros2 launch bar_bringup_lite mujoco.launch.py`, but the bigger win +`ros2 launch humanoid_control_bringup_lite mujoco.launch.py`, but the bigger win is that **every alias runs inside the pixi-managed environment** — ROS 2 Jazzy, the colcon overlay, the visualiser PyPI deps, and the right `RCUTILS_CONSOLE_OUTPUT_FORMAT` are all sourced automatically. @@ -35,42 +35,42 @@ explicit `pixi shell` first. | Alias | Equivalent | Why | |---|---|---| -| `pixi install` | (the pixi install itself) | Solve and materialise the conda + PyPI env into `bar_ws/.pixi/`. Run once per clone and after every `pixi.toml` change. | +| `pixi install` | (the pixi install itself) | Solve and materialise the conda + PyPI env into `humanoid_control_ws/.pixi/`. Run once per clone and after every `pixi.toml` change. | | `pixi shell` | (the pixi shell itself) | Drop into an interactive shell with the env active. Equivalent to `source install/setup.bash` over a sourced ROS 2 Jazzy install. | -| `pixi run setup` | `vcs import --input src/bar_ros2/bar.repos src` | Clone the third-party `mujoco_*` + `ethercat_driver_ros2` sources listed in `bar.repos` into `src/`. | -| `pixi run build` | `colcon build --symlink-install --packages-skip-regex 'ethercat.*\|bar_bringup_prime'` | Build the Lite path (skips the EtherCAT-linked Prime lane that has no conda recipe). | -| `pixi run build-all` | `colcon build --symlink-install` | Same, but includes `bar_bringup_prime` and `ethercat_driver_ros2`. Requires `libethercat` installed on the host. | +| `pixi run setup` | `vcs import --input src/humanoid_control/bar.repos src` | Clone the third-party `mujoco_*` + `ethercat_driver_ros2` sources listed in `bar.repos` into `src/`. | +| `pixi run build` | `colcon build --symlink-install --packages-skip-regex 'ethercat.*\|humanoid_control_bringup_prime'` | Build the Lite path (skips the EtherCAT-linked Prime lane that has no conda recipe). | +| `pixi run build-all` | `colcon build --symlink-install` | Same, but includes `humanoid_control_bringup_prime` and `ethercat_driver_ros2`. Requires `libethercat` installed on the host. | | `pixi run build-pkg ` | `colcon build --symlink-install --packages-select ` | Targeted rebuild of one package — fastest edit-loop while iterating. | -| `pixi run test` | `colcon test --packages-skip-regex 'ethercat.*\|bar_bringup_prime\|mujoco_.*' --ctest-args -LE linter --event-handlers console_cohesion-` | Run BAR-owned tests; skips the vendored `mujoco_*` packages and the CMake-registered linters (which RoboStack ships at newer versions than apt-jazzy, so they'd diverge from the industrial_ci-on-bar_ros2 source of truth). | +| `pixi run test` | `colcon test --packages-skip-regex 'ethercat.*\|humanoid_control_bringup_prime\|mujoco_.*' --ctest-args -LE linter --event-handlers console_cohesion-` | Run BAR-owned tests; skips the vendored `mujoco_*` packages and the CMake-registered linters (which RoboStack ships at newer versions than apt-jazzy, so they'd diverge from the industrial_ci-on-humanoid_control source of truth). | | `pixi run test-lint` | Same as `test`, but keeps the linters. | Use when you specifically want to see uncrustify / cpplint output locally. | | `pixi run test-results` | `colcon test-result --verbose` | Print the per-package test summary after `pixi run test`. | | `pixi run clean` | `rm -rf build install log` | Wipe the colcon overlay (leaves the source tree and `.pixi/` env alone). Handy after a package rename. | -## Launch aliases — bar_ros2 +## Launch aliases — humanoid_control Each alias just wraps a `ros2 launch ` invocation; any extra arguments after the alias are forwarded unchanged. | Alias | Equivalent | Side | |---|---|---| -| `pixi run view` | `ros2 launch bar_bringup_lite view_lite.launch.py` | dev — URDF inspector | -| `pixi run launch-mujoco` | `ros2 launch bar_bringup_lite mujoco.launch.py` | dev — full Lite controller stack in MuJoCo | -| `pixi run launch-real` | `ros2 launch bar_bringup_lite real.launch.py` | robot — real-hardware Lite bringup | -| `pixi run launch-viz` | `ros2 launch bar_bringup_lite viz.launch.py` | host — live URDF + joint-state viewer (`viewer:=viser\|rerun`) | -| `pixi run calibrate` | `ros2 launch bar_bringup_lite calibrate.launch.py` | dev — calibration bringup; writes `calibration.yaml` on Ctrl+C | -| `pixi run launch-policy` | `ros2 launch bar_policy lite_policy.launch.py` | robot — runs `prepare` (resolve ONNX, motion → `.mcap`) then loads the in-process `rl_policy_controller`. Pass `checkpoint_file:=` or `wandb_run_path:=`. | +| `pixi run view` | `ros2 launch humanoid_control_bringup_lite view_lite.launch.py` | dev — URDF inspector | +| `pixi run launch-mujoco` | `ros2 launch humanoid_control_bringup_lite mujoco.launch.py` | dev — full Lite controller stack in MuJoCo | +| `pixi run launch-real` | `ros2 launch humanoid_control_bringup_lite real.launch.py` | robot — real-hardware Lite bringup | +| `pixi run launch-viz` | `ros2 launch humanoid_control_bringup_lite viz.launch.py` | host — live URDF + joint-state viewer (`viewer:=viser\|rerun`) | +| `pixi run calibrate` | `ros2 launch humanoid_control_bringup_lite calibrate.launch.py` | dev — calibration bringup; writes `calibration.yaml` on Ctrl+C | +| `pixi run launch-policy` | `ros2 launch humanoid_control_policy lite_policy.launch.py` | robot — runs `prepare` (resolve ONNX, motion → `.mcap`) then loads the in-process `rl_policy_controller`. Pass `checkpoint_file:=` or `wandb_run_path:=`. | | `pixi run launch-policy-tracking` | `… lite_policy.launch.py` | robot — pass-through alias (back-compat shortcut) | ### Per-tool / CLI aliases | Alias | Equivalent | |---|---| -| `pixi run bar …` | `bar …` (the `bar_cli` console script) | -| `pixi run robstride-ping` | `ros2 run bar_robstride robstride_ping` | -| `pixi run robstride-discover` | `ros2 run bar_robstride robstride_discover` | -| `pixi run mit-slider-gui` | `ros2 run bar_robstride mit_slider_gui` | -| `pixi run rerun-viz` | `ros2 run bar_bringup_lite rerun_viz` | -| `pixi run viser-viz` | `ros2 run bar_bringup_lite viser_viz` | +| `pixi run hc …` | `bar …` (the `humanoid_control_cli` console script) | +| `pixi run robstride-ping` | `ros2 run humanoid_control_robstride robstride_ping` | +| `pixi run robstride-discover` | `ros2 run humanoid_control_robstride robstride_discover` | +| `pixi run mit-slider-gui` | `ros2 run humanoid_control_robstride mit_slider_gui` | +| `pixi run rerun-viz` | `ros2 run humanoid_control_bringup_lite rerun_viz` | +| `pixi run viser-viz` | `ros2 run humanoid_control_bringup_lite viser_viz` | ## Launch aliases — pianist_ros2 @@ -103,7 +103,7 @@ pixi run launch-policy-piano wandb_run_path:=entity/project/run-id ## Adding a new alias -Edit `bar_ws/pixi.toml`'s `[tasks]` block — that's the only file you +Edit `humanoid_control_ws/pixi.toml`'s `[tasks]` block — that's the only file you need to touch: ```toml @@ -115,7 +115,7 @@ Then `pixi run my-thing` works immediately; no rebuild needed. If the alias should live next to the launch file conceptually (e.g. it's a piano-specific helper), the convention today is to -still register it at the workspace level — `bar_ros2` and +still register it at the workspace level — `humanoid_control` and `pianist_ros2` are pure ROS 2 source trees and don't try to expose a workspace-shell-shortcut layer of their own. diff --git a/docs/reference/cli_tools.md b/docs/reference/cli_tools.md index 16bcaaa..9732e6f 100644 --- a/docs/reference/cli_tools.md +++ b/docs/reference/cli_tools.md @@ -4,15 +4,15 @@ title: CLI tools # CLI tools -Standalone executables shipped by `bar_ros2`. The primary entry -point is the unified `bar` CLI from `bar_cli` — `bar bus ping`, -`bar bus discover`, `bar motor slider`, `bar viz rerun`, `bar viz -viser`, `bar calibrate`. Every underlying executable is also -reachable directly as `ros2 run `; the `bar` +Standalone executables shipped by `humanoid_control`. The primary entry +point is the unified `hc` CLI from `humanoid_control_cli` — `hc bus ping`, +`hc bus discover`, `hc motor slider`, `hc viz rerun`, `hc viz +viser`, `hc calibrate`. Every underlying executable is also +reachable directly as `ros2 run `; the `hc` CLI is a thin verb/noun wrapper that calls `os.execvp` on those same targets. -`bar_policy` and `pianist_policy` each ship a `prepare` console script +`humanoid_control_policy` and `pianist_policy` each ship a `prepare` console script (the launch-time policy-artifact prep step); `pianist_policy` also ships the `piano_state_bridge` and `midi_keyboard_driver` key-state nodes. These are normally driven by their launch files, but are reachable via @@ -22,16 +22,16 @@ These are normally driven by their launch files, but are reachable via | Executable | Package | Repo | What it does | |---|---|---|---| -| `bar` (unified CLI) | `bar_cli` | bar_ros2 | Verb/noun entry point (`bar bus ping`, `bar bus discover`, `bar motor slider`, `bar viz rerun`, …). | -| `robstride_ping` | `bar_robstride` | bar_ros2 | Single-actuator probe (GetDeviceId / OperationStatus). Read-only. | -| `robstride_discover` | `bar_robstride` | bar_ros2 | Scan a CAN ID range, print every device that replies. Read-only. | -| `mit_slider_gui` | `bar_robstride` | bar_ros2 | Qt slider window publishing Float64MultiArray to a forward_command_controller. | -| `mode_manager` | `bar_controllers` | bar_ros2 | The FSM orchestrator. Normally launched by bringup; sometimes useful to start manually. | -| `calibrate_robot` | `bar_bringup_lite` | bar_ros2 | Sample (min, max) per joint; write `calibration.yaml` on Ctrl+C. | -| `rerun_viz` | `bar_bringup_lite` | bar_ros2 | Native rerun viewer subscribed to `/robot_description` + `/lite/joint_states`. | -| `viser_viz` | `bar_bringup_lite` | bar_ros2 | Browser viewer (default port 8080). Same subscriptions. | -| `prepare` | `bar_policy` | bar_ros2 | Launch-time prep: resolve the ONNX (local / W&B), convert the LeRobot motion → `.mcap` bag, emit the `rl_policy_controller` overlay (used by `lite_policy.launch.py`). | -| `prepare` | `pianist_policy` | pianist_ros2 | Piano counterpart of `bar_policy prepare` (song → key-state `.mcap`; used by `piano_policy.launch.py`). | +| `hc` (unified CLI) | `humanoid_control_cli` | humanoid_control | Verb/noun entry point (`hc bus ping`, `hc bus discover`, `hc motor slider`, `hc viz rerun`, …). | +| `robstride_ping` | `humanoid_control_robstride` | humanoid_control | Single-actuator probe (GetDeviceId / OperationStatus). Read-only. | +| `robstride_discover` | `humanoid_control_robstride` | humanoid_control | Scan a CAN ID range, print every device that replies. Read-only. | +| `mit_slider_gui` | `humanoid_control_robstride` | humanoid_control | Qt slider window publishing Float64MultiArray to a forward_command_controller. | +| `mode_manager` | `humanoid_controllers` | humanoid_control | The FSM orchestrator. Normally launched by bringup; sometimes useful to start manually. | +| `calibrate_robot` | `humanoid_control_bringup_lite` | humanoid_control | Sample (min, max) per joint; write `calibration.yaml` on Ctrl+C. | +| `rerun_viz` | `humanoid_control_bringup_lite` | humanoid_control | Native rerun viewer subscribed to `/robot_description` + `/lite/joint_states`. | +| `viser_viz` | `humanoid_control_bringup_lite` | humanoid_control | Browser viewer (default port 8080). Same subscriptions. | +| `prepare` | `humanoid_control_policy` | humanoid_control | Launch-time prep: resolve the ONNX (local / W&B), convert the LeRobot motion → `.mcap` bag, emit the `rl_policy_controller` overlay (used by `lite_policy.launch.py`). | +| `prepare` | `pianist_policy` | pianist_ros2 | Piano counterpart of `humanoid_control_policy prepare` (song → key-state `.mcap`; used by `piano_policy.launch.py`). | | `piano_state_bridge` | `pianist_policy` | pianist_ros2 | Sim-side bridge — JointState piano keys → `std_msgs/Float32MultiArray` on `/piano/key_state`. | | `midi_keyboard_driver` | `pianist_policy` | pianist_ros2 | USB-MIDI input → `/piano/key_state` (`std_msgs/Float32MultiArray`, real-piano counterpart of the sim bridge). | @@ -40,11 +40,11 @@ These are normally driven by their launch files, but are reachable via ### `robstride_ping` ```bash -ros2 run bar_robstride robstride_ping --iface can0 --id 11 -ros2 run bar_robstride robstride_ping --iface can0 --id 11 --read-status +ros2 run humanoid_control_robstride robstride_ping --iface can0 --id 11 +ros2 run humanoid_control_robstride robstride_ping --iface can0 --id 11 --read-status # Equivalent via the unified CLI: -bar bus ping --iface can0 --id 11 +hc bus ping --iface can0 --id 11 ``` | Arg | Default | Description | @@ -65,12 +65,12 @@ Used in: [Tutorials → Drive one Robstride](../tutorials/drive_one_robstride.md ### `robstride_discover` ```bash -ros2 run bar_robstride robstride_discover --iface can0 -ros2 run bar_robstride robstride_discover --iface can0 \ +ros2 run humanoid_control_robstride robstride_discover --iface can0 +ros2 run humanoid_control_robstride robstride_discover --iface can0 \ --scan-from 1 --scan-to 127 --per-id-wait-ms 8 # Equivalent via the unified CLI: -bar bus discover --iface can0 +hc bus discover --iface can0 ``` | Arg | Default | Description | @@ -94,15 +94,15 @@ Used in: [How-to → Probe CAN bus](../how_to/probe_can_bus.md), ### `mit_slider_gui` ```bash -ros2 run bar_robstride mit_slider_gui -ros2 run bar_robstride mit_slider_gui \ +ros2 run humanoid_control_robstride mit_slider_gui +ros2 run humanoid_control_robstride mit_slider_gui \ --joint actuator_1 \ --command-topic /forward_mit_controller/commands \ --position-range -3.14 3.14 \ --kp-range 0 10 # Equivalent via the unified CLI: -bar motor slider +hc motor slider ``` | Arg | Default | Description | @@ -126,8 +126,8 @@ Used in: [Tutorials → Drive one Robstride](../tutorials/drive_one_robstride.md ### `mode_manager` ```bash -ros2 run bar_controllers mode_manager -ros2 run bar_controllers mode_manager --ros-args -p tick_rate_hz:=100 +ros2 run humanoid_controllers mode_manager +ros2 run humanoid_controllers mode_manager --ros-args -p tick_rate_hz:=100 ``` | Parameter | Default | Description | @@ -150,8 +150,8 @@ Used in: [Concepts → Five-mode FSM](../concepts/five_mode_fsm.md), ### `calibrate_robot` ```bash -ros2 run bar_bringup_lite calibrate_robot --output ./calibration.yaml -ros2 run bar_bringup_lite calibrate_robot \ +ros2 run humanoid_control_bringup_lite calibrate_robot --output ./calibration.yaml +ros2 run humanoid_control_bringup_lite calibrate_robot \ --output ./calibration.yaml --sweep-threshold 0.3 ``` @@ -170,14 +170,14 @@ Used in: [How-to → Calibrate the zero pose](../how_to/calibrate_zero_pose.md). ### `rerun_viz` / `viser_viz` The two live-viewer executables. **On the tethered deployment they -are spawned via `ros2 launch bar_bringup_lite viz.launch.py` on the +are spawned via `ros2 launch humanoid_control_bringup_lite viz.launch.py` on the operator workstation** (`viewer:=viser` by default; `viewer:=rerun` for the native window). Direct invocation is the single-machine sim/dev shortcut: ```bash -ros2 run bar_bringup_lite rerun_viz # native rerun window -ros2 run bar_bringup_lite viser_viz # browser viewer at http://0.0.0.0:8080 +ros2 run humanoid_control_bringup_lite rerun_viz # native rerun window +ros2 run humanoid_control_bringup_lite viser_viz # browser viewer at http://0.0.0.0:8080 ``` Both read `/robot_description` (latched) once, subscribe to a diff --git a/docs/reference/controllers.md b/docs/reference/controllers.md index 39a1d1c..0dc3b9d 100644 --- a/docs/reference/controllers.md +++ b/docs/reference/controllers.md @@ -11,7 +11,7 @@ for the annotated version including safety-fault edges. ## Plugin-by-plugin -### `bar/ZeroTorqueController` +### `humanoid_control/ZeroTorqueController` **Role**: startup default; safer fault fallback. @@ -25,7 +25,7 @@ for the annotated version including safety-fault edges. |---|---|---|---| | `joints` | `string[]` | — | Required. Joint names to claim (must match URDF). | -### `bar/DampingController` +### `humanoid_control/DampingController` **Role**: compliant fail-safe. The robot stays **soft under gravity** but **resists velocity**. @@ -52,7 +52,7 @@ resistance. | `damping` | `float64[]` | `[]` | Per-joint damping. Empty → use `damping_scalar`. | | `damping_scalar` | `float64` | `1.0` | Used when `damping` is empty. | -### `bar/StandbyController` +### `humanoid_control/StandbyController` **Role**: linearly interpolate joint positions through a pose sequence; ramp `K_p / K_d` from `0` to target gains during the **first** segment so @@ -68,11 +68,11 @@ activation never snaps. | `segment_durations` | `float64[]` | Seconds per pose segment. Length determines how many pose segments are expected. | | `pose_segment_` | `float64[]` | Per-segment target pose vector; one parameter per segment index in `[0, len(segment_durations))`. Each is a per-joint position array sized to `len(joints)`. | -**Publishes**: `~/state` (`bar_msgs/StandbyState`) with `TRANSIENT_LOCAL` QoS +**Publishes**: `~/state` (`humanoid_control_msgs/StandbyState`) with `TRANSIENT_LOCAL` QoS so `mode_manager` sees `is_finished` even on late join. :::tip[How the bundled config interpolates] -`bar_lite_controllers.yaml` ships **two segments**: `pose_segment_0` is +`humanoid_control_lite_controllers.yaml` ships **two segments**: `pose_segment_0` is the zero-pose (where the robot starts), `pose_segment_1` is the piano-ready training default — mirror-symmetric across the sagittal plane (shoulders roll outward, elbows bend in, wrists relax). The LOAD intent @@ -85,7 +85,7 @@ during the first segment. controller-manager side so any non-`OK` `return_type` from `update()` auto-deactivates Standby and activates Damping. -### `bar/RLPolicyController` +### `humanoid_control/RLPolicyController` **Role**: **in-process** ONNX inference — this is the System 0 path that runs *every* learned policy (tracking / piano / locomotion). Each RT @@ -97,7 +97,7 @@ leaving the RT thread. Policies differ only by the loaded `.onnx` + `.mcap`; the ONNX `task_type` metadata selects the term set. Its parameters come from the `rl_policy_controller` overlay that -`bar_policy prepare` (or `pianist_policy prepare`) transcodes from the +`humanoid_control_policy prepare` (or `pianist_policy prepare`) transcodes from the ONNX `custom_metadata_map` — they are not hand-written: | Param | Type | Description | @@ -123,7 +123,7 @@ The contract (`PolicyMetadata` → overlay) is identical either way. See [Policy runner](policy_runner.md). ::: -### `bar/RemotePolicyController` +### `humanoid_control/RemotePolicyController` **Role**: the **System 1/2 external-command ingress** (kept, unchanged). A *non*-real-time source publishes `MITCommand` over DDS to `~/command` @@ -147,24 +147,24 @@ Today the producer is the gravity-compensation runner (`Lite-Gravity-Compensation` — raw CycloneDDS, no `rclpy`); next it will be VLA / manipulation. These are deliberately out-of-process: slower, deliberative, and tolerant of the DDS-hop latency. A producer depends on -`lite_sdk2` (the `bar_msgs` types generated by -[`bar_msgs_dds`](packages.md#bar_msgs_dds) plus the DDS channel layer) +`lite_sdk2` (the `humanoid_control_msgs` types generated by +[`humanoid_control_msgs_dds`](packages.md#humanoid_control_msgs_dds) plus the DDS channel layer) rather than hand-writing message mirrors — see -[Talk to bar_ros2 from Python](../how_to/talk_to_bar_ros2_from_python.md). See +[Talk to humanoid_control from Python](../how_to/talk_to_humanoid_control_from_python.md). See [Policy runner](policy_runner.md) for how the in-process learned-policy path relates. ### `mode_manager` (executable) **NOT a controller plugin** — a regular `rclcpp::Node` compiled as the -`bar_controllers/mode_manager` executable. +`humanoid_controllers/mode_manager` executable. | Input | Topic / source | Purpose | |---|---|---| | Gamepad | `/joy` (`sensor_msgs/Joy`) | DAMP / LOAD / START_LOCOMOTION / START_REMOTE / QUIT intents | | Standby done | `/standby_controller/state` (`StandbyState`) | gate the START intents on `is_finished` | | Safety | `/safety_status` (`SafetyStatus`) | auto-fall to DAMPING on non-OK | -| Trigger services | `/bar/mode/{damp,load,start_remote,start_locomotion,quit}` (`std_srvs/Trigger`) | same intents from the command line | +| Trigger services | `/humanoid_control/mode/{damp,load,start_remote,start_locomotion,quit}` (`std_srvs/Trigger`) | same intents from the command line | | Output | Topic | Purpose | |---|---|---| diff --git a/docs/reference/hardware_specs.md b/docs/reference/hardware_specs.md index a1eb346..34f3c4a 100644 --- a/docs/reference/hardware_specs.md +++ b/docs/reference/hardware_specs.md @@ -2,8 +2,8 @@ This page is the source of truth for **joint counts, actuator specs, and bus topology** on Lite and Prime. The numbers here drive the joint limits in -`bar_description_*` and the per-joint stiffness/damping defaults in -`bar_controllers/config/bar_*_controllers.yaml`. +`humanoid_control_description_*` and the per-joint stiffness/damping defaults in +`humanoid_controllers/config/humanoid_control_*_controllers.yaml`. ## Lite humanoid @@ -18,8 +18,8 @@ either way; the `` neck block is added only in the ### Joint table -Order matches the **canonical index** used by `bar_lite_controllers.yaml`, the -C++ `MITState` struct, and the Python `bar_policy.ObservationManager`. Once a +Order matches the **canonical index** used by `humanoid_control_lite_controllers.yaml`, the +C++ `MITState` struct, and the Python `humanoid_control_policy.ObservationManager`. Once a policy is trained against this order, it is frozen — see "Frozen schemas" in [Architecture](../concepts/architecture.md#frozen-schemas). @@ -60,7 +60,7 @@ the generated file): ``` xacro expands those into `` children on the `` element, which -`bar_robstride/RobstrideSystem::on_init` reads (and, for `torque_limit` / +`humanoid_control_robstride/RobstrideSystem::on_init` reads (and, for `torque_limit` / `current_limit`, also writes to the actuator firmware at `on_activate` via the Robstride parameter IDs `0x700B` and `0x7018` — same writes the upstream `T-K-233/Lite-Lowlevel-Python`'s `humanoid_control/control.py` performs). @@ -85,19 +85,19 @@ the `lite_description` repo and flows back through `bar.repos`: 1. In the `lite_description` repo, edit the joint's `torque_limit` (N·m, float) and / or `current_limit` (A, float) in `robots/lite_dummy/cad/ros2_control.json`. 2. Regenerate the xacro: `uv run robot-assets-generate lite_dummy --only xacro`. -3. Commit + push; bump the `lite_description` pin in `bar_ros2`'s `bar.repos` +3. Commit + push; bump the `lite_description` pin in `humanoid_control`'s `bar.repos` (keep the buildfarm's in sync). 4. Re-import, rebuild, and re-launch: ```sh - cd /bar_ws + cd /humanoid_control_ws pixi shell pixi run setup # vcs import — pulls the regenerated lite_description colcon build --symlink-install --packages-select lite_description # If a bringup is already running, Ctrl+C it first — the firmware-side # caps are written on the `on_activate` transition, so an already- # activated plugin won't pick up the new value until the next bringup. - ros2 launch bar_bringup_lite real.launch.py + ros2 launch humanoid_control_bringup_lite real.launch.py ``` For a throwaway bench experiment, edit the caps directly in the vcs-imported @@ -108,16 +108,16 @@ the `lite_description` repo and flows back through `bar.repos`: 5. Confirm in the bringup log that the new value flowed through: ``` - [bar_robstride] Wrote torque_limit=15.0 to can_id=11 (left_shoulder_pitch) - [bar_robstride] Wrote current_limit=20.0 to can_id=11 (left_shoulder_pitch) + [humanoid_control_robstride] Wrote torque_limit=15.0 to can_id=11 (left_shoulder_pitch) + [humanoid_control_robstride] Wrote current_limit=20.0 to can_id=11 (left_shoulder_pitch) ``` **No separate calibration step.** Unlike `homing_offset` (per-physical-robot, -lives in `bar_bringup_lite/config/calibration.yaml`), torque and current +lives in `humanoid_control_bringup_lite/config/calibration.yaml`), torque and current caps are per-robot-tuning — same value on every Lite physical instance, versioned alongside the URDF. If you want to A/B-test caps across deployments without editing source, set up two checked-out branches of -`bar_ros2` and switch between them rather than splitting the source of +`humanoid_control` and switch between them rather than splitting the source of truth. **Setting to 0 disables the firmware write.** The plugin treats @@ -138,8 +138,8 @@ authoritative for what's *on the bus*, not just what's *in this process*. Lite uses **two SocketCAN buses** (CAN-to-USB adapters), one per arm. Each bus is a separate `` block in the URDF, each loading its own -`bar_robstride/RobstrideSystem` instance. The default bus names come from -`bar_bringup_lite/config/lite_hardware.yaml`, which the launch passes through +`humanoid_control_robstride/RobstrideSystem` instance. The default bus names come from +`humanoid_control_bringup_lite/config/lite_hardware.yaml`, which the launch passes through to xacro as the `hardware_config:=` arg: | Block | Default ifname | CAN ids | @@ -162,20 +162,20 @@ sudo ip link set can1 down 2>/dev/null sudo ip link set can1 up type can bitrate 1000000 # 2. Read-only sanity scan — no Enable, no MIT. -# (the `bar` and `ros2` CLIs assume you've `cd bar_ws && pixi shell`'d.) -bar bus discover --iface can0 --scan-to 32 -bar bus discover --iface can1 --scan-to 32 +# (the `hc` and `ros2` CLIs assume you've `cd humanoid_control_ws && pixi shell`'d.) +hc bus discover --iface can0 --scan-to 32 +hc bus discover --iface can1 --scan-to 32 # Expect 7 + 7 = 14 actuators replying at ids 11..17 and 21..27. # 3. Calibrate the zero pose (once per physical robot). -ros2 launch bar_bringup_lite calibrate.launch.py +ros2 launch humanoid_control_bringup_lite calibrate.launch.py # Hand-sweep every joint to both extremes. Ctrl+C to write calibration.yaml. # 4. Real-hardware bringup. -ros2 launch bar_bringup_lite real.launch.py +ros2 launch humanoid_control_bringup_lite real.launch.py ``` -If `bar bus discover` reports `ENOBUFS` / TX-drop warnings, the actuator +If `hc bus discover` reports `ENOBUFS` / TX-drop warnings, the actuator power is off (no ACKs → frames pile up in the kernel qdisc). Power the motors first. @@ -184,7 +184,7 @@ motors first. A single serial / USB IMU publishes `sensor_msgs/Imu` on `/imu/data`. It is **not** routed through `ros2_control` as a `SensorInterface` — a blocking serial read inside the controller_manager `read()` cycle would block the RT -loop. Consumers (RLPolicyController, bar_policy) cache the latest sample via +loop. Consumers (RLPolicyController, humanoid_control_policy) cache the latest sample via `realtime_tools::RealtimeBuffer`. ## Prime humanoid @@ -197,7 +197,7 @@ Sito actuators for auxiliary joints, running concurrently in the same The Prime description now lives in the external CAD-generated [`prime_description`](https://github.com/T-K-233/Prime-Description) repo — bar deploys the `prime_dummy` variant via `bar.repos` — with the **waist dropped** -(rigid torso, **14 actuated DoF**). `bar_prime_controllers.yaml` binds the real +(rigid torso, **14 actuated DoF**). `humanoid_control_prime_controllers.yaml` binds the real 14-joint set (no longer a placeholder). The joint specs below were early projections; cross-check against `prime_description` + `prime_hardware.yaml`. ::: @@ -206,7 +206,7 @@ projections; cross-check against `prime_description` + `prime_hardware.yaml`. Prime is unique in that **two `` blocks coexist** in its URDF — one binds `ethercat_driver/EthercatDriver`, the other binds -`bar_sito/SitoSystem`. The controller_manager runs both concurrently; +`humanoid_control_sito/SitoSystem`. The controller_manager runs both concurrently; controllers see a single flat joint list regardless of which bus carries them. ## MIT-mode command convention @@ -217,7 +217,7 @@ project: ![MIT-mode hybrid command](/img/diagrams/reference__hardware_specs__03.svg) -Every controller in `bar_controllers` claims **all five** command interfaces, +Every controller in `humanoid_controllers` claims **all five** command interfaces, even when it only writes some of them (writing zero to the rest is the safe default — for example `ZeroTorqueController` writes 0 to everything; `DampingController` writes `K=0, D=damping_value, q_cmd=captured_q`). @@ -238,7 +238,7 @@ silicon and sim with no URDF interface-tag rewrites. - [Architecture](../concepts/architecture.md) — how this hardware surface is consumed by ros2_control and the mode FSM. -- [bar_lite_controllers.yaml](https://github.com/T-K-233/bar_ros2/blob/main/bar_controllers/config/bar_lite_controllers.yaml) +- [humanoid_control_lite_controllers.yaml](https://github.com/Berkeley-Humanoids/humanoid_control/blob/main/humanoid_controllers/config/humanoid_control_lite_controllers.yaml) — the canonical 17-joint binding for every controller. -- [`bar_robstride/include/bar_robstride/robstride_system.hpp`](https://github.com/T-K-233/bar_ros2/blob/main/bar_devices/bar_robstride/include/bar_robstride/robstride_system.hpp) +- [`humanoid_control_robstride/include/humanoid_control_robstride/robstride_system.hpp`](https://github.com/Berkeley-Humanoids/humanoid_control/blob/main/humanoid_control_devices/humanoid_control_robstride/include/humanoid_control_robstride/robstride_system.hpp) — the SystemInterface implementation for the Lite hardware path. \ No newline at end of file diff --git a/docs/reference/launch_args.md b/docs/reference/launch_args.md index 58d2b24..f523b9c 100644 --- a/docs/reference/launch_args.md +++ b/docs/reference/launch_args.md @@ -9,14 +9,14 @@ bundled launch enables that path. Launches live in two repos: -- `bar_ros2` ships the Lite + Prime control-plane bringups (`bar_bringup_lite`, - `bar_bringup_prime`), the URDF inspector (`bar_bringup_lite`), - and the policy prepare-and-load launches (`bar_policy`). +- `humanoid_control` ships the Lite + Prime control-plane bringups (`humanoid_control_bringup_lite`, + `humanoid_control_bringup_prime`), the URDF inspector (`humanoid_control_bringup_lite`), + and the policy prepare-and-load launches (`humanoid_control_policy`). - `pianist_ros2` ships piano-task-specific launches: scene composition (`pianist_bringup`), the piano prepare-and-load launch, and the USB-MIDI driver (both `pianist_policy`). -## `bar_bringup_lite/launch/view_lite.launch.py` +## `humanoid_control_bringup_lite/launch/view_lite.launch.py` URDF inspector — no controller_manager, no physics. @@ -28,19 +28,19 @@ Implicit: forces `use_fake_hardware:=true` on the xacro so the `` block is harmless when `robot_state_publisher` parses the URDF. -## `bar_bringup_lite/launch/real.launch.py` +## `humanoid_control_bringup_lite/launch/real.launch.py` -Real-hardware Lite bringup. Loads **two** `bar_robstride/RobstrideSystem` +Real-hardware Lite bringup. Loads **two** `humanoid_control_robstride/RobstrideSystem` instances, one per physical SocketCAN bus (`LiteLeftArm` claims CAN ids 11..17 on the left bus, `LiteRightArm` claims 21..27 on the right bus). | Arg | Default | Effect | |---|---|---| | `mode` | `arms` | `arms` = 14 joints (default). `arms_neck` = 17 joints (requires neck silicon). | -| `hardware_config` | `/config/lite_hardware.yaml` | Per-machine bus + joint config. Maps the two `` blocks to specific SocketCAN ifnames and joint IDs. Override to retarget a robot whose CAN ifnames differ. | -| `calibration_file` | `/config/calibration.yaml` | Absolute path to the per-physical-robot zero-offset YAML. Pass `''` for identity calibration (only the URDF `direction` sign flip applies, no offset). See [Hardware specs → Bus-bring-up checklist](./hardware_specs.md#bus-bring-up-checklist) for how to regenerate. | +| `hardware_config` | `/config/lite_hardware.yaml` | Per-machine bus + joint config. Maps the two `` blocks to specific SocketCAN ifnames and joint IDs. Override to retarget a robot whose CAN ifnames differ. | +| `calibration_file` | `/config/calibration.yaml` | Absolute path to the per-physical-robot zero-offset YAML. Pass `''` for identity calibration (only the URDF `direction` sign flip applies, no offset). See [Hardware specs → Bus-bring-up checklist](./hardware_specs.md#bus-bring-up-checklist) for how to regenerate. | | `enable_mode_manager` | `true` | `false` skips spawning the FSM orchestrator. Used by `calibrate.launch.py` and for raw-debug bringups where the operator drives controllers directly via `ros2 control switch_controllers`. | -| `enable_gamepad` | `true` | `true` spawns `joy_node` so `mode_manager` can read `/joy`. **The launch hard-fails on missing `joy_dev`.** Pass `false` on a keyboardless lab box to drive the FSM via the `/bar/mode/*` `std_srvs/Trigger` services instead. | +| `enable_gamepad` | `true` | `true` spawns `joy_node` so `mode_manager` can read `/joy`. **The launch hard-fails on missing `joy_dev`.** Pass `false` on a keyboardless lab box to drive the FSM via the `/humanoid_control/mode/*` `std_srvs/Trigger` services instead. | | `joy_dev` | `/dev/input/js0` | Path passed verbatim to `joy_node`'s `dev` parameter. Override when the onboard computer enumerates the gamepad as something other than `js0` (multiple gamepads plugged in, udev rename). The pre-launch check fails fast when the specific path is missing and lists any other `/dev/input/js*` devices it can see, so the error message tells you which override to pass. Ignored when `enable_gamepad:=false`. | The active-policy target is picked by the START button, not a launch @@ -53,13 +53,13 @@ gravity-comp today, VLA later; see [Controllers](./controllers.md)). **Visualisers are not in this launch.** `real.launch.py` is the onboard-computer entrypoint of the tethered deployment split — it publishes `/robot_description` and `/lite/joint_states` over DDS but -spawns no viewers. Run `ros2 launch bar_bringup_lite viz.launch.py` +spawns no viewers. Run `ros2 launch humanoid_control_bringup_lite viz.launch.py` on the operator workstation (see the -[`viz.launch.py` section](#bar_bringup_litelaunchvizlaunchpy) below). +[`viz.launch.py` section](#humanoid_control_bringup_litelaunchvizlaunchpy) below). Implicit on the xacro: `use_fake_hardware:=false use_sim:=false`. -## `bar_bringup_lite/launch/viz.launch.py` +## `humanoid_control_bringup_lite/launch/viz.launch.py` Host-side live visualiser. Runs on the **operator workstation** of the tethered deployment split (not on the onboard computer). Subscribes to @@ -77,7 +77,7 @@ launch twice in two terminals if you need both viewers simultaneously (same pattern as running two mjlab `play` processes upstream). -## `bar_bringup_lite/launch/calibrate.launch.py` +## `humanoid_control_bringup_lite/launch/calibrate.launch.py` Bundles `real.launch.py` with three overrides (`calibration_file:='' enable_mode_manager:='false' enable_gamepad:='false'`) @@ -88,7 +88,7 @@ which is the frame the homing-offset formula expects. | Arg | Default | Effect | |---|---|---| | `hardware_config` | `` | Forwarded to `real.launch.py`. | -| `output` | `$PWD/calibration.yaml` | Path the calibration observer writes on Ctrl+C. After verifying, `mv` it over `bar_bringup_lite/config/calibration.yaml` to make it the default for the next `real.launch.py`. | +| `output` | `$PWD/calibration.yaml` | Path the calibration observer writes on Ctrl+C. After verifying, `mv` it over `humanoid_control_bringup_lite/config/calibration.yaml` to make it the default for the next `real.launch.py`. | | `sweep_threshold` | `0.5` | Minimum joint sweep (rad) below which the prior `homing_offset` is preserved instead of recomputed. Lets you re-calibrate one or two joints at a time without losing the others. | The observer reads per-joint static config (`direction`, `lower_limit`, @@ -98,7 +98,7 @@ per-joint keys as [`T-K-233/Lite-Lowlevel-Python`](https://github.com/T-K-233/Lite-Lowlevel-Python)'s JSON output, so values move between the two stacks unchanged. -## `bar_bringup_lite/launch/mujoco.launch.py` +## `humanoid_control_bringup_lite/launch/mujoco.launch.py` MuJoCo Lite bringup. Loads `mujoco_ros2_control/MujocoSystem` inside the `mujoco_sim` process (which hosts the controller_manager as a physics @@ -118,52 +118,52 @@ Implicit: decision tree in [Packages](packages.md#lite_description--prime_description-external). - Every node runs with `use_sim_time:=true`. Time advances at MuJoCo's pace via `/clock`. -- `bar_bringup_lite/config/sim_overrides.yaml` is layered on top of - `bar_controllers/config/bar_lite_controllers.yaml` so the real-hardware +- `humanoid_control_bringup_lite/config/sim_overrides.yaml` is layered on top of + `humanoid_controllers/config/humanoid_control_lite_controllers.yaml` so the real-hardware launch stays sim-time-free. -## `bar_bringup_prime/launch/real.launch.py` +## `humanoid_control_bringup_prime/launch/real.launch.py` Stub real-hardware Prime bringup. Designed to load both -`ethercat_driver/EthercatDriver` (eRob arms) and `bar_sito/SitoSystem` +`ethercat_driver/EthercatDriver` (eRob arms) and `humanoid_control_sito/SitoSystem` (auxiliary) — two concurrent `` blocks in the URDF. The Prime URDF / MJCF is **not yet imported** from CAD — -`bar_bringup_prime` is a stub today and this launch will not wire +`humanoid_control_bringup_prime` is a stub today and this launch will not wire controllers until that import lands. -## `bar_bringup_prime/launch/mujoco.launch.py` +## `humanoid_control_bringup_prime/launch/mujoco.launch.py` -Stub mirror of `bar_bringup_lite/mujoco.launch.py` for Prime, pending +Stub mirror of `humanoid_control_bringup_lite/mujoco.launch.py` for Prime, pending the Prime MJCF import. -## `bar_policy/launch/lite_policy.launch.py` +## `humanoid_control_policy/launch/lite_policy.launch.py` Prepares and loads the in-process tracking-family policy. It runs -`bar_policy prepare` **synchronously** (resolve the ONNX, convert the +`humanoid_control_policy prepare` **synchronously** (resolve the ONNX, convert the LeRobot motion to a `.mcap` bag, emit the `rl_policy_controller` overlay), then spawns `rl_policy_controller` *inactive* with that overlay into the running controller_manager. The operator's -`START_LOCOMOTION` (R1+A / `/bar/mode/start_locomotion`) activates it. +`START_LOCOMOTION` (R1+A / `/humanoid_control/mode/start_locomotion`) activates it. There is no separate runner process; the task is selected by the ONNX `task_type` metadata. | Arg | Default | Effect | |---|---|---| | `checkpoint_file` | (empty) | Absolute path to a local ONNX checkpoint. Mutually exclusive with `wandb_run_path`. | -| `wandb_run_path` | (empty) | W&B run path (`entity/project/run_id`); `prepare` downloads + caches the ONNX under `~/.cache/bar_policy/wandb//`. | +| `wandb_run_path` | (empty) | W&B run path (`entity/project/run_id`); `prepare` downloads + caches the ONNX under `~/.cache/humanoid_control_policy/wandb//`. | | `wandb_checkpoint_name` | (empty) | Specific checkpoint filename inside the run (default: newest `model_*`). | | `motion_file` | (empty) | Local LeRobot dataset directory; overrides `registry_name` and the ONNX `dataset_repo_id`. | | `registry_name` | (empty) | HuggingFace LeRobot repo id override. | | `episode_index` | `0` | LeRobot dataset episode index to convert. | -| `out_dir` | `~/.cache/bar_policy/launch` | Where the prepared `.onnx` copy, `.mcap` bag, and `rl_policy_params.yaml` overlay are written (fixed so the spawner can find the overlay). | +| `out_dir` | `~/.cache/humanoid_control_policy/launch` | Where the prepared `.onnx` copy, `.mcap` bag, and `rl_policy_params.yaml` overlay are written (fixed so the spawner can find the overlay). | Each arg is forwarded verbatim to the `prepare` CLI (`--checkpoint-file`, `--wandb-run-path`, …). Sibling tracking-task families (piano, etc.) live in their own repos and register their own launch (see `pianist_policy/piano_policy.launch.py` below). -## `bar_policy/launch/lite_tracking.launch.py` (alias) +## `humanoid_control_policy/launch/lite_tracking.launch.py` (alias) Thin pass-through wrapper around `lite_policy.launch.py`, kept for the `launch-policy-tracking` pixi alias and existing scripts. @@ -205,15 +205,15 @@ apart. MuJoCo bringup for the piano task. Composes the Lite robot and the piano MJCF into one scene file (`_runtime_lite_piano.xml`) inside `lite_description`'s `robots/lite_dummy/mjcf/` share dir, then delegates to -`bar_bringup_lite/mujoco.launch.py` with `scene:=_runtime_lite_piano`. +`humanoid_control_bringup_lite/mujoco.launch.py` with `scene:=_runtime_lite_piano`. Also spawns the `piano_state_bridge` sim-side bridge so `/piano/key_state` exists on the sim path. | Arg | Default | Effect | |---|---|---| -| `enable_gamepad` | `true` | Forwarded to `bar_bringup_lite/mujoco.launch.py`. | +| `enable_gamepad` | `true` | Forwarded to `humanoid_control_bringup_lite/mujoco.launch.py`. | | `mode` | `arms` | Forwarded. | -| `hardware_config` | `/config/lite_hardware.yaml` | Forwarded. | +| `hardware_config` | `/config/lite_hardware.yaml` | Forwarded. | `scene:=` is **not** exposed — `pianist_bringup` controls that internally. @@ -241,16 +241,16 @@ robot involved, no tether): ```sh # Drag joints in RViz, no controllers. -ros2 launch bar_bringup_lite view_lite.launch.py +ros2 launch humanoid_control_bringup_lite view_lite.launch.py # MuJoCo physics, /clock from sim time. -ros2 launch bar_bringup_lite mujoco.launch.py +ros2 launch humanoid_control_bringup_lite mujoco.launch.py # Lite + piano in MuJoCo (pianist_bringup composes the scene). ros2 launch pianist_bringup mujoco.launch.py # Calibrate the zero pose (writes ./calibration.yaml on Ctrl+C). -ros2 launch bar_bringup_lite calibrate.launch.py +ros2 launch humanoid_control_bringup_lite calibrate.launch.py ``` **Robot onboard computer** (CM + hardware + FSM + gamepad — boots @@ -258,13 +258,13 @@ the real control plane, no visualisers, no policy runner): ```sh # Real Lite, gamepad on by default. Press R1+B at STANDBY to start the remote policy. -ros2 launch bar_bringup_lite real.launch.py +ros2 launch humanoid_control_bringup_lite real.launch.py -# Same, but on a keyboardless lab box (drive the FSM via /bar/mode/* services). -ros2 launch bar_bringup_lite real.launch.py enable_gamepad:=false +# Same, but on a keyboardless lab box (drive the FSM via /humanoid_control/mode/* services). +ros2 launch humanoid_control_bringup_lite real.launch.py enable_gamepad:=false # Gamepad enumerated as js1 instead of js0 (multiple controllers plugged in). -ros2 launch bar_bringup_lite real.launch.py joy_dev:=/dev/input/js1 +ros2 launch humanoid_control_bringup_lite real.launch.py joy_dev:=/dev/input/js1 ``` **Robot onboard computer — prepare + load a policy** (the in-process @@ -273,8 +273,8 @@ artifacts live here; the launches load `rl_policy_controller` into the local controller_manager): ```sh -# Prepare + load the tracking policy (bar_policy) from a W&B run. -ros2 launch bar_policy lite_policy.launch.py \ +# Prepare + load the tracking policy (humanoid_control_policy) from a W&B run. +ros2 launch humanoid_control_policy lite_policy.launch.py \ wandb_run_path:=user/proj/run_id \ wandb_checkpoint_name:=model_2000.onnx @@ -292,8 +292,8 @@ to the robot strictly via DDS over a wired link): ```sh # Live URDF + /lite/joint_states viewer (browser at :8080 by default). -ros2 launch bar_bringup_lite viz.launch.py # viser -ros2 launch bar_bringup_lite viz.launch.py viewer:=rerun # native rerun window +ros2 launch humanoid_control_bringup_lite viz.launch.py # viser +ros2 launch humanoid_control_bringup_lite viz.launch.py viewer:=rerun # native rerun window ``` Both machines must share `ROS_DOMAIN_ID` and (recommended) `RMW_IMPLEMENTATION`. diff --git a/docs/reference/manual_controllers.md b/docs/reference/manual_controllers.md index 31d26c1..bc9e63a 100644 --- a/docs/reference/manual_controllers.md +++ b/docs/reference/manual_controllers.md @@ -49,7 +49,7 @@ length must match `interface_names`'s length; each element goes straight to the matching command interface in order. The single-actuator bringup -(`bar_robstride/single_robstride_gui.launch.py`) is the canonical +(`humanoid_control_robstride/single_robstride_gui.launch.py`) is the canonical example. ## `joint_trajectory_controller` (stock ros2_controllers) @@ -74,7 +74,7 @@ We don't bundle a YAML for this in the project — the FSM `StandbyController` covers the production trajectory case end-to-end. Drop in stock JTC for one-off scripted tests. -## `bar/MITJointTrajectoryController` (project-local) +## `humanoid_control/MITJointTrajectoryController` (project-local) Custom controller that **owns the full 5-interface MIT surface** and accepts trajectories. Useful when you want the rqt-driven @@ -118,7 +118,7 @@ a one-shot `ros2 topic pub` to drive it. The standard flow (drop into `pixi shell` first so `ros2` is on PATH): ```bash -cd bar_ws && pixi shell +cd humanoid_control_ws && pixi shell # 1. Make sure the controller TYPE is registered with pluginlib ros2 control list_controller_types | grep diff --git a/docs/reference/messages.md b/docs/reference/messages.md index 13534e3..c0cfa0c 100644 --- a/docs/reference/messages.md +++ b/docs/reference/messages.md @@ -1,23 +1,23 @@ # Messages Custom ROS 2 interfaces. **Frozen** once a trained policy depends on the -schema (changing the layout forces retraining). `bar_msgs` ships four +schema (changing the layout forces retraining). `humanoid_control_msgs` ships four messages. The live piano key state is **not** a custom message — it travels as a stock `std_msgs/Float32MultiArray` on `/piano/key_state`, -which keeps `bar_controllers` free of any `pianist_msgs` dependency. +which keeps `humanoid_controllers` free of any `pianist_msgs` dependency. :::note[Off-ROS consumers] Tier-3 (non-`rclpy`) clients get these types from -[`bar_msgs_dds`](packages.md#bar_msgs_dds) — generated from the same `.msg` +[`humanoid_control_msgs_dds`](packages.md#humanoid_control_msgs_dds) — generated from the same `.msg` and wire-compatible — usually via the `lite_sdk2` SDK. See -[Talk to bar_ros2 from Python](../how_to/talk_to_bar_ros2_from_python.md). +[Talk to humanoid_control from Python](../how_to/talk_to_humanoid_control_from_python.md). ::: ## Topology -![bar_msgs pub/sub topology](/img/diagrams/reference__messages__01.svg) +![humanoid_control_msgs pub/sub topology](/img/diagrams/reference__messages__01.svg) -## `bar_msgs/MITCommand` +## `humanoid_control_msgs/MITCommand` The five-MIT-mode-interface command record. It is written **internally** by `RLPolicyController` each tick (in-process, never published), and it is @@ -46,7 +46,7 @@ explicit**: a "position-only" command would still send `velocity=0`, re-creation fully reproducible. ::: -## `bar_msgs/ControlMode` +## `humanoid_control_msgs/ControlMode` Mode-FSM telemetry, published by `mode_manager` at tick rate (50 Hz). @@ -67,7 +67,7 @@ string status_message # human-readable, may carry rejection reason The numeric `mode` field uses the explicit constants above. Consumers should match against the `uint8 = ` defines, not hard-code integers. -## `bar_msgs/StandbyState` +## `humanoid_control_msgs/StandbyState` Published by `StandbyController` on `~/state` (which resolves to `/standby_controller/state`) with `TRANSIENT_LOCAL` (latched) QoS so a @@ -84,7 +84,7 @@ bool is_finished # true once final pose + final gains reached `mode_manager` gates the `START` intent (STANDBY → LOCOMOTION/REMOTE) on `is_finished == true`. -## `bar_msgs/SafetyStatus` +## `humanoid_control_msgs/SafetyStatus` Layered safety telemetry. Any hardware plugin or controller may publish; the `flags` bitmask is **plugin-specific**. @@ -98,7 +98,7 @@ uint8 FAULT = 2 # commands no longer guaranteed; transition recommended uint8 CRITICAL = 3 # immediate fault fallback required uint8 level -string source # e.g. "bar_robstride/can0", "rl_policy_controller" +string source # e.g. "humanoid_control_robstride/can0", "rl_policy_controller" uint32 flags # plugin-specific bitmask string message ``` diff --git a/docs/reference/packages.md b/docs/reference/packages.md index 1c28fc2..d70914b 100644 --- a/docs/reference/packages.md +++ b/docs/reference/packages.md @@ -1,25 +1,25 @@ # Packages The control stack is split across **two sibling repos** that are -cloned side-by-side under `bar_ws/src/`: +cloned side-by-side under `humanoid_control_ws/src/`: -- **[`T-K-233/bar_ros2`](https://github.com/T-K-233/bar_ros2)** — +- **[`Berkeley-Humanoids/humanoid_control`](https://github.com/Berkeley-Humanoids/humanoid_control)** — 12 packages making up the unified low-level control surface (URDF, controllers including in-process ONNX inference, hardware plugins, the launch-time policy-prep tool, both Lite and Prime bringups), plus a - pip-only `bar_msgs_dds` package for off-ROS (Tier-3) clients. No + pip-only `humanoid_control_msgs_dds` package for off-ROS (Tier-3) clients. No task-specific code. - **[`T-K-233/pianist_ros2`](https://github.com/T-K-233/pianist_ros2)** — 4 packages implementing the **piano playing** task on top of - `bar_ros2`: piano MJCF assets, a scene-composition launch, the + `humanoid_control`: piano MJCF assets, a scene-composition launch, the piano-specific messages, and a `pianist_policy` package shipping the piano `prepare` tool + live key-state nodes. -The split is deliberate. `bar_ros2` is robot/control infrastructure +The split is deliberate. `humanoid_control` is robot/control infrastructure that every task reuses; `pianist_ros2` is the first concrete task following the pattern. New task families (locomotion-task, dexterous grasping, etc.) follow the same shape — a sibling repo depending on -`bar_msgs` + `bar_policy`, with its own bringup launch and a +`humanoid_control_msgs` + `humanoid_control_policy`, with its own bringup launch and a `_policy prepare` tool. The learned policy itself always runs **in-process** in the shared C++ `RLPolicyController`; what differs per task is the `.onnx` + `.mcap` and the prepare tool that produces them. @@ -28,21 +28,21 @@ The rest of this page walks each package in turn. The [`pianist_ros2` packages](#task-specific-packages-live-in-sibling-repos) get their own section near the bottom. -## Per-package details (bar_ros2) +## Per-package details (humanoid_control) -### `bar_common` +### `humanoid_control_common` Header-only POD types and real-time helpers. Every C++ package in the workspace depends on this. | Header | Purpose | |---|---| -| `mit_state.hpp` | `bar::MITState` — canonical observation struct (joint pos/vel/effort, IMU quat in **(w, x, y, z)** order, body-frame gyro/accel, last_action). Code-level schema, not a published topic. | +| `mit_state.hpp` | `humanoid_control::MITState` — canonical observation struct (joint pos/vel/effort, IMU quat in **(w, x, y, z)** order, body-frame gyro/accel, last_action). Code-level schema, not a published topic. | | `joint_index_map.hpp` | Bidirectional `name ↔ index` map, used to validate incoming `MITCommand` joint_names against a controller's claimed order. | | `rt_utils.hpp` | RT-safe primitives: `monotonic_ns()`, `all_finite(...)`, `clamp(...)`. No allocations. | -| `loaned_interface_helpers.hpp` | `bar::set_cmd(...)` and `bar::get_state(...)` — discard wrappers for Jazzy's `[[nodiscard]] bool set_value()` and `get_optional()` migration. Centralizes the Kilted migration to one file. | +| `loaned_interface_helpers.hpp` | `humanoid_control::set_cmd(...)` and `humanoid_control::get_state(...)` — discard wrappers for Jazzy's `[[nodiscard]] bool set_value()` and `get_optional()` migration. Centralizes the Kilted migration to one file. | -### `bar_msgs` +### `humanoid_control_msgs` Custom ROS 2 interfaces. Once a trained policy depends on one, it is **frozen**. @@ -55,11 +55,11 @@ Custom ROS 2 interfaces. Once a trained policy depends on one, it is **frozen**. See [Messages reference](messages.md) for full schemas. -### `bar_msgs_dds` +### `humanoid_control_msgs_dds` **Not a colcon package** — a pip package (`COLCON_IGNORE`d) that gives -Tier-3 / off-ROS clients the `bar_msgs` types without `rclpy`. Its -`codegen/emit.py` parses `bar_msgs/msg/*.msg` with ROS's own +Tier-3 / off-ROS clients the `humanoid_control_msgs` types without `rclpy`. Its +`codegen/emit.py` parses `humanoid_control_msgs/msg/*.msg` with ROS's own `rosidl_adapter` and emits `cyclonedds` `IdlStruct` dataclasses to a committed `_generated.py`, baking in the rmw type-name mangling (`pkg::msg::dds_::Name_`) and the `rt/` topic convention. It is **types + @@ -73,16 +73,16 @@ wire conventions only** — no participant/transport. | Generated types | `MITCommand`, `ControlMode`, `SafetyStatus`, `StandbyState` + borrowed `std_msgs/Header`, `builtin_interfaces/Time`, `sensor_msgs/JointState` | The `lite_sdk2` SDK builds its publisher/subscriber layer on top. See -[Talk to bar_ros2 from Python](../how_to/talk_to_bar_ros2_from_python.md). +[Talk to humanoid_control from Python](../how_to/talk_to_humanoid_control_from_python.md). ### `lite_description` / `prime_description` (external) URDF / xacro / meshes / `` blocks. **Lite's description is no longer -in `bar_ros2`** — it lives in the external, CAD-generated +in `humanoid_control`** — it lives in the external, CAD-generated [`lite_description`](https://github.com/Berkeley-Humanoids/Lite-Description) repo (bar deploys the `lite_dummy` variant), pulled in via `bar.repos`. It is **asset-only**: the RViz inspector (`view_lite.launch.py` + `view_lite.rviz`) now -lives in `bar_bringup_lite`. Prime's description likewise lives in the external [`prime_description`](https://github.com/T-K-233/Prime-Description) repo (bar deploys the `prime_dummy` variant, which also carries the hybrid eRob+Sito ``). +lives in `humanoid_control_bringup_lite`. Prime's description likewise lives in the external [`prime_description`](https://github.com/T-K-233/Prime-Description) repo (bar deploys the `prime_dummy` variant, which also carries the hybrid eRob+Sito ``). Layout (Lite shown, inside the `lite_description` repo): @@ -113,21 +113,21 @@ real-hardware path. Values mirror [Hardware specifications → Joint table](./hardware_specs.md#joint-table) for the canonical values. -### `bar_drivers/bar_socketcan` +### `humanoid_control_drivers/humanoid_control_socketcan` Reusable SocketCAN bus library. Owns the kernel-facing CAN socket lifecycle, a dedicated I/O thread, and lock-free buffers. Per-actuator-family plugins -(`bar_robstride`, `bar_sito`) consume its synchronous `read_state()` / +(`humanoid_control_robstride`, `humanoid_control_sito`) consume its synchronous `read_state()` / `write_command()` API. **Pattern reference**: mirrors the `soem_ros2` / `cleardrive_ros2` split from `legged_control2`. -### `bar_devices/bar_robstride` and `bar_devices/bar_sito` +### `humanoid_control_devices/humanoid_control_robstride` and `humanoid_control_devices/humanoid_control_sito` Per-actuator-family `hardware_interface::SystemInterface` plugins. -`bar_robstride` for Lite (and Prime's auxiliary joints if added later); -`bar_sito` for Prime's Sito side. +`humanoid_control_robstride` for Lite (and Prime's auxiliary joints if added later); +`humanoid_control_sito` for Prime's Sito side. Both: - Export the standard **3 state interfaces** (`/position`, `/velocity`, `/effort`). @@ -135,7 +135,7 @@ Both: - Read `can_interface` (system-level) and per-joint `can_id` from URDF params. - Register via `pluginlib` against `hardware_interface::SystemInterface`. -`bar_robstride` additionally: +`humanoid_control_robstride` additionally: - Reads per-joint **`model`** (one of `rs-00`..`rs-06` — drives the MIT-mode scaling limits), **`direction`** (±1), **`lower_limit`** / **`upper_limit`** @@ -154,7 +154,7 @@ Both: keeps the same per-joint keys as [`T-K-233/Lite-Lowlevel-Python`](https://github.com/T-K-233/Lite-Lowlevel-Python)'s JSON output, so values move between the two stacks unchanged. -- Publishes a `bar_msgs/SafetyStatus` on `/safety_status` (TRANSIENT_LOCAL, +- Publishes a `humanoid_control_msgs/SafetyStatus` on `/safety_status` (TRANSIENT_LOCAL, per-bus source field) with bit-flags for `BUS_OFF` / `RX_TIMEOUT` / `TX_QUEUE_OVERRUN` / `MOTOR_FAULT` / `TEMPERATURE_LIMIT` / `INVALID_FRAME`. `mode_manager` subscribes and auto-falls to DAMPING on any non-OK level. @@ -167,17 +167,17 @@ Ships three CLI executables alongside the plugin: | `robstride_discover` | Scan an id range across one bus and print everyone that answers. Read-only, no Enable. | | `mit_slider_gui` | Tk-Qt slider window publishing `Float64MultiArray` to `forward_command_controller/MultiInterfaceForwardCommandController`; manual command of position/velocity/effort/stiffness/damping per joint. | -### `bar_controllers` +### `humanoid_controllers` Five mode-FSM controllers + the standalone `mode_manager` executable. | Plugin | State | Source | |---|---|---| -| `bar/ZeroTorqueController` | startup, safer fault fallback | `zero_torque_controller.cpp` | -| `bar/DampingController` | compliant fail-safe | `damping_controller.cpp` | -| `bar/StandbyController` | pose interpolation + gain ramp | `standby_controller.cpp` | -| `bar/RLPolicyController` | in-process ONNX inference (System 0) — every learned policy | `rl_policy_controller.cpp` | -| `bar/RemotePolicyController` | System 1/2 external-command ingress | `remote_policy_controller.cpp` | +| `humanoid_control/ZeroTorqueController` | startup, safer fault fallback | `zero_torque_controller.cpp` | +| `humanoid_control/DampingController` | compliant fail-safe | `damping_controller.cpp` | +| `humanoid_control/StandbyController` | pose interpolation + gain ramp | `standby_controller.cpp` | +| `humanoid_control/RLPolicyController` | in-process ONNX inference (System 0) — every learned policy | `rl_policy_controller.cpp` | +| `humanoid_control/RemotePolicyController` | System 1/2 external-command ingress | `remote_policy_controller.cpp` | | `mode_manager` exe | FSM orchestrator | `mode_manager.cpp` | `RLPolicyController` now runs full in-process inference. Its runtime @@ -191,32 +191,32 @@ modules live alongside the controllers in this package: | `ActionMapper` | `pos = default + action * scale`, scattered across the full articulation; undriven joints pinned to `position=0` with the policy's `K`/`D`. | The package reads the `.mcap` and configures every policy parameter from -the `rl_policy_controller` overlay that `bar_policy prepare` emits — it -never depends on `bar_policy` or any task message package. +the `rl_policy_controller` overlay that `humanoid_control_policy prepare` emits — it +never depends on `humanoid_control_policy` or any task message package. See [Controllers reference](controllers.md). -### `bar_cli` +### `humanoid_control_cli` -The unified verb/noun CLI surface (`bar bus ping`, `bar bus discover`, -`bar motor slider`, `bar viz rerun`, `bar viz viser`). An ament_python +The unified verb/noun CLI surface (`hc bus ping`, `hc bus discover`, +`hc motor slider`, `hc viz rerun`, `hc viz viser`). An ament_python package that thin-wraps the underlying executables shipped by -`bar_robstride` and `bar_bringup_lite`. Invoke as `bar …` -once `install/setup.bash` is sourced. (`pixi run bar …` is the +`humanoid_control_robstride` and `humanoid_control_bringup_lite`. Invoke as `bar …` +once `install/setup.bash` is sourced. (`pixi run hc …` is the workspace-level shortcut — see [Workspace shortcuts with pixi](../how_to/use_pixi_tasks.md).) -### `bar_policy` +### `humanoid_control_policy` An ament_python package that is a **launch-time prep tool**, not a runtime node. Inference runs in-process in the C++ `RLPolicyController` -(System 0); `bar_policy` does the non-real-time, dependency-heavy work -once at launch. Its `prepare` console script (`ros2 run bar_policy +(System 0); `humanoid_control_policy` does the non-real-time, dependency-heavy work +once at launch. Its `prepare` console script (`ros2 run humanoid_control_policy prepare`) composes: | Module | Role | |---|---| -| `checkpoint_loader.resolve_checkpoint` | Resolve a local `--checkpoint-file` or a `--wandb-run-path` to a local `.onnx`; cache W&B downloads under `~/.cache/bar_policy/wandb//`. | +| `checkpoint_loader.resolve_checkpoint` | Resolve a local `--checkpoint-file` or a `--wandb-run-path` to a local `.onnx`; cache W&B downloads under `~/.cache/humanoid_control_policy/wandb//`. | | `policy_metadata.PolicyMetadata` | Typed access to the self-describing fields baked into the ONNX `custom_metadata_map` (joint names, gains, default pose, observation term names, dataset id, `policy_dt`, …). | | `convert.tracking_frames` | Read the LeRobot episode and emit per-frame arrays (`[pos·3B][ori6d·6B]`). | | `mcap_writer.write_motion_bag` | Write those frames to a single-episode rosbag2 `.mcap` bag (`std_msgs/Float32MultiArray`, via `rosbag2_py`). | @@ -225,36 +225,36 @@ prepare`) composes: The overlay is machine-generated from the checkpoint, so the `.onnx` stays the single source of truth — nothing about the policy is restated by hand in YAML. The C++ controller reads the `.mcap` and the overlay; it -never imports `bar_policy`. +never imports `humanoid_control_policy`. See [Policy runner](policy_runner.md) for the full ONNX metadata schema, the `prepare` CLI args, and the dataset-resolution order. ### Task-specific packages live in sibling repos -`bar_ros2` deliberately does not carry task-specific code. The piano +`humanoid_control` deliberately does not carry task-specific code. The piano playing task lives in [**`T-K-233/pianist_ros2`**](https://github.com/T-K-233/pianist_ros2), -cloned side-by-side under `bar_ws/src/`: +cloned side-by-side under `humanoid_control_ws/src/`: | Package | Build type | What it ships | |---|---|---| | `pianist_assets` | ament_cmake | Piano MJCF (`piano.xml`) installed under `/pianist_assets/mjcf/`. | -| `pianist_bringup` | ament_cmake | `mujoco.launch.py` — composes a `_runtime_lite_piano.xml` scene next to `lite.xml` (so MuJoCo's `meshdir="../meshes/"` resolves), then delegates to `bar_bringup_lite/mujoco.launch.py` with `scene:=_runtime_lite_piano`. Also spawns `piano_state_bridge` so `/piano/key_state` exists on the sim path. | +| `pianist_bringup` | ament_cmake | `mujoco.launch.py` — composes a `_runtime_lite_piano.xml` scene next to `lite.xml` (so MuJoCo's `meshdir="../meshes/"` resolves), then delegates to `humanoid_control_bringup_lite/mujoco.launch.py` with `scene:=_runtime_lite_piano`. Also spawns `piano_state_bridge` so `/piano/key_state` exists on the sim path. | | `pianist_msgs` | ament_cmake | Piano-task messages. No longer carries the key-state stream (that moved to a generic `std_msgs/Float32MultiArray` on `/piano/key_state`). | | `pianist_policy` | ament_python | `prepare` console script + `piano_policy.launch.py` (runs the piano `prepare`, then loads the in-process `rl_policy_controller` inactive — the piano task is selected by the ONNX `task_type='piano'`). Also ships the live key-state nodes `piano_state_bridge` (sim) and `midi_keyboard_driver` (real USB-MIDI), both publishing `std_msgs/Float32MultiArray` on `/piano/key_state`, with a matching `midi_keyboard_driver.launch.py`. | -`pianist_policy`'s `prepare` reuses `bar_policy`'s checkpoint/metadata/ +`pianist_policy`'s `prepare` reuses `humanoid_control_policy`'s checkpoint/metadata/ `.mcap` infrastructure, adding only the MIDI/song → key-state conversion. There is no piano runner and no `pianist_msgs` dependency in -`bar_controllers`: the live key state arrives as a generic float array, +`humanoid_controllers`: the live key state arrives as a generic float array, and the song reference is baked into the `.mcap` the controller loads. -New task families follow the same pattern: depend on `bar_msgs` + -`bar_policy`, ship a `_policy prepare` tool that emits the overlay +New task families follow the same pattern: depend on `humanoid_control_msgs` + +`humanoid_control_policy`, ship a `_policy prepare` tool that emits the overlay + `.mcap`, and a bringup launch composing onto -`bar_bringup_lite/mujoco.launch.py` or `…/real.launch.py`. +`humanoid_control_bringup_lite/mujoco.launch.py` or `…/real.launch.py`. -### `bar_bringup_lite` / `bar_bringup_prime` +### `humanoid_control_bringup_lite` / `humanoid_control_bringup_prime` The "main()" of the project. Each robot ships **parallel launches** (franka_ros2-style per-robot bringup — there is no top-level @@ -265,9 +265,9 @@ for which side runs which): | Launch | Deployment side | Hardware path | Selected xacro args | |---|---|---|---| -| `real.launch.py` | Robot onboard computer | `bar_robstride` / `bar_sito` over SocketCAN (+ EtherCAT for Prime) | `use_fake_hardware:=false use_sim:=false` | +| `real.launch.py` | Robot onboard computer | `humanoid_control_robstride` / `humanoid_control_sito` over SocketCAN (+ EtherCAT for Prime) | `use_fake_hardware:=false use_sim:=false` | | `mujoco.launch.py` | Single-machine sim/dev | `mujoco_ros2_control/MujocoSystem` inside `mujoco_sim` | `use_sim:=true` | -| `calibrate.launch.py` | Single-machine (robot benchtop) | `bar_robstride` with identity calibration + `calibrate_robot` observer | `use_fake_hardware:=false use_sim:=false` | +| `calibrate.launch.py` | Single-machine (robot benchtop) | `humanoid_control_robstride` with identity calibration + `calibrate_robot` observer | `use_fake_hardware:=false use_sim:=false` | | `viz.launch.py` | Operator workstation (host) | DDS-consumer only; no controller_manager, no hardware | n/a — only subscribes | The first two launches: @@ -281,31 +281,31 @@ The first two launches: 5. Start `mode_manager` (when `enable_mode_manager:=true`). 6. Start `joy_node` (when `enable_gamepad:=true`, which is the default). -`bar_bringup_lite/config/sim_overrides.yaml` adds `use_sim_time:=true` -on top of `bar_lite_controllers.yaml` for the MuJoCo path. -`bar_bringup_lite/config/calibration.yaml` is the per-physical-robot -zero offset that `bar_robstride` applies at the bus boundary on the -real path (regenerate via `ros2 launch bar_bringup_lite calibrate.launch.py` — see the -[Launch args](launch_args.md#bar_bringup_litelaunchcalibratelaunchpy) -page). `bar_bringup_lite/config/lite_hardware.yaml` is the per-machine -bus + joint mapping consumed by xacro. `bar_bringup_prime/config/ethercat.yaml` +`humanoid_control_bringup_lite/config/sim_overrides.yaml` adds `use_sim_time:=true` +on top of `humanoid_control_lite_controllers.yaml` for the MuJoCo path. +`humanoid_control_bringup_lite/config/calibration.yaml` is the per-physical-robot +zero offset that `humanoid_control_robstride` applies at the bus boundary on the +real path (regenerate via `ros2 launch humanoid_control_bringup_lite calibrate.launch.py` — see the +[Launch args](launch_args.md#humanoid_control_bringup_litelaunchcalibratelaunchpy) +page). `humanoid_control_bringup_lite/config/lite_hardware.yaml` is the per-machine +bus + joint mapping consumed by xacro. `humanoid_control_bringup_prime/config/ethercat.yaml` configures the IgH master for Prime real-hardware bringup. -`bar_bringup_lite` also ships three operator-facing Python nodes. +`humanoid_control_bringup_lite` also ships three operator-facing Python nodes. The viewers are normally launched on the host side via -`ros2 launch bar_bringup_lite viz.launch.py` (which wraps them and +`ros2 launch humanoid_control_bringup_lite viz.launch.py` (which wraps them and selects between them via `viewer:=viser|rerun`); direct -`ros2 run bar_bringup_lite rerun_viz` / `viser_viz` is the +`ros2 run humanoid_control_bringup_lite rerun_viz` / `viser_viz` is the single-machine sim/dev shortcut: | Executable | Purpose | |---|---| -| `calibrate_robot` | Calibration observer — subscribes `/robot_description` + `/lite/joint_states`, tracks per-joint (min, max), writes the homing-offset YAML on Ctrl+C. Driven by `calibrate.launch.py` (`ros2 launch bar_bringup_lite calibrate.launch.py`). | +| `calibrate_robot` | Calibration observer — subscribes `/robot_description` + `/lite/joint_states`, tracks per-joint (min, max), writes the homing-offset YAML on Ctrl+C. Driven by `calibrate.launch.py` (`ros2 launch humanoid_control_bringup_lite calibrate.launch.py`). | | `rerun_viz` | Live URDF visualization in the **native** [rerun](https://rerun.io) viewer — auto-spawned subprocess by default, or `--connect host:port` to feed a remote one. Subscribes `/robot_description` (latched) and a `--joint-state-topic` (default `/lite/joint_states`); logs per-joint `Transform3D` to `/tf` at the tick rate. `rerun-sdk` ships in the workspace env. | | `viser_viz` | Same subscriptions and resolution pattern, rendering into a **browser** at `http://:` (default `0.0.0.0:8080`) via [viser](https://github.com/nerfstudio-project/viser). Friendlier for headless robot machines and SSH workflows. `viser`, `yourdfpy`, and `scipy` ship in the workspace env. | ## External (vcs-imported, not in this repo) Pinned in `bar.repos` and fetched via -`vcs import --input src/bar_ros2/bar.repos src` — see the +`vcs import --input src/humanoid_control/bar.repos src` — see the [installation page](../getting_started/installation.md#4-pull-third-party-sources). \ No newline at end of file diff --git a/docs/reference/policy_runner.md b/docs/reference/policy_runner.md index e094f07..c2488c8 100644 --- a/docs/reference/policy_runner.md +++ b/docs/reference/policy_runner.md @@ -1,6 +1,6 @@ # Policy runner -The learned policy runs **in-process** in `bar::RLPolicyController` (C++, +The learned policy runs **in-process** in `humanoid_control::RLPolicyController` (C++, real-time — the System 0 path). What "policy runner" used to mean — a Python `rclpy` node streaming `MITCommand` over DDS — is gone. Its dependency-heavy work now happens in a launch-time `prepare` step, and @@ -10,9 +10,9 @@ training↔deployment contract, unchanged), and the in-process observation-term registry. :::note[Migrated from the out-of-process runner] -Earlier docs described `bar_policy.remote_policy_runner` and a +Earlier docs described `humanoid_control_policy.remote_policy_runner` and a `pianist_policy.PianoPolicyRunner` subclass publishing over DDS. Those are -removed. `bar_policy` is now a launch-time **prep tool**, inference is +removed. `humanoid_control_policy` is now a launch-time **prep tool**, inference is in-process in `RLPolicyController`, and `RemotePolicyController` remains only as the System 1/2 external-command ingress (gravity-comp, future VLA). See [Architecture › Policy execution](../concepts/architecture.md). @@ -37,17 +37,17 @@ training and deployment cannot drift independently. ## Composition -**Launch-time `prepare`** (Python, `bar_policy` / `pianist_policy`): +**Launch-time `prepare`** (Python, `humanoid_control_policy` / `pianist_policy`): | Module | Responsibility | |---|---| -| `checkpoint_loader.resolve_checkpoint` | Resolve a local path or a W&B run (`entity/project/run_id`) to a local `.onnx`; cache under `~/.cache/bar_policy/wandb//`. | +| `checkpoint_loader.resolve_checkpoint` | Resolve a local path or a W&B run (`entity/project/run_id`) to a local `.onnx`; cache under `~/.cache/humanoid_control_policy/wandb//`. | | `policy_metadata.load_policy_metadata` | Parse `custom_metadata_map` → frozen `PolicyMetadata`. Helpers `joint_stiffness_map()`, `default_joint_pos_map()`, `action_scale_map()` return `dict[str, float]` keyed by joint name. | | `convert.tracking_frames` / `pianist_policy.prepare.piano_frames` | Read the LeRobot episode and emit per-frame arrays (tracking: `[pos·3B][ori6d·6B]`; piano: `[key_pressed·K]`). | | `mcap_writer.write_motion_bag` | Write those frames to a single-episode rosbag2 `.mcap` bag (`std_msgs/Float32MultiArray`, via `rosbag2_py`). | | `prepare.write_param_overlay` | Emit `rl_policy_params.yaml` — the metadata transcoded into `rl_policy_controller` params (joints, gains, scale, obs names, `motion_file`, `policy_checkpoint`, …). | -**Runtime** (in-process, C++ `bar_controllers`): +**Runtime** (in-process, C++ `humanoid_controllers`): | Module | Responsibility | |---|---| @@ -111,7 +111,7 @@ sources, in this order: 3. **Topic-fed extern terms** — filled from a live subscription. Piano's `key_pressed` reads a generic `std_msgs/Float32MultiArray` on `/piano/key_state` (published by `piano_state_bridge` in sim, - `midi_keyboard_driver` on hardware). This keeps `bar_controllers` free + `midi_keyboard_driver` on hardware). This keeps `humanoid_controllers` free of any `pianist_msgs` dependency. Unknown names fail at `on_configure` — the guarantee is that **every @@ -120,38 +120,38 @@ active. ## Launch flow: `prepare` then spawn -There is no runner process. The launch (`bar_policy/launch/lite_policy.launch.py`, +There is no runner process. The launch (`humanoid_control_policy/launch/lite_policy.launch.py`, or `pianist_policy/launch/piano_policy.launch.py` for piano) does two things, in order: -1. **Runs `prepare` synchronously** — a one-shot `ros2 run bar_policy +1. **Runs `prepare` synchronously** — a one-shot `ros2 run humanoid_control_policy prepare` (`ros2 run pianist_policy prepare` for piano) that resolves the ONNX, writes the `.mcap` motion bag, and emits the `rl_policy_params.yaml` overlay. This is the dependency-heavy, non-real-time work; it must finish before the controller configures. 2. **Spawns `rl_policy_controller` *inactive*** with the overlay as a `--param-file`. The operator's FSM `START_LOCOMOTION` - (`/bar/mode/start_locomotion`, R1+A) is what activates it. + (`/humanoid_control/mode/start_locomotion`, R1+A) is what activates it. The launch args are pass-throughs to the `prepare` CLI below (plus -`out_dir`, defaulting to `~/.cache/bar_policy/launch/`, which fixes the +`out_dir`, defaulting to `~/.cache/humanoid_control_policy/launch/`, which fixes the overlay path the spawner reads). ### `prepare` CLI args -`ros2 run bar_policy prepare` (console script `prepare = -bar_policy.prepare:main`); `pianist_policy prepare` is the piano +`ros2 run humanoid_control_policy prepare` (console script `prepare = +humanoid_control_policy.prepare:main`); `pianist_policy prepare` is the piano counterpart and adds the last two: | Arg | Default | Effect | |---|---|---| | `--checkpoint-file` | (empty) | Path to a local `.onnx`. Mutually exclusive with `--wandb-run-path`. | -| `--wandb-run-path` | (empty) | W&B run path (`entity/project/run_id`); the ONNX is downloaded and cached at `~/.cache/bar_policy/wandb//`. | +| `--wandb-run-path` | (empty) | W&B run path (`entity/project/run_id`); the ONNX is downloaded and cached at `~/.cache/humanoid_control_policy/wandb//`. | | `--wandb-checkpoint-name` | (empty) | Specific `.onnx` filename inside the W&B run (default: newest `model_*`). | | `--motion-file` | (empty) | Local LeRobot dataset dir. Wins over registry and the ONNX-baked repo id. | | `--registry-name` | (empty) | HF repo id to use instead of the ONNX-baked `dataset_repo_id`. Useful when iterating on dataset variants. | | `--episode-index` | `0` | Reference-dataset episode index to convert. | -| `--out-dir` | `~/.cache/bar_policy/artifacts/` | Where the `.onnx` copy, `.mcap` bag, and overlay are written. | +| `--out-dir` | `~/.cache/humanoid_control_policy/artifacts/` | Where the `.onnx` copy, `.mcap` bag, and overlay are written. | | `--skip-stride` | `1` | Piano-only: stride between lookahead frames (the training-time value). | | `--key-state-topic` | `/piano/key_state` | Piano-only: the live key-state topic (`std_msgs/Float32MultiArray`) the controller subscribes to. | @@ -185,7 +185,7 @@ conversion and the piano overlay). At runtime the same in-process `McapPianoReference` provider over `McapTrackingReference`, and the piano-only observation terms (`target_keys`, `progress`, `key_pressed`) resolve through that provider and the live `/piano/key_state` extern. -`bar_controllers` never learns the piano task exists. +`humanoid_controllers` never learns the piano task exists. New task families follow the same pattern: a sibling `_ros2` repo ships a `_policy prepare` tool that emits the overlay + `.mcap`; the @@ -214,12 +214,12 @@ Inside `RLPolicyController::update()` — no process boundary, no DDS hop: The step ordering keeps the policy from observing the *post-action* reference frame on the same tick it commanded against — every tick is `(t, t+1)` in the dataset, never `(t+1, t+1)`. Non-finite observations or -actions trip `bar::rt::all_finite(...)` and return `return_type::ERROR`, +actions trip `humanoid_control::rt::all_finite(...)` and return `return_type::ERROR`, triggering the CM `fallback_controllers`. ## See also -- [`bar/RemotePolicyController`](controllers.md#barremotepolicycontroller) +- [`humanoid_control/RemotePolicyController`](controllers.md#barremotepolicycontroller) — the **System 1/2 external-command ingress** (gravity-comp today, VLA later); no longer part of the learned-policy path. - [Architecture › Policy execution: System 0](../concepts/architecture.md#policy-execution-system-0-in-process-real-time) diff --git a/docs/reference/quick_reference.md b/docs/reference/quick_reference.md index 61a8d76..7a59ddf 100644 --- a/docs/reference/quick_reference.md +++ b/docs/reference/quick_reference.md @@ -11,7 +11,7 @@ parameters. The cheat sheet you print or pin to a second monitor. Every link points at the page with the full details. All commands below assume you've entered the workspace env (e.g. -`cd bar_ws && pixi shell`) so `ros2`, `colcon`, and the BAR console +`cd humanoid_control_ws && pixi shell`) so `ros2`, `colcon`, and the BAR console scripts are on `PATH`. Looking for one-line aliases (`pixi run launch-mujoco`, `pixi run build`, …)? See [How-to → Workspace shortcuts with pixi](../how_to/use_pixi_tasks.md). @@ -22,9 +22,9 @@ Grouped by which machine they run on. See [Concepts → Architecture → Deployment topology](../concepts/architecture.md#deployment-topology) for the split rationale. Launches come from two repos: -- `bar_ros2` ships the Lite + Prime bringups (`bar_bringup_lite`, - `bar_bringup_prime`), the description viewer (`bar_bringup_lite`), - and the policy prepare-and-load launch (`bar_policy`). +- `humanoid_control` ships the Lite + Prime bringups (`humanoid_control_bringup_lite`, + `humanoid_control_bringup_prime`), the description viewer (`humanoid_control_bringup_lite`), + and the policy prepare-and-load launch (`humanoid_control_policy`). - `pianist_ros2` ships the piano-task launches (`pianist_bringup` composes a Lite + piano MuJoCo scene; `pianist_policy` prepares the piano policy and runs the USB-MIDI driver). @@ -33,32 +33,32 @@ for the split rationale. Launches come from two repos: ```bash # Drag joints in RViz — no controllers, no physics -ros2 launch bar_bringup_lite view_lite.launch.py +ros2 launch humanoid_control_bringup_lite view_lite.launch.py # MuJoCo sim — full controller stack, /clock from sim time -ros2 launch bar_bringup_lite mujoco.launch.py +ros2 launch humanoid_control_bringup_lite mujoco.launch.py # Lite + piano in MuJoCo (pianist_bringup composes the scene, spawns piano_state_bridge) ros2 launch pianist_bringup mujoco.launch.py # Calibrate the zero pose (writes ./calibration.yaml on Ctrl+C) -ros2 launch bar_bringup_lite calibrate.launch.py +ros2 launch humanoid_control_bringup_lite calibrate.launch.py ``` ### Robot onboard computer (real bringup) ```bash # Real Lite — both buses, two ros2_control blocks, gamepad + mode_manager -ros2 launch bar_bringup_lite real.launch.py +ros2 launch humanoid_control_bringup_lite real.launch.py -# Real Lite, no gamepad attached (drive the FSM via /bar/mode/* services) -ros2 launch bar_bringup_lite real.launch.py enable_gamepad:=false +# Real Lite, no gamepad attached (drive the FSM via /humanoid_control/mode/* services) +ros2 launch humanoid_control_bringup_lite real.launch.py enable_gamepad:=false # Gamepad enumerated as js1 (multiple controllers plugged into the Jetson) -ros2 launch bar_bringup_lite real.launch.py joy_dev:=/dev/input/js1 +ros2 launch humanoid_control_bringup_lite real.launch.py joy_dev:=/dev/input/js1 # Real Lite, no FSM (raw debug / calibration) -ros2 launch bar_bringup_lite real.launch.py enable_mode_manager:=false +ros2 launch humanoid_control_bringup_lite real.launch.py enable_mode_manager:=false ``` `real.launch.py` boots the real-time control plane only — visualisers @@ -68,10 +68,10 @@ loaded on the robot below. ### Robot onboard computer (prepare + load a policy) ```bash -# Prepare + load the in-process tracking policy (bar_ros2 → bar_policy): +# Prepare + load the in-process tracking policy (humanoid_control → humanoid_control_policy): # runs `prepare` (ONNX → .mcap + overlay), then loads rl_policy_controller # inactive. START_LOCOMOTION (R1+A) activates it. -ros2 launch bar_policy lite_policy.launch.py \ +ros2 launch humanoid_control_policy lite_policy.launch.py \ wandb_run_path:=… wandb_checkpoint_name:=model.onnx # Piano policy (pianist_ros2 → pianist_policy); task picked by ONNX task_type @@ -85,9 +85,9 @@ ros2 launch pianist_policy midi_keyboard_driver.launch.py ### Operator workstation (host side of the tether) ```bash -# Live URDF + /lite/joint_states viewer (bar_bringup_lite) -ros2 launch bar_bringup_lite viz.launch.py # viser, http://0.0.0.0:8080 -ros2 launch bar_bringup_lite viz.launch.py viewer:=rerun # native rerun window +# Live URDF + /lite/joint_states viewer (humanoid_control_bringup_lite) +ros2 launch humanoid_control_bringup_lite viz.launch.py # viser, http://0.0.0.0:8080 +ros2 launch humanoid_control_bringup_lite viz.launch.py viewer:=rerun # native rerun window ``` Both machines must share `ROS_DOMAIN_ID`. Full surface: @@ -109,24 +109,24 @@ ip -d link show can1 ## Diagnostic CLIs -These are the `bar` (bar_cli) verbs — equivalent `ros2 run bar_robstride …` +These are the `hc` (humanoid_control_cli) verbs — equivalent `ros2 run humanoid_control_robstride …` invocations are listed in [CLI tools](./cli_tools.md). ```bash # Scan an ID range; read-only, no Enable -bar bus discover --iface can0 --scan-to 32 -bar bus discover --iface can1 --scan-to 32 +hc bus discover --iface can0 --scan-to 32 +hc bus discover --iface can1 --scan-to 32 # One-shot GetDeviceId / OperationStatus probe -bar bus ping --iface can0 --id 11 +hc bus ping --iface can0 --id 11 # Per-joint slider window (forward_command_controller frontend) -bar motor slider +hc motor slider # Live URDF + /lite/joint_states viewers (single-machine sim/dev shortcuts; -# on the tethered host, prefer `ros2 launch bar_bringup_lite viz.launch.py`) -bar viz viser # browser at :8080 -bar viz rerun # native rerun window +# on the tethered host, prefer `ros2 launch humanoid_control_bringup_lite viz.launch.py`) +hc viz viser # browser at :8080 +hc viz rerun # native rerun window ``` ## Mode-FSM gamepad bindings (Xbox layout) @@ -173,10 +173,10 @@ Always end a session with `zero_torque_controller` active before |---|---|---|---| | `/lite/joint_states` | `sensor_msgs/JointState` | 50 Hz real / 200 Hz sim | always (`joint_state_broadcaster`, remapped at bringup) | | `/imu/data` | `sensor_msgs/Imu` | sensor-rate | always; RELIABLE | -| `/control_mode` | `bar_msgs/ControlMode` | 50 Hz | always (`mode_manager`) | -| `/safety_status` | `bar_msgs/SafetyStatus` | on-change, latched | TRANSIENT_LOCAL; `source` field per bus | -| `/standby_controller/state` | `bar_msgs/StandbyState` | active-only | TRANSIENT_LOCAL; watch for `is_finished:true` before R1+A | -| `/remote_policy_controller/command` | `bar_msgs/MITCommand` | source rate | when a System 1/2 source (gravity-comp, VLA) feeds `remote_policy_controller` | +| `/control_mode` | `humanoid_control_msgs/ControlMode` | 50 Hz | always (`mode_manager`) | +| `/safety_status` | `humanoid_control_msgs/SafetyStatus` | on-change, latched | TRANSIENT_LOCAL; `source` field per bus | +| `/standby_controller/state` | `humanoid_control_msgs/StandbyState` | active-only | TRANSIENT_LOCAL; watch for `is_finished:true` before R1+A | +| `/remote_policy_controller/command` | `humanoid_control_msgs/MITCommand` | source rate | when a System 1/2 source (gravity-comp, VLA) feeds `remote_policy_controller` | | `/piano/key_state` | `std_msgs/Float32MultiArray` | sensor / sim rate | piano runs only (RELIABLE + KEEP_LAST(1)); live key state, in-process `key_pressed` term | | `/joy` | `sensor_msgs/Joy` | sensor-rate | when `enable_gamepad:=true` (default) | @@ -196,26 +196,26 @@ ros2 topic echo --once /lite/joint_states ros2 topic echo --once /safety_status # Drive an FSM transition without a gamepad -ros2 service call /bar/mode/damp std_srvs/srv/Trigger -ros2 service call /bar/mode/load std_srvs/srv/Trigger +ros2 service call /humanoid_control/mode/damp std_srvs/srv/Trigger +ros2 service call /humanoid_control/mode/load std_srvs/srv/Trigger # Fake a System 1/2 MITCommand publish (when remote_policy_controller is active in MuJoCo) ros2 topic pub --once /remote_policy_controller/command \ - bar_msgs/msg/MITCommand "{header: {stamp: now}, joint_names: [...], ...}" + humanoid_control_msgs/msg/MITCommand "{header: {stamp: now}, joint_names: [...], ...}" ``` ## Services for FSM transitions -`std_srvs/Trigger` services on `/bar/mode/*` mirror the gamepad +`std_srvs/Trigger` services on `/humanoid_control/mode/*` mirror the gamepad intents — useful when there's no joystick attached. | Service | Effect | |---|---| -| `/bar/mode/damp` | → DAMPING from any state | -| `/bar/mode/load` | DAMPING → STANDBY | -| `/bar/mode/start_remote` | STANDBY → REMOTE (gated on `is_finished`) | -| `/bar/mode/start_locomotion` | STANDBY → LOCOMOTION (gated on `is_finished`) | -| `/bar/mode/quit` | exit (only from ZERO_TORQUE or DAMPING) | +| `/humanoid_control/mode/damp` | → DAMPING from any state | +| `/humanoid_control/mode/load` | DAMPING → STANDBY | +| `/humanoid_control/mode/start_remote` | STANDBY → REMOTE (gated on `is_finished`) | +| `/humanoid_control/mode/start_locomotion` | STANDBY → LOCOMOTION (gated on `is_finished`) | +| `/humanoid_control/mode/quit` | exit (only from ZERO_TORQUE or DAMPING) | ## The Lite joint table diff --git a/docs/reference/reference_map.md b/docs/reference/reference_map.md index 11a2d64..e78944a 100644 --- a/docs/reference/reference_map.md +++ b/docs/reference/reference_map.md @@ -1,9 +1,9 @@ # Reference map A survey of the open robot low-level control ecosystem we studied while -designing `bar_ros2`. It is **descriptive**, not prescriptive: each entry +designing `humanoid_control`. It is **descriptive**, not prescriptive: each entry records *what the reference is* and *the role it played in our study*, so a -contributor can go read the primary source. Where `bar_ros2` made a +contributor can go read the primary source. Where `humanoid_control` made a specific design choice, the rationale lives in the [Concepts](../concepts/index.md) pages — this page is the map, not the decision log. @@ -22,7 +22,7 @@ layering is remarkably consistent (see [Common layering](#common-layering-patter | ROS 2 — Quality of Service | [https://docs.ros.org/en/jazzy/Concepts/Intermediate/About-Quality-of-Service-Settings.html](https://docs.ros.org/en/jazzy/Concepts/Intermediate/About-Quality-of-Service-Settings.html) | History/depth/reliability/durability/deadline/liveliness — why control vs. logging traffic want different profiles. | | ROS 2 — Executors | [https://docs.ros.org/en/jazzy/Concepts/Intermediate/About-Executors.html](https://docs.ros.org/en/jazzy/Concepts/Intermediate/About-Executors.html) | Callback scheduling and its interaction with control-loop timing and data freshness. | | ROS 2 — Real-time programming demo | [https://docs.ros.org/en/jazzy/Tutorials/Demos/Real-Time-Programming.html](https://docs.ros.org/en/jazzy/Tutorials/Demos/Real-Time-Programming.html) | The "what not to do in the RT path" list: page faults, dynamic allocation, blocking sync; `mlockall`, latency measurement. | -| ros2_control — Getting started | [https://control.ros.org/jazzy/doc/getting_started/getting_started.html](https://control.ros.org/jazzy/doc/getting_started/getting_started.html) | The core architecture `bar_ros2` is built on: controller manager, resource manager, controllers, hardware components. | +| ros2_control — Getting started | [https://control.ros.org/jazzy/doc/getting_started/getting_started.html](https://control.ros.org/jazzy/doc/getting_started/getting_started.html) | The core architecture `humanoid_control` is built on: controller manager, resource manager, controllers, hardware components. | | ROS 2 code style | [https://docs.ros.org/en/rolling/The-ROS2-Project/Contributing/Code-Style-Language-Versions.html](https://docs.ros.org/en/rolling/The-ROS2-Project/Contributing/Code-Style-Language-Versions.html) · [REP-8](https://ros.org/reps/rep-0008.html) | The style floor for our C++ / Python packages. | ### ros2_control in one paragraph @@ -66,7 +66,7 @@ This is exactly the spine described in | instinct_onboard | [https://github.com/project-instinct/instinct_onboard](https://github.com/project-instinct/instinct_onboard) | Onboard inference (Unitree G1, Jetson Orin NX) with **ONNX Runtime CPU/GPU auto-dispatch** and MCAP logging — reference for our in-process ONNX path. | | legged_control template controller | [https://github.com/qiayuanl/legged_template_controller](https://github.com/qiayuanl/legged_template_controller) | Minimal legged-RL controller skeleton. | -These map onto `bar_ros2` as: the **training side** (BeyondMimic, +These map onto `humanoid_control` as: the **training side** (BeyondMimic, `pianist-tracking-mj`) produces a self-describing ONNX; the **deployment side** runs it in-process in `RLPolicyController` (see [Tracking policy](../tutorials/tracking_policy.md) and @@ -76,10 +76,10 @@ side** runs it in-process in `RLPolicyController` (see - **DDS** — ROS 2 core comms and Unitree SDK2 both ride CycloneDDS. Concerns: QoS selection, message compatibility, NIC binding, discovery, - lossy-network behaviour. This is the wire `bar_msgs_dds` targets. + lossy-network behaviour. This is the wire `humanoid_control_msgs_dds` targets. - **CAN / SocketCAN** — OpenArm and the RobStride bridge: `can0`/`slcan` → CAN frames → motor protocol → actuator. The basis for - `bar_socketcan` + `bar_robstride` / `bar_sito`. + `humanoid_control_socketcan` + `humanoid_control_robstride` / `humanoid_control_sito`. - **EtherCAT** — eRob SOEM/IGH and `legged_control2`'s SOEM interfaces: SOEM or IgH master, Distributed Clock, object-dictionary mapping, OP-state transitions, real-time kernel + CPU isolation. The basis for @@ -99,7 +99,7 @@ Transport / bus DDS · SocketCAN · CANopen-like protocol · EtherCAT (SO Actuator / embedded motor firmware · drive state machine · encoder/current loop · safety · calibration ``` -`bar_ros2` lands its own packages on this stack as described in +`humanoid_control` lands its own packages on this stack as described in [Architecture](../concepts/architecture.md) and the [Packages reference](./packages.md). diff --git a/docs/reference/topics_services.md b/docs/reference/topics_services.md index 1edfcaa..810b760 100644 --- a/docs/reference/topics_services.md +++ b/docs/reference/topics_services.md @@ -4,7 +4,7 @@ title: Topics & services # Topics & services -Index of the ROS topics and services that `bar_ros2` publishes, +Index of the ROS topics and services that `humanoid_control` publishes, subscribes, or serves. Use this page to find "who publishes X" or "what topic carries Y". @@ -24,16 +24,16 @@ subscribes, or serves. Use this page to find "who publishes X" or | Topic | Type | QoS | Publisher | When present | |---|---|---|---|---| -| `/control_mode` | `bar_msgs/ControlMode` | RELIABLE depth 10 | `mode_manager` | When `enable_mode_manager:=true` (default for `real.launch.py` / `mujoco.launch.py`). 50 Hz. | -| `/safety_status` | `bar_msgs/SafetyStatus` | RELIABLE TRANSIENT_LOCAL depth 1 | every hardware plugin | Per-bus (`bar_robstride/can0`, `bar_robstride/can1` for Lite). Published only on change. | -| `/standby_controller/state` | `bar_msgs/StandbyState` | RELIABLE TRANSIENT_LOCAL depth 1 | `bar/StandbyController` (when active) | Carries `is_finished` — the gate for `START_*` intents. | +| `/control_mode` | `humanoid_control_msgs/ControlMode` | RELIABLE depth 10 | `mode_manager` | When `enable_mode_manager:=true` (default for `real.launch.py` / `mujoco.launch.py`). 50 Hz. | +| `/safety_status` | `humanoid_control_msgs/SafetyStatus` | RELIABLE TRANSIENT_LOCAL depth 1 | every hardware plugin | Per-bus (`humanoid_control_robstride/can0`, `humanoid_control_robstride/can1` for Lite). Published only on change. | +| `/standby_controller/state` | `humanoid_control_msgs/StandbyState` | RELIABLE TRANSIENT_LOCAL depth 1 | `humanoid_control/StandbyController` (when active) | Carries `is_finished` — the gate for `START_*` intents. | | `/joy` | `sensor_msgs/Joy` | SENSOR_DATA | `joy_node` | When `enable_gamepad:=true` (default). The launch hard-fails on missing `/dev/input/js*`. | ### Active-controller-dependent | Topic | Type | QoS | Direction | When | |---|---|---|---|---| -| `/remote_policy_controller/command` | `bar_msgs/MITCommand` | RELIABLE depth 4 | subscribed by `RemotePolicyController` | When `RemotePolicyController` is active. Published by a System 1/2 external-command source (gravity-comp runner today, VLA / manipulation later). Not used by the learned policies — those run in-process. | +| `/remote_policy_controller/command` | `humanoid_control_msgs/MITCommand` | RELIABLE depth 4 | subscribed by `RemotePolicyController` | When `RemotePolicyController` is active. Published by a System 1/2 external-command source (gravity-comp runner today, VLA / manipulation later). Not used by the learned policies — those run in-process. | | `/piano/key_state` | `std_msgs/Float32MultiArray` | RELIABLE KEEP_LAST(1) | sim: `pianist_policy/piano_state_bridge`; real: `pianist_policy/midi_keyboard_driver` | Piano runs. Live key state (0.0/1.0 per key). Consumed by the in-process `RLPolicyController` as the `key_pressed` extern observation term. | | `/forward_mit_controller/commands` | `std_msgs/Float64MultiArray` | RELIABLE depth 10 | subscribed by upstream `forward_command_controller/MultiInterfaceForwardCommandController` | Used by `mit_slider_gui`. | @@ -44,7 +44,7 @@ standard ROS infrastructure topics: - `/parameter_events`, `/rosout` - `~/get_parameters`, `~/set_parameters`, etc. (per node) -These are conventional ROS — not specific to `bar_ros2`. Mentioned +These are conventional ROS — not specific to `humanoid_control`. Mentioned here so `ros2 topic list` output isn't confusing. ## Services @@ -56,11 +56,11 @@ keyboardless lab boxes or scripted tests. | Service | Effect | |---|---| -| `/bar/mode/damp` | → DAMPING from any state | -| `/bar/mode/load` | DAMPING → STANDBY | -| `/bar/mode/start_remote` | STANDBY → REMOTE (gated on `is_finished`) | -| `/bar/mode/start_locomotion` | STANDBY → LOCOMOTION (gated on `is_finished`) | -| `/bar/mode/quit` | exit (only from ZERO_TORQUE or DAMPING) | +| `/humanoid_control/mode/damp` | → DAMPING from any state | +| `/humanoid_control/mode/load` | DAMPING → STANDBY | +| `/humanoid_control/mode/start_remote` | STANDBY → REMOTE (gated on `is_finished`) | +| `/humanoid_control/mode/start_locomotion` | STANDBY → LOCOMOTION (gated on `is_finished`) | +| `/humanoid_control/mode/quit` | exit (only from ZERO_TORQUE or DAMPING) | ### controller_manager-side (under `/controller_manager`) @@ -103,7 +103,7 @@ durability to receive the latched value. ## Inspecting at runtime -From a sourced workspace env (`cd bar_ws && pixi shell`): +From a sourced workspace env (`cd humanoid_control_ws && pixi shell`): ```bash # What's published right now? @@ -126,7 +126,7 @@ ros2 service info /controller_manager/switch_controller ## See also - [Reference → Messages](./messages.md) — full field schemas for the - custom `bar_msgs` types. + custom `humanoid_control_msgs` types. - [Reference → Quick reference](./quick_reference.md) — common `ros2 topic echo` / `ros2 topic hz` invocations. - [Concepts → Safety pipeline](../concepts/safety_pipeline.md) — what diff --git a/docs/reference/troubleshooting.md b/docs/reference/troubleshooting.md index 95222a3..9a60890 100644 --- a/docs/reference/troubleshooting.md +++ b/docs/reference/troubleshooting.md @@ -53,7 +53,7 @@ the plugin's seeing from URDF. - You hand-edited the YAML and broke a key. **Fix**: open the file, compare keys against -`bar_lite_controllers.yaml`'s `joints:` list. They must match +`humanoid_control_lite_controllers.yaml`'s `joints:` list. They must match character-for-character. Or regenerate the file via [Calibrate the zero pose](../how_to/calibrate_zero_pose.md) — the output uses live URDF names. @@ -73,7 +73,7 @@ hard-fails when the resolved `joy_dev` path is missing. `joy_dev:=/dev/input/jsN` (matching one of them) on the launch command line. 3. **Headless / CI bringup.** Pass `enable_gamepad:=false` and drive - the FSM via the `/bar/mode/*` `std_srvs/Trigger` services + the FSM via the `/humanoid_control/mode/*` `std_srvs/Trigger` services instead. ## ENOBUFS / "Network is down" warnings during bringup @@ -90,7 +90,7 @@ hardware adapter overload at very high frame rates. the USB-to-CAN adapter. 3. **High-rate overload** — only relevant with many joints + tight update_rate. Lower `controller_manager.update_rate` in - `bar_lite_controllers.yaml`, or bump `sudo ip link set canN + `humanoid_control_lite_controllers.yaml`, or bump `sudo ip link set canN txqueuelen 100` (default 10). Full walk: [Diagnose ENOBUFS](../how_to/diagnose_enobufs.md). @@ -141,8 +141,8 @@ xacro). entirely, the hardware plugin probably threw during `on_init` / `on_configure` and took the process down. Common causes: - URDF expansion failed (run `xacro ` directly to see the error). -- `bar_robstride` was rebuilt with an ABI-incompatible bump but - the .so wasn't reinstalled. `colcon build --symlink-install --packages-select bar_robstride`. +- `humanoid_control_robstride` was rebuilt with an ABI-incompatible bump but + the .so wasn't reinstalled. `colcon build --symlink-install --packages-select humanoid_control_robstride`. ## DDS discovery fails between launches and `ros2 topic ...` diff --git a/docs/reference/urdf_args.md b/docs/reference/urdf_args.md index 59c5277..6836771 100644 --- a/docs/reference/urdf_args.md +++ b/docs/reference/urdf_args.md @@ -37,7 +37,7 @@ The xacro selects between three plugin paths based on these: ``` use_sim:=true -> mujoco_ros2_control/MujocoSystem use_fake_hardware:=true (use_sim:=false) -> mock_components/GenericSystem -(both false) -> bar_robstride/RobstrideSystem +(both false) -> humanoid_control_robstride/RobstrideSystem ``` `use_sim` wins over `use_fake_hardware` — same precedence as the @@ -51,7 +51,7 @@ blocks: ```xml - bar_robstride/RobstrideSystem + humanoid_control_robstride/RobstrideSystem ${can_interface_left} ${calibration_file} @@ -60,7 +60,7 @@ blocks: - bar_robstride/RobstrideSystem + humanoid_control_robstride/RobstrideSystem ${can_interface_right} ${calibration_file} @@ -150,7 +150,7 @@ harness): Run these inside `pixi shell` (so `xacro` / `ros2 pkg` are on PATH): ```bash -cd bar_ws && pixi shell +cd humanoid_control_ws && pixi shell # Mock / RViz path xacro $(ros2 pkg prefix lite_description)/share/lite_description/robots/lite_dummy/xacro/lite_dummy.urdf.xacro \ diff --git a/docs/tutorials/build_your_own_controller.md b/docs/tutorials/build_your_own_controller.md index 700e34b..c9516a0 100644 --- a/docs/tutorials/build_your_own_controller.md +++ b/docs/tutorials/build_your_own_controller.md @@ -6,7 +6,7 @@ sidebar_position: 5 # Tutorial: Build your own controller plugin Walk through the pieces of a `controller_interface::ControllerInterface` -plugin by building one yourself. We'll create `bar::HelloController`, +plugin by building one yourself. We'll create `humanoid_control::HelloController`, a minimal-but-real plugin that claims one joint's `position` command interface and writes a sinusoidal target. By the end you'll know: @@ -16,7 +16,7 @@ interface and writes a sinusoidal target. By the end you'll know: - How interface claiming works. - How to load and activate your controller from the running stack. -This is **the** lesson for understanding why `bar_controllers` looks +This is **the** lesson for understanding why `humanoid_controllers` looks the way it does. ## Time + materials @@ -28,21 +28,21 @@ the way it does. ## The plan -We'll add a new controller to `bar_controllers` (rather than a new +We'll add a new controller to `humanoid_controllers` (rather than a new package, to skip the boilerplate). Five files change: | File | What we do | |---|---| -| `bar_controllers/include/bar_controllers/hello_controller.hpp` | New header — class definition | -| `bar_controllers/src/hello_controller.cpp` | New source — lifecycle bodies | -| `bar_controllers/bar_controllers_plugins.xml` | Register the new class with pluginlib | -| `bar_controllers/CMakeLists.txt` | Add the `.cpp` to the library | -| `bar_controllers/config/hello_controller.yaml` | Parameters at load time | +| `humanoid_controllers/include/humanoid_controllers/hello_controller.hpp` | New header — class definition | +| `humanoid_controllers/src/hello_controller.cpp` | New source — lifecycle bodies | +| `humanoid_controllers/humanoid_control_controllers_plugins.xml` | Register the new class with pluginlib | +| `humanoid_controllers/CMakeLists.txt` | Add the `.cpp` to the library | +| `humanoid_controllers/config/hello_controller.yaml` | Parameters at load time | ## Step 1 — Header ```cpp -// bar_controllers/include/bar_controllers/hello_controller.hpp +// humanoid_controllers/include/humanoid_controllers/hello_controller.hpp #pragma once #include @@ -51,7 +51,7 @@ package, to skip the boilerplate). Five files change: #include #include -namespace bar +namespace humanoid_control { // Demo controller for the "build your own" tutorial. Claims one joint's @@ -82,21 +82,21 @@ private: rclcpp::Time activate_time_; }; -} // namespace bar +} // namespace humanoid_control ``` ## Step 2 — Source ```cpp -// bar_controllers/src/hello_controller.cpp -#include "bar_controllers/hello_controller.hpp" +// humanoid_controllers/src/hello_controller.cpp +#include "humanoid_controllers/hello_controller.hpp" #include #include -#include "bar_common/loaned_interface_helpers.hpp" +#include "humanoid_control_common/loaned_interface_helpers.hpp" -namespace bar +namespace humanoid_control { using controller_interface::CallbackReturn; @@ -137,7 +137,7 @@ CallbackReturn HelloController::on_activate(const rclcpp_lifecycle::State &) { // on_activate: command interfaces are bound now. Capture initial state // so we have a baseline. - captured_position_ = bar::get_state(state_interfaces_[0]); + captured_position_ = humanoid_control::get_state(state_interfaces_[0]); activate_time_ = get_node()->now(); return CallbackReturn::SUCCESS; } @@ -168,23 +168,23 @@ return_type HelloController::update( const double t = (time - activate_time_).seconds(); const double target = captured_position_ + amplitude_ * std::sin(2.0 * M_PI * frequency_ * t); - bar::set_cmd(command_interfaces_[0], target); + humanoid_control::set_cmd(command_interfaces_[0], target); return return_type::OK; } -} // namespace bar +} // namespace humanoid_control -PLUGINLIB_EXPORT_CLASS(bar::HelloController, controller_interface::ControllerInterface) +PLUGINLIB_EXPORT_CLASS(humanoid_control::HelloController, controller_interface::ControllerInterface) ``` ## Step 3 — Register with pluginlib -Add to `bar_controllers/bar_controllers_plugins.xml`: +Add to `humanoid_controllers/humanoid_control_controllers_plugins.xml`: ```xml Demo controller: sin-wave around the joint's captured starting position. Used by docs/tutorials/build_your_own_controller. @@ -193,7 +193,7 @@ Add to `bar_controllers/bar_controllers_plugins.xml`: ## Step 4 — CMakeLists Add the new source to the existing library in -`bar_controllers/CMakeLists.txt`: +`humanoid_controllers/CMakeLists.txt`: ```cmake add_library(${PROJECT_NAME} SHARED @@ -210,9 +210,9 @@ add_library(${PROJECT_NAME} SHARED ## Step 5 — Build ```bash -cd ~/bar_ws +cd ~/humanoid_control_ws pixi shell -colcon build --symlink-install --packages-select bar_controllers +colcon build --symlink-install --packages-select humanoid_controllers ``` If the build fails: @@ -224,14 +224,14 @@ Verify pluginlib sees the new controller: ```bash ros2 control list_controller_types | grep Hello -# bar/HelloController controller_interface::ControllerInterface +# humanoid_control/HelloController controller_interface::ControllerInterface ``` ## Step 6 — Run it ```bash # Bring up Lite with the FSM disabled so we can hand-load: -ros2 launch bar_bringup_lite mujoco.launch.py enable_mode_manager:=false +ros2 launch humanoid_control_bringup_lite mujoco.launch.py enable_mode_manager:=false ``` In another terminal, load the controller via the CLI (inside @@ -257,7 +257,7 @@ Confirm it's loaded: ```bash ros2 control list_controllers -# hello_controller bar/HelloController inactive +# hello_controller humanoid_control/HelloController inactive ``` Now activate it — but first deactivate `zero_torque_controller` so @@ -289,19 +289,19 @@ Then `Ctrl+C` the launch. | Pluginlib registration | XML descriptor + `PLUGINLIB_EXPORT_CLASS` macro + CMake reference | | Lifecycle | `on_init` (declare params) → `on_configure` (read params, set up) → `on_activate` (capture state) → `update` (hot path) | | Interface claiming | Returned from `command_interface_configuration()` and `state_interface_configuration()` | -| State reading | `bar::get_state(state_interfaces_[i])` | -| Command writing | `bar::set_cmd(command_interfaces_[i], value)` | +| State reading | `humanoid_control::get_state(state_interfaces_[i])` | +| Command writing | `humanoid_control::set_cmd(command_interfaces_[i], value)` | | Mutual exclusion | Only one controller can claim a given interface — the controller_manager enforces this on `switch_controllers` | ## Where the existing controllers extend this pattern | Controller | Distinct mechanism worth studying | |---|---| -| `bar/ZeroTorqueController` | The minimal case — claims all 5 MIT interfaces, writes 0. Best baseline. | -| `bar/DampingController` | Captures state on activate; uses a YAML per-joint or scalar fallback. | -| `bar/StandbyController` | Multi-segment trajectory with K_p / K_d ramp; publishes its own state topic. | -| `bar/RLPolicyController` | The in-process System 0 policy: preloads a `.mcap` motion reference and runs ONNX inference inside `update()`; observation packing + action mapping, all RT-safe. | -| `bar/RemotePolicyController` | The System 1/2 external-command ingress: subscribes to an `MITCommand` topic; `RealtimeBuffer` for the RT handoff; arrival-time-based stale-command policy. | +| `humanoid_control/ZeroTorqueController` | The minimal case — claims all 5 MIT interfaces, writes 0. Best baseline. | +| `humanoid_control/DampingController` | Captures state on activate; uses a YAML per-joint or scalar fallback. | +| `humanoid_control/StandbyController` | Multi-segment trajectory with K_p / K_d ramp; publishes its own state topic. | +| `humanoid_control/RLPolicyController` | The in-process System 0 policy: preloads a `.mcap` motion reference and runs ONNX inference inside `update()`; observation packing + action mapping, all RT-safe. | +| `humanoid_control/RemotePolicyController` | The System 1/2 external-command ingress: subscribes to an `MITCommand` topic; `RealtimeBuffer` for the RT handoff; arrival-time-based stale-command policy. | Read those in order — the complexity ramps up. @@ -309,6 +309,6 @@ Read those in order — the complexity ramps up. - [`ControllerInterface` API docs](https://control.ros.org/master/doc/api/classcontroller__interface_1_1ControllerInterface.html). - [Reference → Controllers](../reference/controllers.md) — per-plugin parameters. -- [`bar_common/loaned_interface_helpers.hpp`](https://github.com/T-K-233/bar_ros2/blob/main/bar_common/include/bar_common/loaned_interface_helpers.hpp) +- [`humanoid_control_common/loaned_interface_helpers.hpp`](https://github.com/Berkeley-Humanoids/humanoid_control/blob/main/humanoid_control_common/include/humanoid_control_common/loaned_interface_helpers.hpp) — what `get_state` / `set_cmd` actually do (they wrap Jazzy's `[[nodiscard]]` migration helpers). diff --git a/docs/tutorials/drive_one_robstride.md b/docs/tutorials/drive_one_robstride.md index b150482..c649ae1 100644 --- a/docs/tutorials/drive_one_robstride.md +++ b/docs/tutorials/drive_one_robstride.md @@ -11,7 +11,7 @@ You'll wire one actuator to one CAN bus, bring up a minimal By the end you'll have hands-on familiarity with: - The Robstride wire protocol (via `robstride_ping`). -- The `bar_robstride/RobstrideSystem` lifecycle. +- The `humanoid_control_robstride/RobstrideSystem` lifecycle. - The 5-interface MIT command surface. - How calibration plays into the command-to-encoder transform. @@ -55,9 +55,9 @@ ip -d link show can0 ## Step 3 — Ping the motor ```bash -cd bar_ws +cd humanoid_control_ws pixi shell -bar bus ping --iface can0 --id +hc bus ping --iface can0 --id # TX GetDeviceId id=... # RX GetDeviceId reply device= uid=... # stats: rx=1 tx=1 rx_dropped=0 tx_failed=0 @@ -68,7 +68,7 @@ on new Robstride; vendor tool to reassign). If you don't know the ID, scan: ```bash -bar bus discover --iface can0 --scan-to 127 +hc bus discover --iface can0 --scan-to 127 ``` A clean reply confirms three things: the bus is up, the motor is @@ -78,7 +78,7 @@ Enabled the motor yet — `GetDeviceId` is read-only. ## Step 4 — Read live status (still read-only) ```bash -bar bus ping --iface can0 --id --read-status +hc bus ping --iface can0 --id --read-status # RX OperationStatus device= pos= ... rad vel= 0.0 torque= 0.0 temp= ... C fault_bits=0x00 ``` @@ -90,16 +90,16 @@ re-ping, `pos` should change correspondingly. ## Step 5 — Launch the single-motor test stack -`bar_robstride` ships a self-contained launch for this: +`humanoid_control_robstride` ships a self-contained launch for this: ```bash -ros2 launch bar_robstride single_robstride_gui.launch.py \ +ros2 launch humanoid_control_robstride single_robstride_gui.launch.py \ can_id:= ``` This brings up: - A 1-joint URDF describing your motor (`single_robstride_test`). -- `ros2_control_node` loading `bar_robstride/RobstrideSystem`. +- `ros2_control_node` loading `humanoid_control_robstride/RobstrideSystem`. - `joint_state_broadcaster` (active). - `zero_torque_controller` (active — safe). - `forward_mit_controller` (loaded **inactive**). @@ -107,7 +107,7 @@ This brings up: Verify in a second terminal: ```bash -cd bar_ws +cd humanoid_control_ws pixi shell ros2 topic echo --once /joint_states # name: ['actuator_1'] @@ -121,7 +121,7 @@ ros2 control list_controllers ## Step 6 — Slider GUI ```bash -bar motor slider +hc motor slider ``` A Qt window with five sliders (position, velocity, effort, kp, kd) @@ -184,8 +184,8 @@ sudo ip link add dev vcan0 type vcan sudo ip link set up vcan0 ``` -Then run the same `bar bus ping --iface vcan0` and -`bar bus discover --iface vcan0`. You won't get replies +Then run the same `hc bus ping --iface vcan0` and +`hc bus discover --iface vcan0`. You won't get replies (nothing's listening), but the TX path lights up and you can see your own frames with `candump vcan0`. The single-motor launch will boot but report `RX_TIMEOUT` in `/safety_status`. diff --git a/docs/tutorials/index.md b/docs/tutorials/index.md index 182c895..aadffab 100644 --- a/docs/tutorials/index.md +++ b/docs/tutorials/index.md @@ -19,9 +19,9 @@ and [Lite 101](../getting_started/lite_101.md) lesson, nothing more. |---|---|---| | 1 | [Drive one Robstride end-to-end](./drive_one_robstride.md) | A single motor moving under our plugin, on bench hardware. Familiarity with the CAN bus, the MIT command surface, and the calibration math. | | 2 | [MuJoCo + full FSM walkthrough](./mujoco_fsm_walk.md) | The whole five-mode FSM exercised in sim, with the gamepad. Comfort with `mode_manager` intents and the standby pose. | -| 3 | [Run a tracking policy](./tracking_policy.md) | A trained tracking ONNX policy driving the arms in sim. Familiarity with the `bar_policy` runner, the self-describing ONNX metadata, and the LeRobot dataset path. | +| 3 | [Run a tracking policy](./tracking_policy.md) | A trained tracking ONNX policy driving the arms in sim. Familiarity with the `humanoid_control_policy` runner, the self-describing ONNX metadata, and the LeRobot dataset path. | | 4 | [Run the gravity-compensation demo](./run_gravity_compensation.md) | The Lite arms holding against gravity, driven by a host-side Python loop over DDS. Familiarity with the Tier-3 external-client path, the REMOTE FSM mode, and `RemotePolicyController`. | -| 5 | [Build your own controller plugin](./build_your_own_controller.md) | A skeleton `bar/MyController` plugin loaded by the controller_manager. Familiarity with the `pluginlib` machinery and the `ControllerInterface` lifecycle. | +| 5 | [Build your own controller plugin](./build_your_own_controller.md) | A skeleton `humanoid_control/MyController` plugin loaded by the controller_manager. Familiarity with the `pluginlib` machinery and the `ControllerInterface` lifecycle. | :::tip[Tutorial vs how-to] A tutorial **teaches** — it gives you confidence and a mental model. A diff --git a/docs/tutorials/mujoco_fsm_walk.md b/docs/tutorials/mujoco_fsm_walk.md index d0e172b..4900780 100644 --- a/docs/tutorials/mujoco_fsm_walk.md +++ b/docs/tutorials/mujoco_fsm_walk.md @@ -34,7 +34,7 @@ ls /dev/input/js0 Quick test that `joy_node` will be happy (inside `pixi shell`): ```bash -cd bar_ws && pixi shell +cd humanoid_control_ws && pixi shell ros2 run joy joy_node & ros2 topic echo --once /joy # Should print a Joy message with buttons[] and axes[] arrays. @@ -47,7 +47,7 @@ If `joy_node` errors with permissions, your user isn't in the ## Step 1 — Launch with the gamepad ```bash -ros2 launch bar_bringup_lite mujoco.launch.py +ros2 launch humanoid_control_bringup_lite mujoco.launch.py # `enable_gamepad:=true` is already the default; the launch hard-fails # if no joystick is detected. Pass enable_gamepad:=false to bypass. ``` @@ -57,13 +57,13 @@ Two windows / processes come up: - `joy_node` reading `/dev/input/js0`. For an extra live URDF view, open a second terminal and run -`ros2 run bar_bringup_lite rerun_viz` or -`ros2 run bar_bringup_lite viser_viz`. +`ros2 run humanoid_control_bringup_lite rerun_viz` or +`ros2 run humanoid_control_bringup_lite viser_viz`. In a second terminal: ```bash -cd bar_ws +cd humanoid_control_ws pixi shell ros2 control list_controllers # zero_torque_controller active @@ -164,7 +164,7 @@ listening: ```bash ros2 topic pub --once /remote_policy_controller/command \ - bar_msgs/msg/MITCommand \ + humanoid_control_msgs/msg/MITCommand \ "{header: {stamp: now}, joint_names: ['left_shoulder_pitch', 'left_shoulder_roll', 'left_shoulder_yaw', 'left_elbow_pitch', 'left_wrist_yaw', 'left_wrist_roll', 'left_wrist_pitch', diff --git a/docs/tutorials/run_gravity_compensation.md b/docs/tutorials/run_gravity_compensation.md index c3ea589..37bfa8e 100644 --- a/docs/tutorials/run_gravity_compensation.md +++ b/docs/tutorials/run_gravity_compensation.md @@ -14,7 +14,7 @@ gravity-compensation loop that reads joint states and publishes and the difference between the torque-mode and PD-mode gravity loops. This is the worked, end-to-end companion to -[How-to → Talk to bar_ros2 from Python](../how_to/talk_to_bar_ros2_from_python.md): +[How-to → Talk to humanoid_control from Python](../how_to/talk_to_humanoid_control_from_python.md): that page is the recipe, this is the lesson. ## Time + materials @@ -22,7 +22,7 @@ that page is the recipe, this is the lesson. - 20 minutes - A working workspace build (the bringup side) - The [`Lite-Gravity-Compensation`](https://github.com/Berkeley-Humanoids/Lite-Gravity-Compensation) - demo, checked out **anywhere outside `bar_ws`** (it's a standalone + demo, checked out **anywhere outside `humanoid_control_ws`** (it's a standalone Tier-3 project with its own `uv` environment — it only needs to reach the robot's DDS bus, not the colcon workspace) - [`uv`](https://docs.astral.sh/uv/) on PATH for the demo's own env @@ -32,12 +32,12 @@ that page is the recipe, this is the lesson. The gravity-comp runner is **not** a controller and **not** a ROS node. It's an ordinary Python process that joins the same DDS network the -bringup uses. The in-process `bar::RemotePolicyController` is the only +bringup uses. The in-process `humanoid_control::RemotePolicyController` is the only thing that touches the command interfaces; the external loop just feeds it `MITCommand`s: ``` - host-side process (pure pip, no rclpy) bar_ros2 bringup (System 0, RT) + host-side process (pure pip, no rclpy) humanoid_control bringup (System 0, RT) ┌───────────────────────────────┐ ┌──────────────────────────────┐ │ run_ros2_torque.py │ │ joint_state_broadcaster │ │ each tick @ COMMAND_HZ: │ rt/lite/ │ publishes /lite/joint_states│ @@ -75,8 +75,8 @@ uv sync ``` `uv sync` resolves the two host-side packages straight from their git -repos — [`lite_sdk2`](../reference/packages.md#bar_msgs_dds) (the -publisher/subscriber + QoS registry) and `bar_msgs_dds` (the +repos — [`lite_sdk2`](../reference/packages.md#humanoid_control_msgs_dds) (the +publisher/subscriber + QoS registry) and `humanoid_control_msgs_dds` (the ROS-wire-compatible CycloneDDS message types, pulled in transitively). Nothing here links against `rclpy`. @@ -86,7 +86,7 @@ the three rmw conventions — the `rt/` topic prefix, the `pkg::msg::dds_::Name_` type-name mangling, and RELIABLE/KEEP_LAST QoS — so `cyclonedds-python` pairs directly with `rmw_cyclonedds_cpp` *or* `rmw_fastrtps_cpp` on the bringup. See -[How-to → Talk to bar_ros2 from Python](../how_to/talk_to_bar_ros2_from_python.md). +[How-to → Talk to humanoid_control from Python](../how_to/talk_to_humanoid_control_from_python.md). ::: ## Step 2 — Bring up the stack @@ -94,8 +94,8 @@ so `cyclonedds-python` pairs directly with `rmw_cyclonedds_cpp` *or* In the **bringup** terminal (inside `pixi shell`), start MuJoCo: ```bash -cd bar_ws && pixi shell -ros2 launch bar_bringup_lite mujoco.launch.py +cd humanoid_control_ws && pixi shell +ros2 launch humanoid_control_bringup_lite mujoco.launch.py ``` Wait for `zero_torque_controller` to come active. (For real hardware, @@ -109,14 +109,14 @@ transitions through `mode_manager`'s trigger services (in a second terminal, inside `pixi shell`): ```bash -ros2 service call /bar/mode/damp std_srvs/srv/Trigger # → DAMPING (gamepad: X) -ros2 service call /bar/mode/load std_srvs/srv/Trigger # → STANDBY (gamepad: L1+A) +ros2 service call /humanoid_control/mode/damp std_srvs/srv/Trigger # → DAMPING (gamepad: X) +ros2 service call /humanoid_control/mode/load std_srvs/srv/Trigger # → STANDBY (gamepad: L1+A) # Wait until the standby ramp reports finished: ros2 topic echo /standby_controller/state # ... is_finished: true -ros2 service call /bar/mode/start_remote std_srvs/srv/Trigger # → REMOTE (gamepad: R1+B) +ros2 service call /humanoid_control/mode/start_remote std_srvs/srv/Trigger # → REMOTE (gamepad: R1+B) ``` :::caution[`start_remote` is R1+B, not R1+A] @@ -173,7 +173,7 @@ PD mode encodes the same gravity term as a **position offset** (`K=PD_POSITION_KP`, `D=PD_VELOCITY_KD`). The arm feels stiffer and self-centering rather than free-floating. Both publish in `LITE_ARM_JOINTS` order (the `arm_joints` list in -`bar_bringup_lite/config/lite_hardware.yaml`); `RemotePolicyController` +`humanoid_control_bringup_lite/config/lite_hardware.yaml`); `RemotePolicyController` rejects a joint-order mismatch. :::tip[No bringup, no robot] @@ -194,7 +194,7 @@ damping. For a deliberate stop, drive the FSM back down first: ```bash -ros2 service call /bar/mode/damp std_srvs/srv/Trigger # gamepad: X +ros2 service call /humanoid_control/mode/damp std_srvs/srv/Trigger # gamepad: X ``` Then Ctrl-C the runner, then the bringup launch. @@ -203,8 +203,8 @@ Then Ctrl-C the runner, then the bringup launch. | Skill | Page where it's documented in detail | |---|---| -| The Tier-3 external-client (no-`rclpy`) DDS path | [How-to → Talk to bar_ros2 from Python](../how_to/talk_to_bar_ros2_from_python.md) | -| `lite_sdk2` / `bar_msgs_dds` topic + QoS registry | [Reference → Packages](../reference/packages.md#bar_msgs_dds) | +| The Tier-3 external-client (no-`rclpy`) DDS path | [How-to → Talk to humanoid_control from Python](../how_to/talk_to_humanoid_control_from_python.md) | +| `lite_sdk2` / `humanoid_control_msgs_dds` topic + QoS registry | [Reference → Packages](../reference/packages.md#humanoid_control_msgs_dds) | | The REMOTE mode + `start_remote` transition | [Concepts → Five-mode FSM](../concepts/five_mode_fsm.md) | | `RemotePolicyController` and the MIT command write | [Reference → Controllers](../reference/controllers.md) | | The five MIT command interfaces (torque vs PD encoding) | [Concepts → MIT command surface](../concepts/mit_command_surface.md) | diff --git a/docs/tutorials/tracking_policy.md b/docs/tutorials/tracking_policy.md index 76125f2..19f6542 100644 --- a/docs/tutorials/tracking_policy.md +++ b/docs/tutorials/tracking_policy.md @@ -6,7 +6,7 @@ sidebar_position: 3 # Tutorial: Run a tracking policy End-to-end: take a trained ONNX tracking policy, load it into the -**in-process** `bar::RLPolicyController` (this stack is the **System 0** +**in-process** `humanoid_control::RLPolicyController` (this stack is the **System 0** real-time layer), and watch the arms follow a LeRobot teleop dataset under MuJoCo physics. By the end you'll know what the launch-time `prepare` step produces, how the ONNX metadata schema makes everything @@ -33,7 +33,7 @@ inside the RT cycle: ``` launch-time, once: ┌──────────────────────┐ - │ bar_policy prepare │ (CLI, bar_policy — non-real-time) + │ humanoid_control_policy prepare │ (CLI, humanoid_control_policy — non-real-time) │ - resolve ONNX │ │ (local / W&B) │ │ - LeRobot motion │ @@ -45,7 +45,7 @@ inside the RT cycle: │ rl_policy_params.yaml (+ .onnx + .mcap) ▼ ┌──────────────────────┐ - │ RLPolicyController │ (C++, bar_controllers — System 0, in-process) + │ RLPolicyController │ (C++, humanoid_controllers — System 0, in-process) │ each RT tick: │ │ - pack observation │ │ - run ONNX inference│ @@ -75,7 +75,7 @@ any of this into YAML. The same launch as the previous tutorial, no gamepad needed: ```bash -ros2 launch bar_bringup_lite mujoco.launch.py +ros2 launch humanoid_control_bringup_lite mujoco.launch.py ``` Wait for `zero_torque_controller` to come active. @@ -86,7 +86,7 @@ Wait for `zero_torque_controller` to come active. Walk the FSM up to STANDBY. In a second terminal, drop into the env: ```bash -cd bar_ws +cd humanoid_control_ws pixi shell ``` @@ -98,8 +98,8 @@ transitions the gamepad would fire): # X → DAMP # L1+A → LOAD (STANDBY); wait ~4 s for is_finished:true # -ros2 service call /bar/mode/damp std_srvs/srv/Trigger -ros2 service call /bar/mode/load std_srvs/srv/Trigger +ros2 service call /humanoid_control/mode/damp std_srvs/srv/Trigger +ros2 service call /humanoid_control/mode/load std_srvs/srv/Trigger # Wait for is_finished: ros2 topic echo /standby_controller/state @@ -112,15 +112,15 @@ In a third terminal: ```bash # Option (a): local ONNX -ros2 launch bar_policy lite_policy.launch.py \ +ros2 launch humanoid_control_policy lite_policy.launch.py \ checkpoint_file:=/path/to/policy.onnx -# Option (b): W&B run path (downloads + caches to ~/.cache/bar_policy/wandb/) -ros2 launch bar_policy lite_policy.launch.py \ +# Option (b): W&B run path (downloads + caches to ~/.cache/humanoid_control_policy/wandb/) +ros2 launch humanoid_control_policy lite_policy.launch.py \ wandb_run_path:=IsaacLab-Training/mjlab/ # Option (c): W&B run with a specific checkpoint pinned -ros2 launch bar_policy lite_policy.launch.py \ +ros2 launch humanoid_control_policy lite_policy.launch.py \ wandb_run_path:=IsaacLab-Training/mjlab/ \ wandb_checkpoint_name:=model_4000.onnx ``` @@ -131,7 +131,7 @@ pass-through alias for the `launch-policy-tracking` pixi task.) What happens behind the scenes: -1. The launch runs `bar_policy prepare` **synchronously** as a one-shot +1. The launch runs `humanoid_control_policy prepare` **synchronously** as a one-shot step (no long-lived Python node), which: - resolves the checkpoint to a local file via `checkpoint_loader.resolve_checkpoint` (downloading from W&B if @@ -140,8 +140,8 @@ What happens behind the scenes: ``` [prepare] checkpoint : /path/to/policy.onnx [prepare] task_type : tracking - [prepare] motion bag : ~/.cache/bar_policy/launch/motion_tracking_ep0 (240 frames, 2 bodies) - [prepare] overlay : ~/.cache/bar_policy/launch/rl_policy_params.yaml + [prepare] motion bag : ~/.cache/humanoid_control_policy/launch/motion_tracking_ep0 (240 frames, 2 bodies) + [prepare] overlay : ~/.cache/humanoid_control_policy/launch/rl_policy_params.yaml ``` - pulls the LeRobot reference motion (parquet shards from HF Hub) keyed off `episode_index` and converts the chosen episode into a @@ -164,7 +164,7 @@ activate the policy through the FSM (in the FSM-walk terminal, inside `pixi shell`): ```bash -ros2 service call /bar/mode/start_locomotion std_srvs/srv/Trigger +ros2 service call /humanoid_control/mode/start_locomotion std_srvs/srv/Trigger ``` (Gamepad equivalent: **R1 + A**.) `mode_manager` switches the active @@ -202,7 +202,7 @@ and the command write all happen inside the RT `update()`. DAMP first, then exit (still in the `pixi shell` terminal): ```bash -ros2 service call /bar/mode/damp std_srvs/srv/Trigger +ros2 service call /humanoid_control/mode/damp std_srvs/srv/Trigger # Then Ctrl+C the policy launch, then the bringup launch. ``` diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 56414df..eb4ed11 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -4,16 +4,16 @@ import type * as Preset from '@docusaurus/preset-classic'; // https://docusaurus.io/docs/api/docusaurus-config const config: Config = { - title: 'bar_ros2', - tagline: 'BAR humanoid low-level control stack', + title: 'humanoid_control', + tagline: 'humanoid_control low-level control stack', favicon: 'img/logo.svg', // Production URL for GitHub Pages project site. - url: 'https://t-k-233.github.io', - baseUrl: '/BAR-ROS2-Docs/', + url: 'https://berkeley-humanoids.github.io', + baseUrl: '/Humanoid-Control-Website/', - organizationName: 'T-K-233', - projectName: 'BAR-ROS2-Docs', + organizationName: 'Berkeley-Humanoids', + projectName: 'Humanoid-Control-Website', trailingSlash: false, // Fail the build on broken internal links — same policy as VitePress. @@ -32,7 +32,7 @@ const config: Config = { docs: { sidebarPath: './sidebars.ts', editUrl: - 'https://github.com/T-K-233/bar_ros2_docs/tree/main/', + 'https://github.com/Berkeley-Humanoids/Humanoid-Control-Website/tree/main/', routeBasePath: '/', }, blog: false, @@ -50,7 +50,7 @@ const config: Config = { respectPrefersColorScheme: true, }, navbar: { - title: 'bar_ros2', + title: 'humanoid_control', logo: { alt: 'BAR humanoid logo', src: 'img/logo.svg', @@ -62,7 +62,7 @@ const config: Config = { {to: '/concepts/', label: 'Concepts', position: 'left'}, {to: '/reference/packages', label: 'Reference', position: 'left'}, { - href: 'https://github.com/T-K-233/bar_ros2', + href: 'https://github.com/Berkeley-Humanoids/humanoid_control', label: 'GitHub', position: 'right', }, @@ -100,8 +100,8 @@ const config: Config = { title: 'Project', items: [ { - label: 'bar_ros2 on GitHub', - href: 'https://github.com/T-K-233/bar_ros2', + label: 'humanoid_control on GitHub', + href: 'https://github.com/Berkeley-Humanoids/humanoid_control', }, { label: 'Berkeley Architecture Research', @@ -110,7 +110,7 @@ const config: Config = { ], }, ], - copyright: `Copyright © ${new Date().getFullYear()} BAR Dev. Built with Docusaurus. BSD-3-Clause.`, + copyright: `Copyright © ${new Date().getFullYear()} Humanoid Control Dev. Built with Docusaurus. BSD-3-Clause.`, }, prism: { theme: prismThemes.github, diff --git a/package-lock.json b/package-lock.json index 8dd5e68..bd437b7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "bar_ros2_docs", + "name": "humanoid-control-website", "version": "0.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "bar_ros2_docs", + "name": "humanoid-control-website", "version": "0.0.1", "license": "BSD-3-Clause", "dependencies": { diff --git a/package.json b/package.json index b3d363e..a3b2797 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { - "name": "bar_ros2_docs", + "name": "humanoid-control-website", "version": "0.0.1", "private": true, - "description": "Documentation site for bar_ros2 — the BAR humanoid low-level control stack.", + "description": "Documentation site for humanoid_control — the BAR humanoid low-level control stack.", "license": "BSD-3-Clause", "scripts": { "docusaurus": "docusaurus", diff --git a/scripts/draw_diagrams.py b/scripts/draw_diagrams.py index baf2278..01309e7 100644 --- a/scripts/draw_diagrams.py +++ b/scripts/draw_diagrams.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 """ -Hand-laid SVG diagrams for bar_ros2_docs. +Hand-laid SVG diagrams for Humanoid-Control-Website. Each diagram is a small function that returns an SVG string. Run this file to regenerate every diagram into ../static/img/diagrams/. The output @@ -252,22 +252,22 @@ def d_intro_01_system() -> None: s.append(Box(50, 100, 210, 50, "IDE / editor", fill=GOLD_FILL, stroke=GOLD).render()) s.append(Box(50, 170, 210, 70, - ["MuJoCo viewer", "(bar_bringup_lite/mujoco)"], + ["MuJoCo viewer", "(humanoid_control_bringup_lite/mujoco)"], fill=GOLD_FILL, stroke=GOLD).render()) s.append(text(155, 300, "Edits, sim runs, debug", size=11, fill=GREY, anchor="middle")) # Onboard - s.append(Box(340, 100, 220, 50, "bar_bringup_lite / launch", + s.append(Box(340, 100, 220, 50, "humanoid_control_bringup_lite / launch", fill=BLUE_FILL, stroke=BLUE).render()) s.append(Box(340, 170, 220, 60, "controller_manager (50 Hz)", fill=BLUE_FILL, stroke=BLUE).render()) s.append(Box(340, 250, 100, 50, "mode_manager", fill=BLUE_FILL, stroke=BLUE).render()) - s.append(Box(460, 250, 100, 50, "bar_policy", + s.append(Box(460, 250, 100, 50, "humanoid_control_policy", fill=GOLD_FILL, stroke=GOLD).render()) s.append(Box(340, 320, 220, 60, - ["bar_robstride", "(SocketCAN)"], + ["humanoid_control_robstride", "(SocketCAN)"], fill=GREEN_FILL, stroke=GREEN).render()) # Robot @@ -327,29 +327,29 @@ def pkg(x, y, name, sub=None, fill=BLUE_FILL, stroke=BLUE): fill=fill, stroke=stroke).render()) # Shared column - pkg(40, 90, "bar_common", "RT helpers, MITState POD") - pkg(40, 144, "bar_msgs", "MITCommand, ControlMode, ...") - pkg(40, 198, "bar_controllers", "5 mode-FSM + mode_manager") - pkg(40, 252, "bar_policy", "ONNX runner + LeRobot ref") - pkg(40, 306, "bar_socketcan", "SocketCAN bus library") + pkg(40, 90, "humanoid_control_common", "RT helpers, MITState POD") + pkg(40, 144, "humanoid_control_msgs", "MITCommand, ControlMode, ...") + pkg(40, 198, "humanoid_controllers", "5 mode-FSM + mode_manager") + pkg(40, 252, "humanoid_control_policy", "ONNX runner + LeRobot ref") + pkg(40, 306, "humanoid_control_socketcan", "SocketCAN bus library") # Lite column pkg(345, 110, "lite_description", "URDF + xacro + meshes", fill=GREEN_FILL, stroke=GREEN) - pkg(345, 180, "bar_robstride", "Robstride SystemInterface", + pkg(345, 180, "humanoid_control_robstride", "Robstride SystemInterface", fill=GREEN_FILL, stroke=GREEN) - pkg(345, 250, "bar_bringup_lite", "launch + controllers YAML", + pkg(345, 250, "humanoid_control_bringup_lite", "launch + controllers YAML", fill=GREEN_FILL, stroke=GREEN) # Prime column - pkg(645, 110, "bar_description_prime", "URDF + EtherCAT PDO", + pkg(645, 110, "humanoid_control_description_prime", "URDF + EtherCAT PDO", fill=RED_FILL, stroke=RED) - pkg(645, 180, "bar_sito", "Sito SystemInterface", + pkg(645, 180, "humanoid_control_sito", "Sito SystemInterface", fill=RED_FILL, stroke=RED) - pkg(645, 250, "bar_bringup_prime", "+ ethercat.yaml", + pkg(645, 250, "humanoid_control_bringup_prime", "+ ethercat.yaml", fill=RED_FILL, stroke=RED) - # Arrows: bar_robstride -> bar_socketcan + # Arrows: humanoid_control_robstride -> humanoid_control_socketcan s.append(arrow(345, 202, 290, 320, color=GREY)) s.append(arrow(645, 202, 290, 320, color=GREY)) # bringup_lite -> description_lite + hw_robstride + controllers + policy @@ -478,7 +478,7 @@ def d_hw_can_layout() -> None: s.append(arrow(590, 155, 640, 155, label="CAN @ 1 Mbit")) s.append(text(450, 310, - "On real hardware the bar_robstride plugin owns both buses; " + "On real hardware the humanoid_control_robstride plugin owns both buses; " "from the controller's perspective the 17 joints are one flat list.", size=11, anchor="middle", fill=GREY)) @@ -684,7 +684,7 @@ def d_sf_policy_tiers() -> None: s.append(group_box(24, 64, 300, 140, "Launch-time prepare (non-RT, Python)", fill=GOLD_FILL, stroke=GOLD)) s.append(Box(44, 104, 260, 80, - ["bar_policy / pianist_policy", "prepare"], + ["humanoid_control_policy / pianist_policy", "prepare"], sub="resolve ONNX -> .mcap + overlay", fill="white", stroke=GOLD).render()) @@ -749,7 +749,7 @@ def d_lite_mock_launch() -> None: W, H = 920, 540 s = [header(W, H)] s.append(title(20, 30, "MuJoCo bringup spawn sequence", - sub="What happens when you run `ros2 launch bar_bringup_lite mujoco.launch.py`")) + sub="What happens when you run `ros2 launch humanoid_control_bringup_lite mujoco.launch.py`")) lanes = [ ("launch", 100, GREY), @@ -877,7 +877,7 @@ def d_xacro_3way() -> None: s.append(arrow(460, 215, 490, 200, label="true")) # No -> real - s.append(Box(490, 280, 230, 60, "bar_robstride/", sub="RobstrideSystem", + s.append(Box(490, 280, 230, 60, "humanoid_control_robstride/", sub="RobstrideSystem", fill=RED_FILL, stroke=RED).render()) s.append(arrow(370, 240, 490, 305, label="false")) @@ -890,10 +890,10 @@ def d_xacro_3way() -> None: def d_msgs_pubsub() -> None: - """bar_msgs pub/sub topology.""" + """humanoid_control_msgs pub/sub topology.""" W, H = 920, 480 s = [header(W, H)] - s.append(title(20, 30, "bar_msgs pub/sub topology", + s.append(title(20, 30, "humanoid_control_msgs pub/sub topology", sub="Who publishes / who subscribes for each of the 4 active topics")) # 3 columns: publishers / topics / subscribers @@ -912,7 +912,7 @@ def pub(x, y, label, color=BLUE): pub(35, 160, "mode_manager", GOLD) pub(35, 220, "Hardware plugins", RED) pub(35, 280, "Active policy ctrls", BLUE) - pub(35, 340, "bar_policy (Python)", GOLD) + pub(35, 340, "humanoid_control_policy (Python)", GOLD) pub(350, 100, "/standby_controller/state", GREEN) pub(350, 160, "/control_mode", GREEN) @@ -930,7 +930,7 @@ def pub(x, y, label, color=BLUE): (130, 200, 350, 190), # mode_manager -> /control_mode (130, 270, 350, 250), # HW plugins -> /safety_status (130, 270, 350, 250), - (130, 380, 350, 310), # bar_policy -> ~/command + (130, 380, 350, 310), # humanoid_control_policy -> ~/command # topics -> subs (560, 130, 680, 130), # standby/state -> mode_manager (560, 190, 680, 190), # control_mode -> log @@ -964,36 +964,36 @@ def d_arch_module_deps() -> None: W, H = 980, 620 s = [header(W, H)] s.append(title(20, 30, "Module dependency graph", - sub="bar_* packages, build-time deps (solid) and pluginlib runtime deps (dashed)")) + sub="humanoid_control_* packages, build-time deps (solid) and pluginlib runtime deps (dashed)")) # Lane backgrounds (top -> bottom) s.append(group_box(40, 70, 720, 80, "Application / bringup")) s.append(group_box(40, 170, 720, 90, "Controllers + policies")) s.append(group_box(40, 280, 720, 90, "Hardware plugins + URDF")) - s.append(group_box(40, 400, 720, 90, "Foundations (no bar_* deps)")) + s.append(group_box(40, 400, 720, 90, "Foundations (no humanoid_control_* deps)")) s.append(group_box(790, 70, 170, 420, "External", fill="#FAFAFA")) # Application / bringup - s.append(Box(70, 95, 200, 40, "bar_bringup_lite", sub="launch + YAML", + s.append(Box(70, 95, 200, 40, "humanoid_control_bringup_lite", sub="launch + YAML", fill=BLUE_FILL, stroke=BLUE).render()) - s.append(Box(310, 95, 200, 40, "bar_bringup_prime", sub="(scaffold)", + s.append(Box(310, 95, 200, 40, "humanoid_control_bringup_prime", sub="(scaffold)", fill=BLUE_FILL, stroke=BLUE).render()) s.append(Box(550, 95, 190, 40, "pianist_policy", sub="piano key-state", fill=GOLD_FILL, stroke=GOLD).render()) # Controllers + policies - s.append(Box(70, 195, 200, 50, "bar_controllers", + s.append(Box(70, 195, 200, 50, "humanoid_controllers", sub="5 modes + mode_manager", fill=BLUE_FILL, stroke=BLUE).render()) - s.append(Box(310, 195, 200, 50, "bar_policy", + s.append(Box(310, 195, 200, 50, "humanoid_control_policy", sub="ONNX runner (Python)", fill=GOLD_FILL, stroke=GOLD).render()) # Hardware plugins + description - s.append(Box(70, 305, 200, 50, "bar_robstride", + s.append(Box(70, 305, 200, 50, "humanoid_control_robstride", sub="RobstrideSystem", fill=GREEN_FILL, stroke=GREEN).render()) - s.append(Box(310, 305, 200, 50, "bar_sito", + s.append(Box(310, 305, 200, 50, "humanoid_control_sito", sub="(stub)", fill=GREEN_FILL, stroke=GREEN).render()) s.append(Box(550, 305, 190, 50, "lite_description", @@ -1001,13 +1001,13 @@ def d_arch_module_deps() -> None: fill=GREY_FILL, stroke=GREY).render()) # Foundations - s.append(Box(70, 425, 200, 50, "bar_socketcan", + s.append(Box(70, 425, 200, 50, "humanoid_control_socketcan", sub="bus library + I/O thread", fill=GREEN_FILL, stroke=GREEN).render()) - s.append(Box(310, 425, 200, 50, "bar_msgs", + s.append(Box(310, 425, 200, 50, "humanoid_control_msgs", sub="MITCommand, ControlMode, ...", fill=GREY_FILL, stroke=GREY).render()) - s.append(Box(550, 425, 190, 50, "bar_common", + s.append(Box(550, 425, 190, 50, "humanoid_control_common", sub="MITState POD, RT helpers", fill=GREY_FILL, stroke=GREY).render()) @@ -1034,19 +1034,19 @@ def dep(x1, y1, x2, y2, dashed=False, color=GREY): dep(150, 135, 170, 305) # -> hw_robstride dep(210, 135, 600, 305) # -> description_lite dep(230, 135, 360, 425) # -> msgs (transitive but shown) - # pianist_policy -> bar_msgs only + # pianist_policy -> humanoid_control_msgs only dep(620, 135, 400, 425, color=GREY) - # bar_policy -> bar_msgs + bar_common + # humanoid_control_policy -> humanoid_control_msgs + humanoid_control_common dep(380, 245, 380, 425) dep(420, 245, 620, 425, color=GREY) - # bar_controllers -> bar_msgs + bar_common (and pluginlib loads them) + # humanoid_controllers -> humanoid_control_msgs + humanoid_control_common (and pluginlib loads them) dep(170, 245, 340, 425) dep(220, 245, 600, 425, color=GREY) - # hw_robstride -> hw_socketcan + bar_msgs + bar_common + # hw_robstride -> hw_socketcan + humanoid_control_msgs + humanoid_control_common dep(150, 355, 150, 425) dep(200, 355, 380, 425, color=GREY) dep(240, 355, 620, 425, color=GREY) - # hw_sito -> hw_socketcan + bar_msgs + # hw_sito -> hw_socketcan + humanoid_control_msgs dep(380, 355, 200, 425, color=GREY) dep(420, 355, 400, 425, color=GREY) @@ -1061,7 +1061,7 @@ def dep(x1, y1, x2, y2, dashed=False, color=GREY): s.append(text(60, 545, "Dashed arrow = runtime dep only (pluginlib)", size=11, anchor="start", fill=GREY)) s.append(text(60, 570, - "Note: bar_controllers does NOT find_package(bar_robstride) — " + "Note: humanoid_controllers does NOT find_package(humanoid_control_robstride) — " "the plugin is loaded by controller_manager at launch.", size=11, anchor="start", fill=GREY)) @@ -1267,13 +1267,13 @@ def fault(y, name, src): size=10, anchor="middle", fill=GREY)) # Level derivation (middle column) - s.append(Box(380, 110, 200, 40, "SafetyStatus", sub="bar_msgs", + s.append(Box(380, 110, 200, 40, "SafetyStatus", sub="humanoid_control_msgs", fill=GREY_FILL, stroke=GREY).render()) s.append(Box(380, 170, 200, 40, "level: OK / WARN / FAULT / CRITICAL", fill=GREY_FILL, stroke=GREY).render()) s.append(Box(380, 230, 200, 40, "flags: uint32 bit mask", fill=GREY_FILL, stroke=GREY).render()) - s.append(Box(380, 290, 200, 40, "source: 'bar_robstride/can0'", + s.append(Box(380, 290, 200, 40, "source: 'humanoid_control_robstride/can0'", fill=GREY_FILL, stroke=GREY).render()) s.append(Box(380, 360, 200, 50, ["/safety_status", "(TRANSIENT_LOCAL)"], @@ -1400,10 +1400,10 @@ def d_frozen_schemas() -> None: s.append(group_box(460, 70, 420, 380, "Who locks in when you ship")) rows = [ - ("bar_msgs/MITCommand", + ("humanoid_control_msgs/MITCommand", "fields name + order", ["RemotePolicyController (subscriber)", - "bar_policy.ActionMapper (publisher)", + "humanoid_control_policy.ActionMapper (publisher)", "every trained ONNX (action_joint_names)"]), ("Joint order in YAML", "controllers.yaml `joints:` list", diff --git a/sidebars.ts b/sidebars.ts index 648cf3a..8893677 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -52,7 +52,7 @@ const sidebars: SidebarsConfig = { 'how_to/diagnose_enobufs', 'how_to/recover_from_fault', 'how_to/promote_python_to_cpp', - 'how_to/talk_to_bar_ros2_from_python', + 'how_to/talk_to_humanoid_control_from_python', 'how_to/add_new_joint', 'how_to/use_pixi_tasks', ], diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 693e7f9..db34d50 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -40,7 +40,7 @@ function HomepageHeader() { + href="https://github.com/Berkeley-Humanoids/humanoid_control"> GitHub @@ -54,7 +54,7 @@ export default function Home(): ReactNode { return ( + description="Docs for humanoid_control, the BAR humanoid low-level control stack.">
diff --git a/static/img/diagrams/concepts__architecture__02_policy_tiers.svg b/static/img/diagrams/concepts__architecture__02_policy_tiers.svg index ffa5750..f51414d 100644 --- a/static/img/diagrams/concepts__architecture__02_policy_tiers.svg +++ b/static/img/diagrams/concepts__architecture__02_policy_tiers.svg @@ -15,7 +15,7 @@ Policy execution: System 0 (in-process, real-time) Learned policies run in the RT loop; heavy deps confined to a launch-time prepare step Launch-time prepare (non-RT, Python) -bar_policy / pianist_policy +humanoid_control_policy / pianist_policy prepare resolve ONNX -> .mcap + overlay System 0 - RLPolicyController (C++, real-time update()) diff --git a/static/img/diagrams/concepts__architecture__03_module_deps.svg b/static/img/diagrams/concepts__architecture__03_module_deps.svg index d24226b..00ef68f 100644 --- a/static/img/diagrams/concepts__architecture__03_module_deps.svg +++ b/static/img/diagrams/concepts__architecture__03_module_deps.svg @@ -13,33 +13,33 @@ Module dependency graph -bar_* packages, build-time deps (solid) and pluginlib runtime deps (dashed) +humanoid_control_* packages, build-time deps (solid) and pluginlib runtime deps (dashed) Application / bringup Controllers + policies Hardware plugins + URDF -Foundations (no bar_* deps) +Foundations (no humanoid_control_* deps) External -bar_bringup_lite +humanoid_control_bringup_lite launch + YAML -bar_bringup_prime +humanoid_control_bringup_prime (scaffold) pianist_policy piano key-state -bar_controllers +humanoid_controllers 5 modes + mode_manager -bar_policy +humanoid_control_policy ONNX runner (Python) -bar_robstride +humanoid_control_robstride RobstrideSystem -bar_sito +humanoid_control_sito (stub) lite_description URDF/xacro/MJCF -bar_socketcan +humanoid_control_socketcan bus library + I/O thread -bar_msgs +humanoid_control_msgs MITCommand, ControlMode, ... -bar_common +humanoid_control_common MITState POD, RT helpers ros2_control @@ -57,4 +57,4 @@ nlohmann_json -pluginlibSolid arrow = build-time dep (CMake find_package + ament)Dashed arrow = runtime dep only (pluginlib)Note: bar_controllers does NOT find_package(bar_robstride) — the plugin is loaded by controller_manager at launch. +pluginlibSolid arrow = build-time dep (CMake find_package + ament)Dashed arrow = runtime dep only (pluginlib)Note: humanoid_controllers does NOT find_package(humanoid_control_robstride) — the plugin is loaded by controller_manager at launch. diff --git a/static/img/diagrams/concepts__frozen_schemas__01.svg b/static/img/diagrams/concepts__frozen_schemas__01.svg index 4c6232f..13ac346 100644 --- a/static/img/diagrams/concepts__frozen_schemas__01.svg +++ b/static/img/diagrams/concepts__frozen_schemas__01.svg @@ -16,8 +16,8 @@ Changing these requires retraining every policy that depends on them Schema Who locks in when you ship -bar_msgs/MITCommand -fields name + orderRemotePolicyController (subscriber)bar_policy.ActionMapper (publisher)every trained ONNX (action_joint_names) +humanoid_control_msgs/MITCommand +fields name + orderRemotePolicyController (subscriber)humanoid_control_policy.ActionMapper (publisher)every trained ONNX (action_joint_names) Joint order in YAML controllers.yaml `joints:` listRLPolicyController obs indexObservationManager term layoutURDF `` block order MITState (POD + dataclass) diff --git a/static/img/diagrams/concepts__safety_pipeline__01.svg b/static/img/diagrams/concepts__safety_pipeline__01.svg index 39fb9bd..1c67732 100644 --- a/static/img/diagrams/concepts__safety_pipeline__01.svg +++ b/static/img/diagrams/concepts__safety_pipeline__01.svg @@ -30,12 +30,12 @@ INVALID_FRAME DLC / comm-type mismatch(per-tick rebuild from current state, not history) SafetyStatus -bar_msgs +humanoid_control_msgs level: OK / WARN / FAULT / CRITICAL flags: uint32 bit mask -source: 'bar_robstride/can0' +source: 'humanoid_control_robstride/can0' /safety_status (TRANSIENT_LOCAL) diff --git a/static/img/diagrams/getting_started__intro__01.svg b/static/img/diagrams/getting_started__intro__01.svg index f3f88ab..64512c3 100644 --- a/static/img/diagrams/getting_started__intro__01.svg +++ b/static/img/diagrams/getting_started__intro__01.svg @@ -20,17 +20,17 @@ IDE / editor MuJoCo viewer -(bar_bringup_lite/mujoco) +(humanoid_control_bringup_lite/mujoco) Edits, sim runs, debug -bar_bringup_lite / launch +humanoid_control_bringup_lite / launch controller_manager (50 Hz) mode_manager -bar_policy +humanoid_control_policy -bar_robstride +humanoid_control_robstride (SocketCAN) IMU (serial / USB) diff --git a/static/img/diagrams/getting_started__intro__02.svg b/static/img/diagrams/getting_started__intro__02.svg index 0fe5847..72295e3 100644 --- a/static/img/diagrams/getting_started__intro__02.svg +++ b/static/img/diagrams/getting_started__intro__02.svg @@ -17,25 +17,25 @@ Shared (Lite + Prime) Lite-only Prime-only -bar_common +humanoid_control_common RT helpers, MITState POD -bar_msgs +humanoid_control_msgs MITCommand, ControlMode, ... -bar_controllers +humanoid_controllers 5 mode-FSM + mode_manager -bar_policy +humanoid_control_policy ONNX runner + LeRobot ref -bar_socketcan +humanoid_control_socketcan SocketCAN bus library lite_description URDF + xacro + meshes -bar_robstride +humanoid_control_robstride Robstride SystemInterface -bar_bringup_lite +humanoid_control_bringup_lite launch + controllers YAML -bar_description_prime +humanoid_control_description_prime URDF + EtherCAT PDO -bar_sito +humanoid_control_sito Sito SystemInterface -bar_bringup_prime +humanoid_control_bringup_prime + ethercat.yamlArrows = depends on diff --git a/static/img/diagrams/getting_started__lite_101__01_mujoco_spawn.svg b/static/img/diagrams/getting_started__lite_101__01_mujoco_spawn.svg index 645caea..947f882 100644 --- a/static/img/diagrams/getting_started__lite_101__01_mujoco_spawn.svg +++ b/static/img/diagrams/getting_started__lite_101__01_mujoco_spawn.svg @@ -13,7 +13,7 @@ MuJoCo bringup spawn sequence -What happens when you run `ros2 launch bar_bringup_lite mujoco.launch.py`launchxacromujoco_simcontroller_managermode_manager +What happens when you run `ros2 launch humanoid_control_bringup_lite mujoco.launch.py`launchxacromujoco_simcontroller_managermode_manager expand xacro (use_sim:=true) URDF start mujoco_sim diff --git a/static/img/diagrams/reference__hardware_specs__02.svg b/static/img/diagrams/reference__hardware_specs__02.svg index c97fc87..c7438a3 100644 --- a/static/img/diagrams/reference__hardware_specs__02.svg +++ b/static/img/diagrams/reference__hardware_specs__02.svg @@ -37,4 +37,4 @@ CAN @ 1 Mbit -CAN @ 1 MbitOn real hardware the bar_robstride plugin owns both buses; from the controller's perspective the 17 joints are one flat list. +CAN @ 1 MbitOn real hardware the humanoid_control_robstride plugin owns both buses; from the controller's perspective the 17 joints are one flat list. diff --git a/static/img/diagrams/reference__messages__01.svg b/static/img/diagrams/reference__messages__01.svg index 64f23bb..1bd233e 100644 --- a/static/img/diagrams/reference__messages__01.svg +++ b/static/img/diagrams/reference__messages__01.svg @@ -12,7 +12,7 @@ -bar_msgs pub/sub topology +humanoid_control_msgs pub/sub topology Who publishes / who subscribes for each of the 4 active topics Publishers Topics @@ -25,7 +25,7 @@ Active policy ctrls -bar_policy (Python) +humanoid_control_policy (Python) /standby_controller/state diff --git a/static/img/diagrams/reference__packages__01_xacro_selector.svg b/static/img/diagrams/reference__packages__01_xacro_selector.svg index 3ba83a6..b855cc6 100644 --- a/static/img/diagrams/reference__packages__01_xacro_selector.svg +++ b/static/img/diagrams/reference__packages__01_xacro_selector.svg @@ -31,7 +31,7 @@ true -bar_robstride/ +humanoid_control_robstride/ RobstrideSystem falseuse_sim wins over use_fake_hardware when both are true diff --git a/static/img/logo.svg b/static/img/logo.svg index 7f9b800..27a111e 100644 --- a/static/img/logo.svg +++ b/static/img/logo.svg @@ -1,6 +1,6 @@ - +