---json {"name": "Foxglove sensor dashboards"} --- ====== Foxglove sensor dashboards ====== Use the host ROS driver with either USB or Wi-Fi. Foxglove displays ROS topics through ''%%foxglove_bridge%%''; it does not connect directly to Axiom or start firmware acquisition. Complete the [[:axiom:ros2:getting_started|host setup]] first, using host firmware and the setup-file path for your installed ROS distribution. Ready-made layouts: ^Layout ^Display ^ |[[https://github.com/robotical/axiom-ros2/blob/main/examples/foxglove/one-axiom-thermal.json|one-axiom-thermal.json]]|One AMG8833 8×8 thermal Image panel | |[[https://github.com/robotical/axiom-ros2/blob/main/examples/foxglove/two-axiom-imu.json|two-axiom-imu.json]] |Acceleration and angular velocity plots for two boards| |[[https://github.com/robotical/axiom-ros2/blob/main/examples/foxglove/one-axiom-sound.json|one-axiom-sound.json]]|Sound scalars and nine-band spectrum; embedded user script, no extension required| |[[https://github.com/robotical/axiom-ros2/blob/main/examples/foxglove/spectrum-panel/one-axiom-spectrum.json|one-axiom-spectrum.json]]|Frequency-labelled coloured bars; install the optional Axiom Spectrum extension first| Generated sensor topics use model/location roots, for example ''/axiom1/amg8833_b1_169/image'' for a thermal camera and ''/axiom1/lsm6ds_b1_76a/data_raw'' for an IMU. The supplied layouts instead use explicit convenience aliases ''/axiom1/thermal/image'' and ''/axiom1/imu/data_raw''. These are user-chosen destinations, not automatic legacy topics. Set their sources to ''image'' and ''data_raw'' as shown below, or select the actual canonical topics in the imported panels. The bundled layouts use example board namespaces. Match those namespaces/aliases in your board configuration, or select your actual topics in the imported panel settings. ===== Install the bridge and connect a viewer ===== In a prepared terminal at the repository root, install the bridge once for the loaded distribution: source scripts/setup_env.sh sudo apt install "ros-${ROS_DISTRO}-foxglove-bridge" Installation uses the ROS package repositories configured for that distribution. See the [[https://docs.foxglove.dev/docs/getting-started/frameworks/ros2|official ROS bridge guide]] for package availability and source-build options. Start the bridge after the driver is running with the same ROS domain and middleware settings. For multiple independent demos, start each bridge in its demo's domain and connect its viewer to that bridge. If bridges run on one host, give them different listening ports and use the matching port in each viewer. Select physical boards separately; see [[:axiom:ros2:automatic_startup#multiple_demos_on_the_same_wi-fi|shared-network discovery and board selection]]: ros2 launch foxglove_bridge foxglove_bridge_launch.xml Leave it running. Open [[https://app.foxglove.dev|app.foxglove.dev]] in Chrome or the [[https://foxglove.dev/download|Foxglove desktop app]] on a supported computer. Choose **Open connection** from the dashboard or top-left app menu, then **Foxglove WebSocket**: * Viewer on the bridge host: ''%%ws://localhost:8765%%''. * Viewer on another computer: ''%%ws://ROS_HOST_IP:8765%%'', replacing ''%%ROS_HOST_IP%%'' with the bridge host's reachable address, not Axiom's Wi-Fi address. Select **Open** and check that the Axiom topics appear. ''%%localhost%%'' means the computer running the viewer. For a remote viewer, the bridge's TCP port 8765 must be reachable; browser/OS local-network permissions may also need to be allowed. You need account access to direct connections and layout import/editing. Foxglove currently specifies a developer seat for direct connections and editing layouts; see its [[https://docs.foxglove.dev/docs/visualization/connecting/live|live connection]] and [[https://docs.foxglove.dev/docs/visualization/layouts|layout]] documentation. The web viewer needs internet to load and sign in. The direct measurement stream travels between the local bridge and viewer. Desktop offline use depends on [[https://docs.foxglove.dev/docs/standalone-license|standalone licensing]]. [[:axiom:ros2:thermal_camera|RViz]] provides a local thermal-display alternative. ===== Illuminance and scalar plots ===== Illuminance and numeric scalar topics can be plotted directly through the same bridge. First inspect ''%%ros2 topic list -t --no-daemon%%'' and the board's ''devices'' inventory, then use the actual topic paths. See [[:axiom:ros2:standard_messages|Standard messages and mappings]] for software availability, units, invalid readings and descriptor mapping requirements. No optional descriptor mapping is needed for the normal LTR-390 outputs. In the connected Foxglove viewer: - Add a **Plot** panel and open its settings. - Add a series using your Illuminance topic's ''.illuminance'' field. An illustrative path is ''/axiom/ltr_2d390_b1_53/ambient.illuminance''. - Label the panel/series **Illuminance** and the vertical axis **lux**. - Add a second Plot panel for the UVI topic's ''.data'' field, for example ''/axiom/ltr_2d390_b1_53/UVI.data''. Label its axis **UV index**. Keep unlike units on separate plots. - Use **Log time** for headerless Float64 data. For a live connection this is reception time; it is not the original measurement timestamp. Illuminance also provides ''header.stamp'' if measurement-time plotting is required. The example namespace, bus and sensor address are illustrative. Copy complete paths from the viewer rather than assuming ''/axiom'' or address ''53''. A headerless scalar carries no units; use inventory ''output_info'' to choose the axis label. ''sample'' retains timing and validity, while ''device_metadata'' supplies the descriptor. ^ Message type ^ Numeric field for a Plot series ^ | ''sensor_msgs/msg/Illuminance'' | ''.illuminance''; lux | | ''sensor_msgs/msg/Temperature'' | ''.temperature''; °C | | ''sensor_msgs/msg/RelativeHumidity'' | ''.relative_humidity''; fraction | | ''std_msgs/msg/Float64'' | ''.data''; unit from ''output_info'' | These numeric fields do not require parsing the JSON ''data'' topic. A separate sensor output named ''UVI'' is a Float64 topic even though each message's numeric field is also called ''data''. Bool and scalar text outputs can be inspected in **Raw Messages**; their invalid readings are omitted, so a panel may still show its last received value. Check freshness and validity rather than treating a retained display as a new reading. Save the layout after choosing the correct topics and units; it can be reopened without rebuilding each series. The bundled layouts include thermal, two-board IMU and sound displays. The [[:axiom:ros2:sound_sensor|sound walkthrough]] also covers an optional custom coloured-bar spectrum extension and synthetic recording. See the [[https://docs.foxglove.dev/docs/visualization/panels/plot|official Plot panel guide]] for series settings and timestamp sources. ===== Thermal camera on one Axiom ===== The single-camera layout subscribes to ''%%/axiom1/thermal/image%%''. Its Image panel is titled **Axiom 1: Thermal (°C)** and uses Turbo with a fixed **15–40 °C** scale. Values beyond the colour limits clip to the end colours; ROS measurements retain their original values. The native 8×8 grid is not an interpolated camera image. ==== Update and configure ==== For an existing clone already on ''%%main%%'' with no local source changes, stop acquisition, disconnect and stop affected ROS processes before updating. From the repository root: git pull --ff-only origin main source scripts/setup_env.sh rosdep install --from-paths src --ignore-src -r -y colcon build --base-paths src --symlink-install source scripts/setup_env.sh For first setup, use [[:axiom:ros2:getting_started|Install and connect]]. When updating older settings, follow the [[:axiom:ros2:sensors_and_boards#updating_an_existing_installation|naming migration]] too: local alias selectors and exact QoS keys are not updated by Git. A layout-only update needs a pull and reimport, without a rebuild. Changing driver code requires a rebuild and restart. In ''%%config/boards.yaml%%'', use board key ''%%axiom1%%'' for this example. If renaming the earlier ''%%axiom%%'' key, stop its driver first, preserve the USB or Wi-Fi settings, and use automatic startup: remove explicit false overrides for ''%%auto_connect%%'', ''%%auto_reconnect%%'' and ''%%autosub%%''. An identity rule can select the board without a USB path or IP; see [[:axiom:ros2:automatic_startup|automatic startup]]. Merge this alias into the board's existing ''%%topic_aliases%%'' mapping: topic_aliases: thermal/image: {type: AMG8833, source: image} This is a fragment, not a replacement board file. It binds to exactly one online, resolved and fresh AMG8833; use inventory ''%%bus%%'' and ''%%address%%'' selectors if several cameras match. An alias names ROS output rather than installing a device profile. The canonical model/location sensor topic remains available. For another namespace, substitute it throughout the commands and select its image topic in the panel. If you do not already have a board file, this is a complete single-board example. Replace the illustrative ''id'' with your board's firmware ID from ''/axiom_discovery/boards'', then save it as ''config/boards.yaml''. If a file already exists, edit its existing entry instead of overwriting the file or adding a second entry for the same board: discovery: include_unconfigured: false axioms: axiom1: id: '001122334455' topic_aliases: thermal/image: {type: AMG8833, source: image} Stop any existing discovery launch before restarting with this file. The Terminal 1 command below explicitly selects ''config/boards.yaml''; if your file is elsewhere, substitute its path. ==== Start the session ==== The [[:axiom:ros2:getting_started#use_tmux_for_the_ros_consoles|tmux helper]] opens four empty panes with the environment preloaded. Use Terminal 1 for the driver, Terminal 2 for services/inspection, Terminal 3 for the bridge, and Terminal 4 for optional checks. In separate windows or reused panes after a rebuild, source ''%%scripts/setup_env.sh%%'' first. Terminal 1: ros2 launch axiom_driver axiom.launch.py boards_file:=config/boards.yaml Terminal 2: ros2 topic list -t --no-daemon ros2 topic info /axiom1/thermal/image ros2 topic echo /axiom1/thermal/image --once --qos-reliability best_effort Discovery connects and acquires automatically. Expect the topic to be ''%%sensor_msgs/msg/Image%%'' with one publisher. A frame has width/height 8, encoding ''%%32FC1%%'', ''%%is_bigendian: 0%%'', ''%%step: 32%%'', and 256 bytes representing 64 little-endian float32 temperatures in °C. Its header has the sample timestamp and sensor frame. The camera's canonical ''grid'' topic, for example ''/axiom1/amg8833_b1_169/grid'', remains available for the RViz Marker visualiser. The camera must be connected with a supported firmware profile. The publication rate controls delivery, not camera sampling. An echo or viewer alone does not enable acquisition. In Terminal 3, run the bridge command from the section above, then connect the viewer. ==== Import and check ==== - Click the layout name/dropdown in the top toolbar to open **Layouts**. - Choose **Import from file...** and select ''%%examples/foxglove/one-axiom-thermal.json%%'' on the viewer computer. - Open the newly imported layout and save it as **Axiom: thermal camera**. If the checkout is on another computer, download the [[https://raw.githubusercontent.com/robotical/axiom-ros2/main/examples/foxglove/one-axiom-thermal.json|thermal JSON]] to the viewer computer, or copy it there. For example, run from the checkout on the source computer, replacing the login/address of the viewer computer: scp examples/foxglove/one-axiom-thermal.json USER@VIEWER_HOST:~/one-axiom-thermal.json Import the copied file from the viewer computer's home directory. The supplied layout has one thermal panel. Move a hand in front of the camera to see warmer pixels change colour. Pixel order follows firmware; adjust the panel's rotation or flip controls for mounting. Enlarging the display adds no measured pixels. This 2D heatmap needs no TF tree or camera calibration. A spatial 3D projection requires a separate calibration and frame contract. Replacing a JSON file does not update a saved Foxglove layout. Import it again and open the new layout after a layout change. ==== Troubleshoot and finish ==== ^Symptom ^Check ^ |No Axiom topics |Driver running, acquisition enabled, matching ROS domain/middleware | |Viewer cannot connect |Bridge running, correct host address/port, local-network permission and direct-connection entitlement| |No image publisher |Camera online in ''%%/axiom1/devices%%'', correct alias/type/namespace | |Canonical image exists, alias absent|Resolve an ambiguous match with bus/address, or select the canonical sensor topic | |Grid exists, image absent |Build/source/restart the current host driver; Image output needs known Celsius units | |One colour |Inspect temperatures and adjust **Value min** / **Value max** | |Extra panels |Open the newly imported ''%%one-axiom-thermal.json%%'' layout | Stop the bridge in Terminal 3. In Terminal 2: ros2 service call /axiom1/publish_data_subscription \ axiom_interfaces/srv/PublishedDataSubscription '{rate_hz: 0.0}' ros2 service call /axiom1/disconnect axiom_interfaces/srv/Disconnect '{}' Then stop the driver. Published walkthrough: [[https://userguides.robotical.io/axiom/ros2/foxglove|Thermal camera in Foxglove]]. See the [[https://docs.foxglove.dev/docs/visualization/panels/image|Image panel documentation]] for display controls. ===== Two-board IMU plots ===== [[https://github.com/robotical/axiom-ros2/blob/main/examples/foxglove/two-axiom-imu.json|two-axiom-imu.json]] plots X/Y/Z acceleration and angular velocity for ''%%/axiom1/imu/data_raw%%'' and ''%%/axiom2/imu/data_raw%%''. Use board keys ''%%axiom1%%'' and ''%%axiom2%%'', each with its firmware ''%%id%%'' or explicit endpoint and this alias fragment: topic_aliases: imu/data_raw: {type: LSM6DS, source: data_raw} Each alias needs exactly one matching online IMU; use bus/address selectors if needed. Follow the [[:axiom:ros2:sensors_and_boards#multiple_boards|multi-board workflow]] with those namespace names and automatic startup. Both boards connect and acquire automatically; explicit manual control remains available. Use a single Foxglove bridge for the ROS session. Import ''%%examples/foxglove/two-axiom-imu.json%%'' on the viewer computer using the same Layouts menu. For a remote checkout, download the [[https://raw.githubusercontent.com/robotical/axiom-ros2/main/examples/foxglove/two-axiom-imu.json|IMU JSON]] or copy that file to the viewer computer before import. ^Position ^Panel title ^Units^ |Top left |Axiom 1: Acceleration|m/s² | |Bottom left |Axiom 1: Gyroscope |rad/s| |Top right |Axiom 2: Acceleration|m/s² | |Bottom right|Axiom 2: Gyroscope |rad/s| The plots have a rolling 30-second window, automatic vertical scaling, and X red, Y green, Z blue. They use log/receipt time; aligned axes do not synchronise hardware clocks. At rest, acceleration includes about 9.8 m/s² of gravity in total, and angular velocity should be near zero. Tilt/rotate each board to check its own column. These are raw sensor-axis values, not fused orientation or speed. For empty plots, check actual publisher counts, the inventory, acquisition and alias ambiguity. For different namespaces, select those topics in the panel settings. Stop the bridge, then stop acquisition and disconnect both drivers using their respective namespaces before stopping the multi-board launch. Layout configuration and automated image-output evidence are recorded in [[https://github.com/robotical/axiom-ros2/blob/main/docs/validation.md|validation.md]]. Those dated checks do not establish physical mounting orientation or rendering on every workstation. ===== Multizone distance images ===== A supported VL53L5CX descriptor publishes ''sensor_msgs/msg/Image'' directly, using ''32FC1'' distances in **metres**. The driver handles supported distance/status arrays; invalid zones are NaN. Select the actual canonical ''image'' topic from ''devices.public_topics'' or the topic list. A single-zone Range sensor is a scalar plot; it does not produce the same multizone image. # Select the discovered VL53L5CX Image topic, not a scalar range topic. RANGE_IMAGE_TOPIC='PASTE_FULL_MULTIZONE_IMAGE_TOPIC_HERE' # Inspect the type and publisher before opening an Image panel. ros2 topic info "$RANGE_IMAGE_TOPIC" --verbose # Read one frame's dimensions, encoding and data-array size. ros2 topic echo "$RANGE_IMAGE_TOPIC" sensor_msgs/msg/Image \ --qos-reliability best_effort --no-arr --once In the connected viewer, add an **Image** panel and select that topic. Use a colour map and numeric min/max appropriate to distances in metres. Dimensions come from the descriptor/frame; the display does not add resolution or reconstruct a calibrated 3D point cloud. A descriptor providing both thermal and range grids uses distinct ''thermal/image'' and ''range/image'' outputs beneath the sensor root. The bundled thermal layout is deliberately a single AMG8833 camera, with Celsius labels and a 15–40 °C scale. For a distance image, create an Image panel or reconfigure its topic, labels and scale rather than reusing those thermal limits. A 2D heatmap needs no TF projection. To relate pixels to a physical 3D scene, supply separate calibration and transforms. ===== Sound and custom spectrum bars ===== Follow [[:axiom:ros2:sound_sensor|Sound sensor and spectrum]] for the 15 scalar plots, built-in nine-band spectrum layout, or optional **Axiom Spectrum** custom panel. The custom panel reads the existing ''DeviceSample'' topic directly and includes frequency labels, coloured bars, invalid/stale indications and a configurable scale. It requires installing a ''.foxe'' extension on the viewer computer; a layout JSON alone does not install the panel. Both spectrum options use existing decoded samples and need no separate ROS ''bands'' publisher. For local Matplotlib plots or rosbag recording without Foxglove, use [[:axiom:ros2:tools_and_recording|Inspect, plot and record]].