Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -164,15 +164,16 @@ docker-build-x86:
# (ros-tee / perception-tee / nvmm-source) moved to openral-pro with it.

# GStreamer-free deploy smoke inside the open x86 image: asserts `import gi`
# is absent, cv2 / feetech (scservo_sdk) / onnxruntime / omdet are present, and
# `deploy run --config so101_bench.yaml --dry-run` resolves the launch. This is
# what CI (`docker-build.yml`) runs on the built image. Exits non-zero on failure.
# is absent, cv2 / feetech (scservo_sdk) / onnxruntime / omdet plus the LingBot
# msgpack/websocket protocol dependencies are present, and `deploy run --config
# so101_bench.yaml --dry-run` resolves the launch. This is what CI
# (`docker-build.yml`) runs on the built image. Exits non-zero on failure.
docker-smoke-x86-deploy: docker-build-x86
docker run --rm --entrypoint /entrypoint.sh openral:x86 \
bash -lc 'set -e; \
python -c "import cv2, scservo_sdk, onnxruntime; from transformers import AutoModelForZeroShotObjectDetection; \
python -c "import cv2, msgpack, scservo_sdk, onnxruntime, websockets.sync.client; from transformers import AutoModelForZeroShotObjectDetection; \
import importlib.util as u; assert u.find_spec(\"gi\") is None, \"gi present — expected gstreamer-free\"; \
print(\"OK: cv2\", cv2.__version__, \"| feetech + onnxruntime + omdet present | gi absent\")"; \
print(\"OK: cv2\", cv2.__version__, \"| feetech + onnxruntime + omdet + LingBot protocol present | gi absent\")"; \
openral deploy run --config scenes/deploy/so101_bench.yaml --dry-run | grep -q "hal_mode:=real" \
&& echo "OK: deploy run --dry-run resolves"'

Expand Down Expand Up @@ -395,6 +396,7 @@ ros2-build:
--packages-select openral_msgs \
opentelemetry_cpp_vendor \
openral_hal_so100 \
openral_hal_galaxea_a1 \
openral_hal_panda_mobile \
openral_hal_openarm \
openral_hal_franka \
Expand Down Expand Up @@ -494,6 +496,7 @@ ros2-test:
--packages-select openral_msgs \
opentelemetry_cpp_vendor \
openral_hal_so100 \
openral_hal_galaxea_a1 \
openral_hal_panda_mobile \
openral_hal_openarm \
openral_hal_franka \
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ We compose ROS 2, tf2, MoveIt 2 (with optional CUDA-accelerated **cuMotion** pla

**Shipped today** (all workspace packages at `0.1.0`):
- `openral_core` schemas + the `openral` CLI (bare `openral` drops into a REPL)
- HAL adapters for [17 robot platforms](docs/reference/robots.md) — manipulators, mobile manipulators, bimanual arms, humanoids
- HAL adapters for [18 robot platforms](docs/reference/robots.md) — manipulators, mobile manipulators, bimanual arms, humanoids
- [Sensor catalog](docs/reference/sensors_landscape.md) — RGB-D, F/T, and USB-UVC adapters
- `WorldStateAggregator` — 30 Hz tf2-aware snapshot with lifted object detections
- [rSkill packages](docs/reference/rskills.md) spanning every kind — VLA policies (SmolVLA, π0.5, xVLA, MolmoAct2, ACT, Diffusion Policy, 3D Diffuser Actor, RLDX-1, OpenVLA-OFT, GR00T N1.7), open-vocabulary detectors (RT-DETR, OmDet-Turbo, LocateAnything), the Qwen3.5-4B scene VLM (`kind: vlm`), the Robometer-4B reward/progress monitor (`kind: reward`), MoveIt / Nav2 classical-control skills (`kind: ros_action`), and human-authored reasoner playbooks (`kind: playbook`)
Expand Down
40 changes: 40 additions & 0 deletions docker/galaxea_a1_sidecar/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
FROM ros:noetic-ros-base-focal

ENV DEBIAN_FRONTEND=noninteractive
ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8

# The vendor SDK is never copied into this image. Operators mount a separately
# obtained, already-built A1_SDK tree read-only at run time.
RUN apt-get update && apt-get install -y --no-install-recommends \
libconsole-bridge0.4 \
libassimp5 \
liboctomap-dev \
liborocos-kdl1.4 \
python3-serial \
ros-noetic-controller-interface \
ros-noetic-controller-manager \
ros-noetic-joint-state-controller \
ros-noetic-interactive-markers \
ros-noetic-kdl-parser \
ros-noetic-pluginlib \
ros-noetic-robot-state-publisher \
ros-noetic-ros-control \
ros-noetic-ros-controllers \
ros-noetic-tf \
ros-noetic-tf-conversions \
ros-noetic-tf2-ros \
ros-noetic-trac-ik-lib \
ros-noetic-urdf \
ros-noetic-urdf-parser-plugin \
ros-noetic-xacro \
&& rm -rf /var/lib/apt/lists/*

ENV ROS_MASTER_URI=http://127.0.0.1:11311
ENV ROS_HOSTNAME=127.0.0.1

COPY entrypoint.sh /usr/local/bin/openral-a1-entrypoint
RUN chmod 0755 /usr/local/bin/openral-a1-entrypoint

ENTRYPOINT ["/usr/local/bin/openral-a1-entrypoint"]
CMD ["bash"]
14 changes: 14 additions & 0 deletions docker/galaxea_a1_sidecar/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env bash
set -euo pipefail

# shellcheck disable=SC1091
source /opt/ros/noetic/setup.bash

if [[ -z "${A1_SDK_ROOT:-}" || ! -f "${A1_SDK_ROOT}/install/setup.bash" ]]; then
echo "A1_SDK_ROOT must point to a mounted, built Galaxea A1 SDK" >&2
exit 2
fi

# shellcheck disable=SC1090
source "${A1_SDK_ROOT}/install/setup.bash"
exec "$@"
5 changes: 4 additions & 1 deletion docker/inference/Dockerfile.x86
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ COPY python/ python/
# load time (needed on REAL hardware too).
# omdet — the open-vocabulary object detector (omdet-turbo, transformers-based)
# the ros_image_detector_node runs when enable_object_detector is on.
# lingbot — the msgpack + synchronous-websocket protocol dependencies used by
# the out-of-process LingBot policy adapters, including Galaxea A1.
# The `opencv_thread` camera path needs cv2 (opencv-python). It is a per-member
# EXTRA (openral-runner `opencv`), NOT pulled by `uv sync --all-packages`, so it
# is installed explicitly post-sync alongside onnxruntime (which lives only in
Expand All @@ -147,7 +149,7 @@ COPY python/ python/
# uv.lock. TensorRT (`--group tensorrt`) is an OpenRAL Pro plugin — never here.
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --all-packages \
--group sim --group omdet \
--group sim --group omdet --group lingbot \
&& uv pip install --python /workspace/.venv/bin/python onnxruntime opencv-python

# Copy the colcon-buildable trees AFTER the venv resolve so a packages/ tweak
Expand Down Expand Up @@ -185,6 +187,7 @@ RUN bash -lc 'set -eo pipefail \
--packages-select openral_msgs \
opentelemetry_cpp_vendor \
openral_hal_so100 \
openral_hal_galaxea_a1 \
openral_hal_openarm \
openral_world_state \
openral_reasoner_ros \
Expand Down
11 changes: 10 additions & 1 deletion docs/architecture/repo-state-map.html
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,15 @@ <h2 style="margin-top: 22px;">Schemas registry</h2>
outputs: ["JointTrajectory", "/error_recovery/goal"],
schemas: ["RobotDescription", "JointState", "Action"],
},
{
title: "HAL · Galaxea A1 (real-HW)",
pkg: "python/hal · galaxea_a1.py · tools/galaxea_a1_ros1_sidecar.py · docker/galaxea_a1_sidecar · packages/openral_hal_galaxea_a1",
status: "yellow",
desc: "Real-only six-axis A1 HAL over an isolated ROS 1 Noetic sidecar. The operator provides the official SDK; OpenRAL bundles no vendor code. A background transport accepts only literal IPv4 loopback endpoints and keeps network I/O off the HAL hot path. The sidecar owns roscore + official serial driver + joint tracker and stops the full process group on command-lease expiry, disconnect, motor fault, or e-stop. Its locked staged-command relay blocks the tracker's compiled startup pose until it aligns with fresh measured feedback. The manifest at robots/galaxea_a1/robot.yaml includes the official URDF's joint axes and transforms; collision primitives remain uncommitted pending cleared lowering provenance. Unit, socket, ROS lifecycle, and read-only preflight coverage are complete. Real HIL has passed observation, current hold, a bounded 0.01 rad joint round trip, a 10 mm gripper round trip, and current hold through candidate_action → the C++ kernel → safe_action → the real HAL. The LingBot-VA A1 rSkill consumes the external A1 Runtime's paired-camera/model/EEF-IK contracts, explicitly subdivides IK solutions by its own policy_extras bound under the independent HAL ceiling, and returns typed joint + gripper actions to the same OpenRAL safety path.",
inputs: ["Action (6-D + gripper)", "/joint_states_host", "/arm_status_host"],
outputs: ["/arm_joint_target_position", "/gripper_position_control_host", "JointState"],
schemas: ["RobotDescription", "JointState", "Action"],
},
{
title: "HAL · Sawyer (real-HW)",
pkg: "python/hal · sawyer_real.py",
Expand Down Expand Up @@ -1569,7 +1578,7 @@ <h2 style="margin-top: 22px;">Schemas registry</h2>
title: "Tests · HIL",
pkg: "tests/hil",
status: "yellow",
desc: "7 files: test_ur5e, test_ur10e, test_franka_panda, test_sawyer, test_aloha (real-hardware HALs gated by self-hosted [lab-<robot>] runner labels + UR{5,10}E_HOST / *_FCI_HOST env vars), plus test_detect_jetson_live for the auto-provisioning probe. SO-100 / SO-101 / RealSense HIL gates were removed until matching lab hardware exists. The shared rclpy bridge lives in _ros_control_transport.py (RosControlHILTransport) and _aloha_ros_transport.py (4-way ALOHA fan-out). The L4T HIL workflow (`hil-l4t.yml`) that PR #93 added was removed by the 2026-05-14 single-Dockerfile consolidation amendment — L4T returns when the `[self-hosted, l4t]` runner pool is online.",
desc: "8 files: test_ur5e, test_ur10e, test_franka_panda, test_sawyer, test_aloha (real-hardware HALs gated by self-hosted [lab-<robot>] runner labels + UR{5,10}E_HOST / *_FCI_HOST env vars), test_galaxea_a1 (direct HAL observation/hold/joint/gripper gates), test_galaxea_a1_deploy (full candidate_action → C++ kernel → safe_action → real HAL → ROS 1 relay hold + mandatory e-stop), plus test_detect_jetson_live for the auto-provisioning probe. SO-100 / SO-101 / RealSense HIL gates were removed until matching lab hardware exists. The shared rclpy bridge lives in _ros_control_transport.py (RosControlHILTransport) and _aloha_ros_transport.py (4-way ALOHA fan-out). The L4T HIL workflow (`hil-l4t.yml`) that PR #93 added was removed by the 2026-05-14 single-Dockerfile consolidation amendment — L4T returns when the `[self-hosted, l4t]` runner pool is online.",
},
{
title: "CI · Docker image build",
Expand Down
Loading