2013-06-26 05:38:40 -03:00
|
|
|
/// @file AP_TECS.h
|
|
|
|
/// @brief Combined Total Energy Speed & Height Control. This is a instance of an
|
|
|
|
/// AP_SpdHgtControl class
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Written by Paul Riseborough 2013 to provide:
|
|
|
|
* - Combined control of speed and height using throttle to control
|
|
|
|
* total energy and pitch angle to control exchange of energy between
|
|
|
|
* potential and kinetic.
|
|
|
|
* Selectable speed or height priority modes when calculating pitch angle
|
|
|
|
* - Fallback mode when no airspeed measurement is available that
|
2015-09-15 22:17:28 -03:00
|
|
|
* sets throttle based on height rate demand and switches pitch angle control to
|
2013-06-26 05:38:40 -03:00
|
|
|
* height priority
|
2015-09-15 22:17:28 -03:00
|
|
|
* - Underspeed protection that demands maximum throttle switches pitch angle control
|
2013-06-26 05:38:40 -03:00
|
|
|
* to speed priority mode
|
|
|
|
* - Relative ease of tuning through use of intuitive time constant, trim rate and damping parameters and the use
|
|
|
|
* of easy to measure aircraft performance data
|
|
|
|
*/
|
2016-02-17 21:25:50 -04:00
|
|
|
#pragma once
|
2013-06-26 05:38:40 -03:00
|
|
|
|
2015-08-11 03:28:46 -03:00
|
|
|
#include <AP_Math/AP_Math.h>
|
|
|
|
#include <AP_AHRS/AP_AHRS.h>
|
|
|
|
#include <AP_Param/AP_Param.h>
|
|
|
|
#include <AP_Vehicle/AP_Vehicle.h>
|
|
|
|
#include <AP_SpdHgtControl/AP_SpdHgtControl.h>
|
|
|
|
#include <DataFlash/DataFlash.h>
|
2016-11-23 05:35:43 -04:00
|
|
|
#include <AP_Landing/AP_Landing.h>
|
2013-06-26 05:38:40 -03:00
|
|
|
|
|
|
|
class AP_TECS : public AP_SpdHgtControl {
|
|
|
|
public:
|
2016-11-23 05:35:43 -04:00
|
|
|
AP_TECS(AP_AHRS &ahrs, const AP_Vehicle::FixedWing &parms, const AP_Landing &landing) :
|
2015-09-15 22:17:28 -03:00
|
|
|
_ahrs(ahrs),
|
2016-11-23 05:35:43 -04:00
|
|
|
aparm(parms),
|
|
|
|
_landing(landing)
|
2015-09-15 22:17:28 -03:00
|
|
|
{
|
|
|
|
AP_Param::setup_object_defaults(this, var_info);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update of the estimated height and height rate internal state
|
|
|
|
// Update of the inertial speed rate internal state
|
|
|
|
// Should be called at 50Hz or greater
|
2016-04-21 03:45:57 -03:00
|
|
|
void update_50hz(void);
|
2015-09-15 22:17:28 -03:00
|
|
|
|
|
|
|
// Update the control loop calculations
|
|
|
|
void update_pitch_throttle(int32_t hgt_dem_cm,
|
|
|
|
int32_t EAS_dem_cm,
|
2016-12-13 22:19:56 -04:00
|
|
|
enum AP_Vehicle::FixedWing::FlightStage flight_stage,
|
2016-02-12 15:38:40 -04:00
|
|
|
float distance_beyond_land_wp,
|
2013-07-09 07:50:37 -03:00
|
|
|
int32_t ptchMinCO_cd,
|
2013-07-10 00:32:13 -03:00
|
|
|
int16_t throttle_nudge,
|
2015-09-15 22:17:28 -03:00
|
|
|
float hgt_afe,
|
|
|
|
float load_factor);
|
|
|
|
|
|
|
|
// demanded throttle in percentage
|
2016-01-30 03:23:05 -04:00
|
|
|
// should return -100 to 100, usually positive unless reverse thrust is enabled via _THRminf < 0
|
2015-09-15 22:17:28 -03:00
|
|
|
int32_t get_throttle_demand(void) {
|
|
|
|
return int32_t(_throttle_dem * 100.0f);
|
|
|
|
}
|
|
|
|
|
|
|
|
// demanded pitch angle in centi-degrees
|
|
|
|
// should return between -9000 to +9000
|
|
|
|
int32_t get_pitch_demand(void) {
|
|
|
|
return int32_t(_pitch_dem * 5729.5781f);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Rate of change of velocity along X body axis in m/s^2
|
|
|
|
float get_VXdot(void) {
|
|
|
|
return _vel_dot;
|
|
|
|
}
|
|
|
|
|
|
|
|
// return current target airspeed
|
|
|
|
float get_target_airspeed(void) const {
|
|
|
|
return _TAS_dem / _ahrs.get_EAS2TAS();
|
|
|
|
}
|
|
|
|
|
|
|
|
// return maximum climb rate
|
|
|
|
float get_max_climbrate(void) const {
|
|
|
|
return _maxClimbRate;
|
|
|
|
}
|
|
|
|
|
|
|
|
// return landing sink rate
|
|
|
|
float get_land_sinkrate(void) const {
|
|
|
|
return _land_sink;
|
|
|
|
}
|
|
|
|
|
2016-04-13 13:07:33 -03:00
|
|
|
// return landing airspeed
|
|
|
|
float get_land_airspeed(void) const {
|
|
|
|
return _landAirspeed;
|
|
|
|
}
|
|
|
|
|
2015-12-26 23:07:06 -04:00
|
|
|
// return height rate demand, in m/s
|
|
|
|
float get_height_rate_demand(void) const {
|
|
|
|
return _hgt_rate_dem;
|
|
|
|
}
|
2016-01-08 20:13:08 -04:00
|
|
|
|
|
|
|
// set path_proportion
|
|
|
|
void set_path_proportion(float path_proportion) {
|
|
|
|
_path_proportion = constrain_float(path_proportion, 0.0f, 1.0f);
|
|
|
|
}
|
|
|
|
|
2016-01-09 06:50:40 -04:00
|
|
|
// set pitch max limit in degrees
|
|
|
|
void set_pitch_max_limit(int8_t pitch_limit) {
|
|
|
|
_pitch_max_limit = pitch_limit;
|
|
|
|
}
|
2016-10-04 21:52:34 -03:00
|
|
|
|
|
|
|
// force use of synthetic airspeed for one loop
|
|
|
|
void use_synthetic_airspeed(void) {
|
2016-10-19 23:22:39 -03:00
|
|
|
_use_synthetic_airspeed_once = true;
|
2016-10-04 21:52:34 -03:00
|
|
|
}
|
2016-01-09 06:50:40 -04:00
|
|
|
|
2015-09-15 22:17:28 -03:00
|
|
|
// this supports the TECS_* user settable parameters
|
2013-06-26 05:38:40 -03:00
|
|
|
static const struct AP_Param::GroupInfo var_info[];
|
|
|
|
|
|
|
|
private:
|
|
|
|
// Last time update_50Hz was called
|
2016-07-12 02:01:26 -03:00
|
|
|
uint64_t _update_50hz_last_usec;
|
2015-09-15 22:17:28 -03:00
|
|
|
|
2013-06-26 05:38:40 -03:00
|
|
|
// Last time update_speed was called
|
2016-07-12 02:01:26 -03:00
|
|
|
uint64_t _update_speed_last_usec;
|
2015-09-15 22:17:28 -03:00
|
|
|
|
2013-06-26 05:38:40 -03:00
|
|
|
// Last time update_pitch_throttle was called
|
2016-07-12 02:01:26 -03:00
|
|
|
uint64_t _update_pitch_throttle_last_usec;
|
2013-06-26 05:38:40 -03:00
|
|
|
|
2015-09-15 22:17:28 -03:00
|
|
|
// reference to the AHRS object
|
2013-08-14 01:58:49 -03:00
|
|
|
AP_AHRS &_ahrs;
|
2013-06-26 05:38:40 -03:00
|
|
|
|
2016-12-05 20:46:55 -04:00
|
|
|
const AP_Vehicle::FixedWing &aparm;
|
|
|
|
|
2016-11-23 05:35:43 -04:00
|
|
|
// reference to const AP_Landing to access it's params
|
|
|
|
const AP_Landing &_landing;
|
|
|
|
|
2015-09-15 22:17:28 -03:00
|
|
|
// TECS tuning parameters
|
|
|
|
AP_Float _hgtCompFiltOmega;
|
2013-06-26 05:38:40 -03:00
|
|
|
AP_Float _spdCompFiltOmega;
|
|
|
|
AP_Float _maxClimbRate;
|
|
|
|
AP_Float _minSinkRate;
|
|
|
|
AP_Float _maxSinkRate;
|
|
|
|
AP_Float _timeConst;
|
2014-08-27 01:28:39 -03:00
|
|
|
AP_Float _landTimeConst;
|
2013-06-26 05:38:40 -03:00
|
|
|
AP_Float _ptchDamp;
|
2016-02-24 22:18:14 -04:00
|
|
|
AP_Float _land_pitch_damp;
|
2014-11-28 04:32:15 -04:00
|
|
|
AP_Float _landDamp;
|
2013-06-26 05:38:40 -03:00
|
|
|
AP_Float _thrDamp;
|
2016-02-23 18:46:55 -04:00
|
|
|
AP_Float _land_throttle_damp;
|
2013-06-26 05:38:40 -03:00
|
|
|
AP_Float _integGain;
|
2016-02-23 20:20:25 -04:00
|
|
|
AP_Float _integGain_takeoff;
|
|
|
|
AP_Float _integGain_land;
|
2013-06-26 05:38:40 -03:00
|
|
|
AP_Float _vertAccLim;
|
2015-09-15 22:17:28 -03:00
|
|
|
AP_Float _rollComp;
|
|
|
|
AP_Float _spdWeight;
|
|
|
|
AP_Float _spdWeightLand;
|
2014-02-22 13:54:37 -04:00
|
|
|
AP_Float _landThrottle;
|
2014-03-19 17:58:01 -03:00
|
|
|
AP_Float _landAirspeed;
|
2014-08-11 03:45:06 -03:00
|
|
|
AP_Float _land_sink;
|
2016-02-12 15:38:40 -04:00
|
|
|
AP_Float _land_sink_rate_change;
|
2015-09-15 22:17:28 -03:00
|
|
|
AP_Int8 _pitch_max;
|
|
|
|
AP_Int8 _pitch_min;
|
|
|
|
AP_Int8 _land_pitch_max;
|
2016-01-30 03:23:05 -04:00
|
|
|
AP_Float _maxSinkRate_approach;
|
2015-09-15 22:17:28 -03:00
|
|
|
|
2016-01-09 06:50:40 -04:00
|
|
|
// temporary _pitch_max_limit. Cleared on each loop. Clear when >= 90
|
|
|
|
int8_t _pitch_max_limit = 90;
|
|
|
|
|
2015-09-15 22:17:28 -03:00
|
|
|
// current height estimate (above field elevation)
|
2016-07-12 02:01:26 -03:00
|
|
|
float _height;
|
2015-09-15 22:17:28 -03:00
|
|
|
|
2016-01-30 03:23:05 -04:00
|
|
|
// throttle demand in the range from -1.0 to 1.0, usually positive unless reverse thrust is enabled via _THRminf < 0
|
2016-07-12 02:01:26 -03:00
|
|
|
float _throttle_dem;
|
2015-09-15 22:17:28 -03:00
|
|
|
|
|
|
|
// pitch angle demand in radians
|
2016-07-12 02:01:26 -03:00
|
|
|
float _pitch_dem;
|
2015-09-15 22:13:11 -03:00
|
|
|
|
2015-09-15 22:17:28 -03:00
|
|
|
// estimated climb rate (m/s)
|
2016-07-12 02:01:26 -03:00
|
|
|
float _climb_rate;
|
2013-06-26 05:38:40 -03:00
|
|
|
|
2015-09-15 22:17:28 -03:00
|
|
|
/*
|
|
|
|
a filter to estimate climb rate if we don't have it from the EKF
|
|
|
|
*/
|
|
|
|
struct {
|
|
|
|
// height filter second derivative
|
|
|
|
float dd_height;
|
2015-09-15 22:13:11 -03:00
|
|
|
|
2015-09-15 22:17:28 -03:00
|
|
|
// height integration
|
|
|
|
float height;
|
|
|
|
} _height_filter;
|
2013-06-26 05:38:40 -03:00
|
|
|
|
2015-09-15 22:17:28 -03:00
|
|
|
// Integrator state 4 - airspeed filter first derivative
|
2016-07-12 02:01:26 -03:00
|
|
|
float _integDTAS_state;
|
2013-06-26 05:38:40 -03:00
|
|
|
|
2015-09-15 22:17:28 -03:00
|
|
|
// Integrator state 5 - true airspeed
|
2016-07-12 02:01:26 -03:00
|
|
|
float _TAS_state;
|
2013-06-26 05:38:40 -03:00
|
|
|
|
2015-09-15 22:17:28 -03:00
|
|
|
// Integrator state 6 - throttle integrator
|
2016-07-12 02:01:26 -03:00
|
|
|
float _integTHR_state;
|
2013-06-26 05:38:40 -03:00
|
|
|
|
2015-09-15 22:17:28 -03:00
|
|
|
// Integrator state 6 - pitch integrator
|
2016-07-12 02:01:26 -03:00
|
|
|
float _integSEB_state;
|
2013-06-26 05:38:40 -03:00
|
|
|
|
|
|
|
// throttle demand rate limiter state
|
2016-07-12 02:01:26 -03:00
|
|
|
float _last_throttle_dem;
|
2013-06-26 05:38:40 -03:00
|
|
|
|
|
|
|
// pitch demand rate limiter state
|
2016-07-12 02:01:26 -03:00
|
|
|
float _last_pitch_dem;
|
2013-06-26 05:38:40 -03:00
|
|
|
|
|
|
|
// Rate of change of speed along X axis
|
2016-07-12 02:01:26 -03:00
|
|
|
float _vel_dot;
|
2013-06-26 05:38:40 -03:00
|
|
|
|
|
|
|
// Equivalent airspeed
|
2016-07-12 02:01:26 -03:00
|
|
|
float _EAS;
|
2013-06-26 05:38:40 -03:00
|
|
|
|
|
|
|
// True airspeed limits
|
2016-07-12 02:01:26 -03:00
|
|
|
float _TASmax;
|
|
|
|
float _TASmin;
|
2013-06-26 05:38:40 -03:00
|
|
|
|
|
|
|
// Current and last true airspeed demand
|
2016-07-12 02:01:26 -03:00
|
|
|
float _TAS_dem;
|
|
|
|
float _TAS_dem_last;
|
2013-06-26 05:38:40 -03:00
|
|
|
|
|
|
|
// Equivalent airspeed demand
|
2016-07-12 02:01:26 -03:00
|
|
|
float _EAS_dem;
|
2013-06-26 05:38:40 -03:00
|
|
|
|
|
|
|
// height demands
|
2016-07-12 02:01:26 -03:00
|
|
|
float _hgt_dem;
|
|
|
|
float _hgt_dem_in_old;
|
|
|
|
float _hgt_dem_adj;
|
|
|
|
float _hgt_dem_adj_last;
|
|
|
|
float _hgt_rate_dem;
|
|
|
|
float _hgt_dem_prev;
|
|
|
|
float _land_hgt_dem;
|
2013-06-26 05:38:40 -03:00
|
|
|
|
|
|
|
// Speed demand after application of rate limiting
|
|
|
|
// This is the demand tracked by the TECS control loops
|
2016-07-12 02:01:26 -03:00
|
|
|
float _TAS_dem_adj;
|
2013-06-26 05:38:40 -03:00
|
|
|
|
|
|
|
// Speed rate demand after application of rate limiting
|
|
|
|
// This is the demand tracked by the TECS control loops
|
2016-07-12 02:01:26 -03:00
|
|
|
float _TAS_rate_dem;
|
2013-06-26 05:38:40 -03:00
|
|
|
|
2015-09-15 22:17:28 -03:00
|
|
|
// Total energy rate filter state
|
2016-07-12 02:01:26 -03:00
|
|
|
float _STEdotErrLast;
|
2013-06-26 05:38:40 -03:00
|
|
|
|
2016-03-25 18:41:09 -03:00
|
|
|
struct flags {
|
|
|
|
// Underspeed condition
|
|
|
|
bool underspeed:1;
|
2013-06-26 05:38:40 -03:00
|
|
|
|
2016-03-25 18:41:09 -03:00
|
|
|
// Bad descent condition caused by unachievable airspeed demand
|
|
|
|
bool badDescent:1;
|
2016-03-25 17:43:39 -03:00
|
|
|
|
2016-03-25 18:41:09 -03:00
|
|
|
// true when plane is in auto mode and executing a land mission item
|
|
|
|
bool is_doing_auto_land:1;
|
2016-07-05 23:15:55 -03:00
|
|
|
|
|
|
|
// true when we have reached target speed in takeoff
|
|
|
|
bool reached_speed_takeoff:1;
|
2016-03-25 18:41:09 -03:00
|
|
|
};
|
|
|
|
union {
|
|
|
|
struct flags _flags;
|
|
|
|
uint8_t _flags_byte;
|
|
|
|
};
|
2016-03-25 17:43:39 -03:00
|
|
|
|
|
|
|
// time when underspeed started
|
2016-07-12 02:01:26 -03:00
|
|
|
uint32_t _underspeed_start_ms;
|
2013-06-26 05:38:40 -03:00
|
|
|
|
2016-01-30 03:23:05 -04:00
|
|
|
// auto mode flightstage
|
2016-12-13 22:19:56 -04:00
|
|
|
enum AP_Vehicle::FixedWing::FlightStage _flight_stage;
|
2013-06-26 05:38:40 -03:00
|
|
|
|
2015-09-15 22:17:28 -03:00
|
|
|
// pitch demand before limiting
|
2016-07-12 02:01:26 -03:00
|
|
|
float _pitch_dem_unc;
|
2013-06-26 05:38:40 -03:00
|
|
|
|
2015-09-15 22:17:28 -03:00
|
|
|
// Maximum and minimum specific total energy rate limits
|
2016-07-12 02:01:26 -03:00
|
|
|
float _STEdot_max;
|
|
|
|
float _STEdot_min;
|
2013-06-26 05:38:40 -03:00
|
|
|
|
2015-09-15 22:17:28 -03:00
|
|
|
// Maximum and minimum floating point throttle limits
|
2016-07-12 02:01:26 -03:00
|
|
|
float _THRmaxf;
|
|
|
|
float _THRminf;
|
2013-06-26 05:38:40 -03:00
|
|
|
|
2015-09-15 22:17:28 -03:00
|
|
|
// Maximum and minimum floating point pitch limits
|
2016-07-12 02:01:26 -03:00
|
|
|
float _PITCHmaxf;
|
|
|
|
float _PITCHminf;
|
2013-06-26 05:38:40 -03:00
|
|
|
|
|
|
|
// Specific energy quantities
|
2016-07-12 02:01:26 -03:00
|
|
|
float _SPE_dem;
|
|
|
|
float _SKE_dem;
|
|
|
|
float _SPEdot_dem;
|
|
|
|
float _SKEdot_dem;
|
|
|
|
float _SPE_est;
|
|
|
|
float _SKE_est;
|
|
|
|
float _SPEdot;
|
|
|
|
float _SKEdot;
|
2013-06-26 05:38:40 -03:00
|
|
|
|
2015-09-15 22:17:28 -03:00
|
|
|
// Specific energy error quantities
|
2016-07-12 02:01:26 -03:00
|
|
|
float _STE_error;
|
2013-06-26 05:38:40 -03:00
|
|
|
|
2015-09-15 22:17:28 -03:00
|
|
|
// Time since last update of main TECS loop (seconds)
|
2016-07-12 02:01:26 -03:00
|
|
|
float _DT;
|
2013-06-26 05:38:40 -03:00
|
|
|
|
2015-09-15 22:17:28 -03:00
|
|
|
// counter for demanded sink rate on land final
|
2016-07-12 02:01:26 -03:00
|
|
|
uint8_t _flare_counter;
|
2014-08-27 07:13:01 -03:00
|
|
|
|
2016-07-15 17:38:59 -03:00
|
|
|
// slew height demand lag filter value when transition to land
|
|
|
|
float hgt_dem_lag_filter_slew;
|
|
|
|
|
2016-01-08 20:13:08 -04:00
|
|
|
// percent traveled along the previous and next waypoints
|
2016-07-12 02:01:26 -03:00
|
|
|
float _path_proportion;
|
2016-01-08 20:13:08 -04:00
|
|
|
|
2016-07-12 02:01:26 -03:00
|
|
|
float _distance_beyond_land_wp;
|
2016-02-12 15:38:40 -04:00
|
|
|
|
2016-05-13 03:22:33 -03:00
|
|
|
// internal variables to be logged
|
|
|
|
struct {
|
|
|
|
float SKE_weighting;
|
|
|
|
float SPE_error;
|
|
|
|
float SKE_error;
|
|
|
|
float SEB_delta;
|
2016-07-12 02:01:02 -03:00
|
|
|
} logging;
|
2016-10-04 21:52:34 -03:00
|
|
|
|
2016-10-19 23:22:39 -03:00
|
|
|
AP_Int8 _use_synthetic_airspeed;
|
|
|
|
|
2016-10-04 21:52:34 -03:00
|
|
|
// use synthetic airspeed for next loop
|
2016-10-19 23:22:39 -03:00
|
|
|
bool _use_synthetic_airspeed_once;
|
2016-05-13 03:22:33 -03:00
|
|
|
|
2013-06-26 05:38:40 -03:00
|
|
|
// Update the airspeed internal state using a second order complementary filter
|
2014-11-11 22:32:46 -04:00
|
|
|
void _update_speed(float load_factor);
|
2013-06-26 05:38:40 -03:00
|
|
|
|
|
|
|
// Update the demanded airspeed
|
|
|
|
void _update_speed_demand(void);
|
|
|
|
|
|
|
|
// Update the demanded height
|
|
|
|
void _update_height_demand(void);
|
|
|
|
|
2015-09-15 22:17:28 -03:00
|
|
|
// Detect an underspeed condition
|
|
|
|
void _detect_underspeed(void);
|
2013-06-26 05:38:40 -03:00
|
|
|
|
2015-09-15 22:17:28 -03:00
|
|
|
// Update Specific Energy Quantities
|
|
|
|
void _update_energies(void);
|
2013-06-26 05:38:40 -03:00
|
|
|
|
2015-09-15 22:17:28 -03:00
|
|
|
// Update Demanded Throttle
|
2016-07-05 23:15:55 -03:00
|
|
|
void _update_throttle_with_airspeed(void);
|
2013-06-26 05:38:40 -03:00
|
|
|
|
2015-09-15 22:17:28 -03:00
|
|
|
// Update Demanded Throttle Non-Airspeed
|
2016-07-05 23:15:55 -03:00
|
|
|
void _update_throttle_without_airspeed(int16_t throttle_nudge);
|
2013-07-04 18:48:28 -03:00
|
|
|
|
2016-02-23 20:20:25 -04:00
|
|
|
// get integral gain which is flight_stage dependent
|
|
|
|
float _get_i_gain(void);
|
|
|
|
|
2015-09-15 22:17:28 -03:00
|
|
|
// Detect Bad Descent
|
|
|
|
void _detect_bad_descent(void);
|
2013-06-26 05:38:40 -03:00
|
|
|
|
2015-09-15 22:17:28 -03:00
|
|
|
// Update Demanded Pitch Angle
|
|
|
|
void _update_pitch(void);
|
2013-06-26 05:38:40 -03:00
|
|
|
|
2015-09-15 22:17:28 -03:00
|
|
|
// Initialise states and variables
|
|
|
|
void _initialise_states(int32_t ptchMinCO_cd, float hgt_afe);
|
2013-06-26 05:38:40 -03:00
|
|
|
|
2015-09-15 22:17:28 -03:00
|
|
|
// Calculate specific total energy rate limits
|
|
|
|
void _update_STE_rate_lim(void);
|
2013-06-26 05:38:40 -03:00
|
|
|
|
|
|
|
// declares a 5point average filter using floats
|
2015-09-15 22:17:28 -03:00
|
|
|
AverageFilterFloat_Size5 _vdot_filter;
|
2014-08-27 01:28:39 -03:00
|
|
|
|
2015-09-15 22:17:28 -03:00
|
|
|
// current time constant
|
|
|
|
float timeConstant(void) const;
|
2013-06-26 05:38:40 -03:00
|
|
|
};
|
|
|
|
|