This page walks you through getting a working OpenRAL development environment from scratch — whether on a local Ubuntu machine, inside a dev container, or in a GitHub Codespace. It also covers the day-to-day commands you'll use while contributing.
| Requirement | Minimum | Recommended |
|---|---|---|
| OS | Ubuntu 22.04 or 24.04 | Ubuntu 24.04 (ROS 2 Jazzy) |
| Python | 3.12 (only — pyproject.toml pins >=3.12,<3.13) |
3.12 |
| RAM | 8 GB | 16 GB |
| Disk | 20 GB free | 40 GB free |
| GPU | CPU-only (limited) | NVIDIA, 8 GB VRAM |
| Docker | 24+ (for dev container) | 26+ |
macOS 14+ is supported for Python/tooling work. ROS 2 on macOS runs inside the dev container.
git clone https://github.com/OpenRAL/openral
cd OpenRAL
just bootstrap # installs uv, ROS 2, system deps (~5–10 min)
source /opt/ros/jazzy/setup.bash # or 'humble' on Ubuntu 22.04
just sync # install Python workspace deps (always `just sync`,
# never bare `uv sync` — see toolchain.md)The bootstrap script auto-detects Ubuntu 22.04 (→ ROS 2 Humble) or 24.04 (→ ROS 2 Jazzy).
just test # full unit suite, <30 s
just lint # ruff + mypy --strict; expect no errors
uv run openral doctor # diagnose host environmentjust test should run the full unit suite and complete in well under
30 s. The current inventory (file + LOC counts, gaps, follow-ups) is in
tests/README.md.
uv run openral doctor is the canonical environment probe — see the
README's "Quick start" section
for a sample output table; that one is the single source of truth.
Each row will read ok / info / absent / missing depending on
which deps you have installed.
- VS Code with the Dev Containers extension
- Docker Desktop 24+ running locally
F1 → "Dev Containers: Reopen in Container"
VS Code will build Dockerfile.dev (first build ~8 min; subsequent builds use the layer cache) and run uv sync --all-packages automatically.
docker compose -f docker-compose.dev.yml up -d openral-dev
docker compose -f docker-compose.dev.yml exec openral-dev bash
# inside container (always `just sync`, never bare `uv sync`):
just sync
just testThe compose file also starts a Jaeger container for OpenTelemetry traces at http://localhost:16686.
!!! note "Hardware access"
The dev container is started with --privileged and /dev mounted. On Linux hosts this gives USB access to connected robots. On macOS/Windows Docker Desktop, hardware passthrough is limited — use Option A (native Ubuntu) for hardware-in-the-loop work.
- On the GitHub repo page: Code → Codespaces → Create codespace on main.
- Wait for the container to build and
uv sync --all-packagesto complete (~5 min). - Open a terminal and run
just test.
!!! note
Hardware mounts (/dev, /run/udev) are not available in Codespaces. All unit and sim tests work; HIL tests require a self-hosted runner.
All commands use just as the task runner. Run just (no arguments) to list all targets.
just test # all tests in tests/unit/
just test-k so100 # filter by keyword
uv run pytest tests/unit/test_schemas_fuzz.py -v # run a specific filejust lint # ruff check + ruff format --check + mypy --strict (CI parity)
just fmt # auto-fix: ruff format + ruff check --fixjust schema-export # regenerate docs/reference/schemas/*.json
uv run python tools/schema_export.py --check # CI drift-check (exit 1 on drift)If you change any Pydantic model in python/core/, run just schema-export and commit the updated JSON files.
source /opt/ros/jazzy/setup.bash
just ros2-build # colcon build --merge-install
source install/setup.bash
just ros2-test # colcon test + colcon test-result --verbosejust sim-eval scenes/<name>.yaml # canonical entry point
just sim-libero # SmolVLA × LIBERO
just sim-xvla-libero # xVLA × LIBERO
just sim-pi05-libero # π0.5 × LIBERO (≥8 GB VRAM)
just sim-metaworld --task metaworld/reach-v3 # SmolVLA × MetaWorld MT50
just sim-act-aloha # ACT × gym-aloha bimanual cube
just sim-diffusion-pusht # Diffusion Policy × gym-pusht (CPU)just docs # serve at http://localhost:8000 (live-reload)
just docs-build # full build (CI parity, strict mode)python/core/ openral_core — Pydantic v2 schemas (normative)
python/cli/ openral_cli — `openral` CLI entry point
python/hal/ openral_hal — HAL Protocol + per-robot adapters
(so100_sim, so100_follower, franka_panda,
ur5e/ur10e, ros_control)
python/sensors/ openral_sensors — sensor catalog + vendor adapters
python/world_state/ openral_world_state — WorldStateAggregator (30 Hz snapshot)
python/rskill/ openral_rskill — Skill ABC, rSkill loader, runtimes,
SmolVLA adapter
python/sim/ openral_sim — openral sim run registry/runner; LIBERO/MetaWorld
packages/msgs/ — ROS 2 IDL (.msg, .action)
packages/world_state/ — WorldState lifecycle node
packages/openral_hal_*/ — per-robot lifecycle nodes (so100, ur5e,
ur10e, franka)
robots/ — canonical RobotDescription manifests
(so100_follower, franka_panda, sawyer,
aloha_bimanual, pusht_2d,
ur5e, ur10e); auto-discovered
by openral_sim at import.
skills/ — rSkill packages (manifest + eval/)
(smolvla-libero, smolvla-metaworld,
pi05-libero-int8,
xvla-libero, act-aloha,
act-aloha-insertion,
diffusion-pusht)
examples/ — runnable end-to-end demos +
scenes/ SceneEnvironment YAMLs
tests/unit/ — pytest unit tests (<30 s total)
tests/integration/ — launch_testing multi-node tests
tests/sim/ — closed-loop sim (CUDA + HF weights, opt-in)
tests/hil/ — hardware-in-the-loop (lab runners)
tools/schema_export.py — JSON Schema generator + drift check
tools/rskill_publisher.py — rSkill packaging / publish helper
docs/ — mkdocs-material site
Most directories carry a per-package README.md with usage examples and
links back to the canonical schemas — start with the package matching
the layer you're touching.
Full architecture is in docs/architecture/overview.md. For a per-module status canvas (working / in-dev / planned / out-of-scope, with inputs, outputs, and schemas), open docs/architecture/repo-state-map.html — keep it in sync per CLAUDE.md §4.3.
- Create a branch:
git switch -c feat/your-feature. - Make your changes. Run
just lint && just testbefore pushing. - If you changed a Pydantic schema, run
just schema-exportand commit the updated JSON files. - Open a PR. The title should follow Conventional Commits — e.g.
feat(core): add FooSchema. - All CI checks must be green before merge. See
.github/workflows/for what runs.
The full PR checklist is in the repo-root CLAUDE.md (not linked from docs — open it directly in your editor).
Run just sync instead of any bare uv sync. The workspace has multiple
member packages (the root manifest does not list them as direct dependencies),
so the sync needs --all-packages — which just sync supplies — and the
just sync wrapper also runs scripts/repair_hf_libero_install.py before/after
to avoid the hf-libero==0.1.3 distutils-uninstall abort. Add opt-in groups
with just sync --group <name>. See
Managing the Python environment & dependency
groups.
Both openral_core and openral_cli ship py.typed markers. If mypy still complains, make sure you ran just sync and that your interpreter is the workspace venv (which python should point into .venv/).
Source the ROS 2 setup file:
source /opt/ros/jazzy/setup.bash # Ubuntu 24.04
# or
source /opt/ros/humble/setup.bash # Ubuntu 22.04Add this line to your ~/.bashrc for permanent effect.
Make sure you're building from the repo root (the docker-compose.dev.yml sets context: .). Building directly with docker build -f Dockerfile.dev . from the repo root also works.
Install the hooks once after cloning:
just install-hooksThen git commit runs ruff, ruff-format, mypy, codespell, and the
conventional-commit check on changed files automatically, plus DCO auto-sign-off.
Use just install-hooks rather than pre-commit install: the repo pins
core.hooksPath=.githooks (for DCO sign-off), and pre-commit install refuses
to run while core.hooksPath is set. just install-hooks instead wires the
committed .githooks/ wrappers (which call pre-commit run) and pre-builds the
hook environments.