05Software install
Two installs: the laptop (simulation twin + every desktop tool — no ROS needed) and the robot (ROS 2 workspace + the hardware layer on the Jetson). Do the laptop first: everything through 07 · Operate works against the simulator before any hardware exists.
Laptop — the simulation twin
git clone https://github.com/robotmabel/MABEL.git && cd MABEL
python3 -m pip install -r server/requirements.txt # mujoco≥3.0, websockets, aiohttp, opencv, osqp…
cd server && ./run.sh # full stack: physics + cameras + web studio :8097
That is the whole laptop install. run.sh starts the MuJoCo
physics owner, the camera renderer, the teleop gateway, and the Sim Control
Center studio; the terminal becomes the cockpit. Point any client at your
laptop's IP exactly as you later will at the robot.
Robot — Ubuntu 24.04 on the Jetson
The ROS 2 side is RoboStack Jazzy in conda — no apt ROS for the workspace. One script does the whole bring-up from a fresh clone:
cd mabel_ws
./dev_up.sh # installs Miniforge if needed, creates the `mabel` env from
# environment.yml (RoboStack Jazzy + Nav2 + slam-toolbox +
# camera SDKs), colcon-builds the workspace, opens tmux panes
Then, in every shell that talks ROS:
source mabel_ws/scripts/mabel_env.sh # activates `mabel`, overlays install/, pins DDS
- The env pins the DDS trio — CycloneDDS,
ROS_DOMAIN_ID=0, LOCALHOST discovery — and scrubs any apt ROS from the environment. Every process on the robot must agree on these three or the graph splits. - Camera SDK Python APIs (
pyrealsense2,pyzed) install into the same env; the ZED one comes from the locally-installed ZED SDK, not PyPI.
GPU SLAM — the one apt exception
Isaac ROS (cuVSLAM + nvblox) ships only as apt binaries under
/opt/ros/jazzy. The launcher runs those nodes through
mabel_ws/scripts/slam_env.sh, which swaps to the apt stack while
keeping the same DDS settings — both stacks share one graph. Install the
Isaac ROS apt packages per NVIDIA's instructions; skip this entirely with
real_run.sh --no-slam (2D slam-toolbox still works from conda).
The hardware layer
pip install -e hardware_bridge # the `mabel-hw` package (numpy, pyserial, PyYAML)
hardware_bridge/install/install.sh # systemd unit + udev rules (audio, CAN dongle, wrist cams)
hardware_bridgeis the single owner of every device — Teensys, hand serials, cameras, lidar, audio. ROS nodes are thin DDS clients of it; nothing else may open a device.install.shinstallsmabel-hardware-bridge.service(auto-start,Restart=always) and the udev rules that make hot-plug identity work.- Register your two hand adapters' USB serials in
hardware_bridge/mabel_hw/config.py(find them:ls -l /dev/serial/by-id/).
Auto-start
Two services make the robot come up by itself on power:
| Unit | Runs | Installed by |
|---|---|---|
mabel-hardware-bridge | the HAL (run_bridge.sh) | hardware_bridge/install/install.sh |
mabel-bringup | server/real_run.sh headless — SLAM, Nav2, app server | a unit pointing at the script (same pattern as above) |
A manual real_run.sh takes over cleanly from the services and
hands back when it exits — you never have to stop them by hand.
Optional remote access (rathole relay + Caddy on a VPS) is configured under
server/relay/.
Verify before hardware
- Laptop:
./run.shboots to the cockpit; a phone/browser on the same Wi-Fi sees video and drives the sim base - Jetson:
ros2 topic listworks insidemabel_env.sh - Jetson: the bridge service is
active (running)with no hardware attached — every subsystem idles, nothing crashes - Both hand adapter serials + wrist camera hub ports recorded in the config