diff --git a/libraries/AC_AttitudeControl/AC_PosControl.cpp b/libraries/AC_AttitudeControl/AC_PosControl.cpp index ec9c84922b3..8cda28b862c 100644 --- a/libraries/AC_AttitudeControl/AC_PosControl.cpp +++ b/libraries/AC_AttitudeControl/AC_PosControl.cpp @@ -483,6 +483,7 @@ void AC_PosControl::init_xy_controller() _pitch_target = att_target_euler_cd.y; _yaw_target = att_target_euler_cd.z; // todo: this should be thrust vector heading, not yaw. _yaw_rate_target = 0.0f; + _angle_max_override_cd = 0.0; _pos_target.xy() = _inav.get_position_xy_cm().topostype(); @@ -497,7 +498,7 @@ void AC_PosControl::init_xy_controller() // limit acceleration using maximum lean angles float angle_max = MIN(_attitude_control.get_althold_lean_angle_max_cd(), get_lean_angle_max_cd()); - float accel_max = GRAVITY_MSS * 100.0f * tanf(ToRad(angle_max * 0.01f)); + float accel_max = angle_to_accel(angle_max * 0.01) * 100.0; _accel_target.xy().limit_length(accel_max); // initialise I terms from lean angles @@ -634,7 +635,7 @@ void AC_PosControl::update_xy_controller() // limit acceleration using maximum lean angles float angle_max = MIN(_attitude_control.get_althold_lean_angle_max_cd(), get_lean_angle_max_cd()); - float accel_max = GRAVITY_MSS * 100.0f * tanf(ToRad(angle_max * 0.01f)); + float accel_max = angle_to_accel(angle_max * 0.01) * 100; // Define the limit vector before we constrain _accel_target _limit_vector.xy() = _accel_target.xy(); if (!limit_accel_xy(_vel_desired.xy(), _accel_target.xy(), accel_max)) { @@ -986,6 +987,9 @@ void AC_PosControl::update_z_controller() /// get_lean_angle_max_cd - returns the maximum lean angle the autopilot may request float AC_PosControl::get_lean_angle_max_cd() const { + if (is_positive(_angle_max_override_cd)) { + return _angle_max_override_cd; + } if (!is_positive(_lean_angle_max)) { return _attitude_control.lean_angle_max_cd(); } @@ -1166,9 +1170,9 @@ void AC_PosControl::accel_to_lean_angles(float accel_x_cmss, float accel_y_cmss, const float accel_right = -accel_x_cmss * _ahrs.sin_yaw() + accel_y_cmss * _ahrs.cos_yaw(); // update angle targets that will be passed to stabilize controller - pitch_target = atanf(-accel_forward / (GRAVITY_MSS * 100.0f)) * (18000.0f / M_PI); + pitch_target = accel_to_angle(-accel_forward * 0.01) * 100; float cos_pitch_target = cosf(pitch_target * M_PI / 18000.0f); - roll_target = atanf(accel_right * cos_pitch_target / (GRAVITY_MSS * 100.0f)) * (18000.0f / M_PI); + roll_target = accel_to_angle((accel_right * cos_pitch_target)*0.01) * 100; } // lean_angles_to_accel_xy - convert roll, pitch lean target angles to NE frame accelerations in cm/s/s diff --git a/libraries/AC_AttitudeControl/AC_PosControl.h b/libraries/AC_AttitudeControl/AC_PosControl.h index 7ba799ff657..29c4a6f62ca 100644 --- a/libraries/AC_AttitudeControl/AC_PosControl.h +++ b/libraries/AC_AttitudeControl/AC_PosControl.h @@ -343,6 +343,12 @@ public: /// get_lean_angle_max_cd - returns the maximum lean angle the autopilot may request float get_lean_angle_max_cd() const; + /* + set_lean_angle_max_cd - set the maximum lean angle. A value of zero means to use the ANGLE_MAX parameter. + This is reset to zero on init_xy_controller() + */ + void set_lean_angle_max_cd(float angle_max_cd) { _angle_max_override_cd = angle_max_cd; } + /// Other @@ -466,6 +472,9 @@ protected: // high vibration handling bool _vibe_comp_enabled; // true when high vibration compensation is on + // angle max override, if zero then use ANGLE_MAX parameter + float _angle_max_override_cd; + // return true if on a real vehicle or SITL with lock-step scheduling bool has_good_timing(void) const; };