mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-06-09 03:02:36 +08:00
Merge pull request #975 from PX4/fwattrobustify
Make the fw att controller more robust against infinite input
This commit is contained in:
@@ -63,11 +63,22 @@ ECL_PitchController::ECL_PitchController() :
|
||||
_rate_setpoint(0.0f),
|
||||
_bodyrate_setpoint(0.0f)
|
||||
{
|
||||
perf_alloc(PC_COUNT, "fw att control pitch nonfinite input");
|
||||
}
|
||||
|
||||
ECL_PitchController::~ECL_PitchController()
|
||||
{
|
||||
perf_free(_nonfinite_input_perf);
|
||||
}
|
||||
|
||||
float ECL_PitchController::control_attitude(float pitch_setpoint, float roll, float pitch, float airspeed)
|
||||
{
|
||||
|
||||
/* Do not calculate control signal with bad inputs */
|
||||
if (!(isfinite(pitch_setpoint) && isfinite(roll) && isfinite(pitch) && isfinite(airspeed))) {
|
||||
perf_count(_nonfinite_input_perf);
|
||||
warnx("not controlling pitch");
|
||||
return _rate_setpoint;
|
||||
}
|
||||
|
||||
/* flying inverted (wings upside down) ? */
|
||||
bool inverted = false;
|
||||
@@ -123,6 +134,14 @@ float ECL_PitchController::control_bodyrate(float roll, float pitch,
|
||||
float yaw_rate_setpoint,
|
||||
float airspeed_min, float airspeed_max, float airspeed, float scaler, bool lock_integrator)
|
||||
{
|
||||
/* Do not calculate control signal with bad inputs */
|
||||
if (!(isfinite(roll) && isfinite(pitch) && isfinite(pitch_rate) && isfinite(yaw_rate) &&
|
||||
isfinite(yaw_rate_setpoint) && isfinite(airspeed_min) &&
|
||||
isfinite(airspeed_max) && isfinite(scaler))) {
|
||||
perf_count(_nonfinite_input_perf);
|
||||
return math::constrain(_last_output, -1.0f, 1.0f);
|
||||
}
|
||||
|
||||
/* get the usual dt estimate */
|
||||
uint64_t dt_micros = ecl_elapsed_time(&_last_run);
|
||||
_last_run = ecl_absolute_time();
|
||||
|
||||
@@ -51,12 +51,15 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <systemlib/perf_counter.h>
|
||||
|
||||
class __EXPORT ECL_PitchController //XXX: create controller superclass
|
||||
{
|
||||
public:
|
||||
ECL_PitchController();
|
||||
|
||||
~ECL_PitchController();
|
||||
|
||||
float control_attitude(float pitch_setpoint, float roll, float pitch, float airspeed);
|
||||
|
||||
|
||||
@@ -126,6 +129,7 @@ private:
|
||||
float _rate_error;
|
||||
float _rate_setpoint;
|
||||
float _bodyrate_setpoint;
|
||||
perf_counter_t _nonfinite_input_perf;
|
||||
};
|
||||
|
||||
#endif // ECL_PITCH_CONTROLLER_H
|
||||
|
||||
@@ -61,10 +61,21 @@ ECL_RollController::ECL_RollController() :
|
||||
_rate_setpoint(0.0f),
|
||||
_bodyrate_setpoint(0.0f)
|
||||
{
|
||||
perf_alloc(PC_COUNT, "fw att control roll nonfinite input");
|
||||
}
|
||||
|
||||
ECL_RollController::~ECL_RollController()
|
||||
{
|
||||
perf_free(_nonfinite_input_perf);
|
||||
}
|
||||
|
||||
float ECL_RollController::control_attitude(float roll_setpoint, float roll)
|
||||
{
|
||||
/* Do not calculate control signal with bad inputs */
|
||||
if (!(isfinite(roll_setpoint) && isfinite(roll))) {
|
||||
perf_count(_nonfinite_input_perf);
|
||||
return _rate_setpoint;
|
||||
}
|
||||
|
||||
/* Calculate error */
|
||||
float roll_error = roll_setpoint - roll;
|
||||
@@ -86,6 +97,14 @@ float ECL_RollController::control_bodyrate(float pitch,
|
||||
float yaw_rate_setpoint,
|
||||
float airspeed_min, float airspeed_max, float airspeed, float scaler, bool lock_integrator)
|
||||
{
|
||||
/* Do not calculate control signal with bad inputs */
|
||||
if (!(isfinite(pitch) && isfinite(roll_rate) && isfinite(yaw_rate) && isfinite(yaw_rate_setpoint) &&
|
||||
isfinite(airspeed_min) && isfinite(airspeed_max) &&
|
||||
isfinite(scaler))) {
|
||||
perf_count(_nonfinite_input_perf);
|
||||
return math::constrain(_last_output, -1.0f, 1.0f);
|
||||
}
|
||||
|
||||
/* get the usual dt estimate */
|
||||
uint64_t dt_micros = ecl_elapsed_time(&_last_run);
|
||||
_last_run = ecl_absolute_time();
|
||||
@@ -122,8 +141,8 @@ float ECL_RollController::control_bodyrate(float pitch,
|
||||
float id = _rate_error * dt;
|
||||
|
||||
/*
|
||||
* anti-windup: do not allow integrator to increase if actuator is at limit
|
||||
*/
|
||||
* anti-windup: do not allow integrator to increase if actuator is at limit
|
||||
*/
|
||||
if (_last_output < -1.0f) {
|
||||
/* only allow motion to center: increase value */
|
||||
id = math::max(id, 0.0f);
|
||||
|
||||
@@ -51,12 +51,15 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <systemlib/perf_counter.h>
|
||||
|
||||
class __EXPORT ECL_RollController //XXX: create controller superclass
|
||||
{
|
||||
public:
|
||||
ECL_RollController();
|
||||
|
||||
~ECL_RollController();
|
||||
|
||||
float control_attitude(float roll_setpoint, float roll);
|
||||
|
||||
float control_bodyrate(float pitch,
|
||||
@@ -117,6 +120,7 @@ private:
|
||||
float _rate_error;
|
||||
float _rate_setpoint;
|
||||
float _bodyrate_setpoint;
|
||||
perf_counter_t _nonfinite_input_perf;
|
||||
};
|
||||
|
||||
#endif // ECL_ROLL_CONTROLLER_H
|
||||
|
||||
@@ -60,12 +60,25 @@ ECL_YawController::ECL_YawController() :
|
||||
_bodyrate_setpoint(0.0f),
|
||||
_coordinated_min_speed(1.0f)
|
||||
{
|
||||
perf_alloc(PC_COUNT, "fw att control yaw nonfinite input");
|
||||
}
|
||||
|
||||
ECL_YawController::~ECL_YawController()
|
||||
{
|
||||
perf_free(_nonfinite_input_perf);
|
||||
}
|
||||
|
||||
float ECL_YawController::control_attitude(float roll, float pitch,
|
||||
float speed_body_u, float speed_body_v, float speed_body_w,
|
||||
float roll_rate_setpoint, float pitch_rate_setpoint)
|
||||
{
|
||||
/* Do not calculate control signal with bad inputs */
|
||||
if (!(isfinite(roll) && isfinite(pitch) && isfinite(speed_body_u) && isfinite(speed_body_v) &&
|
||||
isfinite(speed_body_w) && isfinite(roll_rate_setpoint) &&
|
||||
isfinite(pitch_rate_setpoint))) {
|
||||
perf_count(_nonfinite_input_perf);
|
||||
return _rate_setpoint;
|
||||
}
|
||||
// static int counter = 0;
|
||||
/* Calculate desired yaw rate from coordinated turn constraint / (no side forces) */
|
||||
_rate_setpoint = 0.0f;
|
||||
@@ -103,6 +116,13 @@ float ECL_YawController::control_bodyrate(float roll, float pitch,
|
||||
float pitch_rate_setpoint,
|
||||
float airspeed_min, float airspeed_max, float airspeed, float scaler, bool lock_integrator)
|
||||
{
|
||||
/* Do not calculate control signal with bad inputs */
|
||||
if (!(isfinite(roll) && isfinite(pitch) && isfinite(pitch_rate) && isfinite(yaw_rate) &&
|
||||
isfinite(pitch_rate_setpoint) && isfinite(airspeed_min) &&
|
||||
isfinite(airspeed_max) && isfinite(scaler))) {
|
||||
perf_count(_nonfinite_input_perf);
|
||||
return math::constrain(_last_output, -1.0f, 1.0f);
|
||||
}
|
||||
/* get the usual dt estimate */
|
||||
uint64_t dt_micros = ecl_elapsed_time(&_last_run);
|
||||
_last_run = ecl_absolute_time();
|
||||
|
||||
@@ -50,12 +50,15 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <systemlib/perf_counter.h>
|
||||
|
||||
class __EXPORT ECL_YawController //XXX: create controller superclass
|
||||
{
|
||||
public:
|
||||
ECL_YawController();
|
||||
|
||||
~ECL_YawController();
|
||||
|
||||
float control_attitude(float roll, float pitch,
|
||||
float speed_body_u, float speed_body_v, float speed_body_w,
|
||||
float roll_rate_setpoint, float pitch_rate_setpoint);
|
||||
@@ -118,6 +121,7 @@ private:
|
||||
float _rate_setpoint;
|
||||
float _bodyrate_setpoint;
|
||||
float _coordinated_min_speed;
|
||||
perf_counter_t _nonfinite_input_perf;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -134,6 +134,8 @@ private:
|
||||
struct vehicle_global_position_s _global_pos; /**< global position */
|
||||
|
||||
perf_counter_t _loop_perf; /**< loop performance counter */
|
||||
perf_counter_t _nonfinite_input_perf; /**< performance counter for non finite input */
|
||||
perf_counter_t _nonfinite_output_perf; /**< performance counter for non finite output */
|
||||
|
||||
bool _setpoint_valid; /**< flag if the position control setpoint is valid */
|
||||
|
||||
@@ -310,6 +312,8 @@ FixedwingAttitudeControl::FixedwingAttitudeControl() :
|
||||
|
||||
/* performance counters */
|
||||
_loop_perf(perf_alloc(PC_ELAPSED, "fw att control")),
|
||||
_nonfinite_input_perf(perf_alloc(PC_COUNT, "fw att control nonfinite input")),
|
||||
_nonfinite_output_perf(perf_alloc(PC_COUNT, "fw att control nonfinite output")),
|
||||
/* states */
|
||||
_setpoint_valid(false)
|
||||
{
|
||||
@@ -387,6 +391,10 @@ FixedwingAttitudeControl::~FixedwingAttitudeControl()
|
||||
} while (_control_task != -1);
|
||||
}
|
||||
|
||||
perf_free(_loop_perf);
|
||||
perf_free(_nonfinite_input_perf);
|
||||
perf_free(_nonfinite_output_perf);
|
||||
|
||||
att_control::g_control = nullptr;
|
||||
}
|
||||
|
||||
@@ -592,6 +600,8 @@ FixedwingAttitudeControl::task_main()
|
||||
|
||||
while (!_task_should_exit) {
|
||||
|
||||
static int loop_counter = 0;
|
||||
|
||||
/* wait for up to 500ms for data */
|
||||
int pret = poll(&fds[0], (sizeof(fds) / sizeof(fds[0])), 100);
|
||||
|
||||
@@ -672,10 +682,12 @@ FixedwingAttitudeControl::task_main()
|
||||
float airspeed;
|
||||
|
||||
/* if airspeed is not updating, we assume the normal average speed */
|
||||
if (!isfinite(_airspeed.true_airspeed_m_s) ||
|
||||
if (bool nonfinite = !isfinite(_airspeed.true_airspeed_m_s) ||
|
||||
hrt_elapsed_time(&_airspeed.timestamp) > 1e6) {
|
||||
airspeed = _parameters.airspeed_trim;
|
||||
|
||||
if (nonfinite) {
|
||||
perf_count(_nonfinite_input_perf);
|
||||
}
|
||||
} else {
|
||||
airspeed = _airspeed.true_airspeed_m_s;
|
||||
}
|
||||
@@ -755,7 +767,9 @@ FixedwingAttitudeControl::task_main()
|
||||
speed_body_v = _att.R[0][1] * _global_pos.vel_n + _att.R[1][1] * _global_pos.vel_e + _att.R[2][1] * _global_pos.vel_d;
|
||||
speed_body_w = _att.R[0][2] * _global_pos.vel_n + _att.R[1][2] * _global_pos.vel_e + _att.R[2][2] * _global_pos.vel_d;
|
||||
} else {
|
||||
warnx("Did not get a valid R\n");
|
||||
if (loop_counter % 10 == 0) {
|
||||
warnx("Did not get a valid R\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Run attitude controllers */
|
||||
@@ -773,7 +787,12 @@ FixedwingAttitudeControl::task_main()
|
||||
_parameters.airspeed_min, _parameters.airspeed_max, airspeed, airspeed_scaling, lock_integrator);
|
||||
_actuators.control[0] = (isfinite(roll_u)) ? roll_u + _parameters.trim_roll : _parameters.trim_roll;
|
||||
if (!isfinite(roll_u)) {
|
||||
warnx("roll_u %.4f", (double)roll_u);
|
||||
_roll_ctrl.reset_integrator();
|
||||
perf_count(_nonfinite_output_perf);
|
||||
|
||||
if (loop_counter % 10 == 0) {
|
||||
warnx("roll_u %.4f", (double)roll_u);
|
||||
}
|
||||
}
|
||||
|
||||
float pitch_u = _pitch_ctrl.control_bodyrate(_att.roll, _att.pitch,
|
||||
@@ -782,8 +801,22 @@ FixedwingAttitudeControl::task_main()
|
||||
_parameters.airspeed_min, _parameters.airspeed_max, airspeed, airspeed_scaling, lock_integrator);
|
||||
_actuators.control[1] = (isfinite(pitch_u)) ? pitch_u + _parameters.trim_pitch : _parameters.trim_pitch;
|
||||
if (!isfinite(pitch_u)) {
|
||||
warnx("pitch_u %.4f, _yaw_ctrl.get_desired_rate() %.4f, airspeed %.4f, airspeed_scaling %.4f, roll_sp %.4f, pitch_sp %.4f, _roll_ctrl.get_desired_rate() %.4f, _pitch_ctrl.get_desired_rate() %.4f att_sp.roll_body %.4f",
|
||||
(double)pitch_u, (double)_yaw_ctrl.get_desired_rate(), (double)airspeed, (double)airspeed_scaling, (double)roll_sp, (double)pitch_sp, (double)_roll_ctrl.get_desired_rate(), (double)_pitch_ctrl.get_desired_rate(), (double)_att_sp.roll_body);
|
||||
_pitch_ctrl.reset_integrator();
|
||||
perf_count(_nonfinite_output_perf);
|
||||
if (loop_counter % 10 == 0) {
|
||||
warnx("pitch_u %.4f, _yaw_ctrl.get_desired_rate() %.4f,"
|
||||
" airspeed %.4f, airspeed_scaling %.4f,"
|
||||
" roll_sp %.4f, pitch_sp %.4f,"
|
||||
" _roll_ctrl.get_desired_rate() %.4f,"
|
||||
" _pitch_ctrl.get_desired_rate() %.4f"
|
||||
" att_sp.roll_body %.4f",
|
||||
(double)pitch_u, (double)_yaw_ctrl.get_desired_rate(),
|
||||
(double)airspeed, (double)airspeed_scaling,
|
||||
(double)roll_sp, (double)pitch_sp,
|
||||
(double)_roll_ctrl.get_desired_rate(),
|
||||
(double)_pitch_ctrl.get_desired_rate(),
|
||||
(double)_att_sp.roll_body);
|
||||
}
|
||||
}
|
||||
|
||||
float yaw_u = _yaw_ctrl.control_bodyrate(_att.roll, _att.pitch,
|
||||
@@ -792,16 +825,25 @@ FixedwingAttitudeControl::task_main()
|
||||
_parameters.airspeed_min, _parameters.airspeed_max, airspeed, airspeed_scaling, lock_integrator);
|
||||
_actuators.control[2] = (isfinite(yaw_u)) ? yaw_u + _parameters.trim_yaw : _parameters.trim_yaw;
|
||||
if (!isfinite(yaw_u)) {
|
||||
warnx("yaw_u %.4f", (double)yaw_u);
|
||||
_yaw_ctrl.reset_integrator();
|
||||
perf_count(_nonfinite_output_perf);
|
||||
if (loop_counter % 10 == 0) {
|
||||
warnx("yaw_u %.4f", (double)yaw_u);
|
||||
}
|
||||
}
|
||||
|
||||
/* throttle passed through */
|
||||
_actuators.control[3] = (isfinite(throttle_sp)) ? throttle_sp : 0.0f;
|
||||
if (!isfinite(throttle_sp)) {
|
||||
warnx("throttle_sp %.4f", (double)throttle_sp);
|
||||
if (loop_counter % 10 == 0) {
|
||||
warnx("throttle_sp %.4f", (double)throttle_sp);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
warnx("Non-finite setpoint roll_sp: %.4f, pitch_sp %.4f", (double)roll_sp, (double)pitch_sp);
|
||||
perf_count(_nonfinite_input_perf);
|
||||
if (loop_counter % 10 == 0) {
|
||||
warnx("Non-finite setpoint roll_sp: %.4f, pitch_sp %.4f", (double)roll_sp, (double)pitch_sp);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -865,6 +907,7 @@ FixedwingAttitudeControl::task_main()
|
||||
|
||||
}
|
||||
|
||||
loop_counter++;
|
||||
perf_end(_loop_perf);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user