Table of Contents

Build the Axiom driver on Linux, select a connection in a board configuration file, and request sensor data through ROS services. This walkthrough uses one board in the /axiom namespace.

Build the workspace

Start with Ubuntu 24.04 and ROS 2 Jazzy, with rosdep, colcon and Git installed. For ROS installation, follow the official Ubuntu instructions. The source repository is private; authenticate with a GitHub account that has access.

mkdir -p ~/Projects
cd ~/Projects
git clone https://github.com/robotical/axiom-ros2.git
cd axiom-ros2

source /opt/ros/jazzy/setup.bash
rosdep update
rosdep install --from-paths src --ignore-src -r -y
colcon build --base-paths src --symlink-install

If this machine has never used rosdep, run sudo rosdep init once before rosdep update. A successful build ends with a summary of finished packages.

Create local configuration

From the repository root:

cp config/machine.env.example config/machine.env
cp config/boards.yaml.example config/boards.yaml
File Contains
config/machine.env ROS setup path, workspace path, ROS_DOMAIN_ID, guide port and board-file path. The workspace defaults to this checkout.
config/boards.yaml Board namespaces, USB serial paths or WebSocket addresses, and driver startup settings.

Both files are ignored by Git. Edit the copies for this machine. Every terminal in the same session must use the same ROS domain.

Wi-Fi board

First connect Axiom to your Wi-Fi network. Use its actual IP address in boards.yaml; 192.168.1.20 below is an example:

axioms:
  axiom:
    transport: ws
    device_uri: ws://192.168.1.20/ws
    auto_connect: false
    auto_reconnect: false
    autosub: false

Check that the board is reachable before starting ROS:

curl --max-time 5 http://192.168.1.20/api/v

Expect a JSON reply with rslt: “ok” and the board's firmware version. This checks reachability; the ROS driver uses the framed /ws WebSocket endpoint. Wi-Fi credentials are configured on Axiom separately.

USB board

Find the Linux serial path:

ls -l /dev/serial/by-id/

Then use a stable path in boards.yaml:

axioms:
  axiom:
    transport: serial
    serial.port: /dev/serial/by-id/REPLACE_WITH_AXIOM_DEVICE
    auto_connect: false
    auto_reconnect: false
    autosub: false

If the system supplies no by-id path, use its actual /dev/ttyACM… or /dev/ttyUSB… device. Your account must have serial-device access. On Ubuntu this normally means membership of dialout; after adding membership, log out and back in.

Prepare each ROS terminal

Run this in every terminal you use for the session:

source ~/Projects/axiom-ros2/scripts/setup_env.sh

It sources ROS and the built workspace and loads machine.env. It starts no nodes. If you cloned elsewhere, use that checkout's absolute path.

Terminal 1: start the driver

ros2 launch axiom_driver axiom_minimal_launch.py \
  namespace:=/axiom \
  boards_file:="$AXIOM_ROS_BOARDS_FILE"

Leave this terminal running. The axiom entry selects /axiom as the board namespace. With the configuration above, the node starts disconnected and acquisition remains off.

Terminal 2: connect, then start acquisition

Verify the loaded settings:

ros2 param get /axiom/axiom_bridge_node transport
ros2 param get /axiom/axiom_bridge_node device_uri

For USB, also inspect serial.port. Connect using the configured address or port:

ros2 service call /axiom/connect axiom_interfaces/srv/Connect '{device_uri: ""}'

Expect success: true. The empty device_uri uses the board's configuration. Connection alone does not start measurements.

ros2 service call /axiom/publish_data_subscription \
  axiom_interfaces/srv/PublishedDataSubscription '{rate_hz: 20.0}'

ros2 topic list -t --no-daemon

Expect another success: true and sensor topics once firmware packets arrive. 20.0 requests a packet delivery rate of 20 Hz; it does not set each sensor's sampling rate.

Inspect a measurement

Choose the exact topic from ros2 topic list -t. For an IMU, a path might be /axiom/bus_1/device_76a/imu/data_raw. Addresses are firmware identities, so yours may differ.

ros2 topic echo /axiom/bus_1/device_76a/imu/data_raw \
  sensor_msgs/msg/Imu --qos-reliability best_effort --once

Replace the example path with yours. A ROS echo subscribes to an existing topic; it does not enable firmware acquisition. Acceleration is in m/s² and includes gravity; angular velocity is in rad/s. This message has no fused orientation.

To watch the device inventory, run this separately and stop it with Ctrl+C:

ros2 topic echo /axiom/devices --qos-durability transient_local

Stop the session

In Terminal 2:

ros2 service call /axiom/publish_data_subscription \
  axiom_interfaces/srv/PublishedDataSubscription '{rate_hz: 0.0}'
ros2 service call /axiom/disconnect axiom_interfaces/srv/Disconnect '{}'

Then press Ctrl+C in Terminal 1. Stopping an echo subscriber alone leaves firmware acquisition running.

If something does not work

Symptom Check
Package not found Build successfully, then source scripts/setup_env.sh in this terminal.
Connect service waits Keep Terminal 1 running; check ros2 node list --no-daemon and that both terminals use the same ROS domain.
Wi-Fi timeout Check the current IP, the /api/v reply and the configured /ws address. After an IP change, edit the board file and relaunch the driver.
USB permission denied Check the device path, account permissions and whether another application owns the serial port.
Connected, no measurements Call publish_data_subscription, check its response and inspect /axiom/devices.
Echo receives nothing Use the exact discovered topic and --qos-reliability best_effort.

Next: Sensors and multiple boards or Thermal camera in RViz.