// pos_to_rate_z - position to rate controller for Z axis // calculates desired rate in earth-frame z axis and passes to rate controller // vel_up_max, vel_down_max should have already been set before calling this method void AC_PosControl::pos_to_rate_z() { float curr_alt = _inav.get_altitude(); // clear position limit flags _limit.pos_up = false; _limit.pos_down = false; // do not let target alt get above limit if (_alt_max > 0 && _pos_target.z > _alt_max) { _pos_target.z = _alt_max; _limit.pos_up = true; } // calculate altitude error _pos_error.z = _pos_target.z - curr_alt; // do not let target altitude get too far from current altitude if (_pos_error.z > _leash_up_z) { _pos_target.z = curr_alt + _leash_up_z; _pos_error.z = _leash_up_z; _limit.pos_up = true; } if (_pos_error.z < -_leash_down_z) { _pos_target.z = curr_alt - _leash_down_z; _pos_error.z = -_leash_down_z; _limit.pos_down = true; } // calculate _vel_target.z using from _pos_error.z using sqrt controller _vel_target.z = AC_AttitudeControl::sqrt_controller(_pos_error.z, _p_alt_pos.kP(), _accel_z_cms); // call rate based throttle controller which will update accel based throttle controller targets rate_to_accel_z(); }
// pos_to_rate_z - position to rate controller for Z axis // calculates desired rate in earth-frame z axis and passes to rate controller // vel_up_max, vel_down_max should have already been set before calling this method void AC_PosControl::pos_to_rate_z() { float curr_alt = _inav.get_altitude(); float linear_distance; // half the distance we swap between linear and sqrt and the distance we offset sqrt. // clear position limit flags _limit.pos_up = false; _limit.pos_down = false; // do not let target alt get above limit if (_alt_max > 0 && _pos_target.z > _alt_max) { _pos_target.z = _alt_max; _limit.pos_up = true; } // calculate altitude error _pos_error.z = _pos_target.z - curr_alt; // do not let target altitude get too far from current altitude if (_pos_error.z > _leash_up_z) { _pos_target.z = curr_alt + _leash_up_z; _pos_error.z = _leash_up_z; _limit.pos_up = true; } if (_pos_error.z < -_leash_down_z) { _pos_target.z = curr_alt - _leash_down_z; _pos_error.z = -_leash_down_z; _limit.pos_down = true; } // check kP to avoid division by zero if (_p_alt_pos.kP() != 0.0f) { linear_distance = _accel_z_cms/(2.0f*_p_alt_pos.kP()*_p_alt_pos.kP()); if (_pos_error.z > 2*linear_distance ) { _vel_target.z = safe_sqrt(2.0f*_accel_z_cms*(_pos_error.z-linear_distance)); }else if (_pos_error.z < -2.0f*linear_distance) { _vel_target.z = -safe_sqrt(2.0f*_accel_z_cms*(-_pos_error.z-linear_distance)); }else{ _vel_target.z = _p_alt_pos.get_p(_pos_error.z); } }else{ _vel_target.z = 0; } // call rate based throttle controller which will update accel based throttle controller targets rate_to_accel_z(); }
// pos_to_rate_z - position to rate controller for Z axis // calculates desired rate in earth-frame z axis and passes to rate controller // vel_up_max, vel_down_max should have already been set before calling this method void AC_PosControl::pos_to_rate_z() { float curr_alt = _inav.get_altitude(); // clear position limit flags _limit.pos_up = false; _limit.pos_down = false; // calculate altitude error _pos_error.z = _pos_target.z - curr_alt; // do not let target altitude get too far from current altitude if (_pos_error.z > _leash_up_z) { _pos_target.z = curr_alt + _leash_up_z; _pos_error.z = _leash_up_z; _limit.pos_up = true; } if (_pos_error.z < -_leash_down_z) { _pos_target.z = curr_alt - _leash_down_z; _pos_error.z = -_leash_down_z; _limit.pos_down = true; } // calculate _vel_target.z using from _pos_error.z using sqrt controller _vel_target.z = AC_AttitudeControl::sqrt_controller(_pos_error.z, _p_pos_z.kP(), _accel_z_cms); // check speed limits // To-Do: check these speed limits here or in the pos->rate controller _limit.vel_up = false; _limit.vel_down = false; if (_vel_target.z < _speed_down_cms) { _vel_target.z = _speed_down_cms; _limit.vel_down = true; } if (_vel_target.z > _speed_up_cms) { _vel_target.z = _speed_up_cms; _limit.vel_up = true; } // add feed forward component if (_flags.use_desvel_ff_z) { _vel_target.z += _vel_desired.z; } // call rate based throttle controller which will update accel based throttle controller targets rate_to_accel_z(); }