mirror of
https://github.com/ArduPilot/ardupilot
synced 2025-02-21 07:13:56 -04:00
AP_TECS: Add flags to indicate gliding flight, and use these with AP_Soaring.
This commit is contained in:
parent
dc8c062fbe
commit
684ee11fc3
@ -577,13 +577,6 @@ void Plane::update_alt()
|
|||||||
if (flight_stage == AP_Vehicle::FixedWing::FLIGHT_LAND && current_loc.past_interval_finish_line(prev_WP_loc, next_WP_loc)) {
|
if (flight_stage == AP_Vehicle::FixedWing::FLIGHT_LAND && current_loc.past_interval_finish_line(prev_WP_loc, next_WP_loc)) {
|
||||||
distance_beyond_land_wp = current_loc.get_distance(next_WP_loc);
|
distance_beyond_land_wp = current_loc.get_distance(next_WP_loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool soaring_active = false;
|
|
||||||
#if SOARING_ENABLED == ENABLED
|
|
||||||
if (g2.soaring_controller.is_active() && g2.soaring_controller.get_throttle_suppressed()) {
|
|
||||||
soaring_active = true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SpdHgt_Controller->update_pitch_throttle(relative_target_altitude_cm(),
|
SpdHgt_Controller->update_pitch_throttle(relative_target_altitude_cm(),
|
||||||
target_airspeed_cm,
|
target_airspeed_cm,
|
||||||
@ -592,8 +585,7 @@ void Plane::update_alt()
|
|||||||
get_takeoff_pitch_min_cd(),
|
get_takeoff_pitch_min_cd(),
|
||||||
throttle_nudge,
|
throttle_nudge,
|
||||||
tecs_hgt_afe(),
|
tecs_hgt_afe(),
|
||||||
aerodynamic_load_factor,
|
aerodynamic_load_factor);
|
||||||
soaring_active);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,8 @@ bool ModeLoiter::_enter()
|
|||||||
plane.loiter_angle_reset();
|
plane.loiter_angle_reset();
|
||||||
|
|
||||||
#if SOARING_ENABLED == ENABLED
|
#if SOARING_ENABLED == ENABLED
|
||||||
if (plane.g2.soaring_controller.is_active() && plane.g2.soaring_controller.suppress_throttle()) {
|
if (plane.g2.soaring_controller.is_active() &&
|
||||||
|
(plane.g2.soaring_controller.suppress_throttle() || plane.aparm.throttle_max==0)) {
|
||||||
plane.g2.soaring_controller.init_thermalling();
|
plane.g2.soaring_controller.init_thermalling();
|
||||||
plane.g2.soaring_controller.get_target(plane.next_WP_loc); // ahead on flight path
|
plane.g2.soaring_controller.get_target(plane.next_WP_loc); // ahead on flight path
|
||||||
}
|
}
|
||||||
|
@ -470,16 +470,6 @@ void Plane::set_servos_controlled(void)
|
|||||||
SRV_Channels::set_output_scaled(SRV_Channel::k_throttle,
|
SRV_Channels::set_output_scaled(SRV_Channel::k_throttle,
|
||||||
constrain_int16(quadplane.forward_throttle_pct(), min_throttle, max_throttle));
|
constrain_int16(quadplane.forward_throttle_pct(), min_throttle, max_throttle));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SOARING_ENABLED == ENABLED
|
|
||||||
// suppress throttle when soaring is active
|
|
||||||
if ((control_mode == &mode_fbwb || control_mode == &mode_cruise ||
|
|
||||||
control_mode == &mode_auto || control_mode == &mode_loiter) &&
|
|
||||||
g2.soaring_controller.is_active() &&
|
|
||||||
g2.soaring_controller.get_throttle_suppressed()) {
|
|
||||||
SRV_Channels::set_output_scaled(SRV_Channel::k_throttle, 0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
void Plane::update_soaring() {
|
void Plane::update_soaring() {
|
||||||
|
|
||||||
if (!g2.soaring_controller.is_active()) {
|
if (!g2.soaring_controller.is_active()) {
|
||||||
|
// This also sets the TECS gliding_requested to false.
|
||||||
|
g2.soaring_controller.set_throttle_suppressed(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,18 +24,18 @@ void Plane::update_soaring() {
|
|||||||
break;
|
break;
|
||||||
case Mode::Number::FLY_BY_WIRE_B:
|
case Mode::Number::FLY_BY_WIRE_B:
|
||||||
case Mode::Number::CRUISE:
|
case Mode::Number::CRUISE:
|
||||||
if (!g2.soaring_controller.suppress_throttle()) {
|
if (!g2.soaring_controller.suppress_throttle() && aparm.throttle_max > 0) {
|
||||||
gcs().send_text(MAV_SEVERITY_INFO, "Soaring: forcing RTL");
|
gcs().send_text(MAV_SEVERITY_INFO, "Soaring: forcing RTL");
|
||||||
set_mode(mode_rtl, ModeReason::SOARING_FBW_B_WITH_MOTOR_RUNNING);
|
set_mode(mode_rtl, ModeReason::SOARING_FBW_B_WITH_MOTOR_RUNNING);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Mode::Number::LOITER:
|
case Mode::Number::LOITER:
|
||||||
// Do nothing. We will switch back to auto/rtl before enabling throttle.
|
// Never use throttle in LOITER with soaring active.
|
||||||
|
g2.soaring_controller.set_throttle_suppressed(true);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// This does not affect the throttle since suppressed is only checked in the above three modes.
|
// In any other mode allow throttle.
|
||||||
// It ensures that the soaring always starts with throttle suppressed though.
|
g2.soaring_controller.set_throttle_suppressed(false);
|
||||||
g2.soaring_controller.set_throttle_suppressed(true);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,12 +153,14 @@ bool SoaringController::suppress_throttle()
|
|||||||
|
|
||||||
if (_throttle_suppressed && (alt < alt_min)) {
|
if (_throttle_suppressed && (alt < alt_min)) {
|
||||||
// Time to throttle up
|
// Time to throttle up
|
||||||
_throttle_suppressed = false;
|
set_throttle_suppressed(false);
|
||||||
} else if ((!_throttle_suppressed) && (alt > alt_cutoff)) {
|
} else if ((!_throttle_suppressed) && (alt > alt_cutoff)) {
|
||||||
// Start glide
|
// Start glide
|
||||||
_throttle_suppressed = true;
|
set_throttle_suppressed(true);
|
||||||
|
|
||||||
// Zero the pitch integrator - the nose is currently raised to climb, we need to go back to glide.
|
// Zero the pitch integrator - the nose is currently raised to climb, we need to go back to glide.
|
||||||
_spdHgt.reset_pitch_I();
|
_spdHgt.reset_pitch_I();
|
||||||
|
|
||||||
_cruise_start_time_us = AP_HAL::micros64();
|
_cruise_start_time_us = AP_HAL::micros64();
|
||||||
// Reset the filtered vario rate - it is currently elevated due to the climb rate and would otherwise take a while to fall again,
|
// Reset the filtered vario rate - it is currently elevated due to the climb rate and would otherwise take a while to fall again,
|
||||||
// leading to false positives.
|
// leading to false positives.
|
||||||
@ -275,10 +277,10 @@ void SoaringController::init_thermalling()
|
|||||||
|
|
||||||
void SoaringController::init_cruising()
|
void SoaringController::init_cruising()
|
||||||
{
|
{
|
||||||
if (is_active() && suppress_throttle()) {
|
if (is_active()) {
|
||||||
_cruise_start_time_us = AP_HAL::micros64();
|
_cruise_start_time_us = AP_HAL::micros64();
|
||||||
// Start glide. Will be updated on the next loop.
|
// Start glide. Will be updated on the next loop.
|
||||||
_throttle_suppressed = true;
|
set_throttle_suppressed(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,3 +346,11 @@ bool SoaringController::is_active() const
|
|||||||
// active when above 1700
|
// active when above 1700
|
||||||
return RC_Channels::get_radio_in(soar_active_ch-1) >= 1700;
|
return RC_Channels::get_radio_in(soar_active_ch-1) >= 1700;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SoaringController::set_throttle_suppressed(bool suppressed)
|
||||||
|
{
|
||||||
|
_throttle_suppressed = suppressed;
|
||||||
|
|
||||||
|
// Let the TECS know.
|
||||||
|
_spdHgt.set_gliding_requested_flag(suppressed);
|
||||||
|
}
|
@ -93,14 +93,13 @@ public:
|
|||||||
void update_thermalling();
|
void update_thermalling();
|
||||||
void update_cruising();
|
void update_cruising();
|
||||||
bool is_active() const;
|
bool is_active() const;
|
||||||
|
void set_throttle_suppressed(bool suppressed);
|
||||||
|
|
||||||
bool get_throttle_suppressed() const
|
bool get_throttle_suppressed() const
|
||||||
{
|
{
|
||||||
return _throttle_suppressed;
|
return _throttle_suppressed;
|
||||||
}
|
}
|
||||||
void set_throttle_suppressed(bool suppressed)
|
|
||||||
{
|
|
||||||
_throttle_suppressed = suppressed;
|
|
||||||
}
|
|
||||||
float get_vario_reading() const
|
float get_vario_reading() const
|
||||||
{
|
{
|
||||||
return _vario.displayed_reading;
|
return _vario.displayed_reading;
|
||||||
|
@ -31,8 +31,7 @@ public:
|
|||||||
int32_t ptchMinCO_cd,
|
int32_t ptchMinCO_cd,
|
||||||
int16_t throttle_nudge,
|
int16_t throttle_nudge,
|
||||||
float hgt_afe,
|
float hgt_afe,
|
||||||
float load_factor,
|
float load_factor) = 0;
|
||||||
bool soaring_active) = 0;
|
|
||||||
|
|
||||||
// demanded throttle in percentage
|
// demanded throttle in percentage
|
||||||
// should return 0 to 100
|
// should return 0 to 100
|
||||||
@ -66,6 +65,12 @@ public:
|
|||||||
// reset on next loop
|
// reset on next loop
|
||||||
virtual void reset(void) = 0;
|
virtual void reset(void) = 0;
|
||||||
|
|
||||||
|
// set gliding requested flag
|
||||||
|
virtual void set_gliding_requested_flag(bool gliding_requested) = 0;
|
||||||
|
|
||||||
|
// set propulsion failed flag
|
||||||
|
virtual void set_propulsion_failed_flag(bool propulsion_failed) = 0;
|
||||||
|
|
||||||
// add new controllers to this enum. Users can then
|
// add new controllers to this enum. Users can then
|
||||||
// select which controller to use by setting the
|
// select which controller to use by setting the
|
||||||
// SPDHGT_CONTROLLER parameter
|
// SPDHGT_CONTROLLER parameter
|
||||||
|
@ -641,6 +641,10 @@ void AP_TECS::_update_throttle_with_airspeed(void)
|
|||||||
{
|
{
|
||||||
_throttle_dem = 1.0f;
|
_throttle_dem = 1.0f;
|
||||||
}
|
}
|
||||||
|
else if (_flags.is_gliding)
|
||||||
|
{
|
||||||
|
_throttle_dem = 0.0f;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Calculate gain scaler from specific energy error to throttle
|
// Calculate gain scaler from specific energy error to throttle
|
||||||
@ -755,6 +759,11 @@ void AP_TECS::_update_throttle_without_airspeed(int16_t throttle_nudge)
|
|||||||
_throttle_dem = nomThr;
|
_throttle_dem = nomThr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_flags.is_gliding)
|
||||||
|
{
|
||||||
|
_throttle_dem = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate additional throttle for turn drag compensation including throttle nudging
|
// Calculate additional throttle for turn drag compensation including throttle nudging
|
||||||
const Matrix3f &rotMat = _ahrs.get_rotation_body_to_ned();
|
const Matrix3f &rotMat = _ahrs.get_rotation_body_to_ned();
|
||||||
// Use the demanded rate of change of total energy as the feed-forward demand, but add
|
// Use the demanded rate of change of total energy as the feed-forward demand, but add
|
||||||
@ -780,7 +789,7 @@ void AP_TECS::_detect_bad_descent(void)
|
|||||||
// 2) Specific total energy error > 0
|
// 2) Specific total energy error > 0
|
||||||
// This mode will produce an undulating speed and height response as it cuts in and out but will prevent the aircraft from descending into the ground if an unachievable speed demand is set
|
// This mode will produce an undulating speed and height response as it cuts in and out but will prevent the aircraft from descending into the ground if an unachievable speed demand is set
|
||||||
float STEdot = _SPEdot + _SKEdot;
|
float STEdot = _SPEdot + _SKEdot;
|
||||||
if ((!_flags.underspeed && (_STE_error > 200.0f) && (STEdot < 0.0f) && (_throttle_dem >= _THRmaxf * 0.9f)) || (_flags.badDescent && !_flags.underspeed && (_STE_error > 0.0f)))
|
if (((!_flags.underspeed && (_STE_error > 200.0f) && (STEdot < 0.0f) && (_throttle_dem >= _THRmaxf * 0.9f)) || (_flags.badDescent && !_flags.underspeed && (_STE_error > 0.0f))) && !_flags.is_gliding)
|
||||||
{
|
{
|
||||||
_flags.badDescent = true;
|
_flags.badDescent = true;
|
||||||
}
|
}
|
||||||
@ -807,7 +816,7 @@ void AP_TECS::_update_pitch(void)
|
|||||||
// height. This is needed as the usual relationship of speed
|
// height. This is needed as the usual relationship of speed
|
||||||
// and height is broken by the VTOL motors
|
// and height is broken by the VTOL motors
|
||||||
SKE_weighting = 0.0f;
|
SKE_weighting = 0.0f;
|
||||||
} else if ( _flags.underspeed || _flight_stage == AP_Vehicle::FixedWing::FLIGHT_TAKEOFF || _flight_stage == AP_Vehicle::FixedWing::FLIGHT_ABORT_LAND) {
|
} else if ( _flags.underspeed || _flight_stage == AP_Vehicle::FixedWing::FLIGHT_TAKEOFF || _flight_stage == AP_Vehicle::FixedWing::FLIGHT_ABORT_LAND || _flags.is_gliding) {
|
||||||
SKE_weighting = 2.0f;
|
SKE_weighting = 2.0f;
|
||||||
} else if (_flags.is_doing_auto_land) {
|
} else if (_flags.is_doing_auto_land) {
|
||||||
if (_spdWeightLand < 0) {
|
if (_spdWeightLand < 0) {
|
||||||
@ -902,7 +911,9 @@ void AP_TECS::_update_pitch(void)
|
|||||||
|
|
||||||
|
|
||||||
// Add a feedforward term from demanded airspeed to pitch.
|
// Add a feedforward term from demanded airspeed to pitch.
|
||||||
_pitch_dem_unc += (_TAS_dem_adj - _pitch_ff_v0) * _pitch_ff_k;
|
if (_flags.is_gliding) {
|
||||||
|
_pitch_dem_unc += (_TAS_dem_adj - _pitch_ff_v0) * _pitch_ff_k;
|
||||||
|
}
|
||||||
|
|
||||||
// Constrain pitch demand
|
// Constrain pitch demand
|
||||||
_pitch_dem = constrain_float(_pitch_dem_unc, _PITCHminf, _PITCHmaxf);
|
_pitch_dem = constrain_float(_pitch_dem_unc, _PITCHminf, _PITCHmaxf);
|
||||||
@ -980,14 +991,14 @@ void AP_TECS::update_pitch_throttle(int32_t hgt_dem_cm,
|
|||||||
int32_t ptchMinCO_cd,
|
int32_t ptchMinCO_cd,
|
||||||
int16_t throttle_nudge,
|
int16_t throttle_nudge,
|
||||||
float hgt_afe,
|
float hgt_afe,
|
||||||
float load_factor,
|
float load_factor)
|
||||||
bool soaring_active)
|
|
||||||
{
|
{
|
||||||
// Calculate time in seconds since last update
|
// Calculate time in seconds since last update
|
||||||
uint64_t now = AP_HAL::micros64();
|
uint64_t now = AP_HAL::micros64();
|
||||||
_DT = (now - _update_pitch_throttle_last_usec) * 1.0e-6f;
|
_DT = (now - _update_pitch_throttle_last_usec) * 1.0e-6f;
|
||||||
_update_pitch_throttle_last_usec = now;
|
_update_pitch_throttle_last_usec = now;
|
||||||
|
|
||||||
|
_flags.is_gliding = _flags.gliding_requested || _flags.propulsion_failed || aparm.throttle_max==0;
|
||||||
_flags.is_doing_auto_land = (flight_stage == AP_Vehicle::FixedWing::FLIGHT_LAND);
|
_flags.is_doing_auto_land = (flight_stage == AP_Vehicle::FixedWing::FLIGHT_LAND);
|
||||||
_distance_beyond_land_wp = distance_beyond_land_wp;
|
_distance_beyond_land_wp = distance_beyond_land_wp;
|
||||||
_flight_stage = flight_stage;
|
_flight_stage = flight_stage;
|
||||||
@ -1141,8 +1152,7 @@ void AP_TECS::update_pitch_throttle(int32_t hgt_dem_cm,
|
|||||||
// Detect bad descent due to demanded airspeed being too high
|
// Detect bad descent due to demanded airspeed being too high
|
||||||
_detect_bad_descent();
|
_detect_bad_descent();
|
||||||
|
|
||||||
// when soaring is active we never trigger a bad descent
|
if (_options & OPTION_GLIDER_ONLY) {
|
||||||
if (soaring_active || (_options & OPTION_GLIDER_ONLY)) {
|
|
||||||
_flags.badDescent = false;
|
_flags.badDescent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,8 +52,7 @@ public:
|
|||||||
int32_t ptchMinCO_cd,
|
int32_t ptchMinCO_cd,
|
||||||
int16_t throttle_nudge,
|
int16_t throttle_nudge,
|
||||||
float hgt_afe,
|
float hgt_afe,
|
||||||
float load_factor,
|
float load_factor) override;
|
||||||
bool soaring_active) override;
|
|
||||||
|
|
||||||
// demanded throttle in percentage
|
// demanded throttle in percentage
|
||||||
// should return -100 to 100, usually positive unless reverse thrust is enabled via _THRminf < 0
|
// should return -100 to 100, usually positive unless reverse thrust is enabled via _THRminf < 0
|
||||||
@ -107,6 +106,17 @@ public:
|
|||||||
_path_proportion = constrain_float(path_proportion, 0.0f, 1.0f);
|
_path_proportion = constrain_float(path_proportion, 0.0f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set soaring flag
|
||||||
|
void set_gliding_requested_flag(bool gliding_requested) override {
|
||||||
|
_flags.gliding_requested = gliding_requested;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set propulsion failed flag
|
||||||
|
void set_propulsion_failed_flag(bool propulsion_failed) override {
|
||||||
|
_flags.propulsion_failed = propulsion_failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// set pitch max limit in degrees
|
// set pitch max limit in degrees
|
||||||
void set_pitch_max_limit(int8_t pitch_limit) {
|
void set_pitch_max_limit(int8_t pitch_limit) {
|
||||||
_pitch_max_limit = pitch_limit;
|
_pitch_max_limit = pitch_limit;
|
||||||
@ -272,6 +282,18 @@ private:
|
|||||||
|
|
||||||
// true when we have reached target speed in takeoff
|
// true when we have reached target speed in takeoff
|
||||||
bool reached_speed_takeoff:1;
|
bool reached_speed_takeoff:1;
|
||||||
|
|
||||||
|
// true if the soaring feature has requested gliding flight
|
||||||
|
bool gliding_requested:1;
|
||||||
|
|
||||||
|
// true when we are in gliding flight, in one of three situations;
|
||||||
|
// - THR_MAX=0
|
||||||
|
// - gliding has been requested e.g. by soaring feature
|
||||||
|
// - engine failure detected (detection not implemented currently)
|
||||||
|
bool is_gliding:1;
|
||||||
|
|
||||||
|
// true if a propulsion failure is detected.
|
||||||
|
bool propulsion_failed:1;
|
||||||
};
|
};
|
||||||
union {
|
union {
|
||||||
struct flags _flags;
|
struct flags _flags;
|
||||||
|
Loading…
Reference in New Issue
Block a user