Wendy for ROS 2
Inspect and debug live ROS 2 systems on a WendyOS device from the CLI, with no SSH. Nodes, topics, services, parameters, actions, lifecycle nodes, components, and rosbags.
wendy device ros2 brings the full ros2 command-line experience to a remote
device. List nodes and topics, echo messages, watch publish rates, render the
connectivity graph, read and set parameters, drive actions and lifecycle nodes,
and record rosbags, all from your machine, over the same secure connection the
CLI already uses.
Standard, upstream ROS 2. WendyOS runs real ROS 2 from stock containers, Humble
by default, configurable per app. Choose your middleware with frameworks.ros2.rmw:
CycloneDDS (default), Fast DDS, RTI Connext, or GurumDDS.
How it works
The agent discovers ROS 2 app containers (those deployed with a frameworks.ros2
config in wendy.json) and starts a CLI sidecar in the same DDS domain. Your
ros2 commands run inside that sidecar over gRPC.
ROS 2 discovery is app-local by default: Wendy injects ROS_LOCALHOST_ONLY=1
so unrelated apps and robots do not discover each other. A bridge or inspection
tool that intentionally needs the device's wider ROS 2 graph can opt in with
"discoveryScope": "host" in frameworks.ros2; pair it with a host-network
entitlement so DDS can reach the device interfaces.
No SSH, no source /opt/ros/<distro>/setup.bash, and no extra ports. If a device
runs apps across multiple RMW implementations (for example CycloneDDS and Fast
DDS), results are tagged with the RMW they came from, such as [cyclonedds].
Scaffold a ROS 2 app
wendy init writes the frameworks.ros2 block for you. Pass --framework ros2,
plus any of the --ros2-* flags to override the defaults:
wendy init \
--app-id my-ros2-app \
--target wendyos \
--language swift \
--framework ros2 \
--ros2-rmw cyclonedds \
--ros2-discovery-scope host \
--assistant skipAny --ros2-* flag on its own implies --framework ros2, and values are
validated up front, so a mistyped RMW or distro fails at init rather than at
deploy time. Run wendy init interactively on a WendyOS target and it asks
whether the app uses ROS 2, then walks through middleware, discovery scope, and
domain ID.
Existing projects need no scaffolding — add the frameworks.ros2 key to
wendy.json by hand and wendy run picks it up on the next deploy. See
wendy.json for every field.
Prerequisites
- A ROS 2 app running on the device. See Multi-app deployments for a complete talker/listener stack and the host-networking entitlement DDS discovery needs.
- A device selected as your default (or pass
--device). See Discovering devices.
Every subcommand accepts --domain to override the ROS_DOMAIN_ID. By default it
is read from the app's ROS 2 config, so you rarely need to set it. That includes
auto-derived domains: an app whose frameworks.ros2 omits domainId gets a
stable domain hashed from its appId (in the 0 to 232 range), and the CLI
follows it automatically. Every subcommand also honors the global --json flag
for machine-readable output.
Explore the graph
List what's running and how it's connected:
# Running nodes
wendy device ros2 nodes
# Topics (add --all for publisher/subscriber counts)
wendy device ros2 topics
wendy device ros2 topics --all
# Type, endpoints, and QoS for a single topic
wendy device ros2 topic info /chatter
# Services
wendy device ros2 servicesRender the node/topic connectivity graph as ASCII, or as Graphviz dot to pipe
into your own tooling:
wendy device ros2 graph
wendy device ros2 graph --format dotWatch live data
Stream deserialized messages from a topic, optionally stopping after a fixed count:
# Stream until ctrl-c
wendy device ros2 echo /chatter
# Stop after 10 messages
wendy device ros2 echo /chatter --count 10Monitor a topic's publish rate:
wendy device ros2 hz /chatterParameters
Read parameters across the whole system or a single node, and change them live, no restart required:
# List all parameters (or just one node's)
wendy device ros2 params
wendy device ros2 params --node /talker
# Get and set a single parameter
wendy device ros2 param get /talker use_sim_time
wendy device ros2 param set /talker use_sim_time trueCall a service
wendy device ros2 call /reset std_srvs/srv/EmptyPass a request payload as the optional third argument when the service type needs one.
Actions
List action servers, inspect one, and send goals with live feedback:
wendy device ros2 action list
wendy device ros2 action info /navigate
# Send a goal; add --feedback to stream feedback while it runs
wendy device ros2 action send_goal /navigate nav2_msgs/action/NavigateToPose "{pose: ...}" --feedbackCancel all in-flight goals on an action server (a Wendy extension; the upstream
ros2 action CLI has no cancel verb):
wendy device ros2 action cancel /navigateLifecycle nodes
Inspect and drive managed (lifecycle) nodes through their state machine:
# Lifecycle nodes on the system
wendy device ros2 lifecycle nodes
# Current state and available transitions for one node
wendy device ros2 lifecycle get /lifecycle_talker
wendy device ros2 lifecycle list /lifecycle_talker
# Trigger a transition (configure, activate, deactivate, cleanup, shutdown)
wendy device ros2 lifecycle set /lifecycle_talker configureComponents
Manage composable nodes in a running component container:
wendy device ros2 component list
wendy device ros2 component load /ComponentManager composition composition::Talker
wendy device ros2 component unload /ComponentManager 1Record rosbags
Record topics to a bag on the device, list what's been recorded, and pull a bag back to your machine:
# Record specific topics (ctrl-c to stop and finalize)
wendy device ros2 bag record /camera/image_raw /imu
# Optionally name the bag (defaults to an auto-named, timestamped bag)
wendy device ros2 bag record /scan --output drive-test
# List bags on the device
wendy device ros2 bag list
# Download a bag to a local directory
wendy device ros2 bag download drive-test ./local-bagsRun bag download with no arguments to pick from the device's bags
interactively. On a device running apps across multiple RMW implementations,
recording all topics captures one RMW's graph and warns about the others;
record explicit topic lists per RMW if you need both.
Health checks
Run ros2 doctor against the device's ROS 2 environment:
wendy device ros2 doctorAnything else
For any ros2 subcommand not wrapped above, use the raw passthrough. Flags meant
for Wendy (like --domain) go before the ros2 command word; everything after is
handed straight to ros2:
wendy device ros2 exec topic echo /chatter --once
wendy device ros2 --domain 42 exec node info /talkerVisualize in Foxglove
To see this data in real time on plots and panels, bridge the device's topics into Foxglove Studio with Wendy for Foxglove.
Related
- Multi-app deployments: deploy a ROS 2
stack with
wendy.jsonservices ordocker-compose.yml. - Entitlements: the host-network access ROS 2 discovery requires.
Robotics
Build, deploy, and operate ROS 2 robots with WendyOS. Standard, upstream ROS 2 from prototype to production fleet.
Wendy for Foxglove
Stream a WendyOS device's live ROS 2 topics into Foxglove Studio for real-time visualization, with a single command and nothing to install on the device by hand.