ROS 2 driver for the Athena 110-LED WS2812B status light ring.
It uses SPI hardware (via /dev/spidev3.0) on the Radxa Zero 3E, rendering a priority-composited pipeline of visual effects.
-
Hardware Connection: The WS2812B data line must be connected to the Radxa's SPI MOSI pin (typically SPI3 MOSI on pin 19).
-
Enable SPI Overlay: Ensure the
spidev3.0device is enabled in the Radxa device tree overlays so it appears as/dev/spidev3.0. -
Permissions (udev rule): The ROS node needs permission to write to the SPI device. Create a new file
/etc/udev/rules.d/99-spidev.ruleswith the following content:SUBSYSTEM=="spidev", KERNEL=="spidev3.0", GROUP="dialout", MODE="0660"Note: Ensure the user running the ROS node is part of the
dialoutgroup (sudo usermod -aG dialout $USER). Reload rules or reboot for it to take effect:sudo udevadm control --reload-rules && sudo udevadm trigger
ros2 run athena_status_led_driver athena_status_led_driver_nodeTo simulate effects on your PC, you can use the simulate parameter to run a terminal simulation of the LED ring:
ros2 run athena_status_led_driver athena_status_led_driver_node --ros-args -p simulate:=true-
Subscribers:
/operating_mode(std_msgs/msg/String): Expected values:autonomous(Blue),driving(Yellow-Orange),manipulation(Red-Orange),safe(Green)./battery(athena_firmware_interface_msgs/msg/BatteryStatus): Readspower_sourceand cell voltages.
-
Services:
~/set_spot_light(athena_status_led_driver_msgs/srv/SetSpotLight): Controls a directional white arc.# Example: turn on an 80-degree wide arc aiming at 90 degrees at 50% brightness ros2 service call /athena_status_led_driver/set_spot_light athena_status_led_driver_msgs/srv/SetSpotLight "{enable: true, brightness: 0.5, direction_deg: 90.0, width_deg: 80.0}"
Effects are rendered in the order they are added in the controller (lowest to highest priority visually). "Fill" effects write all pixels. "Blend" effects selectively modify pixels.
- Rainbow Loading (Fill): Spinning HSV rainbow active on startup. Deactivated permanently when the first
operating_modemessage arrives. - Operating Mode (Fill): Static color based on current mode. Overwrites the rainbow.
- Battery Pulse (Blend): Red sine wave pulsing when both batteries have a cell under 3.8V.
- Power Supply Chase (Blend): A few green LEDs circling when connected to external power.
- Spot Light Mode (Blend): Directional white illumination arc controlled via service.
The effect system is designed for easy extension without modifying the core controller logic.
-
Create the effect class: Inherit from
athena_status_led_driver::LedEffectand implement the 3 core methods:isActive(): Should the effect render on this frame?update(double dt): Advance your animation state (e.g. phase, offset) bydtseconds.render(std::vector<Color>& pixels): Modify thepixelsarray. Either overwrite all pixels (fill) or selectively change/blend specific pixels based on your logic.
Tip: Inspect
include/athena_status_led_driver/battery_pulse_effect.hppfor a blending example, orrainbow_loading_effect.hppfor a fill example. -
Add it to the Node:
- Include your header in
src/athena_status_led_driver.cpp. - Instantiate your effect in
AthenaStatusLedDriver::setup(). - Add it to the controller list using
controller_->addEffect(my_new_effect_);. - Note on ordering: Add it before effects that should visually draw on top of it, and after effects it should draw over or overwrite.
- Include your header in