OpenClaw plugin for the ROSClaw stack.
This repository is the OpenClaw-facing half of ROSClaw. It turns the robot-side
surfaces exported by rosclaw-ros2 into AI tools, direct commands, safety
checks, and prompt context.
| Repo | Responsibility |
|---|---|
rosclaw |
Workspace bootstrap, top-level setup flow, Docker Compose, demos, integration tests |
rosclaw-ros2 |
Robot-side discovery, safety, perception, bringup, relay, and WebRTC bridges |
rosclaw-plugin |
OpenClaw plugin that consumes the robot manifest and exposes ROS 2 tools |
If you want the full stack running quickly, start with the bootstrap repo:
rosclaw. If you are changing the
OpenClaw integration layer, start here.
The plugin expects the companion ROS 2 packages from
rosclaw-ros2 to be built and
running. The default path is:
ros2 launch rosclaw_bringup rosclaw.launch.py platform:=turtlebot3That starts:
rosbridge_websocketlistening onws://0.0.0.0:9090/rosclaw/manifestand/rosclaw/get_manifest/rosclaw/estop,/rosclaw/safety_status, and/rosclaw/set_safety_policy
If you are scoping the robot with robot_namespace:=/robot1, remember that for
the plugin config in step 3.
openclaw plugins install @openclaw/rosclawThe default client transport is rosbridge:
{
"transport": {
"mode": "rosbridge"
},
"rosbridge": {
"url": "ws://<robot-ip>:9090",
"reconnect": true,
"reconnectInterval": 3000
},
"robot": {
"name": "Robot",
"namespace": ""
},
"safety": {
"maxLinearVelocity": 1.0,
"maxAngularVelocity": 1.5,
"workspaceLimits": {
"xMin": -10,
"xMax": 10,
"yMin": -10,
"yMax": 10
}
}
}Set robot.namespace to the same value you used for
ros2 launch ... robot_namespace:=... on the robot side.
ROSClaw uses a robot-owned capability manifest for introspection rather than
generic rosapi-style probing.
The rosclaw_discovery node runs on the robot, introspects the ROS 2 graph,
and publishes a typed CapabilityManifest. The plugin consumes this through
the /rosclaw/get_manifest service and caches the result for 60 seconds.
Why this design:
- The robot owns its self-description instead of the plugin guessing from the raw graph.
- The manifest is curated, so the agent sees relevant topics, services, and actions instead of ROS plumbing noise.
- One typed service call returns topics, services, and actions together.
- The manifest schema is ours to evolve as the stack grows.
Operational constraints:
rosclaw_discoverymust be running on the robot or manifest requests fail.- The plugin clears its manifest cache whenever transport reconnects.
- If
robot.namespaceis set, the manifest request is scoped to that robot.
This is the main cross-repo distinction to keep straight:
- The plugin exposes client transport modes
rosbridgeandlocal. - The robot-side repo exposes optional
relayandwebrtcbridge nodes for remote sessions. relayandwebrtcare deployment options launched fromrosclaw_bringup; they are not plugin config values in this repo.
| Mode | Transport | Dependency | Best fit |
|---|---|---|---|
rosbridge |
WebSocket | Pure JS | Default LAN or VPN deployment |
local |
Direct DDS via rclnodejs |
Optional native addon | Gateway runs on a sourced Linux ROS host |
Notes:
rosbridgeis the default path across the top-level docs.localrequires Linux plus a sourced ROS 2 environment.- Remote relay/WebRTC deployments still depend on the robot-side bridge nodes
from
rosclaw-ros2and the signaling server fromrosclaw-signaling.
| Key | Default | Description |
|---|---|---|
transport.mode |
"rosbridge" |
Transport mode: rosbridge or local |
rosbridge.url |
"ws://localhost:9090" |
WebSocket URL of the robot-side rosbridge server |
rosbridge.reconnect |
true |
Auto-reconnect on disconnect; clears manifest and safety cache on reconnect |
rosbridge.reconnectInterval |
3000 |
Milliseconds between reconnect attempts |
local.domainId |
0 |
ROS 2 domain ID for direct DDS mode |
robot.name |
"Robot" |
Display name used in logs |
robot.namespace |
"" |
Robot namespace filter passed to /rosclaw/get_manifest and used by /estop |
safety.maxLinearVelocity |
1.0 |
Fallback max linear velocity in m/s |
safety.maxAngularVelocity |
1.5 |
Fallback max angular velocity in rad/s |
safety.workspaceLimits |
{xMin: -10, xMax: 10, yMin: -10, yMax: 10} |
Navigation goal bounds in meters |
The plugin config schema also lives in
openclaw.plugin.json.
Safety limits come from two sources, merged at runtime:
| Limit | Source | Precedence |
|---|---|---|
maxLinearVelocity |
Robot's /rosclaw/safety_status topic |
Robot-reported wins if available |
maxAngularVelocity |
Robot's /rosclaw/safety_status topic |
Robot-reported wins if available |
workspaceLimits |
Plugin config only | Always from config |
On each prompt build, the plugin reads /rosclaw/safety_status with a short
timeout. Robot-reported velocity limits override config fallbacks when present.
Workspace limits stay local to the plugin. On transport reconnect, both the
manifest cache and robot-reported safety limits are cleared.
If the robot publishes /rosclaw/scene via rosclaw_perception, the plugin
reads the latest scene description during prompt build and injects it into the
agent's system prompt under a "Current Scene" heading.
This gives the agent spatial awareness without requiring a camera snapshot tool call for every prompt. Scene messages include a timestamp so stale data can be detected.
| Tool | Description |
|---|---|
ros2_publish |
Publish a message to a ROS 2 topic |
ros2_subscribe_once |
Subscribe to a topic and return one message |
ros2_service_call |
Call a ROS 2 service |
ros2_action_goal |
Send a goal to a ROS 2 action server |
ros2_param_get |
Read a ROS 2 parameter |
ros2_param_set |
Update a ROS 2 parameter |
ros2_list_topics |
Fetch the robot capability manifest |
ros2_camera_snapshot |
Capture a camera frame and return the image |
| Command | Description |
|---|---|
/estop |
Emergency stop; use /estop release to release it |
/transport |
Show or switch between rosbridge and local at runtime |
before_prompt_buildfetches the capability manifest, syncs safety limits, reads the latest scene description, and injects that context into the agent prompt.before_tool_callvalidates velocity limits, workspace bounds, protected parameter updates, and protected service calls.
check-statusnavigate-totake-photopick-object
Build and test the repo directly:
npm install
npm run build
npm testFor end-to-end bringup, use the workspace bootstrap repo so this plugin and the robot-side packages share one workspace layout.
Apache-2.0