---json
{"name": "Lighting controls in RViz"}
---
====== Lighting controls in RViz ======
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 [[:axiom:ros2:getting_started|Install and connect]].
===== Prepare the driver and profile =====
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. [[:axiom:device_library:start|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.
===== Open the panel =====
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.
{{ :axiom:ros2:lighting-panel-6615363.png?760&nolink |RViz lighting panel with requested settings and reported module status}}
//The sensor path in this bench-test illustration is an example. Select the path shown by your own live driver.//
===== Colour, brightness and Off =====
* **Choose colour** streams changes from the picker. **Apply colour** sends the selected colour again after a pattern or Off, even when the selection has not changed.
* **Apply brightness** sends the proposed value in 0–255. It does not stop the pattern. The input initially proposes 64; the separate module-status line is the reported brightness, not this input box.
* **Off** stops the pattern and clears the whole chain. **Closing RViz does not switch the hardware off**: press Off explicitly when finished.
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.
===== Four-tier stack patterns =====
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.
===== Use the same controls from ROS commands =====
Read actual paths from the board's ''devices'' inventory, using [[:axiom:ros2:output_topics#find_the_actual_inputs|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.
===== Read status and recover =====
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. |
===== Validation scope =====
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 [[https://github.com/robotical/axiom-ros2/blob/main/docs/lighting.md|the repository lighting guide]].