@@ -2023,6 +2023,9 @@ void QuadPlane::motors_output(bool run_rate_controller)
20232023 last_motors_active_ms = now;
20242024 }
20252025
2026+ // Run thrust loss check
2027+ thrust_loss_check ();
2028+
20262029}
20272030
20282031/*
@@ -4879,4 +4882,64 @@ void QuadPlane::Log_Write_AttRate()
48794882
48804883}
48814884
4885+ // check for loss of thrust and trigger thrust boost in motors library
4886+ void QuadPlane::thrust_loss_check ()
4887+ {
4888+ // return if already engaged, disarmed, not flying, or motors not active
4889+ if (motors->get_thrust_boost () || !motors->armed () || !plane.is_flying () || (motors->get_desired_spool_state () != AP_Motors::DesiredSpoolState::THROTTLE_UNLIMITED)) {
4890+ thrust_loss_counter = 0 ;
4891+ return ;
4892+ }
4893+
4894+ // check for desired angle under 15 degrees
4895+ const Vector3f& angle_target_rad = attitude_control->get_att_target_euler_rad ();
4896+ if (angle_target_rad.xy ().length_squared () > sq (radians (15.0 ))) {
4897+ thrust_loss_counter = 0 ;
4898+ return ;
4899+ }
4900+
4901+ // check for throttle over 90% or throttle saturation
4902+ if ((attitude_control->get_throttle_in () < 0.9 ) && (!motors->limit .throttle_upper )) {
4903+ thrust_loss_counter = 0 ;
4904+ return ;
4905+ }
4906+
4907+ // check throttle is over 25% to prevent checks triggering from thrust limitations caused by low commanded throttle
4908+ if ((attitude_control->get_throttle_in () < 0 .25f )) {
4909+ thrust_loss_counter = 0 ;
4910+ return ;
4911+ }
4912+
4913+ // check for descent
4914+ Vector3f vel_NED;
4915+ if (!ahrs.get_velocity_NED (vel_NED) || !is_positive (vel_NED.z )) {
4916+ // we have no vertical velocity estimate and/or we are not descending
4917+ thrust_loss_counter = 0 ;
4918+ return ;
4919+ }
4920+
4921+ // check for angle error over 30 degrees to ensure the aircraft has attitude control
4922+ const float angle_error = attitude_control->get_att_error_angle_deg ();
4923+ if (angle_error >= 30.0 ) {
4924+ thrust_loss_counter = 0 ;
4925+ return ;
4926+ }
4927+
4928+ // the aircraft is descending with low requested roll and pitch, at full available throttle, with attitude control
4929+ // we may have lost thrust
4930+ thrust_loss_counter++;
4931+
4932+ // check if thrust loss for 1 second
4933+ if (thrust_loss_counter >= plane.scheduler .get_loop_rate_hz ()) {
4934+ // reset counter
4935+ thrust_loss_counter = 0 ;
4936+ LOGGER_WRITE_ERROR (LogErrorSubsystem::THRUST_LOSS_CHECK, LogErrorCode::FAILSAFE_OCCURRED);
4937+ // send message to gcs
4938+ gcs ().send_text (MAV_SEVERITY_EMERGENCY, " Potential VTOL Thrust Loss (%u)" , motors->get_lost_motor () + 1 );
4939+ // enable thrust loss handling
4940+ motors->set_thrust_boost (true );
4941+ // the motors library disables this when it is no longer needed to achieve the commanded output
4942+ }
4943+ }
4944+
48824945#endif // HAL_QUADPLANE_ENABLED
0 commit comments