2017-02-26 19:13:46 -04:00
|
|
|
/*
|
|
|
|
Soaring Controller class by Samuel Tabor
|
|
|
|
|
|
|
|
Provides a layer between the thermal centring algorithm and the main
|
|
|
|
code for managing navigation targets, data logging, tuning parameters,
|
|
|
|
algorithm inputs and eventually other soaring strategies such as
|
2020-09-09 03:40:18 -03:00
|
|
|
speed-to-fly. AP_TECS library used for reference.
|
2017-02-26 19:13:46 -04:00
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2022-11-06 19:20:59 -04:00
|
|
|
#include <AP_HAL/AP_HAL_Boards.h>
|
2017-02-26 19:13:46 -04:00
|
|
|
|
2020-09-23 05:16:45 -03:00
|
|
|
#ifndef HAL_SOARING_ENABLED
|
2022-11-02 06:11:44 -03:00
|
|
|
#define HAL_SOARING_ENABLED 1
|
2020-09-16 04:46:56 -03:00
|
|
|
#endif
|
|
|
|
|
2020-09-23 05:20:07 -03:00
|
|
|
#if HAL_SOARING_ENABLED
|
|
|
|
|
2022-11-06 19:20:59 -04:00
|
|
|
#include <AP_Param/AP_Param.h>
|
|
|
|
#include <AP_Math/AP_Math.h>
|
|
|
|
#include "ExtendedKalmanFilter.h"
|
|
|
|
#include "Variometer.h"
|
|
|
|
#include "SpeedToFly.h"
|
|
|
|
|
2024-11-22 11:44:55 -04:00
|
|
|
static constexpr float INITIAL_THERMAL_RADIUS = 80.0;
|
|
|
|
static constexpr float INITIAL_STRENGTH_COVARIANCE = 0.0049;
|
|
|
|
static constexpr float INITIAL_RADIUS_COVARIANCE = 400.0;
|
|
|
|
static constexpr float INITIAL_POSITION_COVARIANCE = 400.0;
|
2017-04-27 18:44:03 -03:00
|
|
|
|
2017-02-26 19:13:46 -04:00
|
|
|
|
|
|
|
class SoaringController {
|
2022-07-14 13:21:15 -03:00
|
|
|
Variometer::PolarParams _polarParams;
|
2017-02-26 19:13:46 -04:00
|
|
|
ExtendedKalmanFilter _ekf{};
|
2022-11-06 19:20:59 -04:00
|
|
|
class AP_TECS &_tecs;
|
2017-04-27 18:44:03 -03:00
|
|
|
Variometer _vario;
|
2021-02-28 08:54:34 -04:00
|
|
|
SpeedToFly _speedToFly;
|
|
|
|
|
2022-09-29 20:10:41 -03:00
|
|
|
const AP_FixedWing &_aparm;
|
2017-02-26 19:13:46 -04:00
|
|
|
|
|
|
|
// store aircraft location at last update
|
2019-03-29 11:10:11 -03:00
|
|
|
Vector3f _prev_update_location;
|
2017-02-26 19:13:46 -04:00
|
|
|
|
|
|
|
// store time thermal was entered for hysteresis
|
2019-08-07 19:33:06 -03:00
|
|
|
uint64_t _thermal_start_time_us;
|
2017-02-26 19:13:46 -04:00
|
|
|
|
2019-06-08 22:10:35 -03:00
|
|
|
// store position thermal was entered as a backup check
|
|
|
|
Vector3f _thermal_start_pos;
|
2019-06-07 21:19:42 -03:00
|
|
|
|
2017-02-26 19:13:46 -04:00
|
|
|
// store time cruise was entered for hysteresis
|
2019-08-07 19:33:06 -03:00
|
|
|
uint64_t _cruise_start_time_us;
|
2017-02-26 19:13:46 -04:00
|
|
|
|
|
|
|
// store time of last update
|
2019-08-07 19:33:06 -03:00
|
|
|
uint64_t _prev_update_time;
|
2017-02-26 19:13:46 -04:00
|
|
|
|
|
|
|
bool _throttle_suppressed;
|
|
|
|
|
|
|
|
float McCready(float alt);
|
|
|
|
|
2019-06-22 13:02:35 -03:00
|
|
|
float _thermalability;
|
|
|
|
|
2021-06-06 03:47:58 -03:00
|
|
|
LowPassFilter<float> _position_x_filter{1/60.0};
|
|
|
|
LowPassFilter<float> _position_y_filter{1/60.0};
|
2020-01-11 11:14:28 -04:00
|
|
|
|
2017-02-26 19:13:46 -04:00
|
|
|
protected:
|
|
|
|
AP_Int8 soar_active;
|
|
|
|
AP_Float thermal_vspeed;
|
|
|
|
AP_Float thermal_q1;
|
|
|
|
AP_Float thermal_q2;
|
|
|
|
AP_Float thermal_r;
|
|
|
|
AP_Float thermal_distance_ahead;
|
|
|
|
AP_Int16 min_thermal_s;
|
|
|
|
AP_Int16 min_cruise_s;
|
|
|
|
AP_Float alt_max;
|
|
|
|
AP_Float alt_min;
|
|
|
|
AP_Float alt_cutoff;
|
2019-06-08 22:10:35 -03:00
|
|
|
AP_Float max_drift;
|
2021-01-20 17:07:31 -04:00
|
|
|
AP_Float thermal_bank;
|
2020-07-10 11:14:23 -03:00
|
|
|
AP_Float soar_thermal_airspeed;
|
|
|
|
AP_Float soar_cruise_airspeed;
|
|
|
|
AP_Float soar_thermal_flap;
|
2019-06-08 22:10:35 -03:00
|
|
|
|
2017-02-26 19:13:46 -04:00
|
|
|
public:
|
2022-09-29 20:10:41 -03:00
|
|
|
SoaringController(class AP_TECS &tecs, const AP_FixedWing &parms);
|
2017-02-26 19:13:46 -04:00
|
|
|
|
2020-04-05 08:38:19 -03:00
|
|
|
enum class LoiterStatus {
|
|
|
|
DISABLED,
|
2019-06-05 15:23:29 -03:00
|
|
|
ALT_TOO_HIGH,
|
|
|
|
ALT_TOO_LOW,
|
|
|
|
THERMAL_WEAK,
|
2019-06-07 21:19:42 -03:00
|
|
|
ALT_LOST,
|
2019-06-09 07:01:16 -03:00
|
|
|
DRIFT_EXCEEDED,
|
2020-09-07 08:59:47 -03:00
|
|
|
GOOD_TO_KEEP_LOITERING,
|
|
|
|
EXIT_COMMANDED,
|
2020-04-05 08:38:19 -03:00
|
|
|
};
|
2019-06-05 15:23:29 -03:00
|
|
|
|
2020-04-05 08:38:19 -03:00
|
|
|
enum class ActiveStatus {
|
2020-07-13 05:46:51 -03:00
|
|
|
SOARING_DISABLED,
|
2020-04-05 08:38:19 -03:00
|
|
|
MANUAL_MODE_CHANGE,
|
|
|
|
AUTO_MODE_CHANGE
|
|
|
|
};
|
2019-08-18 12:02:15 -03:00
|
|
|
|
2019-06-17 09:15:53 -03:00
|
|
|
AP_Float max_radius;
|
|
|
|
|
2017-02-26 19:13:46 -04:00
|
|
|
// this supports the TECS_* user settable parameters
|
|
|
|
static const struct AP_Param::GroupInfo var_info[];
|
|
|
|
void get_target(Location & wp);
|
|
|
|
bool suppress_throttle();
|
|
|
|
bool check_thermal_criteria();
|
2019-06-22 14:51:17 -03:00
|
|
|
LoiterStatus check_cruise_criteria(Vector2f prev_wp, Vector2f next_wp);
|
2017-02-26 19:13:46 -04:00
|
|
|
void init_thermalling();
|
|
|
|
void init_cruising();
|
|
|
|
void update_thermalling();
|
|
|
|
void update_cruising();
|
2018-10-18 09:51:21 -03:00
|
|
|
void set_throttle_suppressed(bool suppressed);
|
|
|
|
|
2017-03-03 05:16:40 -04:00
|
|
|
bool get_throttle_suppressed() const
|
2017-02-26 19:13:46 -04:00
|
|
|
{
|
|
|
|
return _throttle_suppressed;
|
|
|
|
}
|
2018-10-18 09:51:21 -03:00
|
|
|
|
2018-01-28 19:03:36 -04:00
|
|
|
float get_vario_reading() const
|
2017-02-26 19:13:46 -04:00
|
|
|
{
|
2021-04-04 09:17:05 -03:00
|
|
|
return _vario.get_displayed_value();
|
2017-02-26 19:13:46 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void update_vario();
|
2019-06-07 12:07:06 -03:00
|
|
|
|
2019-06-22 14:51:17 -03:00
|
|
|
bool check_drift(Vector2f prev_wp, Vector2f next_wp);
|
|
|
|
|
2021-08-03 08:08:14 -03:00
|
|
|
void update_active_state(bool override_disable);
|
2019-08-18 12:02:15 -03:00
|
|
|
|
2020-04-05 08:38:19 -03:00
|
|
|
bool is_active() const {return _last_update_status>=SoaringController::ActiveStatus::MANUAL_MODE_CHANGE;};
|
2019-07-15 07:27:29 -03:00
|
|
|
|
2020-07-13 05:46:51 -03:00
|
|
|
void set_pilot_desired_state(ActiveStatus pilot_desired_state) {_pilot_desired_state = pilot_desired_state;};
|
|
|
|
|
2020-09-07 08:51:56 -03:00
|
|
|
float get_alt_cutoff() const {return alt_cutoff;}
|
|
|
|
|
2020-07-13 10:10:05 -03:00
|
|
|
float get_circling_time() const {return _vario.tau;}
|
|
|
|
|
2021-01-20 17:07:31 -04:00
|
|
|
float get_thermalling_radius() const;
|
|
|
|
|
2020-07-10 11:14:23 -03:00
|
|
|
float get_thermalling_target_airspeed();
|
|
|
|
|
|
|
|
float get_cruising_target_airspeed();
|
|
|
|
|
|
|
|
float get_thermalling_flap() const
|
|
|
|
{
|
|
|
|
return soar_thermal_flap;
|
|
|
|
}
|
|
|
|
|
2019-06-07 12:07:06 -03:00
|
|
|
private:
|
2020-04-05 08:38:19 -03:00
|
|
|
|
|
|
|
ActiveStatus _last_update_status;
|
|
|
|
|
2020-07-13 05:46:51 -03:00
|
|
|
ActiveStatus _pilot_desired_state = ActiveStatus::AUTO_MODE_CHANGE;
|
|
|
|
|
2021-08-03 08:08:14 -03:00
|
|
|
ActiveStatus active_state(bool override_disable) const;
|
2020-09-07 08:59:47 -03:00
|
|
|
|
|
|
|
bool _exit_commanded;
|
2017-02-26 19:13:46 -04:00
|
|
|
};
|
2020-09-23 05:20:07 -03:00
|
|
|
|
2020-09-29 22:28:22 -03:00
|
|
|
#endif // HAL_SOARING_ENABLED
|