30 #include "generated/airframe.h"
48 #ifndef GUIDANCE_INDI_SPEED_GAIN
49 #define GUIDANCE_INDI_SPEED_GAIN 1.8
50 #define GUIDANCE_INDI_SPEED_GAINZ 1.8
53 #ifndef GUIDANCE_INDI_POS_GAIN
54 #define GUIDANCE_INDI_POS_GAIN 0.5
55 #define GUIDANCE_INDI_POS_GAINZ 0.5
58 #ifndef GUIDANCE_INDI_LIFTD_ASQ
59 #define GUIDANCE_INDI_LIFTD_ASQ 0.20
66 #ifndef GUIDANCE_INDI_LIFTD_P50
67 #define GUIDANCE_INDI_LIFTD_P80 (GUIDANCE_INDI_LIFTD_ASQ*12*12)
68 #define GUIDANCE_INDI_LIFTD_P50 (GUIDANCE_INDI_LIFTD_P80/2)
78 .heading_bank_gain = GUIDANCE_INDI_HEADING_BANK_GAIN,
84 #ifndef GUIDANCE_INDI_MAX_AIRSPEED
85 #error "You must have an airspeed sensor to use this guidance"
94 #if GUIDANCE_INDI_HYBRID_USE_WLS
95 #if GUIDANCE_INDI_HYBRID_U > WLS_N_U
96 #error Matrix-WLS_N_U too small: increase WLS_N_U in airframe file
99 #if GUIDANCE_INDI_HYBRID_V > WLS_N_V
100 #error Matrix-WLS_N_V too small: increase WLS_N_V in airframe file
107 #ifndef GUIDANCE_INDI_ZERO_AIRSPEED
108 #define GUIDANCE_INDI_ZERO_AIRSPEED FALSE
112 #ifndef TURN_AIRSPEED_TH
113 #define TURN_AIRSPEED_TH 10.0
125 #ifdef GUIDANCE_INDI_SPECIFIC_FORCE_GAIN
127 static void guidance_indi_filter_thrust(
void);
129 #ifdef GUIDANCE_INDI_THRUST_DYNAMICS
130 #warning GUIDANCE_INDI_THRUST_DYNAMICS is deprecated, use GUIDANCE_INDI_THRUST_DYNAMICS_FREQ instead.
131 #warning "The thrust dynamics are now specified in continuous time with the corner frequency of the first order model!"
132 #warning "define GUIDANCE_INDI_THRUST_DYNAMICS_FREQ in rad/s"
133 #warning "Use -ln(1 - old_number) * PERIODIC_FREQUENCY to compute it from the old value."
136 #ifndef GUIDANCE_INDI_THRUST_DYNAMICS_FREQ
137 #ifndef STABILIZATION_INDI_ACT_FREQ_P
138 #error "You need to define GUIDANCE_INDI_THRUST_DYNAMICS_FREQ to be able to use indi vertical control"
140 #define GUIDANCE_INDI_THRUST_DYNAMICS_FREQ STABILIZATION_INDI_ACT_FREQ_P
146 #ifndef GUIDANCE_INDI_FILTER_CUTOFF
147 #ifdef STABILIZATION_INDI_FILT_CUTOFF
148 #define GUIDANCE_INDI_FILTER_CUTOFF STABILIZATION_INDI_FILT_CUTOFF
150 #define GUIDANCE_INDI_FILTER_CUTOFF 3.0
154 #ifndef GUIDANCE_INDI_AIRSPEED_FILT_CUTOFF
155 #define GUIDANCE_INDI_AIRSPEED_FILT_CUTOFF 0.5
158 #ifndef GUIDANCE_INDI_CLIMB_SPEED_FWD
159 #define GUIDANCE_INDI_CLIMB_SPEED_FWD 4.0
162 #ifndef GUIDANCE_INDI_DESCEND_SPEED_FWD
163 #define GUIDANCE_INDI_DESCEND_SPEED_FWD -4.0
189 float Ga[GUIDANCE_INDI_HYBRID_V][GUIDANCE_INDI_HYBRID_U];
192 #if GUIDANCE_INDI_HYBRID_USE_WLS
194 float du_min_gih[GUIDANCE_INDI_HYBRID_U];
195 float du_max_gih[GUIDANCE_INDI_HYBRID_U];
196 float du_pref_gih[GUIDANCE_INDI_HYBRID_U];
197 float *Bwls_gih[GUIDANCE_INDI_HYBRID_V];
198 #ifdef GUIDANCE_INDI_HYBRID_WLS_PRIORITIES
199 float Wv_gih[GUIDANCE_INDI_HYBRID_V] = GUIDANCE_INDI_HYBRID_WLS_PRIORITIES;
201 float Wv_gih[GUIDANCE_INDI_HYBRID_V] = { 100.f, 100.f, 1.f };
203 #ifdef GUIDANCE_INDI_HYBRID_WLS_WU
204 float Wu_gih[GUIDANCE_INDI_HYBRID_U] = GUIDANCE_INDI_HYBRID_WLS_WU;
206 float Wu_gih[GUIDANCE_INDI_HYBRID_U] = { 1.f, 1.f, 1.f };
223 #ifndef GUIDANCE_INDI_VEL_SP_ID
224 #define GUIDANCE_INDI_VEL_SP_ID ABI_BROADCAST
233 #if PERIODIC_TELEMETRY
237 pprz_msg_send_GUIDANCE_INDI_HYBRID(trans,
dev, AC_ID,
252 #if GUIDANCE_INDI_HYBRID_USE_WLS
253 static void debug(
struct transport_tx *trans,
struct link_device *
dev,
char* name,
float* data,
int datasize)
255 pprz_msg_send_DEBUG_VECT(trans,
dev,AC_ID,
269 debug(trans,
dev,
"du_min_gih", du_min_gih, GUIDANCE_INDI_HYBRID_U);
272 debug(trans,
dev,
"du_max_gih", du_max_gih, GUIDANCE_INDI_HYBRID_U);
275 debug(trans,
dev,
"du_pref_gih", du_pref_gih, GUIDANCE_INDI_HYBRID_U);
278 debug(trans,
dev,
"Wu_gih", Wu_gih, GUIDANCE_INDI_HYBRID_U);
281 debug(trans,
dev,
"Wv_gih", Wv_gih, GUIDANCE_INDI_HYBRID_V);
284 debug(trans,
dev,
"Bwls_gih[0]", Bwls_gih[0], GUIDANCE_INDI_HYBRID_U);
305 #ifdef GUIDANCE_INDI_SPECIFIC_FORCE_GAIN
306 #ifdef GUIDANCE_INDI_THRUST_DYNAMICS
309 thrust_dyn = 1-exp(-GUIDANCE_INDI_THRUST_DYNAMICS_FREQ/PERIODIC_FREQUENCY);
314 float sample_time = 1.0/PERIODIC_FREQUENCY;
315 for(
int8_t i=0; i<3; i++) {
326 #if GUIDANCE_INDI_HYBRID_USE_WLS
327 for (
int8_t i = 0; i < GUIDANCE_INDI_HYBRID_V; i++) {
332 #if PERIODIC_TELEMETRY
352 float sample_time = 1.0 / PERIODIC_FREQUENCY;
353 for (
int8_t i = 0; i < 3; i++) {
395 #if GUIDANCE_INDI_RC_DEBUG
396 #warning "GUIDANCE_INDI_RC_DEBUG lets you control the accelerations via RC, but disables autonomous flight!"
401 sp_accel.
x = cosf(psi) * rc_x - sinf(psi) * rc_y;
402 sp_accel.
y = sinf(psi) * rc_x + cosf(psi) * rc_y;
419 Bound(a_diff.x, -6.0, 6.0);
420 Bound(a_diff.y, -6.0, 6.0);
421 Bound(a_diff.z, -9.0, 9.0);
425 #ifndef GUIDANCE_INDI_SPECIFIC_FORCE_GAIN
426 #ifndef STABILIZATION_ATTITUDE_INDI_FULL
435 #if GUIDANCE_INDI_HYBRID_USE_WLS
440 float du_gih[GUIDANCE_INDI_HYBRID_U];
443 du_gih,
v_gih, du_min_gih, du_max_gih,
444 Bwls_gih, 0, 0, Wv_gih, Wu_gih, du_pref_gih, 100000, 10,
445 GUIDANCE_INDI_HYBRID_U, GUIDANCE_INDI_HYBRID_V);
460 #if GUIDANCE_INDI_HYBRID_U > 3
461 thrust_vect.
x = du_gih[3];
472 const float max_phi = RadOfDeg(60.0f);
473 #if GUIDANCE_INDI_ZERO_AIRSPEED
474 float airspeed_turn = 0.f;
479 Bound(airspeed_turn, 10.0f, 30.0f);
502 if (fabsf(coordinated_turn_roll) < max_phi) {
503 omega = 9.81f / airspeed_turn * tanf(coordinated_turn_roll);
505 omega = 9.81f / airspeed_turn * 1.72305f * ((coordinated_turn_roll > 0.0f) - (coordinated_turn_roll < 0.0f));
508 #ifdef FWD_SIDESLIP_GAIN
519 ff_rates.
p = -sinf(euler_zyx->
theta) * omega;
520 ff_rates.q = cosf(euler_zyx->
theta) * sinf(euler_zyx->
phi) * omega;
521 ff_rates.r = cosf(euler_zyx->
theta) * cosf(euler_zyx->
phi) * omega;
534 #ifdef STABILIZATION_ATTITUDE_SP_PSI_DELTA_LIMIT
535 float delta_limit = STABILIZATION_ATTITUDE_SP_PSI_DELTA_LIMIT;
539 if (delta_psi > delta_limit) {
541 }
else if (delta_psi < -delta_limit) {
549 #ifdef GUIDANCE_INDI_SPECIFIC_FORCE_GAIN
550 guidance_indi_filter_thrust();
554 Bound(
thrust_in, GUIDANCE_INDI_MIN_THROTTLE, 9600);
556 #if GUIDANCE_INDI_RC_DEBUG
577 struct FloatVect3 accel_sp = { 0.f, 0.f, 0.f };
583 float cpsi = cosf(psi);
584 float spsi = sinf(psi);
589 #if GUIDANCE_INDI_ZERO_AIRSPEED
590 float airspeed = 0.f;
598 struct FloatVect2 airspeed_v = { cpsi * airspeed, spsi * airspeed };
600 VECT2_DIFF(windspeed, *groundspeed, airspeed_v);
610 float groundspeed_factor = 0.0f;
618 float dv = bv * bv - 4.0f * av * cv;
624 float d_sqrt = sqrtf(dv);
626 groundspeed_factor = (-bv + d_sqrt) / (2.0f * av);
652 accel_sp.
x = cpsi * sp_accel_b.x - spsi * sp_accel_b.y;
653 accel_sp.
y = spsi * sp_accel_b.x + cpsi * sp_accel_b.y;
658 if (airspeed > 10.f) {
661 float speed_increment = speed_sp_b_x - groundspeed_x;
669 gi_speed_sp.
x = cpsi * speed_sp_b_x - spsi * speed_sp_b_y;
670 gi_speed_sp.
y = spsi * speed_sp_b_x + cpsi * speed_sp_b_y;
682 BoundAbs(accel_sp.
z, 3.0);
773 #ifdef GUIDANCE_INDI_SPECIFIC_FORCE_GAIN
777 void guidance_indi_filter_thrust(
void)
822 if (airspeed < 12.f) {
827 float pitch_interp = DegOfRad(theta);
828 const float min_pitch = -80.0f;
829 const float middle_pitch = -50.0f;
830 const float max_pitch = -20.0f;
832 Bound(pitch_interp, min_pitch, max_pitch);
833 if (pitch_interp > middle_pitch) {
834 float ratio = (pitch_interp - max_pitch)/(middle_pitch - max_pitch);
837 float ratio = (pitch_interp - middle_pitch)/(min_pitch - middle_pitch);
860 #if GUIDANCE_INDI_HYBRID_USE_AS_DEFAULT
Main include for ABI (AirBorneInterface).
Event structure to store callbacks in a linked list.
#define THRUST_INCREMENT_ID
Core autopilot interface common to all firmwares.
static void float_quat_normalize(struct FloatQuat *q)
#define FLOAT_ANGLE_NORMALIZE(_a)
void float_mat3_mult(struct FloatVect3 *vect_out, float mat[3][3], struct FloatVect3 vect_in)
Multiply 3D matrix with vector.
void float_vect3_bound_in_2d(struct FloatVect3 *vect3, float bound)
void float_quat_of_eulers_zxy(struct FloatQuat *q, struct FloatEulers *e)
quat from euler rotation 'ZXY' This rotation order is useful if you need 90 deg pitch
void float_eulers_of_quat_zxy(struct FloatEulers *e, struct FloatQuat *q)
euler rotation 'ZXY' This rotation order is useful if you need 90 deg pitch
bool float_mat_inv_3d(float inv_out[3][3], float mat_in[3][3])
3x3 matrix inverse
#define FLOAT_VECT2_NORM(_v)
#define VECT2_DIFF(_c, _a, _b)
#define INT_MULT_RSHIFT(_a, _b, _r)
#define ANGLE_BFP_OF_REAL(_af)
#define INT32_PERCENTAGE_FRAC
#define POS_FLOAT_OF_BFP(_ai)
#define SPEED_FLOAT_OF_BFP(_ai)
#define BFP_OF_REAL(_vr, _frac)
#define ACCEL_FLOAT_OF_BFP(_ai)
static struct NedCoor_f * stateGetAccelNed_f(void)
Get acceleration in NED coordinates (float).
static struct FloatEulers * stateGetNedToBodyEulers_f(void)
Get vehicle body attitude euler angles (float).
static struct FloatQuat * stateGetNedToBodyQuat_f(void)
Get vehicle body attitude quaternion (float).
static struct NedCoor_f * stateGetPositionNed_f(void)
Get position in local NED coordinates (float).
static struct NedCoor_f * stateGetSpeedNed_f(void)
Get ground speed in local NED coordinates (float).
static struct Int32Vect3 * stateGetAccelBody_i(void)
Get acceleration in Body coordinates (int).
static float stateGetAirspeed_f(void)
Get airspeed (float).
float guidance_indi_specific_force_gain
struct FloatVect3 indi_vel_sp
bool force_forward
forward flight for hybrid nav
Butterworth2LowPass accely_filt
static void vel_sp_cb(uint8_t sender_id, struct FloatVect3 *vel_sp)
ABI callback that obtains the velocity setpoint from a module.
Butterworth2LowPass roll_filt
#define GUIDANCE_INDI_SPEED_GAINZ
#define GUIDANCE_INDI_CLIMB_SPEED_FWD
struct guidance_indi_hybrid_params gih_params
struct FloatVect3 gi_speed_sp
float guidance_indi_min_pitch
float guidance_indi_max_bank
struct StabilizationSetpoint guidance_indi_run_mode(bool in_flight UNUSED, struct HorizontalGuidance *gh, struct VerticalGuidance *gv, enum GuidanceIndiHybrid_HMode h_mode, enum GuidanceIndiHybrid_VMode v_mode)
struct FloatVect3 sp_accel
static void send_guidance_indi_debug(struct transport_tx *trans UNUSED, struct link_device *dev UNUSED)
struct FloatEulers guidance_euler_cmd
float guidance_indi_pitch_pref_deg
#define GUIDANCE_INDI_LIFTD_ASQ
float guidance_indi_airspeed_filt_cutoff
void guidance_indi_enter(void)
Call upon entering indi guidance.
Butterworth2LowPass guidance_indi_airspeed_filt
Butterworth2LowPass pitch_filt
#define GUIDANCE_INDI_POS_GAIN
bool take_heading_control
float guidance_indi_hybrid_heading_sp
float WEAK guidance_indi_get_liftd(float airspeed, float theta)
Get the derivative of lift w.r.t.
#define GUIDANCE_INDI_LIFTD_P50
static void send_guidance_indi_hybrid(struct transport_tx *trans, struct link_device *dev)
void guidance_indi_init(void)
Init function.
#define GUIDANCE_INDI_FILTER_CUTOFF
#define GUIDANCE_INDI_DESCEND_SPEED_FWD
float Ga[GUIDANCE_INDI_HYBRID_V][GUIDANCE_INDI_HYBRID_U]
struct FloatVect3 euler_cmd
static float bound_vz_sp(float vz_sp)
struct FloatEulers eulers_zxy
state eulers in zxy order
Butterworth2LowPass filt_accel_ned[3]
#define GUIDANCE_INDI_AIRSPEED_FILT_CUTOFF
#define GUIDANCE_INDI_POS_GAINZ
float guidance_indi_max_airspeed
static struct FloatVect3 compute_accel_from_speed_sp(void)
#define GUIDANCE_INDI_VEL_SP_ID
struct StabilizationSetpoint guidance_indi_run(struct FloatVect3 *accel_sp, float heading_sp)
void guidance_indi_propagate_filters(void)
Low pass the accelerometer measurements to remove noise from vibrations.
bool guidance_indi_airspeed_filtering
#define GUIDANCE_INDI_LIFTD_P80
Butterworth2LowPass thrust_filt
#define GUIDANCE_INDI_SPEED_GAIN
struct FloatVect2 desired_airspeed
A guidance mode based on Incremental Nonlinear Dynamic Inversion Come to ICRA2016 to learn more!
void guidance_indi_calcg_wing(float Gmat[GUIDANCE_INDI_HYBRID_V][GUIDANCE_INDI_HYBRID_U], struct FloatVect3 a_diff, float v_body[GUIDANCE_INDI_HYBRID_V])
Perform WLS.
@ GUIDANCE_INDI_HYBRID_V_POS
@ GUIDANCE_INDI_HYBRID_V_SPEED
@ GUIDANCE_INDI_HYBRID_V_ACCEL
@ GUIDANCE_INDI_HYBRID_H_SPEED
@ GUIDANCE_INDI_HYBRID_H_ACCEL
@ GUIDANCE_INDI_HYBRID_H_POS
void WEAK guidance_indi_hybrid_set_wls_settings(float body_v[3], float roll_angle, float pitch_angle)
#define GUIDANCE_INDI_MAX_PITCH
#define GUIDANCE_INDI_MIN_PITCH
static enum GuidanceOneloop_VMode _v_mode
void guidance_v_run_enter(void)
static struct VerticalGuidance * _gv
int32_t guidance_v_run_speed(bool in_flight UNUSED, struct VerticalGuidance *gv)
int32_t guidance_v_run_pos(bool in_flight UNUSED, struct VerticalGuidance *gv)
int32_t guidance_v_run_accel(bool in_flight UNUSED, struct VerticalGuidance *gv)
Simple first order low pass filter with bilinear transform.
static void init_butterworth_2_low_pass(Butterworth2LowPass *filter, float tau, float sample_time, float value)
Init a second order Butterworth filter.
static float update_butterworth_2_low_pass(Butterworth2LowPass *filter, float value)
Update second order Butterworth low pass filter state with a new value.
Second order low pass filter structure.
vector in North East Down coordinates Units: meters
struct RadioControl radio_control
Generic interface for radio control modules.
pprz_t values[RADIO_CONTROL_NB_CHANNEL]
#define RADIO_ROLL
Redefining RADIO_* Do not use with radio.h (ppm rc)
Some helper functions to check RC sticks.
int32_t transition_percentage
void guidance_h_run_enter(void)
struct StabilizationSetpoint guidance_h_run_pos(bool in_flight, struct HorizontalGuidance *gh)
struct StabilizationSetpoint guidance_h_run_speed(bool in_flight, struct HorizontalGuidance *gh)
struct StabilizationSetpoint guidance_h_run_accel(bool in_flight, struct HorizontalGuidance *gh)
#define GUIDANCE_H_MAX_BANK
Max bank controlled by guidance.
struct VerticalGuidance guidance_v
int32_t z_ref
altitude reference in meters.
int32_t zd_ref
vertical speed reference in meter/s.
int32_t zdd_ref
vertical acceleration reference in meter/s^2.
struct RotorcraftNavigation nav
Rotorcraft navigation functions.
float descend_vspeed
descend speed setting, mostly used in flight plans
float heading
heading setpoint (in radians)
float climb_vspeed
climb speed setting, mostly used in flight plans
struct StabilizationSetpoint stab_sp_from_quat_ff_rates_f(struct FloatQuat *quat, struct FloatRates *rates)
int32_t stabilization_cmd[COMMANDS_NB]
Stabilization commands.
int32_t transition_theta_offset
float stabilization_attitude_get_heading_f(void)
Read an attitude setpoint from the RC.
Rotorcraft attitude reference generation.
API to get/set the generic vehicle states.
static const struct usb_device_descriptor dev
union StabilizationSetpoint::@278 sp
Architecture independent timing functions.
static float get_sys_time_float(void)
Get the time in seconds since startup.
int8_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint8_t _id, telemetry_cb _cb)
Register a telemetry callback function.
Periodic telemetry system header (includes downlink utility and generated code).
#define DefaultPeriodic
Set default periodic telemetry.
int int32_t
Typedef defining 32 bit int type.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
signed char int8_t
Typedef defining 8 bit char type.
int wls_alloc(float *u, float *v, float *umin, float *umax, float **B, float *u_guess, float *W_init, float *Wv, float *Wu, float *up, float gamma_sq, int imax, int n_u, int n_v)
active set algorithm for control allocation