---json
{"name": "Install and connect"}
---
====== ROS 2: install and connect ======
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 [[https://docs.ros.org/en/jazzy/Installation/Ubuntu-Install-Debs.html|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: [[:axiom:ros2:sensors_and_boards|Sensors and multiple boards]] or [[:axiom:ros2:thermal_camera|Thermal camera in RViz]].