-
Notifications
You must be signed in to change notification settings - Fork 16.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Plane: On Critical Battery, Land #5000
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -146,13 +146,38 @@ void Plane::low_battery_event(void) | |
if (flight_stage != AP_SpdHgtControl::FLIGHT_LAND_FINAL && | ||
flight_stage != AP_SpdHgtControl::FLIGHT_LAND_PREFLARE && | ||
flight_stage != AP_SpdHgtControl::FLIGHT_LAND_APPROACH) { | ||
set_mode(RTL, MODE_REASON_BATTERY_FAILSAFE); | ||
aparm.throttle_cruise.load(); | ||
set_mode(RTL, MODE_REASON_BATTERY_FAILSAFE); | ||
aparm.throttle_cruise.load(); | ||
} | ||
failsafe.low_battery = true; | ||
AP_Notify::flags.failsafe_battery = true; | ||
} | ||
|
||
void Plane::critical_battery_event(void) | ||
{ | ||
if (failsafe.critical_battery) { | ||
return; | ||
} | ||
gcs_send_text_fmt(MAV_SEVERITY_WARNING, "Critical battery %.2fV used %.0f mAh", | ||
(double)battery.voltage(), (double)battery.current_total_mah()); | ||
if (flight_stage != AP_SpdHgtControl::FLIGHT_LAND_FINAL && | ||
flight_stage != AP_SpdHgtControl::FLIGHT_LAND_PREFLARE && | ||
flight_stage != AP_SpdHgtControl::FLIGHT_LAND_APPROACH) { | ||
set_mode(RTL, MODE_REASON_BATTERY_FAILSAFE); | ||
aparm.throttle_cruise.load(); | ||
|
||
// Go directly to the landing sequence | ||
jump_to_landing_sequence(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove jump_to_landing_seq and auto_state.checked_for_auto. They are handled when RTL is set and RTL_AUTOLAND >0. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @magicrub this is meant to be independent of RTL_AUTOLAND There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we don't want it to autoland if RTL_AUTOLAND == 0, it should come back home and loiter like a simple RTL. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. RTL_AUTOLAND 3 being this new behaviour would be fine. The objection is that none of the current RTL_AUTOLAND options allow RTL without also doing a landing. I want RTL on low battery, but I want to have time before just going into the landing sequence, and on normal RTL there should be a option that says loiter indefinitely at a rallypoint/home until battery is low, then land. That is primarily what this is meant to address. If you think RTL_AUTOLAND 3 meaning perform a normal RTL until critical battery and only then perform a autoland I'm fine with that. |
||
|
||
// prevent running the expensive jump_to_landing_sequence | ||
// on every loop | ||
auto_state.checked_for_autoland = true; | ||
} | ||
failsafe.critical_battery = true; | ||
AP_Notify::flags.failsafe_battery = true; | ||
} | ||
|
||
|
||
void Plane::update_events(void) | ||
{ | ||
ServoRelayEvents.update_events(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -279,12 +279,31 @@ uint8_t AP_BattMonitor::capacity_remaining_pct(uint8_t instance) const | |
} | ||
} | ||
|
||
/// exhausted - returns true if the voltage remains below the low_voltage for 10 seconds or remaining capacity falls below min_capacity_mah | ||
bool AP_BattMonitor::exhausted(uint8_t instance, float low_voltage, float min_capacity_mah) | ||
/// status - returns BattMonitor_STATUS_CRITICAL if the voltage remains below the critical_voltage | ||
/// for 10 seconds or remaining capacity falls below critical_capacity_mah. | ||
/// returns BattMonitor_STATUS_LOW if the voltage remains below the low_voltage for 10 | ||
/// seconds or remaining capacity falls below min_capacity_mah. | ||
/// returns BattMonitor_STATUS_NORMAL otherwise. | ||
AP_BattMonitor::BattMonitor_Status AP_BattMonitor::status(uint8_t instance, float low_voltage, | ||
float critical_voltage, float min_capacity_mah, float critical_capacity_mah) | ||
{ | ||
// exit immediately if no monitors setup | ||
if (_num_instances == 0 || instance >= _num_instances) { | ||
return false; | ||
return BattMonitor_STATUS_NORMAL; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. there should probably be a BattMonitor_STATUS_UNKNOWN to handle this case but then you can't use != BattMonitor_STATUS_NORMAL in the code |
||
} | ||
|
||
if((state[instance].voltage > 0) && (critical_voltage > 0) && (state[instance].voltage < critical_voltage)) { | ||
// this is the first time our voltage has dropped below minimum so start timer | ||
if (state[instance].critical_voltage_start_ms == 0) { | ||
state[instance].critical_voltage_start_ms = AP_HAL::millis(); | ||
} else if (AP_HAL::millis() - state[instance].critical_voltage_start_ms > AP_BATT_LOW_VOLT_TIMEOUT_MS) { | ||
return BattMonitor_STATUS_CRITICAL; | ||
} | ||
} | ||
|
||
// check capacity if current monitoring is enabled | ||
if (has_current(instance) && (critical_capacity_mah > 0) && (_pack_capacity[instance] - state[instance].current_total_mah < critical_capacity_mah)) { | ||
return BattMonitor_STATUS_CRITICAL; | ||
} | ||
|
||
// check voltage | ||
|
@@ -293,20 +312,20 @@ bool AP_BattMonitor::exhausted(uint8_t instance, float low_voltage, float min_ca | |
if (state[instance].low_voltage_start_ms == 0) { | ||
state[instance].low_voltage_start_ms = AP_HAL::millis(); | ||
} else if (AP_HAL::millis() - state[instance].low_voltage_start_ms > AP_BATT_LOW_VOLT_TIMEOUT_MS) { | ||
return true; | ||
return BattMonitor_STATUS_LOW; | ||
} | ||
} else { | ||
// acceptable voltage so reset timer | ||
state[instance].low_voltage_start_ms = 0; | ||
state[instance].critical_voltage_start_ms = 0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This also needs to be reset on it's own for proper debounce |
||
} | ||
|
||
// check capacity if current monitoring is enabled | ||
if (has_current(instance) && (min_capacity_mah > 0) && (_pack_capacity[instance] - state[instance].current_total_mah < min_capacity_mah)) { | ||
return true; | ||
return BattMonitor_STATUS_LOW; | ||
} | ||
|
||
// if we've gotten this far then battery is ok | ||
return false; | ||
return BattMonitor_STATUS_NORMAL; | ||
} | ||
|
||
// return true if any battery is pushing too much power | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,6 +44,13 @@ class AP_BattMonitor | |
BattMonitor_TYPE_BEBOP = 6 | ||
}; | ||
|
||
// Battery monitor driver types | ||
enum BattMonitor_Status { | ||
BattMonitor_STATUS_NORMAL, | ||
BattMonitor_STATUS_LOW, | ||
BattMonitor_STATUS_CRITICAL, | ||
}; | ||
|
||
// The BattMonitor_State structure is filled in by the backend driver | ||
struct BattMonitor_State { | ||
uint8_t instance; // the instance number of this monitor | ||
|
@@ -54,6 +61,7 @@ class AP_BattMonitor | |
float current_total_mah; // total current draw since start-up | ||
uint32_t last_time_micros; // time when voltage and current was last read | ||
uint32_t low_voltage_start_ms; // time when voltage dropped below the minimum | ||
uint32_t critical_voltage_start_ms; // time when voltage dropped below the minimum | ||
}; | ||
|
||
// Return the number of battery monitor instances | ||
|
@@ -98,9 +106,14 @@ class AP_BattMonitor | |
int32_t pack_capacity_mah(uint8_t instance) const; | ||
int32_t pack_capacity_mah() const { return pack_capacity_mah(AP_BATT_PRIMARY_INSTANCE); } | ||
|
||
/// exhausted - returns true if the battery's voltage remains below the low_voltage for 10 seconds or remaining capacity falls below min_capacity | ||
bool exhausted(uint8_t instance, float low_voltage, float min_capacity_mah); | ||
bool exhausted(float low_voltage, float min_capacity_mah) { return exhausted(AP_BATT_PRIMARY_INSTANCE, low_voltage, min_capacity_mah); } | ||
/// status - returns BattMonitor_STATUS_CRITICAL if the voltage remains below the critical_voltage | ||
/// for 10 seconds or remaining capacity falls below critical_capacity_mah. | ||
/// returns BattMonitor_STATUS_LOW if the voltage remains below the low_voltage for 10 | ||
/// seconds or remaining capacity falls below min_capacity_mah. | ||
/// returns BattMonitor_STATUS_NORMAL otherwise. | ||
enum BattMonitor_Status status(uint8_t instance, float low_voltage, float critical_voltage, float min_capacity_mah, float critical_capacity_mah); | ||
enum BattMonitor_Status status(float low_voltage, float critical_voltage, float min_capacity_mah, float critical_capacity_mah) { | ||
return status(AP_BATT_PRIMARY_INSTANCE, low_voltage, critical_voltage, min_capacity_mah, critical_capacity_mah); } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. when doing multi-line functions in header, move the last } below it. |
||
|
||
/// get_type - returns battery monitor type | ||
enum BattMonitor_Type get_type() { return get_type(AP_BATT_PRIMARY_INSTANCE); } | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also needs to check for ::FLIGHT_LAND_ABORT. If you're ever in that state then you're already at home trying to land
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@magicrub Should that thought be applied to the low_battery_event() as well? (Line 146 of this same file) I can see the arguments either way on that one...