# Linux setup Run the project on the Linux workstation used for robot deployment. Windows is suitable for editing and reviewing these files; building, testing, simulation, and robot operation belong on Linux. ## Runtime environment The hardware deployment uses ROS 2 Humble, Unitree `unitree_hg` messages, CycloneDDS, the Unitree Python SDK, and an existing OptiTrack ROS environment. The ROS Humble system Python is used for the motion-capture adapter. The controller Python must have CUDA-enabled PyTorch and access to the ROS Python packages needed by the predictor. | Dependency | Used by | | --- | --- | | NumPy, PyYAML | Configuration, observations, geometry, logs | | PyTorch with CUDA | CLoSD generation and online TD3 learning | | ONNX Runtime | CPU tracking-policy and residual inference | | MuJoCo | Offline simulation and robot geometry | | pyzmq | Ball, robot, and racket data transport | | `onnx` | Export only; not required to run an existing ONNX model | | ROS 2 Humble, `rclpy`, standard ROS messages | Predictor and motion-capture interfaces | | `unitree_hg`, `rclcpp`, `ament_cmake`, colcon, C++17 compiler | C++ bridge build | | `unitree_sdk2py` | Native LowState inspection and MotionSwitcher checks | | Bash, tmux, iproute2, util-linux, coreutils | Launchers, interface checks, process inspection | The included native CLoSD bundle uses the implementation in `runtime/`; its normal inference path does not require installing the full CLoSD or MotionBricks training repositories. A GPU is required for the configured generator and learner. ONNX inference uses CPU; installing `onnxruntime-gpu` is unnecessary for this configuration. Use a Python environment compatible with your installed CUDA driver and ROS setup. The [requirements file](../requirements.txt) lists Python dependencies; it is not a lockfile or a claim of a validated fresh installation. After selecting the appropriate CUDA PyTorch build, install the remaining dependencies on Linux: ```bash export H2_ROOT="$PWD" export H2_PY="$(command -v python3)" "$H2_PY" -m pip install -r requirements.txt ``` For re-exporting your own residual checkpoint, use [requirements-export.txt](../requirements-export.txt). Do not install ROS packages with this pip command; use your configured ROS and Unitree installation. Record the exact environment used for a successful validation before describing it as reproducible. ## Files and paths Download the repository with its actual model and mesh files. A Git clone that contains only large-file pointer text is not ready for inference. The model inventory is in the [README](../README.md#included-models-and-scope). Keep the relative layout unchanged: configuration resolves the Stage-C policy, H2 CLoSD bundle, ready pose, MJCF/meshes, and ball calibration inside this tree. The existing `ARTIFACTS.sha256` file describes the required deployment artifacts; startup and preflight use it. A missing or mismatched artifact must be resolved before continuing. Do not bypass this check or replace a model with a different policy while retaining its filename. Set these variables in each hardware terminal before sourcing the ROS environment. Replace the example paths and interface with your site values: ```bash export H2_ROOT="$PWD" export H2_PY="$(command -v python3)" export H2_IF=enp4s0f0 export UNITREE_ROS2_ROOT="$HOME/unitree_ros2" export H2_ADAPTER_ROOT="$HOME/mocap_ego_adapter" ``` `UNITREE_ROS2_ROOT` is the installed Unitree ROS workspace, with `install/setup.bash`. `H2_ADAPTER_ROOT` selects your configured motion-capture adapter package, with `scripts/mocap_ego_zmq_adapter_physics.py` and the importable `mocap_ego_adapter` package. The adapter runs with `/usr/bin/python3`; install its ROS-side dependencies in that environment. The default adapter location is a sibling `mocap_ego_adapter` directory, and the default Unitree workspace is `$HOME/unitree_ros2`. The hardware launcher uses the configured OptiTrack driver and does not start a new driver. Its adapter uses FastDDS, ROS domain 0, and `ROS_LOCALHOST_ONLY=0`. The hardware predictor and bridge use CycloneDDS on the selected robot interface, also in domain 0. Confirm these settings against your running driver before launching a session. The default source topics and coordinate transforms are site calibration, not general robot constants. In particular, the adapter expects split input topics, meters at ROS input, millimeters at ZMQ output, `reference_frame=world`, `input_origin=p1_corner`, and side `P1`. The runner and predictor both use `robot_base_origin_world=(-1.87, 0.0, -0.76)`. RL racket measurements default to `/test_pat1/pose` with the rigid-body origin at the racket center. Verify these choices during site commissioning; update both ends together when adapting a site. ## Offline checks With no production runner or bridge active, run from the repository root: ```bash "$H2_PY" scripts/preflight.py --policy-only "$H2_PY" scripts/preflight.py "$H2_PY" run_sim_shm.py \ --ack-simulation-only H2-MUJOCO-SIMULATION-ONLY \ --duration-s 9.0 ``` The first command checks policy/assets without generating a CLoSD reference. The second exercises CUDA generation. The simulator uses isolated shared memory and no robot middleware. Require both preflights to report `PREFLIGHT PASS` and simulation to report `passed=true`. The full `tests/` regression suite is not included in this publication copy. Before hardware progression, run the full suite from a development checkout matching this release and require `OK`; inspect skips as well as failures. The standalone checks above do not replace that requirement. The mainline offline simulation is the public starting point. `run_live_sim_shm.py` and its launcher are retained for a configured live-input installation; the `original` live-simulation path also expects its isolated upstream adapter/predictor tree through `H2_UPSTREAM_ROOT`. It is not needed for offline validation or the original hardware pipeline. ## Script entry points Use `scripts/launch_h2_tmux.sh` for hardware sessions. Select `--rl-mode train` for online learning, `--rl-mode baseline` for base-policy scoring with RL settings, or `--rl-mode residual --rl-checkpoint PATH` for fixed-residual evaluation without exploration or learning. Preview a selection with `--dry-run --deployment-version original` before a live launch. The separate `--eval-policy baseline` option uses the record-only scoring configuration and cannot be combined with RL modes; its shutdown helper is `scripts/stop_h2_policy_eval.sh`. Live-input simulation uses `scripts/launch_h2_live_sim_tmux.sh` and `scripts/stop_h2_live_sim_tmux.sh`. The `h2_*orchestrator.sh`, `h2_*tmux_pane.sh`, and shared helper files are called by the launchers to start processes in order; they are not additional user entry points. The `inspect_*` tools inspect distinct inputs: native robot state, planner/adapter packets, shared memory, raw racket poses, or paired ball/racket measurements. Keep these tools available for site setup and diagnosis. `scripts/analyze_timing.py` reads recorded timing data, and `scripts/export_real_residual.py` exports a training checkpoint for inference. ## Build the ROS bridge On the robot workstation with the selected interface configured and UP: ```bash source scripts/source_unitree_env.sh "$H2_IF" colcon build --packages-select cpp_lowcmd_bridge \ --cmake-args -DCMAKE_BUILD_TYPE=Release source install/setup.bash ros2 run cpp_lowcmd_bridge h2_lowcmd_shm_bridge --print-contract ros2 run cpp_lowcmd_bridge h2_lowcmd_shm_bridge \ --validate-network-only --network-interface "$H2_IF" ``` The contract must report H2BR v7, 1544 bytes, 31 state DOFs, 35 LowCmd slots, PR mode 0, and 1000 Hz. Network validation checks the local interface and DDS configuration; it does not prove robot identity. Complete site-specific hardware commissioning before any command-producing launch.