Skip to main content

Usage

This guide shows you how to run ROS 2 nodes with Cerulion RCL Hooks enabled. Once set up, the hooks will automatically hijack all published messages before serialization and publish them directly to Cerulion shared memory, enabling sub-microsecond latencies. Your ROS 2 nodes seamlessly transfer to Cerulion without any code changes.

Prerequisites

Before running nodes with the hooks, ensure you have:

Built Library

The shared library built (see Installation Guide)

ROS Workspace

A ROS 2 workspace with your nodes built and sourced

Cerulion Running

Cerulion transport system running and accessible

Node Executable

A ROS 2 node you want to run with hooks enabled

Running a ROS Node with Hooks

The process involves launching your ROS node with the LD_PRELOAD environment variable pointing to the hooks library. Let’s walk through it step by step.
1

Source your ROS workspace

First, source the ROS workspace that contains the node you want to run:
source /path/to/your_ros_ws/install/setup.bash
Replace /path/to/your_ros_ws with the actual path to your ROS 2 workspace. This is typically where you’ve built your ROS packages.
Sourcing the workspace sets up the ROS environment variables and makes your built packages available. You need to do this in the same terminal session where you’ll run the node.
2

Launch the node with LD_PRELOAD

Run your ROS node with the hooks library preloaded:
LD_PRELOAD=/home/cerulion/cerulion-dev/target/debug/libcerulion_rcl_hooks.so \
ros2 run <package_name> <node_executable>
Replace:
  • /home/cerulion/cerulion-dev/target/debug/libcerulion_rcl_hooks.so with the path to your built library
  • <package_name> with your ROS package name
  • <node_executable> with the executable name
Make sure to use the full absolute path to the .so file. Relative paths may not work correctly with LD_PRELOAD.
3

Example: Running a camera node

Here’s a concrete example for a camera node:
LD_PRELOAD=/home/cerulion/cerulion-dev/target/debug/libcerulion_rcl_hooks.so \
ros2 run image_publisher image_publisher_node
This runs the image_publisher package’s node with hooks enabled.
4

Observe the hook logs

The hooks write diagnostic messages to stderr. You should see messages like:
[Cerulion Hook] Library loaded - RCL hooks active
[Cerulion Hook] enter rcl_publisher_init topic='/camera/color/image_raw'
[Cerulion Hook] Published to 'camera/color/image_raw' seq=0 size=921600
If you see these messages, the hooks are working correctly! The library has loaded and is intercepting ROS calls.
5

Save logs for later inspection (optional)

To save hook diagnostics to a file:
LD_PRELOAD=/home/cerulion/cerulion-dev/target/debug/libcerulion_rcl_hooks.so \
ros2 run <package_name> <node_executable> 2>hook_logs.txt
This redirects stderr (where hook messages go) to hook_logs.txt.

Running ROS Bags with Hooks

You can also use RCL Hooks with ROS 2 bag playback. This allows you to replay recorded bag files and have their messages automatically hijacked and published to Cerulion, just like with live nodes.
1

Source your ROS workspace

First, source the ROS workspace:
source /path/to/your_ros_ws/install/setup.bash
2

Play a bag file with LD_PRELOAD

Run ros2 bag play with the hooks library preloaded:
LD_PRELOAD=/home/cerulion/cerulion-dev/target/debug/libcerulion_rcl_hooks.so \
ros2 bag play /path/to/your_bag_directory
Replace:
  • /home/cerulion/cerulion-dev/target/debug/libcerulion_rcl_hooks.so with the path to your built library
  • /path/to/your_bag_directory with the path to your ROS 2 bag directory
3

Example: Playing a camera bag

Here’s a concrete example for playing a bag file containing camera data:
LD_PRELOAD=/home/cerulion/cerulion-dev/target/debug/libcerulion_rcl_hooks.so \
ros2 bag play ~/bags/camera_recording_2024_01_15
This replays the bag file with hooks enabled, automatically hijacking all published messages and sending them to Cerulion.
4

Play specific topics (optional)

You can also play only specific topics from the bag:
LD_PRELOAD=/home/cerulion/cerulion-dev/target/debug/libcerulion_rcl_hooks.so \
ros2 bag play /path/to/your_bag_directory --topics /camera/color/image_raw /imu/data
This is useful when you only want to replay certain topics that have corresponding schemas.
5

Observe the hook logs

Just like with live nodes, you’ll see hook diagnostic messages:
[Cerulion Hook] Library loaded - RCL hooks active
[Cerulion Hook] enter rcl_publisher_init topic='/camera/color/image_raw'
[Cerulion Hook] Published to 'camera/color/image_raw' seq=0 size=921600
[Cerulion Hook] Published to 'camera/color/image_raw' seq=1 size=921600
If you see these messages, the hooks are working correctly with your bag playback!
When playing ROS bags with hooks enabled, messages are hijacked just like with live nodes. The bag player publishes messages, and the hooks intercept them before serialization, routing them to Cerulion shared memory. This is perfect for testing, replaying recorded data, or processing historical sensor data through Cerulion.
Using hooks with bag playback is an excellent way to test your Cerulion setup without needing live sensor hardware. You can replay recorded data and verify that all topics are being properly hijacked and published to Cerulion.

Understanding the Logs

The hooks provide diagnostic information to help you understand what’s happening. Here’s what to look for:

Library Loaded

[Cerulion Hook] Library loaded - RCL hooks active
This confirms the hooks library was successfully loaded and is ready to intercept ROS calls.

Publisher Initialization

[Cerulion Hook] enter rcl_publisher_init topic='/camera/color/image_raw'
This shows when a ROS publisher is created. The hooks record the topic name and message type for later use.

Message Publishing

[Cerulion Hook] Published to 'camera/color/image_raw' seq=0 size=921600
This indicates:
  • Topic name: camera/color/image_raw
  • Sequence number: 0 (increments with each message)
  • Message size: 921600 bytes
The sequence number helps you track message flow. Each published message gets a unique sequence number.

Schema Processing Failures

If you see:
[Cerulion Hook] Serialization failed...
This means the hooks couldn’t process a ROS message for Cerulion. Common causes:
  • Missing schema for the message type
  • Incompatible field mappings
  • Message structure issues
When processing fails, the message is hijacked and does not continue to ROS subscribers. Cerulion won’t receive that message either. Make sure you have the correct schema for your message type.

What Gets Published to Cerulion?

The hooks automatically hijack messages for topics that have corresponding schemas. By default, this includes:

Image Streams

Camera feeds, compressed images, depth images, and other image transports

Sensor Data

IMU readings, camera info, sensor metadata, and calibration data

Transform Data

TF static transforms and dynamic transform updates

Custom Topics

Any topic with a matching schema in schemas_ros2/

Topic Inclusion Logic

Topics are included based on the virtual_subscription_count function in the hooks source code. To hijack additional topics:
  1. Ensure a schema exists in schemas_ros2/ for the message type
  2. Update the topic inclusion logic in the hooks (if needed)
  3. Rebuild the hooks library
Most common ROS message types already have schemas included. You only need to add schemas for custom message types or less common formats.

Verifying It’s Working

Here’s how to confirm the hooks are working correctly:
1

Check library is loaded

Use lsof to verify the hooks library is loaded in your process:
lsof -p $(pgrep -f "ros2 run") | grep cerulion_rcl_hooks
You should see the library file listed.
2

Monitor hook output

Watch for hook log messages in your terminal. If you see initialization and publishing messages, the hooks are active.
3

Verify Cerulion receives data

Check your Cerulion dashboard or logs to confirm messages are being received. The topic names should match your ROS topics.
4

Confirm seamless transition

Verify that your ROS 2 nodes are operating normally. The hooks hijack messages before they reach ROS subscribers, but your drivers won’t know the difference - the transition to Cerulion is completely seamless.
If Cerulion receives data and your ROS 2 nodes continue operating normally, everything is configured correctly! The hooks have successfully hijacked messages and your drivers are seamlessly using Cerulion.

Using Release Builds

For production use, use the optimized release build:
LD_PRELOAD=/home/cerulion/cerulion-dev/target/release/libcerulion_rcl_hooks.so \
ros2 run <package_name> <node_executable>
The release build:
  • Runs faster (optimized code)
  • Uses less memory
  • Has smaller binary size
  • Takes longer to compile
Use debug builds for development and troubleshooting, and release builds for production deployments.

Advanced: Environment Variables

You can set LD_PRELOAD in your environment for convenience:
export LD_PRELOAD=/home/cerulion/cerulion-dev/target/debug/libcerulion_rcl_hooks.so
ros2 run <package_name> <node_executable>
Remember that LD_PRELOAD affects all processes launched from that terminal. If you don’t want hooks on other processes, use the inline syntax instead.

Troubleshooting

If something isn’t working, check the Troubleshooting Guide for common issues and solutions.

Next Steps

Now that you’re running nodes with hooks enabled, you might want to:
  • Learn about troubleshooting common issues
  • Understand how to add schemas for custom message types
  • Explore Cerulion’s visualization and analysis tools