Axiom's firmware descriptors drive ROS sensor discovery. You do not need to list every sensor in boards.yaml. Follow Install and connect first and leave acquisition running.
ros2 topic list -t --no-daemon
ros2 service list -t
ros2 topic echo /axiom/devices --qos-durability transient_local
Stop the inventory echo with Ctrl+C before entering another command. Sensor topics live beneath the board namespace, for example:
| Topic suffix | ROS type |
|---|---|
| …/imu/data_raw | sensor_msgs/msg/Imu |
| …/range | sensor_msgs/msg/Range; metres, with NaN for invalid readings |
| …/temperature | sensor_msgs/msg/Temperature; °C |
| …/humidity | sensor_msgs/msg/RelativeHumidity; fraction from 0 to 1 |
| …/thermal/grid | axiom_interfaces/msg/ThermalGrid; dimensions and pixel temperatures |
| …/sample | axiom_interfaces/msg/DeviceSample; decoded values, validity and timing information |
The canonical path contains the firmware bus and normalised hexadecimal device address, such as /axiom/bus_1/device_76a/…. Use the inventory or topic list instead of assuming an address from the connector number.
A subscriber can keep a topic name in the graph after its publisher disappears. Check publisher count, not just whether the name is listed:
ros2 topic info /axiom/bus_1/device_129/range --verbose
Replace this example with the actual sensor topic. A waiting echo does not mean the publisher is still connected.
Firmware must recognise the device and supply a compatible descriptor. For a new sensor type, start with the Device Library. Standard descriptor profiles need no per-sensor ROS configuration; unsupported custom binary formats or ROS mappings can require driver changes.
Aliases provide preferred names for application code while preserving the identity-based topics. Add rules to a board entry only when you want an alias:
axioms:
axiom:
transport: ws
device_uri: ws://192.168.1.20/ws
auto_connect: false
auto_reconnect: false
autosub: false
topic_aliases:
imu/data_raw: {type: LSM6DS, source: imu/data_raw}
range: {type: VL53L4CD, source: range}
These rules can add /axiom/imu/data_raw and /axiom/range. They are not a sensor support list. An alias binds only when exactly one matching device is online, resolved and fresh. If several sensors match, add the desired string bus and address selectors from the inventory, or use a canonical topic. Relaunch the driver after changing aliases.
Descriptors can expose configuration and output operations as services beneath:
/axiom/bus_BUS/device_ADDRESS/commands/COMMAND
Find the real paths with ros2 service list -t. Inspect argument order, units and permitted values in /axiom/device_metadata or the dashboard's information dialogs.
ros2 topic echo /axiom/device_metadata --qos-durability transient_local --once
For example, an LSM6DS descriptor may expose this sample-rate service:
ros2 service call /axiom/bus_1/device_76a/commands/set_sample_rate \
axiom_interfaces/srv/DeviceCommand '{values: [52.0]}'
Use the discovered path and a rate advertised by that device. Numeric values follow descriptor argument order. No-argument commands use {values: []}. A successful reply confirms firmware acknowledgement; it does not prove physical completion of an actuator movement. Unsupported custom value formats are not advertised as callable services.
Add a separate namespace and endpoint for each board. This manual example uses one Linux USB connection and one Wi-Fi connection:
axioms:
axiom/front:
transport: serial
serial.port: /dev/serial/by-id/REPLACE_WITH_FRONT_AXIOM
auto_connect: false
auto_reconnect: false
autosub: false
axiom/rear:
transport: ws
device_uri: ws://192.168.1.21/ws
auto_connect: false
auto_reconnect: false
autosub: false
Save it in the board file selected by machine.env. In Terminal 1:
ros2 launch axiom_driver multi_axiom.launch.py \
boards_file:="$AXIOM_ROS_BOARDS_FILE"
In Terminal 2, connect and enable acquisition for each board separately:
ros2 service call /axiom/front/connect axiom_interfaces/srv/Connect '{device_uri: ""}'
ros2 service call /axiom/front/publish_data_subscription \
axiom_interfaces/srv/PublishedDataSubscription '{rate_hz: 20.0}'
ros2 service call /axiom/rear/connect axiom_interfaces/srv/Connect '{device_uri: ""}'
ros2 service call /axiom/rear/publish_data_subscription \
axiom_interfaces/srv/PublishedDataSubscription '{rate_hz: 20.0}'
Each driver has its own connection, metadata, queues, aliases and frame prefix. Topics and services live under /axiom/front or /axiom/rear, so identical sensor addresses on different boards do not conflict. Duplicate namespaces, frame IDs and endpoints are rejected.
For an unattended application, auto_connect: true and autosub: true combine the connection and acquisition steps at startup. auto_reconnect: true separately enables retries after an unexpected connection loss. The manual example above enables none of these.
Stop acquisition and disconnect both boards using their respective service namespaces before stopping the launch process.
Back to Axiom with ROS 2.