Skip to main content
Every node port carries a typed message. This guide shows how to use the built-in ROS 2 message types, how fixed and variable fields differ when you write them, and how to define your own workspace schema. For the full type list and reference details, see the message types reference and graph and schema files reference.

Use a ROS 2 message type

Cerulion ships native_ros2_messages — 254 message types across 22 ROS 2 packages, generated from the upstream .msg files. Import the type you need from its package module:
Reference a type as a port by giving it a field on the node struct:
In a graph, schemas are written with a slash (sensor_msgs/Image). The colon form sensor_msgs::Image is also accepted and normalized to the slash form.
Always import package-qualified. A few names exist in more than one package — Pose2D is in both geometry_msgs and vision_msgs — so a bare name is ambiguous. cerulion schema list prints every package and its types.

Fixed vs variable fields

How you write a message field depends on its size:
  • Fixed primitive fields (numbers, bytes, for example height, width, is_bigendian) live in a fixed section and are written directly. The macro derefs to that section and writes straight to shared memory.
  • Variable-length fields (string, T[]) have no fixed size, so the macro routes a write through a generated setter and a read through a generated accessor.
For sensor_msgs/Image, height and width are fixed, while encoding (a string) and data (a uint8[]) are variable:
On the reading side, a fixed field is read directly and a variable field through its accessor:
Writing a variable field used to require declaring it in the attribute (#[output(data, encoding)], or complex(...) for a nested one). Both forms are gone: #[output] is the canonical form for every schema.
The ROS 2 primitive types map to Rust as follows (a representative subset):

Define a custom schema

When no built-in type fits, define a workspace schema.

Create the schema file

cerulion schema create <name> writes schemas/<name>.yaml — the name verbatim, no case change — holding a skeleton whose single entry key is the PascalCased name.
The generated schemas/Reading.yaml:

Add fields

Edit schemas/Reading.yaml. fields: is a mapping whose key is "<type> <name>", so quote each key and leave its value empty. A T[] suffix marks a variable-length array; T[N] is a fixed-size one.

Inspect it

cerulion schema info <name> reports the name, description, field count, and a hash.
schema info resolves four sources in order — your workspace’s schemas/*.yaml, your workspace’s .msg store, the built-in ROS 2 types, and a connected robot’s own types — and the source: line names which one answered. cerulion schema list prints all of them, marking a built-in that a store entry overrides.

The .msg store

A workspace can also carry ROS message definitions verbatim, as .msg files under schemas/<package>/msg/<Type>.msg. cerulion ros2 attach writes the types it discovered there, so a robot’s own message definitions land in your workspace without being hand-translated to YAML. Store types are first-class everywhere a name and a hash are enough: graph validate, recording, replay, and schema info. They sit between your workspace YAML and the built-ins, so a YAML schema of the same name wins and a built-in of the same name is outranked.
A store type cannot type a node port. cerulion node create and node modify refuse it, naming the store type and the remedy, because a store type has no generated Rust type — the use native_ros2_messages::…; line the scaffolder would write could never compile. Convert it to a workspace YAML schema first.Declaring the same name twice is refused outright rather than resolved by precedence: two schemas/*.yaml files declaring one entry name, a <name>.yaml beside another file’s <name> entry, or a YAML definition the .msg store also spells. The error names every source. Declare each name once.
Delete a schema you no longer need:

Next steps

Define a node

Put these message types to work on node ports.

Message types

Every available package and type.