mirror of https://github.com/ArduPilot/ardupilot
AR_AttitudeControl: balancebot gets pitch limit protection
This commit is contained in:
parent
ef7bb2d4e0
commit
71ae3f0a13
|
@ -40,6 +40,9 @@
|
||||||
#define AR_ATTCONTROL_PITCH_THR_IMAX 1.0f
|
#define AR_ATTCONTROL_PITCH_THR_IMAX 1.0f
|
||||||
#define AR_ATTCONTROL_PITCH_THR_FILT 10.0f
|
#define AR_ATTCONTROL_PITCH_THR_FILT 10.0f
|
||||||
#define AR_ATTCONTROL_BAL_PITCH_FF 0.4f
|
#define AR_ATTCONTROL_BAL_PITCH_FF 0.4f
|
||||||
|
#define AR_ATTCONTROL_PITCH_LIM_TC 0.5f // pitch limit default time constant
|
||||||
|
#define AR_ATTCONTROL_PITCH_RELAX_RATIO 0.5f // pitch limit relaxed 2x slower than it is limited
|
||||||
|
#define AR_ATTCONTROL_PITCH_LIM_THR_THRESH 0.60 // pitch limiting starts if throttle exceeds 60%
|
||||||
#define AR_ATTCONTROL_DT 0.02f
|
#define AR_ATTCONTROL_DT 0.02f
|
||||||
#define AR_ATTCONTROL_TIMEOUT_MS 200
|
#define AR_ATTCONTROL_TIMEOUT_MS 200
|
||||||
#define AR_ATTCONTROL_HEEL_SAIL_P 1.0f
|
#define AR_ATTCONTROL_HEEL_SAIL_P 1.0f
|
||||||
|
@ -443,6 +446,22 @@ const AP_Param::GroupInfo AR_AttitudeControl::var_info[] = {
|
||||||
// @User: Standard
|
// @User: Standard
|
||||||
AP_GROUPINFO("_TURN_MAX_G", 13, AR_AttitudeControl, _turn_lateral_G_max, 0.6f),
|
AP_GROUPINFO("_TURN_MAX_G", 13, AR_AttitudeControl, _turn_lateral_G_max, 0.6f),
|
||||||
|
|
||||||
|
// @Param: _BAL_LIM_TC
|
||||||
|
// @DisplayName: Pitch control limit time constant
|
||||||
|
// @Description: Pitch control limit time constant to protect against falling. Lower values limit pitch more quickly, higher values limit more slowly. Set to 0 to disable
|
||||||
|
// @Range: 0.0 5.0
|
||||||
|
// @Increment: 0.01
|
||||||
|
// @User: Standard
|
||||||
|
AP_GROUPINFO("_BAL_LIM_TC", 14, AR_AttitudeControl, _pitch_limit_tc, AR_ATTCONTROL_PITCH_LIM_TC),
|
||||||
|
|
||||||
|
// @Param: _BAL_LIM_THR
|
||||||
|
// @DisplayName: Pitch control limit throttle threshold
|
||||||
|
// @Description: Pitch control limit throttle threshold. Pitch angle will be limited if throttle crosses this threshold (from 0 to 1)
|
||||||
|
// @Range: 0.0 1.0
|
||||||
|
// @Increment: 0.01
|
||||||
|
// @User: Standard
|
||||||
|
AP_GROUPINFO("_BAL_LIM_THR", 15, AR_AttitudeControl, _pitch_limit_throttle_thresh, AR_ATTCONTROL_PITCH_LIM_THR_THRESH),
|
||||||
|
|
||||||
AP_GROUPEND
|
AP_GROUPEND
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -716,8 +735,9 @@ float AR_AttitudeControl::get_throttle_out_stop(bool motor_limit_low, bool motor
|
||||||
|
|
||||||
// balancebot pitch to throttle controller
|
// balancebot pitch to throttle controller
|
||||||
// returns a throttle output from -1 to +1 given a desired pitch angle (in radians)
|
// returns a throttle output from -1 to +1 given a desired pitch angle (in radians)
|
||||||
|
// pitch_max should be the user defined max pitch angle (in radians)
|
||||||
// motor_limit should be true if the motors have hit their upper or lower limit
|
// motor_limit should be true if the motors have hit their upper or lower limit
|
||||||
float AR_AttitudeControl::get_throttle_out_from_pitch(float desired_pitch, bool motor_limit, float dt)
|
float AR_AttitudeControl::get_throttle_out_from_pitch(float desired_pitch, float pitch_max, bool motor_limit, float dt)
|
||||||
{
|
{
|
||||||
// sanity check dt
|
// sanity check dt
|
||||||
dt = constrain_float(dt, 0.0f, 1.0f);
|
dt = constrain_float(dt, 0.0f, 1.0f);
|
||||||
|
@ -727,9 +747,20 @@ float AR_AttitudeControl::get_throttle_out_from_pitch(float desired_pitch, bool
|
||||||
if ((_balance_last_ms == 0) || ((now - _balance_last_ms) > AR_ATTCONTROL_TIMEOUT_MS)) {
|
if ((_balance_last_ms == 0) || ((now - _balance_last_ms) > AR_ATTCONTROL_TIMEOUT_MS)) {
|
||||||
_pitch_to_throttle_pid.reset_filter();
|
_pitch_to_throttle_pid.reset_filter();
|
||||||
_pitch_to_throttle_pid.reset_I();
|
_pitch_to_throttle_pid.reset_I();
|
||||||
|
_pitch_limit_low = -pitch_max;
|
||||||
|
_pitch_limit_high = pitch_max;
|
||||||
}
|
}
|
||||||
_balance_last_ms = now;
|
_balance_last_ms = now;
|
||||||
|
|
||||||
|
// limit desired pitch to protect against falling
|
||||||
|
const bool pitch_limit_active = (_pitch_limit_tc >= 0.01) && (_pitch_limit_throttle_thresh > 0);
|
||||||
|
if (pitch_limit_active) {
|
||||||
|
desired_pitch = constrain_float(desired_pitch, _pitch_limit_low, _pitch_limit_high);
|
||||||
|
_pitch_limited = (desired_pitch <= _pitch_limit_low || desired_pitch >= _pitch_limit_high);
|
||||||
|
} else {
|
||||||
|
_pitch_limited = false;
|
||||||
|
}
|
||||||
|
|
||||||
// set PID's dt
|
// set PID's dt
|
||||||
_pitch_to_throttle_pid.set_dt(dt);
|
_pitch_to_throttle_pid.set_dt(dt);
|
||||||
|
|
||||||
|
@ -741,6 +772,25 @@ float AR_AttitudeControl::get_throttle_out_from_pitch(float desired_pitch, bool
|
||||||
output += _pitch_to_throttle_pid.update_all(desired_pitch, pitch_rad, motor_limit);
|
output += _pitch_to_throttle_pid.update_all(desired_pitch, pitch_rad, motor_limit);
|
||||||
output += _pitch_to_throttle_pid.get_ff();
|
output += _pitch_to_throttle_pid.get_ff();
|
||||||
|
|
||||||
|
// update pitch limits for next iteration
|
||||||
|
// note: pitch is positive when leaning backwards, negative when leaning forward
|
||||||
|
if (pitch_limit_active) {
|
||||||
|
const float pitch_limit_incr = 1.0/_pitch_limit_tc * dt * pitch_max;
|
||||||
|
const float pitch_relax_incr = pitch_limit_incr * AR_ATTCONTROL_PITCH_RELAX_RATIO;
|
||||||
|
if (output <= -_pitch_limit_throttle_thresh) {
|
||||||
|
// very low negative throttle output means we must lower pitch_high (e.g. reduce leaning backwards)
|
||||||
|
_pitch_limit_high = MAX(_pitch_limit_high - pitch_limit_incr, 0);
|
||||||
|
} else {
|
||||||
|
_pitch_limit_high = MIN(_pitch_limit_high + pitch_relax_incr, pitch_max);
|
||||||
|
}
|
||||||
|
if (output >= _pitch_limit_throttle_thresh) {
|
||||||
|
// very high positive throttle output means we must raise pitch_low (reduce leaning forwards)
|
||||||
|
_pitch_limit_low = MIN(_pitch_limit_low + pitch_limit_incr, 0);
|
||||||
|
} else {
|
||||||
|
_pitch_limit_low = MAX(_pitch_limit_low - pitch_relax_incr, -pitch_max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// constrain and return final output
|
// constrain and return final output
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,8 +68,13 @@ public:
|
||||||
|
|
||||||
// balancebot pitch to throttle controller
|
// balancebot pitch to throttle controller
|
||||||
// returns a throttle output from -1 to +1 given a desired pitch angle (in radians)
|
// returns a throttle output from -1 to +1 given a desired pitch angle (in radians)
|
||||||
|
// pitch_max should be the user defined max pitch angle (in radians)
|
||||||
// motor_limit should be true if the motors have hit their upper or lower limit
|
// motor_limit should be true if the motors have hit their upper or lower limit
|
||||||
float get_throttle_out_from_pitch(float desired_pitch, bool motor_limit, float dt);
|
float get_throttle_out_from_pitch(float desired_pitch, float pitch_max, bool motor_limit, float dt);
|
||||||
|
|
||||||
|
// returns true if the pitch angle has been limited to prevent falling over
|
||||||
|
// pitch limit protection is implemented within get_throttle_out_from_pitch
|
||||||
|
bool pitch_limited() const { return _pitch_limited; }
|
||||||
|
|
||||||
// get latest desired pitch in radians for reporting purposes
|
// get latest desired pitch in radians for reporting purposes
|
||||||
float get_desired_pitch() const;
|
float get_desired_pitch() const;
|
||||||
|
@ -122,6 +127,8 @@ private:
|
||||||
AC_PID _throttle_speed_pid; // throttle speed controller
|
AC_PID _throttle_speed_pid; // throttle speed controller
|
||||||
AC_PID _pitch_to_throttle_pid;// balancebot pitch controller
|
AC_PID _pitch_to_throttle_pid;// balancebot pitch controller
|
||||||
AP_Float _pitch_to_throttle_ff; // balancebot feed forward from current pitch angle
|
AP_Float _pitch_to_throttle_ff; // balancebot feed forward from current pitch angle
|
||||||
|
AP_Float _pitch_limit_tc; // balancebot pitch limit protection time constant
|
||||||
|
AP_Float _pitch_limit_throttle_thresh; // balancebot pitch limit throttle threshold (in the range 0 to 1.0)
|
||||||
|
|
||||||
AP_Float _throttle_accel_max; // speed/throttle control acceleration (and deceleration) maximum in m/s/s. 0 to disable limits
|
AP_Float _throttle_accel_max; // speed/throttle control acceleration (and deceleration) maximum in m/s/s. 0 to disable limits
|
||||||
AP_Float _throttle_decel_max; // speed/throttle control deceleration maximum in m/s/s. 0 to use ATC_ACCEL_MAX for deceleration
|
AP_Float _throttle_decel_max; // speed/throttle control deceleration maximum in m/s/s. 0 to use ATC_ACCEL_MAX for deceleration
|
||||||
|
@ -146,7 +153,10 @@ private:
|
||||||
AP_PIDInfo _throttle_speed_pid_info; // local copy of throttle_speed controller's PID info to allow reporting of unusual FF
|
AP_PIDInfo _throttle_speed_pid_info; // local copy of throttle_speed controller's PID info to allow reporting of unusual FF
|
||||||
|
|
||||||
// balancebot pitch control
|
// balancebot pitch control
|
||||||
uint32_t _balance_last_ms = 0;
|
uint32_t _balance_last_ms = 0; // system time that get_throttle_out_from_pitch was last called
|
||||||
|
float _pitch_limit_low = 0; // min desired pitch (in radians) used to protect against falling over
|
||||||
|
float _pitch_limit_high = 0; // max desired pitch (in radians) used to protect against falling over
|
||||||
|
bool _pitch_limited = false; // true if pitch was limited on last call to get_throttle_out_from_pitch
|
||||||
|
|
||||||
// Sailboat heel control
|
// Sailboat heel control
|
||||||
AC_PID _sailboat_heel_pid; // Sailboat heel angle pid controller
|
AC_PID _sailboat_heel_pid; // Sailboat heel angle pid controller
|
||||||
|
|
Loading…
Reference in New Issue