Skip to content

ROSClaw/rosclaw-ros2

Repository files navigation

ROSClaw ROS 2 Packages

Robot-side ROS 2 packages for the ROSClaw stack.

This repository contains the runtime half of ROSClaw: discovery, safety, optional Gemini perception, optional remote bridges, and the launch/config bundles that expose a robot to the OpenClaw plugin.

How This Repo Fits

Repo Responsibility
rosclaw Workspace bootstrap, Docker Compose, demos, top-level docs, integration tests
rosclaw-ros2 Robot-side ROS 2 packages and launch files
rosclaw-plugin OpenClaw plugin that consumes the manifest, scene, and safety surfaces exported by this repo

If you want the full stack up quickly, start with the bootstrap repo: rosclaw. If you are changing robot-side behavior, start here.

Package Map

Package Purpose
rosclaw_msgs ROS interfaces shared by the rest of the stack
rosclaw_discovery Publishes a capability manifest and serves on-demand manifest requests
rosclaw_estop Handles robot-side emergency stop and publishes safety status
rosclaw_perception Publishes structured scene descriptions and typed perception snapshots
rosclaw_webrtc_bridge Robot-side relay and WebRTC bridge nodes for remote sessions
rosclaw_bringup Launch files and platform config bundles

Repository layout:

rosclaw_msgs/            Interface definitions (.msg / .srv)
rosclaw_discovery/       Discovery node and standalone launch file
rosclaw_estop/           Safety / emergency-stop node and launch file
rosclaw_perception/      Gemini perception node and package-specific docs
rosclaw_webrtc_bridge/   Relay and WebRTC transport bridge nodes
rosclaw_bringup/         Cross-package launch files and platform config bundles
tests/                   Cross-package unit tests

Package-level READMEs exist where behavior is non-trivial or commonly used on its own.

Requirements

  • ROS 2 Humble or newer
  • Python 3.10+
  • rosdep initialized on the machine

Optional:

  • Gemini perception: pip install 'google-genai>=1.0.0'
  • Relay/WebRTC transports: install declared system dependencies through rosdep

Build

Recommended: use the bootstrap workspace

The simplest path is the workspace bootstrap repo:

git clone https://github.com/ROSClaw/rosclaw.git
cd rosclaw
./scripts/setup.sh

That imports this repo under src/rosclaw-ros2 and sets up the companion repos.

Standalone development

cd ~/ros2_ws/src
ln -s /path/to/rosclaw-ros2 rosclaw-ros2

cd ~/ros2_ws
source /opt/ros/$ROS_DISTRO/setup.bash
rosdep update
rosdep install --from-paths src --ignore-src -r -y

colcon build --packages-select rosclaw_msgs rosclaw_discovery rosclaw_estop rosclaw_bringup
source install/setup.bash

Build optional packages only if you use them:

colcon build --packages-select rosclaw_perception rosclaw_webrtc_bridge

Quick Start

Standard robot bringup

This launches discovery, estop, and rosbridge for a single robot:

ros2 launch rosclaw_bringup rosclaw.launch.py platform:=turtlebot3

Equivalent platform choices:

ros2 launch rosclaw_bringup rosclaw.launch.py platform:=go2
ros2 launch rosclaw_bringup rosclaw.launch.py platform:=g1
ros2 launch rosclaw_bringup rosclaw.launch.py platform:=generic

What you get by default:

  • rosbridge_websocket listening on ws://0.0.0.0:9090
  • /rosclaw/manifest and /rosclaw/get_manifest
  • /rosclaw/estop, /rosclaw/safety_status, and /rosclaw/set_safety_policy

If something is already listening on 127.0.0.1:9090, bringup fails by default. Set reuse_existing_rosbridge:=true only when you intentionally want to reuse that websocket server.

Connect the plugin

The companion plugin repo is rosclaw-plugin. In the default path, configure the plugin with transport mode rosbridge and point it at:

ws://<robot-ip>:9090

If you launch with robot_namespace:=/robot1, set the plugin's robot.namespace to /robot1 as well.

Perception

Enable Gemini scene analysis:

export GEMINI_API_KEY=your-api-key
ros2 launch rosclaw_bringup rosclaw.launch.py platform:=turtlebot3 perception:=true

This adds:

  • /rosclaw/scene for JSON scene summaries
  • /rosclaw/perception for typed snapshots with image bytes and detections
  • /rosclaw/perception_status for health reporting

Perception details and scene schema live in rosclaw_perception/README.md.

Remote / cloud transport

Relay transport:

ros2 launch rosclaw_bringup rosclaw.launch.py \
    platform:=turtlebot3 \
    relay:=true \
    signaling_url:=ws://your-signaling-server.com \
    robot_token:=your-auth-token \
    robot_key:=your-secret-key \
    robot_id:=robot_1

WebRTC transport:

ros2 launch rosclaw_bringup rosclaw.launch.py \
    platform:=turtlebot3 \
    webrtc:=true \
    signaling_url:=wss://your-signaling-server.com \
    robot_token:=your-auth-token \
    robot_key:=your-secret-key \
    robot_id:=robot_1

You can run rosbridge and relay/WebRTC together or disable rosbridge entirely:

ros2 launch rosclaw_bringup rosclaw.launch.py \
    platform:=go2 \
    rosbridge:=false \
    webrtc:=true

Transport Boundary

Across the full ROSClaw stack:

  • The plugin repo exposes client transport modes rosbridge and local.
  • This repo launches robot-side relay and webrtc bridges for remote deployments.
  • relay and webrtc are coordinated with rosclaw-signaling; they are not plugin config values.

That distinction matters when reading the docs:

  • If you are configuring the OpenClaw plugin, look for transport.mode, rosbridge.url, and local.domainId.
  • If you are configuring the robot-side deployment, look for bringup launch arguments such as rosbridge, relay, webrtc, signaling_url, and robot_namespace.

Simulation

ros2 launch rosclaw_bringup sim_turtlebot3.launch.py

Or directly:

ros2 launch rosclaw_bringup rosclaw.launch.py \
    platform:=sim_turtlebot3 \
    use_sim_time:=true

With perception:

export GEMINI_API_KEY=your-api-key
ros2 launch rosclaw_bringup rosclaw.launch.py \
    platform:=sim_turtlebot3 \
    use_sim_time:=true \
    perception:=true

Fleet / Multi-Robot Usage

Set robot_namespace to scope discovery, estop, perception, relay, and WebRTC to one robot:

ros2 launch rosclaw_bringup rosclaw.launch.py \
    platform:=turtlebot3 \
    robot_namespace:=/robot1 \
    perception:=true \
    relay:=true \
    robot_id:=robot_1

With robot_namespace:=/robot1:

  • /rosclaw/manifest becomes /robot1/rosclaw/manifest
  • /rosclaw/get_manifest becomes /robot1/rosclaw/get_manifest
  • /rosclaw/estop becomes /robot1/rosclaw/estop
  • /rosclaw/safety_status becomes /robot1/rosclaw/safety_status
  • /rosclaw/scene becomes /robot1/rosclaw/scene
  • relative config defaults such as cmd_vel and camera/image_raw/compressed become /robot1/cmd_vel and /robot1/camera/image_raw/compressed

Important transport behavior:

  • Relay/WebRTC sessions are namespace-enforced. Requests outside the configured robot namespace are rejected.
  • Rosbridge is namespace-safe by convention, not hard-isolated. It still exposes the full ROS graph, so clients must use the intended namespaced endpoints.

Bringup Interface

Primary launch file:

ros2 launch rosclaw_bringup rosclaw.launch.py ...

Arguments:

Argument Default Description
platform turtlebot3 Config bundle to load: turtlebot3, go2, g1, generic, sim_turtlebot3
use_sim_time false Use simulation clock
rosbridge true Launch rosbridge_websocket on port 9090
reuse_existing_rosbridge false Reuse an already-running rosbridge listener on 127.0.0.1:9090
relay false Launch the relay bridge
webrtc false Launch the WebRTC bridge
perception false Launch Gemini perception
robot_namespace "" Namespace all ROSClaw endpoints for fleet deployments
safety_config "" Override safety_policy.yaml
discovery_config "" Override discovery.yaml
perception_config "" Override perception.yaml
signaling_url ws://localhost:8443 Signaling server URL for relay/WebRTC
robot_token "" Signaling-server auth token
robot_key "" Secret key checked on session invitation
robot_id robot_1 Robot identifier presented to the signaling layer

Convenience launch files are also provided:

  • turtlebot3.launch.py
  • go2.launch.py
  • g1.launch.py
  • generic.launch.py
  • sim_turtlebot3.launch.py

Configuration Model

Each platform in rosclaw_bringup/config/<platform>/ ships three files:

  • safety_policy.yaml
  • discovery.yaml
  • perception.yaml

The important convention is that namespace-sensitive defaults are relative:

  • cmd_vel
  • camera/image_raw/compressed
  • rosclaw/manifest
  • rosclaw/get_manifest

That means robot_namespace:=/robot1 automatically scopes them under /robot1. Use absolute overrides only if your underlying robot stack is intentionally global.

Example safety_policy.yaml:

/**:
  ros__parameters:
    linear_max: 1.0
    angular_max: 2.84
    cmd_vel_topic: "cmd_vel"
    estop_rate: 10.0
    allowlisted_topics:
      - "cmd_vel"
      - "odom"
      - "scan"
      - "camera/image_raw/compressed"

Example discovery.yaml:

/**:
  ros__parameters:
    robot_name: "TurtleBot3"
    robot_namespace: ""
    publish_interval: 2.0
    exclude_prefixes:
      - "/rosout"
      - "/parameter_events"
      - "rosclaw/manifest"
      - "rosclaw/get_manifest"

Example perception.yaml:

/**:
  ros__parameters:
    camera_topic: "camera/image_raw/compressed"
    frame_rate: 1.0
    gemini_model: "gemini-2.5-flash"
    api_key_env: "GEMINI_API_KEY"
    inference_timeout: 20.0
    max_retries: 2
    empty_cycles_before_refresh: 4

ROS Interfaces

The names below are the single-robot graph names. In fleet mode, prefix the rosclaw/... endpoints and relative platform topics with the robot namespace.

Published Topics

Topic Type Source
/rosclaw/manifest rosclaw_msgs/CapabilityManifest discovery
/rosclaw/safety_status rosclaw_msgs/SafetyStatus estop
/rosclaw/scene std_msgs/String perception
/rosclaw/perception rosclaw_msgs/PerceptionSnapshot perception
/rosclaw/perception_status std_msgs/String perception
/cmd_vel geometry_msgs/Twist estop zero-velocity output

Subscribed Topics

Topic Type Consumer
/rosclaw/estop std_msgs/Bool estop
<camera_topic> sensor_msgs/CompressedImage perception

Services

Service Type Provider
/rosclaw/get_manifest rosclaw_msgs/GetManifest discovery
/rosclaw/set_safety_policy rosclaw_msgs/SetSafetyPolicy estop

Message / Service Notes

  • CapabilityManifest includes robot_name, robot_namespace, and lists of topics, services, and actions.
  • SafetyStatus includes estop state, velocity limits, and resolved allowlisted topics.
  • GetManifest accepts a robot_namespace query and returns a manifest.
  • SetSafetyPolicy updates velocity limits and allowlisted topics at runtime.

See rosclaw_msgs/msg/ and rosclaw_msgs/srv/ for the exact definitions.

Safety Model

rosclaw_estop is the robot-side safety authority:

  1. A true message on /rosclaw/estop immediately starts zero-velocity publishing on the configured cmd_vel topic.
  2. /rosclaw/safety_status is latched so late subscribers receive the current safety state.
  3. /rosclaw/set_safety_policy allows runtime updates to velocity limits and allowlisted topics.
  4. Plugin-side validation is still expected as defense in depth.

allowlisted_topics are informational. They are published for clients and operators; the estop node does not use them as an execution gate.

Operational Checks

Single-robot examples:

Trigger estop:

ros2 topic pub --once /rosclaw/estop std_msgs/Bool "data: true"

Release estop:

ros2 topic pub --once /rosclaw/estop std_msgs/Bool "data: false"

Read safety status:

ros2 topic echo /rosclaw/safety_status --once

Query discovery:

ros2 service call /rosclaw/get_manifest rosclaw_msgs/srv/GetManifest "{robot_namespace: ''}"

In fleet mode, use the namespaced equivalents such as /robot1/rosclaw/estop and /robot1/rosclaw/get_manifest.

Platform Defaults

Platform Linear Max Angular Max Camera Topic Robot Name
TurtleBot3 1.0 m/s 2.84 rad/s /camera/image_raw/compressed TurtleBot3
Unitree Go2 2.0 m/s 3.0 rad/s /utlidar/depth_image/compressed Go2
Unitree G1 1.5 m/s 2.0 rad/s /camera/color/image_raw/compressed G1
Generic 0.5 m/s 1.0 rad/s /camera/compressed Robot
Sim TurtleBot3 1.0 m/s 2.84 rad/s /camera/image_raw/compressed TurtleBot3 (Sim)

Those are the resolved graph names for a single robot. The shipped config files store the namespace-sensitive topic defaults as relative names.

Adding A New Platform

  1. Create rosclaw_bringup/config/<platform>/.
  2. Add safety_policy.yaml, discovery.yaml, and perception.yaml.
  3. Use config/generic/ as the starting point.
  4. Optionally add launch/<platform>.launch.py as a convenience wrapper.

No packaging change is required for a new config directory; setup.py discovers platform config directories automatically.

License

Apache-2.0

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors