From 05abb178cbc9779ca6c8e141feb76b99ba448b5b Mon Sep 17 00:00:00 2001 From: Bob Long Date: Wed, 25 Sep 2024 12:11:37 +1000 Subject: [PATCH] AP_BattMonitor: add option minimum volt option --- .../AP_BattMonitor/AP_BattMonitor_Params.cpp | 2 +- .../AP_BattMonitor/AP_BattMonitor_Params.h | 2 ++ .../AP_BattMonitor/AP_BattMonitor_Sum.cpp | 31 ++++++++++++++++--- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/libraries/AP_BattMonitor/AP_BattMonitor_Params.cpp b/libraries/AP_BattMonitor/AP_BattMonitor_Params.cpp index 0eb859d2a4..486634ce57 100644 --- a/libraries/AP_BattMonitor/AP_BattMonitor_Params.cpp +++ b/libraries/AP_BattMonitor/AP_BattMonitor_Params.cpp @@ -150,7 +150,7 @@ const AP_Param::GroupInfo AP_BattMonitor_Params::var_info[] = { // @Param: OPTIONS // @DisplayName: Battery monitor options // @Description: This sets options to change the behaviour of the battery monitor - // @Bitmask: 0:Ignore DroneCAN SoC, 1:MPPT reports input voltage and current, 2:MPPT Powered off when disarmed, 3:MPPT Powered on when armed, 4:MPPT Powered off at boot, 5:MPPT Powered on at boot, 6:Send resistance compensated voltage to GCS, 7:Allow DroneCAN InfoAux to be from a different CAN node + // @Bitmask: 0:Ignore DroneCAN SoC, 1:MPPT reports input voltage and current, 2:MPPT Powered off when disarmed, 3:MPPT Powered on when armed, 4:MPPT Powered off at boot, 5:MPPT Powered on at boot, 6:Send resistance compensated voltage to GCS, 7:Allow DroneCAN InfoAux to be from a different CAN node, 9:Sum monitor measures minimum voltage instead of average // @User: Advanced AP_GROUPINFO("OPTIONS", 21, AP_BattMonitor_Params, _options, 0), #endif // HAL_BUILD_AP_PERIPH diff --git a/libraries/AP_BattMonitor/AP_BattMonitor_Params.h b/libraries/AP_BattMonitor/AP_BattMonitor_Params.h index 2088845c39..33b31777bc 100644 --- a/libraries/AP_BattMonitor/AP_BattMonitor_Params.h +++ b/libraries/AP_BattMonitor/AP_BattMonitor_Params.h @@ -26,6 +26,8 @@ class AP_BattMonitor_Params { MPPT_Power_On_At_Boot = (1U<<5), // MPPT Enabled at startup (aka boot), if HW supports it. If Power_Off_at_Boot is also set, the behavior is Power_Off_at_Boot GCS_Resting_Voltage = (1U<<6), // send resistance resting voltage to GCS AllowSplitAuxInfo = (1U<<7), // allow different node to provide aux info for DroneCAN + InternalUseOnly = (1U<<8), // for use internally to ArduPilot, not to be (eg.) sent via MAVLink BATTERY_STATUS + Minimum_Voltage = (1U<<9), // sum monitor measures minimum voltage rather than average }; BattMonitor_LowVoltage_Source failsafe_voltage_source(void) const { return (enum BattMonitor_LowVoltage_Source)_failsafe_voltage_source.get(); } diff --git a/libraries/AP_BattMonitor/AP_BattMonitor_Sum.cpp b/libraries/AP_BattMonitor/AP_BattMonitor_Sum.cpp index 2a7401d326..ff19204976 100644 --- a/libraries/AP_BattMonitor/AP_BattMonitor_Sum.cpp +++ b/libraries/AP_BattMonitor/AP_BattMonitor_Sum.cpp @@ -50,10 +50,14 @@ void AP_BattMonitor_Sum::read() { float voltage_sum = 0; + float voltage_min = 0; uint8_t voltage_count = 0; float current_sum = 0; uint8_t current_count = 0; + float consumed_mah_sum = 0; + float consumed_wh_sum = 0; + for (uint8_t i=0; i<_mon.num_instances(); i++) { if (i == _instance) { // never include self @@ -70,26 +74,43 @@ AP_BattMonitor_Sum::read() if (!_mon.healthy(i)) { continue; } - voltage_sum += _mon.voltage(i); + const float voltage = _mon.voltage(i); + if (voltage_count == 0 || voltage < voltage_min) { + voltage_min = voltage; + } + voltage_sum += voltage; voltage_count++; float current; if (_mon.current_amps(current, i)) { current_sum += current; current_count++; } + + float consumed_mah; + if (_mon.consumed_mah(consumed_mah, i)) { + consumed_mah_sum += consumed_mah; + } + + float consumed_wh; + if (_mon.consumed_wh(consumed_wh, i)) { + consumed_wh_sum += consumed_wh; + } } const uint32_t tnow_us = AP_HAL::micros(); - const uint32_t dt_us = tnow_us - _state.last_time_micros; if (voltage_count > 0) { - _state.voltage = voltage_sum / voltage_count; + if (option_is_set(AP_BattMonitor_Params::Options::Minimum_Voltage)) { + _state.voltage = voltage_min; + } else { + _state.voltage = voltage_sum / voltage_count; + } } if (current_count > 0) { _state.current_amps = current_sum; + _state.consumed_mah = consumed_mah_sum; + _state.consumed_wh = consumed_wh_sum; } - update_consumed(_state, dt_us); - _has_current = (current_count > 0); _state.healthy = (voltage_count > 0);