ardupilot/Rover/crash_check.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

66 lines
2.7 KiB
C++
Raw Permalink Normal View History

2016-11-21 12:08:24 -04:00
#include "Rover.h"
// Code to detect a crash or block
static const uint16_t CRASH_CHECK_TRIGGER_SEC = 2; // 2 seconds blocked indicates a crash
static const float CRASH_CHECK_THROTTLE_MIN = 5.0f; // vehicle must have a throttle greater that 5% to be considered crashed
static const float CRASH_CHECK_VEL_MIN = 0.08f; // vehicle must have a velocity under 0.08 m/s or rad/s to be considered crashed
2016-11-21 12:08:24 -04:00
// crash_check - disarms motors if a crash or block has been detected
// crashes are detected by the vehicle being static (no speed) for more than CRASH_CHECK_TRIGGER_SEC and motor are running
// called at 10Hz
void Rover::crash_check()
{
2018-07-28 20:25:54 -03:00
static uint16_t crash_counter; // number of iterations vehicle may have been crashed
bool crashed = false; //stores crash state
2016-11-21 12:08:24 -04:00
2018-07-28 20:25:54 -03:00
// return immediately if disarmed, crash checking is disabled or vehicle is Hold, Manual or Acro mode(if it is not a balance bot)
if (!arming.is_armed() || g.fs_crash_check == FS_CRASH_DISABLE || ((!control_mode->is_autopilot_mode()) && (!is_balancebot()))) {
crash_counter = 0;
return;
}
2016-11-21 12:08:24 -04:00
2018-07-28 20:25:54 -03:00
// Crashed if pitch/roll > crash_angle
if ((g2.crash_angle != 0) && ((fabsf(ahrs.get_pitch()) > radians(g2.crash_angle)) || (fabsf(ahrs.get_roll()) > radians(g2.crash_angle)))) {
2018-07-28 20:25:54 -03:00
crashed = true;
}
2018-07-28 20:25:54 -03:00
// TODO : Check if min vel can be calculated
// min_vel = ( CRASH_CHECK_THROTTLE_MIN * g.speed_cruise) / g.throttle_cruise;
2016-11-21 12:08:24 -04:00
2018-07-28 20:25:54 -03:00
if (!is_balancebot()) {
if (!crashed && ((ahrs.groundspeed() >= CRASH_CHECK_VEL_MIN) || // Check velocity
(fabsf(ahrs.get_gyro().z) >= CRASH_CHECK_VEL_MIN) || // Check turn speed
(fabsf(g2.motors.get_throttle()) < CRASH_CHECK_THROTTLE_MIN))) {
crash_counter = 0;
return;
}
2016-11-21 12:08:24 -04:00
2018-07-28 20:25:54 -03:00
// we may be crashing
crash_counter++;
2016-11-21 12:08:24 -04:00
2018-07-28 20:25:54 -03:00
// check if crashing for 2 seconds
if (crash_counter >= (CRASH_CHECK_TRIGGER_SEC * 10)) {
crashed = true;
}
}
2018-07-28 20:25:54 -03:00
if (crashed) {
LOGGER_WRITE_ERROR(LogErrorSubsystem::CRASH_CHECK,
LogErrorCode::CRASH_CHECK_CRASH);
2018-07-28 20:25:54 -03:00
if (is_balancebot()) {
// send message to gcs
gcs().send_text(MAV_SEVERITY_EMERGENCY, "Crash: Disarming");
2020-02-21 09:09:57 -04:00
arming.disarm(AP_Arming::Method::CRASH);
2018-07-28 20:25:54 -03:00
} else {
// send message to gcs
gcs().send_text(MAV_SEVERITY_EMERGENCY, "Crash: Going to HOLD");
// change mode to hold and disarm
set_mode(mode_hold, ModeReason::CRASH_FAILSAFE);
2018-07-28 20:25:54 -03:00
if (g.fs_crash_check == FS_CRASH_HOLD_AND_DISARM) {
2020-02-21 09:09:57 -04:00
arming.disarm(AP_Arming::Method::CRASH);
2018-07-28 20:25:54 -03:00
}
}
2016-11-21 12:08:24 -04:00
}
}