cerulion ros2 attach points Cerulion at a robot that is already running ROS 2. It discovers the live DDS topics, generates a bridge graph for the ones whose types resolve, and runs it — so those topics become ordinary Cerulion topics you can echo, record, visualize, and consume from your own nodes.
Run it on the robot, or on a machine on the robot’s DDS network.
Look before you write
--dry-run prints the discovery report and stops: it writes nothing and runs nothing.
The report tells you which topics resolved to a known type and which did not. A topic whose type Cerulion cannot resolve is left out of the generated graph — add the message definition to your workspace and re-run if you need it.
Read the migration section
Every attach report ends with aMIGRATION section — no flag, --dry-run included. It groups the discovered processes by whether they could run on Cerulion transport directly instead of being bridged, and prints the commands that would do it:
.msg files, and stays bridged when a type resolves nowhere.
Endpoints attach cannot attribute to a node are counted as topics rather than processes, and their line says so: no ros_discovery_info record was seen for them, which is either a vendor or raw-DDS process or a node table the discovery window did not observe. Where such a topic’s type does resolve, the line still tells you what a restart would buy. On a robot that publishes no node table at all, the section says plainly that no restartable process can be named, and prints no command block — there is no process to name in it.
Paste the ros2: block into a graph file and fill in each package and executable: DDS discovery sees endpoints, not launch metadata, so attach cannot know which package ships a node. See Or run the ROS 2 nodes on Cerulion transport below.
ROS plumbing endpoints — parameter services,
/rosout, /parameter_events, ros_discovery_info — are left out of the judgment. Every ROS 2 node carries them under any RMW, so counting them would mark every stock node unrestartable. A process that exposed nothing else is listed as having no message endpoints seen.Generate and run the bridge
graphs/go2.yaml plus graphs/go2.bridge.yaml, asks you to confirm, and then runs the bridge. Use --yes for scripts and non-interactive shells.
--robot-name is not the network identity. The name that shows up in cerulion topic list and over mDNS comes from the machine’s hostname, or from CERULION_ROBOT_IDENTITY if you set it.See the data on your desk
The generated graph bridges the robot’s topics and nothing else — no visualization node is staged on the robot, which keeps the robot’s job to shipping raw frames. To look at the data, work from your own machine:Consume a bridged topic from your own node
A bridged topic is a normal topic, so wire an input to it by absolute name:Record a bridged system
A bridge run records like any other run, and a recording of one plays back as a robot substitute when the robot is not available:Use plain
bag play for a bridge recording. A bridge node reads a live device rather than computing from its graph inputs, and --resim all re-executes every node in the bag — including the bridge, against DDS that is no longer there. See Record and replay a run.Or run the ROS 2 nodes on Cerulion transport
Bridging carries another robot’s DDS traffic across. When the ROS 2 nodes are yours to launch, run them on Cerulion transport instead of bridging to them — swap the command, not the stack:run or launch reaches ros2 untouched, and Cerulion stages the child so ROS 2 loads rmw_cerulion — the nodes’ topics land on the same shared-memory transport your native nodes use. This is Unix only. See cerulion ros2.
The topics keep their ROS names verbatim: a ROS 2 publisher on /camera/image_raw is the Cerulion topic /camera/image_raw, leading slash included, so you wire an #[input] to it and record it under the name ROS 2 already uses. Each of those publishers also registers its topic with the machine’s network plane, so a ROS 2 node’s output is announced and demandable from your desk exactly like a native node’s — see Reach remote robots.
A ROS 2 publisher has no graph YAML to size its payloads in, so each variable-length message type gets the same per-type shared-memory budget Cerulion gives one of its own outputs of that schema — a type Cerulion does not know takes 128 MiB. A message larger than its budget fails to publish, loudly; raise the ceiling for that type with CERULION_RMW_SLICE_CEILING:
ros2: entries beside your native nodes and run cerulion graph run:
graph run spawns and supervises each entry; a ros2: entry declares no ports, so its topics meet native nodes by absolute topic name. See ros2: entries.
Next steps
Message types
The 254 built-in ROS 2 messages that resolve out of the box.
Record and replay a run
Bag a bridged system and play it back without the robot.