AC_AttitudeControl: added single loop override of angle P gains

this is used by quadplanes in back-transiton to prevent oscillation
caused by driving the fixed wing controller too fast
This commit is contained in:
Andrew Tridgell 2022-10-11 09:14:35 +11:00 committed by Randy Mackay
parent f6069c35f4
commit 71ad3587dd
2 changed files with 37 additions and 8 deletions

View File

@ -849,8 +849,10 @@ void AC_AttitudeControl::input_shaping_rate_predictor(const Vector2f &error_angl
target_ang_vel.x = input_shaping_angle(wrap_PI(error_angle.x), _input_tc, get_accel_roll_max_radss(), target_ang_vel.x, dt); target_ang_vel.x = input_shaping_angle(wrap_PI(error_angle.x), _input_tc, get_accel_roll_max_radss(), target_ang_vel.x, dt);
target_ang_vel.y = input_shaping_angle(wrap_PI(error_angle.y), _input_tc, get_accel_pitch_max_radss(), target_ang_vel.y, dt); target_ang_vel.y = input_shaping_angle(wrap_PI(error_angle.y), _input_tc, get_accel_pitch_max_radss(), target_ang_vel.y, dt);
} else { } else {
target_ang_vel.x = _p_angle_roll.get_p(wrap_PI(error_angle.x)); const float angleP_roll = _p_angle_roll.kP() * _angle_P_scale.x;
target_ang_vel.y = _p_angle_pitch.get_p(wrap_PI(error_angle.y)); const float angleP_pitch = _p_angle_pitch.kP() * _angle_P_scale.y;
target_ang_vel.x = angleP_roll * wrap_PI(error_angle.x);
target_ang_vel.y = angleP_pitch * wrap_PI(error_angle.y);
} }
// Limit the angular velocity correction // Limit the angular velocity correction
Vector3f ang_vel(target_ang_vel.x, target_ang_vel.y, 0.0f); Vector3f ang_vel(target_ang_vel.x, target_ang_vel.y, 0.0f);
@ -988,25 +990,33 @@ Vector3f AC_AttitudeControl::update_ang_vel_target_from_att_error(const Vector3f
{ {
Vector3f rate_target_ang_vel; Vector3f rate_target_ang_vel;
// Compute the roll angular velocity demand from the roll angle error // Compute the roll angular velocity demand from the roll angle error
const float angleP_roll = _p_angle_roll.kP() * _angle_P_scale.x;
if (_use_sqrt_controller && !is_zero(get_accel_roll_max_radss())) { if (_use_sqrt_controller && !is_zero(get_accel_roll_max_radss())) {
rate_target_ang_vel.x = sqrt_controller(attitude_error_rot_vec_rad.x, _p_angle_roll.kP(), constrain_float(get_accel_roll_max_radss() / 2.0f, AC_ATTITUDE_ACCEL_RP_CONTROLLER_MIN_RADSS, AC_ATTITUDE_ACCEL_RP_CONTROLLER_MAX_RADSS), _dt); rate_target_ang_vel.x = sqrt_controller(attitude_error_rot_vec_rad.x, angleP_roll, constrain_float(get_accel_roll_max_radss() / 2.0f, AC_ATTITUDE_ACCEL_RP_CONTROLLER_MIN_RADSS, AC_ATTITUDE_ACCEL_RP_CONTROLLER_MAX_RADSS), _dt);
} else { } else {
rate_target_ang_vel.x = _p_angle_roll.kP() * attitude_error_rot_vec_rad.x; rate_target_ang_vel.x = angleP_roll * attitude_error_rot_vec_rad.x;
} }
// Compute the pitch angular velocity demand from the pitch angle error // Compute the pitch angular velocity demand from the pitch angle error
const float angleP_pitch = _p_angle_pitch.kP() * _angle_P_scale.y;
if (_use_sqrt_controller && !is_zero(get_accel_pitch_max_radss())) { if (_use_sqrt_controller && !is_zero(get_accel_pitch_max_radss())) {
rate_target_ang_vel.y = sqrt_controller(attitude_error_rot_vec_rad.y, _p_angle_pitch.kP(), constrain_float(get_accel_pitch_max_radss() / 2.0f, AC_ATTITUDE_ACCEL_RP_CONTROLLER_MIN_RADSS, AC_ATTITUDE_ACCEL_RP_CONTROLLER_MAX_RADSS), _dt); rate_target_ang_vel.y = sqrt_controller(attitude_error_rot_vec_rad.y, angleP_pitch, constrain_float(get_accel_pitch_max_radss() / 2.0f, AC_ATTITUDE_ACCEL_RP_CONTROLLER_MIN_RADSS, AC_ATTITUDE_ACCEL_RP_CONTROLLER_MAX_RADSS), _dt);
} else { } else {
rate_target_ang_vel.y = _p_angle_pitch.kP() * attitude_error_rot_vec_rad.y; rate_target_ang_vel.y = angleP_pitch * attitude_error_rot_vec_rad.y;
} }
// Compute the yaw angular velocity demand from the yaw angle error // Compute the yaw angular velocity demand from the yaw angle error
const float angleP_yaw = _p_angle_yaw.kP() * _angle_P_scale.z;
if (_use_sqrt_controller && !is_zero(get_accel_yaw_max_radss())) { if (_use_sqrt_controller && !is_zero(get_accel_yaw_max_radss())) {
rate_target_ang_vel.z = sqrt_controller(attitude_error_rot_vec_rad.z, _p_angle_yaw.kP(), constrain_float(get_accel_yaw_max_radss() / 2.0f, AC_ATTITUDE_ACCEL_Y_CONTROLLER_MIN_RADSS, AC_ATTITUDE_ACCEL_Y_CONTROLLER_MAX_RADSS), _dt); rate_target_ang_vel.z = sqrt_controller(attitude_error_rot_vec_rad.z, angleP_yaw, constrain_float(get_accel_yaw_max_radss() / 2.0f, AC_ATTITUDE_ACCEL_Y_CONTROLLER_MIN_RADSS, AC_ATTITUDE_ACCEL_Y_CONTROLLER_MAX_RADSS), _dt);
} else { } else {
rate_target_ang_vel.z = _p_angle_yaw.kP() * attitude_error_rot_vec_rad.z; rate_target_ang_vel.z = angleP_yaw * attitude_error_rot_vec_rad.z;
} }
// reset angle P scaling, saving used value for logging
_angle_P_scale_used = _angle_P_scale;
_angle_P_scale = Vector3f{1,1,1};
return rate_target_ang_vel; return rate_target_ang_vel;
} }

View File

@ -376,6 +376,19 @@ public:
// Sets the yaw rate shaping time constant // Sets the yaw rate shaping time constant
void set_yaw_rate_tc(float input_tc) { _rate_y_tc = input_tc; } void set_yaw_rate_tc(float input_tc) { _rate_y_tc = input_tc; }
// setup a one loop angle P scale multiplier. This replaces any previous scale applied
// so should only be used when only one source of scaling is needed
void set_angle_P_scale(const Vector3f &angle_P_scale) { _angle_P_scale = angle_P_scale; }
// setup a one loop angle P scale multiplier, multiplying by any
// previously applied scale from this loop. This allows for more
// than one type of scale factor to be applied for different
// purposes
void set_angle_P_scale_mult(const Vector3f &angle_P_scale) { _angle_P_scale *= angle_P_scale; }
// get the value of the angle P scale that was used in the last loop, for logging
const Vector3f &get_angle_P_scale_logging(void) const { return _angle_P_scale_used; }
// User settable parameters // User settable parameters
static const struct AP_Param::GroupInfo var_info[]; static const struct AP_Param::GroupInfo var_info[];
@ -495,6 +508,12 @@ protected:
float _rate_rp_tc; float _rate_rp_tc;
float _rate_y_tc; float _rate_y_tc;
// angle P scaling vector for roll, pitch, yaw
Vector3f _angle_P_scale{1,1,1};
// angle scale used for last loop, used for logging
Vector3f _angle_P_scale_used;
// References to external libraries // References to external libraries
const AP_AHRS_View& _ahrs; const AP_AHRS_View& _ahrs;
const AP_Vehicle::MultiCopter &_aparm; const AP_Vehicle::MultiCopter &_aparm;