From 642a4a5fc7afd913661c24b2394497917f5b53da Mon Sep 17 00:00:00 2001 From: Paul Riseborough <p_riseborough@live.com.au> Date: Wed, 18 Oct 2017 08:22:35 +1100 Subject: [PATCH] mc_pos_control: respect estimator max speed and min height limits --- .../mc_pos_control/mc_pos_control_main.cpp | 48 ++++++++++++++++++- .../mc_pos_control/mc_pos_control_params.c | 14 ++++++ 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/src/modules/mc_pos_control/mc_pos_control_main.cpp b/src/modules/mc_pos_control/mc_pos_control_main.cpp index 94fb42bbcd..009d2e43f3 100644 --- a/src/modules/mc_pos_control/mc_pos_control_main.cpp +++ b/src/modules/mc_pos_control/mc_pos_control_main.cpp @@ -231,6 +231,7 @@ private: param_t opt_recover; param_t rc_flt_smp_rate; param_t rc_flt_cutoff; + param_t acc_max_flow_xy; } _params_handles; /**< handles for interesting parameters */ struct { @@ -259,6 +260,7 @@ private: float rc_flt_smp_rate; float rc_flt_cutoff; + float acc_max_flow_xy; math::Vector<3> pos_p; math::Vector<3> vel_p; @@ -298,6 +300,8 @@ private: float _takeoff_vel_limit; /**< velocity limit value which gets ramped up */ + float _min_hagl_limit; /**< minimum continuous height above ground (m) */ + // counters for reset events on position and velocity states // they are used to identify a reset event uint8_t _z_reset_counter; @@ -474,6 +478,7 @@ MulticopterPositionControl::MulticopterPositionControl() : _manual_jerk_limit_z(1.0f), _z_derivative(0.0f), _takeoff_vel_limit(0.0f), + _min_hagl_limit(0.0f), _z_reset_counter(0), _xy_reset_counter(0), _heading_reset_counter(0) @@ -537,6 +542,7 @@ MulticopterPositionControl::MulticopterPositionControl() : _params_handles.alt_mode = param_find("MPC_ALT_MODE"); _params_handles.rc_flt_cutoff = param_find("RC_FLT_CUTOFF"); _params_handles.rc_flt_smp_rate = param_find("RC_FLT_SMP_RATE"); + _params_handles.acc_max_flow_xy = param_find("MPC_ACC_HOR_FLOW"); /* fetch initial parameter values */ parameters_update(true); @@ -703,6 +709,16 @@ MulticopterPositionControl::parameters_update(bool force) /* we only use jerk for braking if jerk_hor_max > jerk_hor_min; otherwise just set jerk very large */ _manual_jerk_limit_z = (_jerk_hor_max.get() > _jerk_hor_min.get()) ? _jerk_hor_max.get() : 1000000.f; + /* Get parameter values used to fly within optical flow sensor limits */ + param_t handle = param_find("SENS_FLOW_MINRNG"); + + if (handle != PARAM_INVALID) { + param_get(handle, &_min_hagl_limit); + } + + if (_params_handles.acc_max_flow_xy != PARAM_INVALID) { + param_get(handle, &_params.acc_max_flow_xy); + } } @@ -1357,6 +1373,7 @@ MulticopterPositionControl::control_manual() /* reset position setpoint to current position if needed */ reset_pos_sp(); + } /* prepare yaw to rotate into NED frame */ @@ -2482,6 +2499,18 @@ MulticopterPositionControl::calculate_velocity_setpoint() _vel_sp(2) = math::max(_vel_sp(2), -vel_limit); } + // encourage pilot to respect respect flow sensor minimum height limitations + if (_local_pos.limit_hagl && _local_pos.dist_bottom_valid && _control_mode.flag_control_manual_enabled + && _control_mode.flag_control_altitude_enabled) { + // If distance to ground is less than limit, increment set point upwards at up to the landing descent rate + if (_local_pos.dist_bottom < _min_hagl_limit) { + float climb_rate_bias = fminf(1.5f * _params.pos_p(2) * (_min_hagl_limit - _local_pos.dist_bottom), _params.land_speed); + _vel_sp(2) -= climb_rate_bias; + _pos_sp(2) -= climb_rate_bias * dt; + + } + } + /* limit vertical downwards speed (positive z) close to ground * for now we use the altitude above home and assume that we want to land at same height as we took off */ float vel_limit = math::gradual(altitude_above_home, @@ -3048,8 +3077,23 @@ MulticopterPositionControl::task_main() /* set dt for control blocks */ setDt(dt); - /* set default max velocity in xy to vel_max */ - _vel_max_xy = _params.vel_max_xy; + /* set default max velocity in xy to vel_max + * Apply estimator limits if applicable */ + if (_local_pos.vxy_max > 0.0f) { + // use the minimum of the estimator and user specified limit + _vel_max_xy = fminf(_params.vel_max_xy, _local_pos.vxy_max); + // Allow for a minimum of 0.3 m/s for repositioning + _vel_max_xy = fmaxf(_vel_max_xy, 0.3f); + + } else { + // raise the limit at a constant rate up to the user specified value + if (_vel_max_xy >= _params.vel_max_xy) { + _vel_max_xy = _params.vel_max_xy; + + } else { + _vel_max_xy += dt * _params.acc_max_flow_xy; + } + } /* reset flags when landed */ if (_vehicle_land_detected.landed) { diff --git a/src/modules/mc_pos_control/mc_pos_control_params.c b/src/modules/mc_pos_control/mc_pos_control_params.c index 511bfec7c9..245cbaadbf 100644 --- a/src/modules/mc_pos_control/mc_pos_control_params.c +++ b/src/modules/mc_pos_control/mc_pos_control_params.c @@ -437,6 +437,20 @@ PARAM_DEFINE_FLOAT(MPC_ACC_HOR, 5.0f); */ PARAM_DEFINE_FLOAT(MPC_DEC_HOR_SLOW, 5.0f); +/** + * Horizontal acceleration in manual modes when optical flow ground speed limit is removed. + * If full stick is being applied and the EKF starts using GPS whilst using optical flow, + * the vehicle will accelerate at this rate until the normal position control speed is achieved. + * + * @unit m/s/s + * @min 0.2 + * @max 2.0 + * @increment 0.1 + * @decimal 1 + * @group Multicopter Position Control + */ +PARAM_DEFINE_FLOAT(MPC_ACC_HOR_FLOW, 0.5f); + /** * Maximum vertical acceleration in velocity controlled modes upward * -- GitLab