2017-02-07 20:49:55 -04:00
# include "AC_PosControl_Sub.h"
2019-12-10 05:31:08 -04:00
AC_PosControl_Sub : : AC_PosControl_Sub ( AP_AHRS_View & ahrs , const AP_InertialNav & inav ,
2021-04-16 12:53:14 -03:00
const AP_Motors & motors , AC_AttitudeControl & attitude_control , float dt ) :
AC_PosControl ( ahrs , inav , motors , attitude_control , dt ) ,
2017-02-07 20:49:55 -04:00
_alt_max ( 0.0f ) ,
_alt_min ( 0.0f )
{ }
2021-08-06 06:40:56 -03:00
/// input_accel_z - calculate a jerk limited path from the current position, velocity and acceleration to an input acceleration.
2021-04-16 12:53:14 -03:00
/// The function takes the current position, velocity, and acceleration and calculates the required jerk limited adjustment to the acceleration for the next time dt.
2021-08-06 06:40:56 -03:00
/// The kinematic path is constrained by the maximum acceleration and jerk set using the function set_max_speed_accel_z.
/// The parameter limit_output specifies if the velocity and acceleration limits are applied to the sum of commanded and correction values or just correction.
void AC_PosControl_Sub : : input_vel_accel_z ( float & vel , const float accel , bool force_descend , bool limit_output )
2017-02-07 20:49:55 -04:00
{
2021-04-16 12:53:14 -03:00
// check for ekf z position reset
2021-05-19 11:09:31 -03:00
handle_ekf_z_reset ( ) ;
2017-02-07 20:49:55 -04:00
2021-04-16 12:53:14 -03:00
// limit desired velocity to prevent breeching altitude limits
if ( _alt_min < 0 & & _alt_min < _alt_max & & _alt_max < 100 & & _pos_target . z < _alt_min ) {
2021-06-21 04:26:39 -03:00
vel = constrain_float ( vel ,
2021-04-16 12:53:14 -03:00
sqrt_controller ( _alt_min - _pos_target . z , 0.0f , _accel_max_z_cmss , 0.0f ) ,
sqrt_controller ( _alt_max - _pos_target . z , 0.0f , _accel_max_z_cmss , 0.0f ) ) ;
2017-02-07 20:49:55 -04:00
}
// calculated increased maximum acceleration if over speed
2021-04-16 12:53:14 -03:00
float accel_z_cms = _accel_max_z_cmss ;
if ( _vel_desired . z < _vel_max_down_cms & & ! is_zero ( _vel_max_down_cms ) ) {
accel_z_cms * = POSCONTROL_OVERSPEED_GAIN_Z * _vel_desired . z / _vel_max_down_cms ;
2017-02-07 20:49:55 -04:00
}
2021-04-16 12:53:14 -03:00
if ( _vel_desired . z > _vel_max_up_cms & & ! is_zero ( _vel_max_up_cms ) ) {
accel_z_cms * = POSCONTROL_OVERSPEED_GAIN_Z * _vel_desired . z / _vel_max_up_cms ;
2017-02-07 20:49:55 -04:00
}
// adjust desired alt if motors have not hit their limits
2021-06-21 04:26:39 -03:00
update_pos_vel_accel ( _pos_target . z , _vel_desired . z , _accel_desired . z , _dt , _limit_vector . z ) ;
2017-02-07 20:49:55 -04:00
2021-04-16 12:53:14 -03:00
// prevent altitude target from breeching altitude limits
2021-05-19 11:09:31 -03:00
if ( is_negative ( _alt_min ) & & _alt_min < _alt_max & & _alt_max < 100 & & _pos_target . z < _alt_min ) {
2021-04-16 12:53:14 -03:00
_pos_target . z = constrain_float ( _pos_target . z , _alt_min , _alt_max ) ;
2017-02-07 20:49:55 -04:00
}
2021-06-21 04:26:39 -03:00
shape_vel_accel ( vel , accel ,
2021-04-16 12:53:14 -03:00
_vel_desired . z , _accel_desired . z ,
- accel_z_cms , accel_z_cms ,
2021-08-06 06:40:56 -03:00
_jerk_xy_max , _dt , limit_output ) ;
2019-03-18 14:11:25 -03:00
2021-06-21 04:26:39 -03:00
update_vel_accel ( vel , accel , _dt , _limit_vector . z ) ;
2019-03-18 14:11:25 -03:00
}