Connect one Axiom with an AMG8833 8×8 thermal camera, request its measurements and display a heatmap with a temperature label for every pixel. This uses axiom_driver, axiom_thermal_viz and RViz. The dashboard is optional.
Expected display
Illustrative 8×8 frame generated for this screenshot. The commands below use the measurements from your camera.
Before starting
Complete Install and connect. For Wi-Fi, set the axiom entry in boards.yaml to transport: ws and device_uri: ws://YOUR_AXIOM_IP/ws. Keep auto_connect, auto_reconnect and autosub false. Attach the camera to Axiom.
Build the supplied RViz configuration from the repository root:
source scripts/setup_env.sh
rosdep install --from-paths src examples/scenarios-dashboard/src --ignore-src -r -y
colcon build --base-paths src examples/scenarios-dashboard/src --symlink-install
source scripts/setup_env.sh
Open four terminals and source ~/Projects/axiom-ros2/scripts/setup_env.sh in each. If a driver is already running, use that session rather than starting a duplicate.
Terminal 1: start the driver
ros2 launch axiom_driver axiom_minimal_launch.py \
namespace:=/axiom boards_file:="$AXIOM_ROS_BOARDS_FILE"
Leave it running. It reads the selected board's connection settings.
Terminal 2: connect and request data
ros2 service call /axiom/connect axiom_interfaces/srv/Connect '{device_uri: ""}'
ros2 service call /axiom/publish_data_subscription \
axiom_interfaces/srv/PublishedDataSubscription '{rate_hz: 20.0}'
ros2 topic list -t --no-daemon
Both service calls should return success: true. Find the topic ending in /thermal/grid, with type axiom_interfaces/msg/ThermalGrid. No thermal entry is required in the board file.
Set the exact discovered path; this is an example address:
THERMAL_TOPIC=/axiom/bus_1/device_169/thermal/grid
ros2 topic echo "$THERMAL_TOPIC" axiom_interfaces/msg/ThermalGrid \
--qos-reliability best_effort --once
Expect width: 8, height: 8, 64 values in temperature_c and a nonempty header.frame_id. The prompt returns after one frame. Do not continue if no frame arrives.
Terminal 3: convert the grid to RViz markers
Variables belong to the terminal where you set them. Set the same camera topic here, replacing the example path with yours:
THERMAL_TOPIC=/axiom/bus_1/device_169/thermal/grid
ros2 run axiom_thermal_viz thermal_heatmap --ros-args \
-r __ns:=/sensing \
-p input_topic:="$THERMAL_TOPIC" \
-p output_topic:=thermal_heatmap \
-p use_dynamic_range:=false \
-p min_temperature:=15.0 \
-p max_temperature:=40.0
Keep it running. It subscribes to the grid and publishes /sensing/thermal_heatmap markers and /sensing/thermal_heatmap_labels temperature labels. The colour scale stays fixed at 15–40 °C.
Terminal 4: select the frame and open RViz
Use the actual camera topic in this terminal too:
THERMAL_TOPIC=/axiom/bus_1/device_169/thermal/grid
THERMAL_FRAME="$(ros2 topic echo "$THERMAL_TOPIC" \
axiom_interfaces/msg/ThermalGrid --field header.frame_id \
--qos-reliability best_effort --once | sed -n '1p')"
printf '%s\n' "$THERMAL_FRAME"
Once a frame name is printed, run RViz in this same terminal:
ros2 run rviz2 rviz2 \
-d "$(ros2 pkg prefix --share axiom_marty_demo)/config/thermal.rviz" \
-f "${THERMAL_FRAME:?No camera frame received}"
You should see an 8×8 heatmap with small temperatures in °C. Move your hand near the camera and watch the cells change. Marker size is a display layout; it is not a measurement of the object's physical size or position.
If RViz is empty
| Check | What to look for |
|---|---|
| Raw grid | The Terminal 2 echo returns a frame. If not, check acquisition and whether the camera is online in /axiom/devices. |
| Adapter input | input_topic exactly matches the discovered thermal topic. |
| Marker publisher | ros2 topic info /sensing/thermal_heatmap --verbose reports a publisher. |
| Fixed Frame | It matches header.frame_id from the camera message. |
| Displays | Heatmap uses a Marker display on /sensing/thermal_heatmap; labels use MarkerArray on /sensing/thermal_heatmap_labels. |
| Colour saturation | Temperatures outside 15–40 °C clip to the end colours. Adjust the limits or enable use_dynamic_range. |
The heatmap can render in its own sensor frame without another TF node. RViz may still report a global warning that no TF data has been received. To place the camera in a robot's coordinate system, supply its actual mounting transform separately.
Clean up
Press Ctrl+C in Terminal 4, then Terminal 3. 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 '{}'
Finally, press Ctrl+C in Terminal 1. Back to Axiom with ROS 2.