AC_PosControl: remove various unnecessary timing hacks
This commit is contained in:
parent
5438d38df5
commit
557d339cf1
@ -35,9 +35,9 @@ AC_PosControl::AC_PosControl(const AP_AHRS& ahrs, const AP_InertialNav& inav,
|
|||||||
_pid_rate_lat(pid_rate_lat),
|
_pid_rate_lat(pid_rate_lat),
|
||||||
_pid_rate_lon(pid_rate_lon),
|
_pid_rate_lon(pid_rate_lon),
|
||||||
_dt(POSCONTROL_DT_10HZ),
|
_dt(POSCONTROL_DT_10HZ),
|
||||||
|
_dt_xy(POSCONTROL_DT_50HZ),
|
||||||
_last_update_xy_ms(0),
|
_last_update_xy_ms(0),
|
||||||
_last_update_z_ms(0),
|
_last_update_z_ms(0),
|
||||||
_last_update_vel_xyz_ms(0),
|
|
||||||
_speed_down_cms(POSCONTROL_SPEED_DOWN),
|
_speed_down_cms(POSCONTROL_SPEED_DOWN),
|
||||||
_speed_up_cms(POSCONTROL_SPEED_UP),
|
_speed_up_cms(POSCONTROL_SPEED_UP),
|
||||||
_speed_cms(POSCONTROL_SPEED),
|
_speed_cms(POSCONTROL_SPEED),
|
||||||
@ -49,10 +49,7 @@ AC_PosControl::AC_PosControl(const AP_AHRS& ahrs, const AP_InertialNav& inav,
|
|||||||
_roll_target(0.0f),
|
_roll_target(0.0f),
|
||||||
_pitch_target(0.0f),
|
_pitch_target(0.0f),
|
||||||
_alt_max(0.0f),
|
_alt_max(0.0f),
|
||||||
_distance_to_target(0.0f),
|
_distance_to_target(0.0f)
|
||||||
_xy_step(0),
|
|
||||||
_dt_xy(0.0f),
|
|
||||||
_vel_xyz_step(0)
|
|
||||||
{
|
{
|
||||||
AP_Param::setup_object_defaults(this, var_info);
|
AP_Param::setup_object_defaults(this, var_info);
|
||||||
|
|
||||||
@ -502,9 +499,6 @@ bool AC_PosControl::is_active_xy() const
|
|||||||
/// this does not update the xy target
|
/// this does not update the xy target
|
||||||
void AC_PosControl::init_xy_controller(bool reset_I)
|
void AC_PosControl::init_xy_controller(bool reset_I)
|
||||||
{
|
{
|
||||||
// reset xy controller to first step
|
|
||||||
_xy_step = 0;
|
|
||||||
|
|
||||||
// set roll, pitch lean angle targets to current attitude
|
// set roll, pitch lean angle targets to current attitude
|
||||||
_roll_target = _ahrs.roll_sensor;
|
_roll_target = _ahrs.roll_sensor;
|
||||||
_pitch_target = _ahrs.pitch_sensor;
|
_pitch_target = _ahrs.pitch_sensor;
|
||||||
@ -520,65 +514,46 @@ void AC_PosControl::init_xy_controller(bool reset_I)
|
|||||||
// flag reset required in rate to accel step
|
// flag reset required in rate to accel step
|
||||||
_flags.reset_desired_vel_to_pos = true;
|
_flags.reset_desired_vel_to_pos = true;
|
||||||
_flags.reset_rate_to_accel_xy = true;
|
_flags.reset_rate_to_accel_xy = true;
|
||||||
|
|
||||||
// update update time
|
|
||||||
_last_update_xy_ms = hal.scheduler->millis();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// update_xy_controller - run the horizontal position controller - should be called at 100hz or higher
|
/// update_xy_controller - run the horizontal position controller - should be called at 100hz or higher
|
||||||
void AC_PosControl::update_xy_controller(bool use_desired_velocity, float ekfNavVelGainScaler)
|
void AC_PosControl::update_xy_controller(bool use_desired_velocity, float ekfNavVelGainScaler)
|
||||||
{
|
{
|
||||||
// catch if we've just been started
|
// compute dt
|
||||||
uint32_t now = hal.scheduler->millis();
|
uint32_t now = hal.scheduler->millis();
|
||||||
if ((now - _last_update_xy_ms) >= POSCONTROL_ACTIVE_TIMEOUT_MS) {
|
float dt = (now - _last_update_xy_ms) / 1000.0f;
|
||||||
init_xy_controller();
|
_last_update_xy_ms = now;
|
||||||
now = _last_update_xy_ms;
|
|
||||||
|
// sanity check dt - expect to be called faster than ~5hz
|
||||||
|
if (dt > POSCONTROL_ACTIVE_TIMEOUT_MS) {
|
||||||
|
dt = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if xy leash needs to be recalculated
|
// check if xy leash needs to be recalculated
|
||||||
calc_leash_length_xy();
|
calc_leash_length_xy();
|
||||||
|
|
||||||
// reset step back to 0 if loiter or waypoint parents have triggered an update and we completed the last full cycle
|
// translate any adjustments from pilot to loiter target
|
||||||
if (_flags.force_recalc_xy && _xy_step > 3) {
|
desired_vel_to_pos(dt);
|
||||||
_flags.force_recalc_xy = false;
|
|
||||||
_xy_step = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// run loiter steps
|
// run position controller's position error to desired velocity step
|
||||||
switch (_xy_step) {
|
pos_to_rate_xy(use_desired_velocity, dt, ekfNavVelGainScaler);
|
||||||
case 0:
|
|
||||||
// capture time since last iteration
|
|
||||||
_dt_xy = (now - _last_update_xy_ms) / 1000.0f;
|
|
||||||
_last_update_xy_ms = now;
|
|
||||||
|
|
||||||
// translate any adjustments from pilot to loiter target
|
// run position controller's velocity to acceleration step
|
||||||
desired_vel_to_pos(_dt_xy);
|
rate_to_accel_xy(dt, ekfNavVelGainScaler);
|
||||||
_xy_step++;
|
|
||||||
break;
|
// run position controller's acceleration to lean angle step
|
||||||
case 1:
|
accel_to_lean_angles(dt, ekfNavVelGainScaler);
|
||||||
// run position controller's position error to desired velocity step
|
}
|
||||||
pos_to_rate_xy(use_desired_velocity,_dt_xy, ekfNavVelGainScaler);
|
|
||||||
_xy_step++;
|
float AC_PosControl::time_since_last_xy_update() const
|
||||||
break;
|
{
|
||||||
case 2:
|
uint32_t now = hal.scheduler->millis();
|
||||||
// run position controller's velocity to acceleration step
|
return (now - _last_update_xy_ms)*0.001f;
|
||||||
rate_to_accel_xy(_dt_xy, ekfNavVelGainScaler);
|
|
||||||
_xy_step++;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
// run position controller's acceleration to lean angle step
|
|
||||||
accel_to_lean_angles(ekfNavVelGainScaler);
|
|
||||||
_xy_step++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// init_vel_controller_xyz - initialise the velocity controller - should be called once before the caller attempts to use the controller
|
/// init_vel_controller_xyz - initialise the velocity controller - should be called once before the caller attempts to use the controller
|
||||||
void AC_PosControl::init_vel_controller_xyz()
|
void AC_PosControl::init_vel_controller_xyz()
|
||||||
{
|
{
|
||||||
// force the xy velocity controller to run immediately
|
|
||||||
_vel_xyz_step = 3;
|
|
||||||
|
|
||||||
// set roll, pitch lean angle targets to current attitude
|
// set roll, pitch lean angle targets to current attitude
|
||||||
_roll_target = _ahrs.roll_sensor;
|
_roll_target = _ahrs.roll_sensor;
|
||||||
_pitch_target = _ahrs.pitch_sensor;
|
_pitch_target = _ahrs.pitch_sensor;
|
||||||
@ -599,9 +574,6 @@ void AC_PosControl::init_vel_controller_xyz()
|
|||||||
// move current vehicle velocity into feed forward velocity
|
// move current vehicle velocity into feed forward velocity
|
||||||
const Vector3f& curr_vel = _inav.get_velocity();
|
const Vector3f& curr_vel = _inav.get_velocity();
|
||||||
set_desired_velocity_xy(curr_vel.x, curr_vel.y);
|
set_desired_velocity_xy(curr_vel.x, curr_vel.y);
|
||||||
|
|
||||||
// record update time
|
|
||||||
_last_update_vel_xyz_ms = hal.scheduler->millis();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// update_velocity_controller_xyz - run the velocity controller - should be called at 100hz or higher
|
/// update_velocity_controller_xyz - run the velocity controller - should be called at 100hz or higher
|
||||||
@ -612,40 +584,36 @@ void AC_PosControl::update_vel_controller_xyz(float ekfNavVelGainScaler)
|
|||||||
{
|
{
|
||||||
// capture time since last iteration
|
// capture time since last iteration
|
||||||
uint32_t now = hal.scheduler->millis();
|
uint32_t now = hal.scheduler->millis();
|
||||||
float dt_xy = (now - _last_update_vel_xyz_ms) / 1000.0f;
|
float dt = (now - _last_update_xy_ms) / 1000.0f;
|
||||||
|
|
||||||
|
// sanity check dt - expect to be called faster than ~5hz
|
||||||
|
if (dt >= POSCONTROL_ACTIVE_TIMEOUT_MS) {
|
||||||
|
dt = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
// check if xy leash needs to be recalculated
|
// check if xy leash needs to be recalculated
|
||||||
calc_leash_length_xy();
|
calc_leash_length_xy();
|
||||||
|
|
||||||
// we will run the horizontal component every 4th iteration (i.e. 50hz on Pixhawk, 20hz on APM)
|
// apply desired velocity request to position target
|
||||||
if (dt_xy >= POSCONTROL_VEL_UPDATE_TIME) {
|
desired_vel_to_pos(dt);
|
||||||
|
|
||||||
// record update time
|
// run position controller's position error to desired velocity step
|
||||||
_last_update_vel_xyz_ms = now;
|
pos_to_rate_xy(true, dt, ekfNavVelGainScaler);
|
||||||
|
|
||||||
// sanity check dt
|
// run velocity to acceleration step
|
||||||
if (dt_xy >= POSCONTROL_ACTIVE_TIMEOUT_MS) {
|
rate_to_accel_xy(dt, ekfNavVelGainScaler);
|
||||||
dt_xy = 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
// apply desired velocity request to position target
|
// run acceleration to lean angle step
|
||||||
desired_vel_to_pos(dt_xy);
|
accel_to_lean_angles(dt, ekfNavVelGainScaler);
|
||||||
|
|
||||||
// run position controller's position error to desired velocity step
|
|
||||||
pos_to_rate_xy(true, dt_xy, ekfNavVelGainScaler);
|
|
||||||
|
|
||||||
// run velocity to acceleration step
|
|
||||||
rate_to_accel_xy(dt_xy, ekfNavVelGainScaler);
|
|
||||||
|
|
||||||
// run acceleration to lean angle step
|
|
||||||
accel_to_lean_angles(ekfNavVelGainScaler);
|
|
||||||
}
|
|
||||||
|
|
||||||
// update altitude target
|
// update altitude target
|
||||||
set_alt_target_from_climb_rate(_vel_desired.z, _dt);
|
set_alt_target_from_climb_rate(_vel_desired.z, dt);
|
||||||
|
|
||||||
// run z-axis position controller
|
// run z-axis position controller
|
||||||
update_z_controller();
|
update_z_controller();
|
||||||
|
|
||||||
|
// record update time
|
||||||
|
_last_update_xy_ms = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -817,15 +785,8 @@ void AC_PosControl::rate_to_accel_xy(float dt, float ekfNavVelGainScaler)
|
|||||||
|
|
||||||
/// accel_to_lean_angles - horizontal desired acceleration to lean angles
|
/// accel_to_lean_angles - horizontal desired acceleration to lean angles
|
||||||
/// converts desired accelerations provided in lat/lon frame to roll/pitch angles
|
/// converts desired accelerations provided in lat/lon frame to roll/pitch angles
|
||||||
void AC_PosControl::accel_to_lean_angles(float ekfNavVelGainScaler)
|
void AC_PosControl::accel_to_lean_angles(float dt, float ekfNavVelGainScaler)
|
||||||
{
|
{
|
||||||
// catch if we've just been started
|
|
||||||
uint32_t now = hal.scheduler->millis();
|
|
||||||
if ((now - _last_update_xy_ms) >= POSCONTROL_ACTIVE_TIMEOUT_MS) {
|
|
||||||
now = _last_update_xy_ms;
|
|
||||||
}
|
|
||||||
float dt_xy = (now - _last_update_xy_ms) * 0.001f;
|
|
||||||
|
|
||||||
float accel_right, accel_forward;
|
float accel_right, accel_forward;
|
||||||
float lean_angle_max = _attitude_control.lean_angle_max();
|
float lean_angle_max = _attitude_control.lean_angle_max();
|
||||||
|
|
||||||
@ -842,7 +803,7 @@ void AC_PosControl::accel_to_lean_angles(float ekfNavVelGainScaler)
|
|||||||
// apply a rate limit of 100 deg/sec - required due to optical flow sensor saturation and impulse noise effects
|
// apply a rate limit of 100 deg/sec - required due to optical flow sensor saturation and impulse noise effects
|
||||||
static float lastRollDem = 0.0f;
|
static float lastRollDem = 0.0f;
|
||||||
static float lastPitchDem = 0.0f;
|
static float lastPitchDem = 0.0f;
|
||||||
float maxDeltaAngle = dt_xy * 10000.0f;
|
float maxDeltaAngle = dt * 10000.0f;
|
||||||
if (_roll_target - lastRollDem > maxDeltaAngle) {
|
if (_roll_target - lastRollDem > maxDeltaAngle) {
|
||||||
_roll_target = lastRollDem + maxDeltaAngle;
|
_roll_target = lastRollDem + maxDeltaAngle;
|
||||||
} else if (_roll_target - lastRollDem < -maxDeltaAngle) {
|
} else if (_roll_target - lastRollDem < -maxDeltaAngle) {
|
||||||
@ -858,7 +819,7 @@ void AC_PosControl::accel_to_lean_angles(float ekfNavVelGainScaler)
|
|||||||
|
|
||||||
// 5Hz lowpass filter on angles - required due to optical flow noise
|
// 5Hz lowpass filter on angles - required due to optical flow noise
|
||||||
float freq_cut = 5.0f * ekfNavVelGainScaler;
|
float freq_cut = 5.0f * ekfNavVelGainScaler;
|
||||||
float alpha = constrain_float(dt_xy/(dt_xy + 1.0f/(2.0f*(float)M_PI*freq_cut)),0.0f,1.0f);
|
float alpha = constrain_float(dt/(dt + 1.0f/(2.0f*(float)M_PI*freq_cut)),0.0f,1.0f);
|
||||||
static float roll_target_filtered = 0.0f;
|
static float roll_target_filtered = 0.0f;
|
||||||
static float pitch_target_filtered = 0.0f;
|
static float pitch_target_filtered = 0.0f;
|
||||||
|
|
||||||
|
@ -33,13 +33,12 @@
|
|||||||
#define POSCONTROL_LEASH_LENGTH_MIN 100.0f // minimum leash lengths in cm
|
#define POSCONTROL_LEASH_LENGTH_MIN 100.0f // minimum leash lengths in cm
|
||||||
|
|
||||||
#define POSCONTROL_DT_10HZ 0.10f // time difference in seconds for 10hz update rate
|
#define POSCONTROL_DT_10HZ 0.10f // time difference in seconds for 10hz update rate
|
||||||
|
#define POSCONTROL_DT_50HZ 0.02f // time difference in seconds for 50hz update rate
|
||||||
|
|
||||||
#define POSCONTROL_ACTIVE_TIMEOUT_MS 200 // position controller is considered active if it has been called within the past 200ms (0.2 seconds)
|
#define POSCONTROL_ACTIVE_TIMEOUT_MS 200 // position controller is considered active if it has been called within the past 200ms (0.2 seconds)
|
||||||
|
|
||||||
#define POSCONTROL_ACCEL_Z_DTERM_FILTER 20 // Z axis accel controller's D term filter (in hz)
|
#define POSCONTROL_ACCEL_Z_DTERM_FILTER 20 // Z axis accel controller's D term filter (in hz)
|
||||||
|
|
||||||
#define POSCONTROL_VEL_UPDATE_TIME 0.020f // 50hz update rate on high speed CPUs (Pixhawk, Flymaple)
|
|
||||||
|
|
||||||
#define POSCONTROL_VEL_ERROR_CUTOFF_FREQ 4.0 // 4hz low-pass filter on velocity error
|
#define POSCONTROL_VEL_ERROR_CUTOFF_FREQ 4.0 // 4hz low-pass filter on velocity error
|
||||||
#define POSCONTROL_ACCEL_ERROR_CUTOFF_FREQ 2.0 // 2hz low-pass filter on accel error
|
#define POSCONTROL_ACCEL_ERROR_CUTOFF_FREQ 2.0 // 2hz low-pass filter on accel error
|
||||||
|
|
||||||
@ -62,6 +61,9 @@ public:
|
|||||||
void set_dt(float delta_sec);
|
void set_dt(float delta_sec);
|
||||||
float get_dt() const { return _dt; }
|
float get_dt() const { return _dt; }
|
||||||
|
|
||||||
|
void set_dt_xy(float dt_xy) { _dt_xy = dt_xy; }
|
||||||
|
float get_dt_xy() const { return _dt_xy; }
|
||||||
|
|
||||||
///
|
///
|
||||||
/// z position controller
|
/// z position controller
|
||||||
///
|
///
|
||||||
@ -249,6 +251,8 @@ public:
|
|||||||
// lean_angles_to_accel - convert roll, pitch lean angles to lat/lon frame accelerations in cm/s/s
|
// lean_angles_to_accel - convert roll, pitch lean angles to lat/lon frame accelerations in cm/s/s
|
||||||
void lean_angles_to_accel(float& accel_x_cmss, float& accel_y_cmss) const;
|
void lean_angles_to_accel(float& accel_x_cmss, float& accel_y_cmss) const;
|
||||||
|
|
||||||
|
float time_since_last_xy_update() const;
|
||||||
|
|
||||||
static const struct AP_Param::GroupInfo var_info[];
|
static const struct AP_Param::GroupInfo var_info[];
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -313,7 +317,7 @@ private:
|
|||||||
|
|
||||||
/// accel_to_lean_angles - horizontal desired acceleration to lean angles
|
/// accel_to_lean_angles - horizontal desired acceleration to lean angles
|
||||||
/// converts desired accelerations provided in lat/lon frame to roll/pitch angles
|
/// converts desired accelerations provided in lat/lon frame to roll/pitch angles
|
||||||
void accel_to_lean_angles(float ekfNavVelGainScaler);
|
void accel_to_lean_angles(float dt_xy, float ekfNavVelGainScaler);
|
||||||
|
|
||||||
/// calc_leash_length - calculates the horizontal leash length given a maximum speed, acceleration and position kP gain
|
/// calc_leash_length - calculates the horizontal leash length given a maximum speed, acceleration and position kP gain
|
||||||
float calc_leash_length(float speed_cms, float accel_cms, float kP) const;
|
float calc_leash_length(float speed_cms, float accel_cms, float kP) const;
|
||||||
@ -337,9 +341,9 @@ private:
|
|||||||
|
|
||||||
// internal variables
|
// internal variables
|
||||||
float _dt; // time difference (in seconds) between calls from the main program
|
float _dt; // time difference (in seconds) between calls from the main program
|
||||||
|
float _dt_xy; // time difference (in seconds) between update_xy_controller and update_vel_controller_xyz calls
|
||||||
uint32_t _last_update_xy_ms; // system time of last update_xy_controller call
|
uint32_t _last_update_xy_ms; // system time of last update_xy_controller call
|
||||||
uint32_t _last_update_z_ms; // system time of last update_z_controller call
|
uint32_t _last_update_z_ms; // system time of last update_z_controller call
|
||||||
uint32_t _last_update_vel_xyz_ms;// system time of last update_vel_controller_xyz call
|
|
||||||
float _speed_down_cms; // max descent rate in cm/s
|
float _speed_down_cms; // max descent rate in cm/s
|
||||||
float _speed_up_cms; // max climb rate in cm/s
|
float _speed_up_cms; // max climb rate in cm/s
|
||||||
float _speed_cms; // max horizontal speed in cm/s
|
float _speed_cms; // max horizontal speed in cm/s
|
||||||
@ -365,12 +369,7 @@ private:
|
|||||||
Vector3f _accel_feedforward; // feedforward acceleration in cm/s/s
|
Vector3f _accel_feedforward; // feedforward acceleration in cm/s/s
|
||||||
float _alt_max; // max altitude - should be updated from the main code with altitude limit from fence
|
float _alt_max; // max altitude - should be updated from the main code with altitude limit from fence
|
||||||
float _distance_to_target; // distance to position target - for reporting only
|
float _distance_to_target; // distance to position target - for reporting only
|
||||||
uint8_t _xy_step; // used to decide which portion of horizontal position controller to run during this iteration
|
|
||||||
float _dt_xy; // time difference in seconds between horizontal position updates
|
|
||||||
LowPassFilterFloat _vel_error_filter; // low-pass-filter on z-axis velocity error
|
LowPassFilterFloat _vel_error_filter; // low-pass-filter on z-axis velocity error
|
||||||
LowPassFilterFloat _accel_error_filter; // low-pass-filter on z-axis accelerometer error
|
LowPassFilterFloat _accel_error_filter; // low-pass-filter on z-axis accelerometer error
|
||||||
|
|
||||||
// velocity controller internal variables
|
|
||||||
uint8_t _vel_xyz_step; // used to decide which portion of velocity controller to run during this iteration
|
|
||||||
};
|
};
|
||||||
#endif // AC_POSCONTROL_H
|
#endif // AC_POSCONTROL_H
|
||||||
|
Loading…
Reference in New Issue
Block a user