diff --git a/docs/en/dronecan/index.md b/docs/en/dronecan/index.md index 00ba948cbc..11e556cbcf 100644 --- a/docs/en/dronecan/index.md +++ b/docs/en/dronecan/index.md @@ -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 diff --git a/src/drivers/uavcan/module.yaml b/src/drivers/uavcan/module.yaml index 9518e06494..ec35a50998 100644 --- a/src/drivers/uavcan/module.yaml +++ b/src/drivers/uavcan/module.yaml @@ -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: diff --git a/src/drivers/uavcan/rgbled.cpp b/src/drivers/uavcan/rgbled.cpp index 3ee0e1225e..c8bfdcd245 100644 --- a/src/drivers/uavcan/rgbled.cpp +++ b/src/drivers/uavcan/rgbled.cpp @@ -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(_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; diff --git a/src/drivers/uavcan/rgbled.hpp b/src/drivers/uavcan/rgbled.hpp index ee189019e2..6e90668185 100644 --- a/src/drivers/uavcan/rgbled.hpp +++ b/src/drivers/uavcan/rgbled.hpp @@ -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) _param_lgt_num, - (ParamInt) _param_uavcan_lgt_antcl + (ParamInt) _param_lgt_mode ) }; diff --git a/src/drivers/uavcan/uavcan_params.c b/src/drivers/uavcan/uavcan_params.c index 9dd90e2e4c..36cf551c8a 100644 --- a/src/drivers/uavcan/uavcan_params.c +++ b/src/drivers/uavcan/uavcan_params.c @@ -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