Added support for colored navigation lights and hybrid light functions.

add functionality for Status or Off
This commit is contained in:
Claudio Chies
2026-01-20 09:15:19 +01:00
committed by Matthias Grob
parent d965df930c
commit 637cece115
5 changed files with 94 additions and 25 deletions
+7 -3
View File
@@ -287,11 +287,15 @@ PX4 can control LEDs via DroneCAN [LightsCommand](https://dronecan.github.io/Spe
Configuration:
1. Set [UAVCAN_LGT_NUM](../advanced_config/parameter_reference.md#UAVCAN_LGT_NUM) to the number of lights (0 disables). You might need to reopen the ground station to have parameters for new instances available.
1. Set [UAVCAN_LGT_NUM](../advanced_config/parameter_reference.md#UAVCAN_LGT_NUM) to the number of lights (0-2, 0 disables).
You might need to reopen the ground station to have parameters for new instances available.
2. For each light slot (0 to NUM-1), set:
- `UAVCAN_LGT_IDx`: The `light_id` matching your peripheral.
- `UAVCAN_LGT_FNx`: `Status` for system status colours, or `Anti-collision` for white beacon.
3. For anti-collision lights, [UAVCAN_LGT_ANTCL](../advanced_config/parameter_reference.md#UAVCAN_LGT_ANTCL) controls when they illuminate (off, armed, prearmed, always on).
- `UAVCAN_LGT_FNx`: The light function. Available options:
- `Status`: System status colours from the LED controller.
- `Anti-collision` to `White Navigation`: Light functions controlled by `UAVCAN_LGT_MODE`.
- `Status / Anti-collision` to `Status / Off`: Hybrid modes that show status colours when `UAVCAN_LGT_MODE` is inactive, and switch to the second function when active.
3. [UAVCAN_LGT_MODE](../advanced_config/parameter_reference.md#UAVCAN_LGT_MODE) controls when navigation lights turn on (off, armed, prearmed, always on).
4. Reboot for any changes to take effect.
## QGC CANNODE Parameter Configuration
+15 -7
View File
@@ -1,4 +1,5 @@
__max_num_uavcan_lights: &max_num_uavcan_lights 3 # Needs to be equal to MAX_NUM_UAVCAN_LIGHTS constant
__max_num_uavcan_lights: &max_num_uavcan_lights 2 # NOTE: This value must match MAX_NUM_UAVCAN_LIGHTS in rgbled.hpp
module_name: UAVCAN
parameters:
@@ -54,18 +55,25 @@ parameters:
description:
short: Light ${i} function
long: |
Function assigned to light ${i}.
0: Status - displays system status colors
1: Anti-collision - white beacon controlled by LGT_ANTCL parameter
Function for light ${i}. Navigation lights ("Anti-collision" to "White Navigation") follow UAVCAN_LGT_MODE.
Hybrid ("Status / Anti-collision" - "Status / White Navigation"): status when UAVCAN_LGT_MODE is inactive, second function to use when active.
type: enum
num_instances: *max_num_uavcan_lights
instance_start: 0
min: 0
max: 1
max: 9
default: 0
values:
0: Status Light
1: Anti-collision Light
0: Status
1: Anti-collision
2: Red Navigation
3: Green Navigation
4: White Navigation
5: Status / Anti-collision
6: Status / Red Navigation
7: Status / Green Navigation
8: Status / White Navigation
9: Status / Off
actuator_output:
show_subgroups_if: 'UAVCAN_ENABLE>=3'
config_parameters:
+40 -5
View File
@@ -131,14 +131,17 @@ void UavcanRGBController::periodic_update(const uavcan::TimerEvent &)
status_color = rgb888_to_rgb565(brightness, brightness, brightness);
break;
default:
case led_control_s::COLOR_OFF:
default:
break;
}
// Build and send light commands for all configured lights
uavcan::equipment::indication::LightsCommand light_command;
const bool light_mode_active = check_light_state(static_cast<LightMode>(_param_lgt_mode.get()));
brightness = light_mode_active ? 255 : 0;
for (uint8_t i = 0; i < _num_lights; i++) {
uavcan::equipment::indication::SingleLightCommand cmd;
cmd.light_id = _light_ids[i];
@@ -149,8 +152,40 @@ void UavcanRGBController::periodic_update(const uavcan::TimerEvent &)
break;
case LightFunction::AntiCollision:
uint8_t brigtness = is_anticolision_on() ? 255 : 0;
cmd.color = rgb888_to_rgb565(brigtness, brigtness, brigtness);
cmd.color = rgb888_to_rgb565(brightness, brightness, brightness);
break;
case LightFunction::RedNavigation:
cmd.color = rgb888_to_rgb565(brightness, 0, 0);
break;
case LightFunction::GreenNavigation:
cmd.color = rgb888_to_rgb565(0, brightness, 0);
break;
case LightFunction::WhiteNavigation:
cmd.color = rgb888_to_rgb565(brightness, brightness, brightness);
break;
// Hybrid functions: show status when UAVCAN_LGT_MODE inactive, navigation light when active
case LightFunction::StatusOrAntiCollision:
cmd.color = light_mode_active ? rgb888_to_rgb565(brightness, brightness, brightness) : status_color;
break;
case LightFunction::StatusOrRedNavigation:
cmd.color = light_mode_active ? rgb888_to_rgb565(brightness, 0, 0) : status_color;
break;
case LightFunction::StatusOrGreenNavigation:
cmd.color = light_mode_active ? rgb888_to_rgb565(0, brightness, 0) : status_color;
break;
case LightFunction::StatusOrWhiteNavigation:
cmd.color = light_mode_active ? rgb888_to_rgb565(brightness, brightness, brightness) : status_color;
break;
case LightFunction::StatusOrOff:
cmd.color = light_mode_active ? rgb888_to_rgb565(0, 0, 0) : status_color;
break;
}
@@ -160,12 +195,12 @@ void UavcanRGBController::periodic_update(const uavcan::TimerEvent &)
_uavcan_pub_lights_cmd.broadcast(light_command);
}
bool UavcanRGBController::is_anticolision_on()
bool UavcanRGBController::check_light_state(LightMode mode)
{
actuator_armed_s actuator_armed{};
_actuator_armed_sub.copy(&actuator_armed);
switch (_param_uavcan_lgt_antcl.get()) {
switch (_param_lgt_mode.get()) {
case 3: // Always on
return true;
+25 -7
View File
@@ -54,18 +54,36 @@ private:
// Max update rate to avoid excessive bus traffic
static constexpr unsigned MAX_RATE_HZ = 20;
// Maximum number of configurable lights
static constexpr uint8_t MAX_NUM_UAVCAN_LIGHTS = 3;
// NOTE: This value must match __max_num_uavcan_lights in module.yaml
static constexpr uint8_t MAX_NUM_UAVCAN_LIGHTS = 2;
// Light function types
// Light function types - must match values in module.yaml UAVCAN_LGT_FN
enum class LightFunction : uint8_t {
Status = 0, // System status colors from led_control
AntiCollision = 1 // White beacon based on arm state
Status = 0, // System status colors from led_control
AntiCollision = 1, // White beacon based on arm state
RedNavigation = 2, // Red navigation light
GreenNavigation = 3, // Green navigation light
WhiteNavigation = 4, // White navigation light
StatusOrAntiCollision = 5, // Status when LGT_MODE inactive, white beacon when active
StatusOrRedNavigation = 6, // Status when LGT_MODE inactive, red nav when active
StatusOrGreenNavigation = 7, // Status when LGT_MODE inactive, green nav when active
StatusOrWhiteNavigation = 8, // Status when LGT_MODE inactive, white nav when active
StatusOrOff = 9 // Status when LGT_MODE inactive, off when active
};
enum class LightMode : uint8_t {
Off = 0,
WhenArmed = 1,
WhenPrearmed = 2,
AlwaysOn = 3
};
// White light intensity levels
enum class Brightness { None, Full };
void periodic_update(const uavcan::TimerEvent &);
bool is_anticolision_on(); ///< Evaluates current on state of collision lights accordingt to UAVCAN_LGT_ANTCL
bool check_light_state(LightMode mode);
uavcan::equipment::indication::RGB565 rgb888_to_rgb565(uint8_t red, uint8_t green, uint8_t blue);
@@ -91,6 +109,6 @@ private:
DEFINE_PARAMETERS(
(ParamInt<px4::params::UAVCAN_LGT_NUM>) _param_lgt_num,
(ParamInt<px4::params::UAVCAN_LGT_ANTCL>) _param_uavcan_lgt_antcl
(ParamInt<px4::params::UAVCAN_LGT_MODE>) _param_lgt_mode
)
};
+7 -3
View File
@@ -132,10 +132,14 @@ PARAM_DEFINE_FLOAT(UAVCAN_ECU_MAXF, 15.0f);
PARAM_DEFINE_INT32(UAVCAN_ECU_FUELT, 1);
/**
* UAVCAN ANTI_COLLISION light operating mode
* UAVCAN Navigation light operating mode
*
* This parameter defines the minimum condition under which the system will command
* lights with anti-collision function to turn on (white).
* Navigation lights to turn on. Affects lights with functions: Anti-collision, Colored Navigation Lights or Hybrid lights.
*
* For hybrid functions (StatusOrAntiCollision, etc.), the light
* displays status colors when this mode is inactive, and switches to the
* navigation light function when this mode becomes active.
*
* 0 - Always off
* 1 - When autopilot is armed
@@ -151,7 +155,7 @@ PARAM_DEFINE_INT32(UAVCAN_ECU_FUELT, 1);
* @reboot_required true
* @group UAVCAN
*/
PARAM_DEFINE_INT32(UAVCAN_LGT_ANTCL, 2);
PARAM_DEFINE_INT32(UAVCAN_LGT_MODE, 1);
/**
* publish Arming Status stream