Control the supported Robotical 32-LED, four-tier light from the Axiom host driver. The RViz panel discovers live lights and offers a colour picker, brightness, Off and four fixed-colour tiers. Individual pixels are also available through ROS command topics; the panel is not a pixel-painting editor.
The panel uses the driver's existing ROS interfaces. It opens no USB connection and needs no native ROS/Zenoh firmware. Start with Install and connect.
Use current host firmware with the light's profile available in the active library. Built-in profiles count: published 0.1.21-devlib-host includes RoboticalLEDStick, so this light does not require a custom Device Library file. Device Library explains profile management. This adapter is for the supported four-tier contract, not every RSAO or LED-strip layout.
If updating an existing checkout, stop its driver and viewers before rebuilding. From the axiom-ros2 repository root:
# Obtain the current main source.
git pull --ff-only
# Load the chosen ROS installation and workspace settings.
source scripts/setup_env.sh
# Install the declared RViz/Qt and other workspace dependencies.
rosdep install --from-paths src --ignore-src -r -y
# Build the workspace, including the new axiom_light_panel package.
colcon build --symlink-install
# Source the rebuilt overlay in this and every reused terminal.
source scripts/setup_env.sh
In Terminal 1, start normal discovery and leave it running:
# Use the same configuration, ROS domain and middleware in every terminal.
source scripts/setup_env.sh
# Discover, connect and acquire from the configured Axioms.
ros2 launch axiom_driver axiom.launch.py
A stopped/disconnected serial driver releases its port for the browser Device Library editor. They cannot simultaneously own the same USB port. Changing a stored library file needs the appropriate board restart before its definitions become active; reconnect the ROS driver afterwards. Do not change library files just to switch a light's colour.
In Terminal 2, from the same checkout:
# Load the same ROS environment as the driver.
source scripts/setup_env.sh
# Open stock RViz with the saved lighting layout.
ros2 launch axiom_light_panel lights.launch.py
Alternatively, choose Panels → Add New Panel → axiom_light_panel/LightPanel in an existing RViz window. Select the light by its discovered board/sensor path. No board namespace, USB port or device address is a launch argument. Multiple supported lights have separate entries; use the one belonging to your board.
The sensor path in this bench-test illustration is an example. Select the path shown by your own live driver.
Opening the panel, selecting a light and reconnecting send no output commands. Controls disable when live inventory is unavailable/stale. No cached output is replayed after recovery; make a fresh input when ready.
Rows appear top first: red, amber, green, blue. Each tier supports Off, Steady, Flash or Opposite phase. Set the fastest/base period in milliseconds and a per-tier multiplier of 1×, 2×, 4× or 8×, then press Apply stack pattern once. Changing a setting alone does not start or continuously resend the pattern. Reapplying restarts its clock.
A tier's period is base × multiplier. Opposite phase lights the second half of its period; ordinary Flash lights the first half. The colours are fixed by tier position and are separate from the solid-colour picker. The GUI offers explicit base periods from 40 to 65535 ms.
Whole colour and Off replace the entire chain and stop an active pattern. A single-pixel write also stops it but leaves untouched pixels at their last pattern frame. Brightness preserves the pattern. These commands do not alter polling or sensor measurement rates.
Read actual paths from the board's devices inventory, using Find the actual inputs. Prefix its relative paths with your selected board namespace. For example:
# Set each variable to a full advertised path for your own light.
COLOUR_TOPIC='PASTE_DISCOVERED_COLOUR_TOPIC_HERE'
STACK_SERVICE='PASTE_DISCOVERED_STACKLIGHT_SERVICE_HERE'
BRIGHTNESS_SERVICE='PASTE_DISCOVERED_BRIGHTNESS_SERVICE_HERE'
OFF_SERVICE='PASTE_DISCOVERED_OFF_SERVICE_HERE'
# Publish whole-light red; alpha is ignored.
ros2 topic pub --once "$COLOUR_TOPIC" std_msgs/msg/ColorRGBA \
'{r: 1.0, g: 0.0, b: 0.0, a: 1.0}'
# Apply alternating tiers: base milliseconds, then four BOTTOM-FIRST state bytes.
ros2 service call "$STACK_SERVICE" axiom_interfaces/srv/DeviceCommand \
'{values: [250, 2, 3, 2, 3]}'
# Change brightness while retaining the current pattern.
ros2 service call "$BRIGHTNESS_SERVICE" axiom_interfaces/srv/DeviceCommand '{values: [64]}'
# Stop flashing and switch off every pixel.
ros2 service call "$OFF_SERVICE" axiom_interfaces/srv/DeviceCommand '{values: []}'
The whole-colour input is std_msgs/msg/ColorRGBA, with finite RGB channels in 0..1. The driver supports the existing three-byte form and packed t: >I / f: 06x descriptors, converting RGB to 0xRRGGBB internally. Pixel inputs end in pixel_0, pixel_1, etc. Use the advertised index rather than assuming all boards have 32 pixels.
The supported stack descriptor uses vt: stacklight, f: STACKLIGHT, t: >HBBBB and NY: 4. The service takes base period, blue/bottom, green, amber, red/top. Base 0 selects 250 ms; otherwise use 40–65535 ms. Each state is mode + 4 × rate, where mode is 0 Off, 1 Steady, 2 Flash, 3 Opposite phase, and rate 0–3 selects the four multipliers. Values must be integers; reserved bits, bad periods and wrong argument counts are rejected. Other custom vt formats remain unsupported.
Controls show requested settings. A service acknowledgement confirms driver/firmware request processing, not physical light output. The separate module-status line reports flags, accepted-command count, error count, last error and brightness. Missing or old feedback is labelled unknown; unknown is not zero errors. Flag bit 2 (value 4) means a pattern is running. Counters wrap at 256.
Service calls are asynchronous. Rejection/timeout appears in the panel without freezing it. A timed-out request may have reached the device: inspect status before trying again. The driver keeps only the latest pending colour target; it does not build a queue of stale picker positions.
| Symptom | Check |
|---|---|
| No light in the selector | Current rebuilt package, matching ROS domain, connected driver, online/fresh metadata and supported whole-colour descriptor. |
| Controls disabled | Device inventory freshness and the driver's command-topic subscription. |
| Brightness differs from the input box | The box is a proposed setting. Read module status; Apply sends it. |
| Flashing stops after a pixel change | Expected: a pixel write cancels the pattern; untouched pixels retain their last frame. |
| Device Library cannot open USB | Stop/disconnect the serial owner first; return to ROS after finishing library work. |
The 32-pixel light was checked through typed ROS commands, independent CRC-protected module readback and the panel loaded through RViz's plugin machinery. Stock rviz2 launch was also checked. Software disconnect/reconnect sent no cached output, and sensor data continued during commands. This does not establish physical unplug/replacement handling or long-duration/visual phase accuracy for every hardware model. Source and maintainer verification steps are in the repository lighting guide.