82 #include "generated/airframe.h"
103 #ifndef ONELOOP_ANDI_NUM_THRUSTERS
109 #ifndef ONELOOP_ANDI_SCHEDULING
110 #define ONELOOP_ANDI_SCHEDULING FALSE
113 #ifdef ONELOOP_ANDI_FILT_CUTOFF
119 #ifdef ONELOOP_ANDI_FILT_CUTOFF_ACC
125 #ifdef ONELOOP_ANDI_FILT_CUTOFF_VEL
131 #ifdef ONELOOP_ANDI_FILT_CUTOFF_POS
137 #ifdef ONELOOP_ANDI_FILT_CUTOFF_P
138 #define ONELOOP_ANDI_FILTER_ROLL_RATE TRUE
144 #ifdef ONELOOP_ANDI_FILT_CUTOFF_Q
145 #define ONELOOP_ANDI_FILTER_PITCH_RATE TRUE
151 #ifdef ONELOOP_ANDI_FILT_CUTOFF_R
152 #define ONELOOP_ANDI_FILTER_YAW_RATE TRUE
165 float max_r = RadOfDeg(MAX_R);
168 #ifdef ONELOOP_ANDI_ACT_IS_SERVO
174 #ifdef ONELOOP_ANDI_ACT_DYN
177 #error "You must specify the actuator dynamics"
181 #ifdef ONELOOP_ANDI_ACT_MAX
187 #ifdef ONELOOP_ANDI_ACT_MIN
193 #ifdef ONELOOP_ANDI_ACT_MAX_NORM
199 #ifdef ONELOOP_ANDI_ACT_MIN_NORM
205 #ifdef ONELOOP_ANDI_NU_NORM_MAX
211 #ifdef ONELOOP_ANDI_U_PREF
217 #ifndef ONELOOP_ANDI_DEBUG_MODE
218 #define ONELOOP_ANDI_DEBUG_MODE FALSE
222 #define ONELOOP_ANDI_MAX_BANK act_max[COMMAND_ROLL]
223 #define ONELOOP_ANDI_MAX_PHI act_max[COMMAND_ROLL]
225 #define ONELOOP_ANDI_MAX_THETA act_max[COMMAND_PITCH]
227 #ifndef ONELOOP_THETA_PREF_MAX
233 #if ANDI_NUM_ACT_TOT != WLS_N_U_MAX
234 #error Matrix-WLS_N_U_MAX is not equal to the number of actuators: define WLS_N_U_MAX == ANDI_NUM_ACT_TOT in airframe file
235 #define WLS_N_U_MAX == ANDI_NUM_ACT_TOT
237 #if ANDI_OUTPUTS != WLS_N_V_MAX
238 #error Matrix-WLS_N_V_MAX is not equal to the number of controlled axis: define WLS_N_V_MAX == ANDI_OUTPUTS in airframe file
239 #define WLS_N_V_MAX == ANDI_OUTPUTS
242 #ifndef ONELOOP_ANDI_AIRSPEED_SWITCH_THRESHOLD
243 #define ONELOOP_ANDI_AIRSPEED_SWITCH_THRESHOLD 10.0
247 #ifdef NAV_HYBRID_MAX_DECELERATION
253 #ifdef ONELOOP_MAX_JERK
259 #ifdef ONELOOP_MAX_ANGULAR_JERK
260 float max_j_ang = ONELOOP_MAX_ANGULAR_JERK;
265 #ifdef NAV_HYBRID_MAX_AIRSPEED
273 #ifdef NAV_HYBRID_MAX_SPEED_V
279 #ifndef FWD_SIDESLIP_GAIN
285 #ifndef ONELOOP_ANDI_WU_QUAD_MOTORS_FWD
305 void err_nd(
float err[],
float a[],
float b[],
float k[],
int n);
306 void err_sum_nd(
float err[],
float a[],
float b[],
float k[],
float c[],
int n);
307 void integrate_nd(
float dt,
float a[],
float a_dot[],
int n);
310 float bound_v_from_a(
float e_x[],
float v_bound,
float a_bound,
int n);
311 void rm_2nd(
float dt,
float* x_ref,
float* x_d_ref,
float* x_2d_ref,
float x_des,
float k1_rm,
float k2_rm);
312 void rm_3rd(
float dt,
float* x_ref,
float* x_d_ref,
float* x_2d_ref,
float* x_3d_ref,
float x_des,
float k1_rm,
float k2_rm,
float k3_rm);
313 void rm_3rd_head(
float dt,
float* x_ref,
float* x_d_ref,
float* x_2d_ref,
float* x_3d_ref,
float x_des,
float k1_rm,
float k2_rm,
float k3_rm);
314 void rm_3rd_attitude(
float dt,
float x_ref[3],
float x_d_ref[3],
float x_2d_ref[3],
float x_3d_ref[3],
float x_des[3],
bool ow_psi,
float psi_overwrite[4],
float k1_rm[3],
float k2_rm[3],
float k3_rm[3],
float max_ang_jerk);
315 void rm_3rd_pos(
float dt,
float x_ref[],
float x_d_ref[],
float x_2d_ref[],
float x_3d_ref[],
float x_des[],
float k1_rm[],
float k2_rm[],
float k3_rm[],
float x_d_bound,
float x_2d_bound,
float x_3d_bound,
int n);
316 void rm_2nd_pos(
float dt,
float x_d_ref[],
float x_2d_ref[],
float x_3d_ref[],
float x_d_des[],
float k2_rm[],
float k3_rm[],
float x_2d_bound,
float x_3d_bound,
int n);
317 void rm_1st_pos(
float dt,
float x_2d_ref[],
float x_3d_ref[],
float x_2d_des[],
float k3_rm[],
float x_3d_bound,
int n);
318 void ec_3rd_att(
float y_4d[3],
float x_ref[3],
float x_d_ref[3],
float x_2d_ref[3],
float x_3d_ref[3],
float x[3],
float x_d[3],
float x_2d[3],
float k1_e[3],
float k2_e[3],
float k3_e[3],
float max_ang_jerk);
319 void ec_3rd_pos(
float y_4d[],
float x_ref[],
float x_d_ref[],
float x_2d_ref[],
float x_3d_ref[],
float x[],
float x_d[],
float x_2d[],
float k1_e[],
float k2_e[],
float k3_e[],
float x_d_bound,
float x_2d_bound,
float x_3d_bound,
int n);
323 void chirp_pos(
float time_elapsed,
float f0,
float f1,
float t_chirp,
float A,
int8_t n,
float psi,
float p_ref[],
float v_ref[],
float a_ref[],
float j_ref[],
float p_ref_0[]);
324 void chirp_call(
bool*
chirp_on,
bool*
chirp_first_call,
float*
t_0_chirp,
float* time_elapsed,
float f0,
float f1,
float t_chirp,
float A,
int8_t n,
float psi,
float p_ref[],
float v_ref[],
float a_ref[],
float j_ref[],
float p_ref_0[]);
339 static float dt_1l = 1./PERIODIC_FREQUENCY;
340 static float g = 9.81;
364 static float psi_vec[4] = {0.0, 0.0, 0.0, 0.0};
366 #if ONELOOP_ANDI_HEADING_MANUAL
371 #if ONELOOP_ANDI_YAW_STICK_IN_AUTO
385 #ifdef ONELOOP_ANDI_WV
386 .Wv = ONELOOP_ANDI_WV,
390 #ifdef ONELOOP_ANDI_WU
391 .Wu = ONELOOP_ANDI_WU,
403 #ifdef ONELOOP_ANDI_WV
409 #ifdef ONELOOP_ANDI_WU
465 #if PERIODIC_TELEMETRY
498 pprz_msg_send_EFF_MAT_STAB(trans,
dev, AC_ID,
508 pprz_msg_send_EFF_MAT_GUID(trans,
dev, AC_ID,
516 pprz_msg_send_STAB_ATTITUDE(trans,
dev, AC_ID,
517 3, temp_eulers_zxy_des,
535 pprz_msg_send_GUIDANCE(trans,
dev, AC_ID,
559 static void debug_vect(
struct transport_tx *trans,
struct link_device *
dev,
char *name,
float *data,
int datasize)
561 pprz_msg_send_DEBUG_VECT(trans,
dev, AC_ID,
568 float temp_debug_vect[9];
585 if (input < FLT_EPSILON) {
596 return (omega * omega);
602 return (2* zeta * omega);
608 return (omega_n * omega_n * p1);
615 return (omega_n * omega_n + 2 * zeta * omega_n * p1);
622 return (2 * zeta * omega_n + p1);
627 static float k_rm_1_3_f(
float omega_n,
float zeta,
float p1) {
631 return (omega_n * omega_n * p1) / (omega_n * omega_n + omega_n * p1 * zeta * 2.0);
634 static float k_rm_2_3_f(
float omega_n,
float zeta,
float p1) {
638 return (omega_n * omega_n + omega_n * p1 * zeta * 2.0) / (p1 + omega_n * zeta * 2.0);
641 static float k_rm_3_3_f(
float omega_n,
float zeta,
float p1) {
645 return p1 + omega_n * zeta * 2.0;
651 float sphi = sinf(e[0]);
652 float cphi = cosf(e[0]);
653 float stheta = sinf(e[1]);
654 float ctheta = cosf(e[1]);
655 r[0] = edot[0] - stheta * edot[2];
656 r[1] = cphi * edot[1] + sphi * ctheta * edot[2];
657 r[2] = -sphi * edot[1] + cphi * ctheta * edot[2];
663 float sphi = sinf(e[0]);
664 float cphi = cosf(e[0]);
665 float stheta = sinf(e[1]);
666 float ctheta = cosf(e[1]);
667 if (fabs(ctheta) < FLT_EPSILON){
668 ctheta = FLT_EPSILON;
670 edot[0] = r[0] + sphi*stheta/ctheta*r[1] + cphi*stheta/ctheta*r[2];
671 edot[1] = cphi*r[1] - sphi*r[2];
672 edot[2] = sphi/ctheta*r[1] + cphi/ctheta*r[2];
676 void err_nd(
float err[],
float a[],
float b[],
float k[],
int n)
679 for (i = 0; i < n; i++) {
680 err[i] = k[i] * (a[i] -
b[i]);
685 void err_sum_nd(
float err[],
float a[],
float b[],
float k[],
float c[],
int n)
688 for (i = 0; i < n; i++) {
689 err[i] = k[i] * (a[i] -
b[i]);
698 for (i = 0; i < n; i++) {
699 a[i] = a[i] + dt * a_dot[i];
707 if((norm-bound) > FLT_EPSILON) {
708 float scale = bound/norm;
710 for(i = 0; i < n; i++) {
719 float v[2] = {vect->
x, vect->
y};
720 float sign_v0 = (v[0] > 0.f) ? 1.f : (v[0] < 0.f) ? -1.f : 0.f;
721 float sign_v1 = (v[1] > 0.f) ? 1.f : (v[1] < 0.f) ? -1.f : 0.f;
726 if((norm-bound) > FLT_EPSILON) {
727 v[0] =
Min(v[0], bound);
728 float acc_b_y_2 = bound*bound - v[0]*v[0];
730 v[1] = sqrtf(acc_b_y_2);
732 vect->
x = sign_v0*v[0];
733 vect->
y = sign_v1*v[1];
739 norm = fmaxf(norm, 1.0);
740 float v_bound_a = sqrtf(fabs(2.0 * a_bound * norm));
741 return fminf(v_bound, v_bound_a);
758 void rm_3rd_attitude(
float dt,
float x_ref[3],
float x_d_ref[3],
float x_2d_ref[3],
float x_3d_ref[3],
float x_des[3],
bool ow_psi,
float psi_overwrite[4],
float k1_rm[3],
float k2_rm[3],
float k3_rm[3],
float max_ang_jerk){
763 float x_d_eul_ref[3];
764 err_nd(e_x, x_des, x_ref, k1_rm, 3);
765 float temp_diff = x_des[2] - x_ref[2];
766 NormRadAngle(temp_diff);
767 e_x[2] = k1_rm[2] * temp_diff;
769 err_nd(e_x_d, e_x_rates, x_d_ref, k2_rm, 3);
770 err_nd(e_x_2d, e_x_d, x_2d_ref, k3_rm, 3);
773 if(ow_psi){x_3d_ref[2] = psi_overwrite[3];}
775 if(ow_psi){x_2d_ref[2] = psi_overwrite[2];}
777 if(ow_psi){x_d_ref[2] = psi_overwrite[1];}
780 if(ow_psi){x_ref[2] = psi_overwrite[0];}
781 NormRadAngle(x_ref[2]);
799 void rm_3rd(
float dt,
float* x_ref,
float* x_d_ref,
float* x_2d_ref,
float* x_3d_ref,
float x_des,
float k1_rm,
float k2_rm,
float k3_rm){
800 float e_x = k1_rm * (x_des- *x_ref);
801 float e_x_d = k2_rm * (e_x- *x_d_ref);
802 float e_x_2d = k3_rm * (e_x_d- *x_2d_ref);
804 *x_2d_ref = (*x_2d_ref + dt * (*x_3d_ref));
805 *x_d_ref = (*x_d_ref + dt * (*x_2d_ref));
806 *x_ref = (*x_ref + dt * (*x_d_ref ));
821 void rm_3rd_head(
float dt,
float* x_ref,
float* x_d_ref,
float* x_2d_ref,
float* x_3d_ref,
float x_des,
float k1_rm,
float k2_rm,
float k3_rm){
822 float temp_diff = x_des - *x_ref;
823 NormRadAngle(temp_diff);
824 float e_x = k1_rm * temp_diff;
825 float e_x_d = k2_rm * (e_x- *x_d_ref);
826 float e_x_2d = k3_rm * (e_x_d- *x_2d_ref);
828 *x_2d_ref = (*x_2d_ref + dt * (*x_3d_ref));
829 *x_d_ref = (*x_d_ref + dt * (*x_2d_ref));
830 *x_ref = (*x_ref + dt * (*x_d_ref ));
849 void rm_3rd_pos(
float dt,
float x_ref[],
float x_d_ref[],
float x_2d_ref[],
float x_3d_ref[],
float x_des[],
float k1_rm[],
float k2_rm[],
float k3_rm[],
float x_d_bound,
float x_2d_bound,
float x_3d_bound,
int n){
853 err_nd(e_x, x_des, x_ref, k1_rm, n);
856 err_nd(e_x_d, e_x, x_d_ref, k2_rm, n);
858 err_nd(e_x_2d, e_x_d, x_2d_ref, k3_rm, n);
879 void rm_2nd_pos(
float dt,
float x_d_ref[],
float x_2d_ref[],
float x_3d_ref[],
float x_d_des[],
float k2_rm[],
float k3_rm[],
float x_2d_bound,
float x_3d_bound,
int n){
882 err_nd(e_x_d, x_d_des, x_d_ref, k2_rm, n);
884 err_nd(e_x_2d, e_x_d, x_2d_ref, k3_rm, n);
901 void rm_1st_pos(
float dt,
float x_2d_ref[],
float x_3d_ref[],
float x_2d_des[],
float k3_rm[],
float x_3d_bound,
int n){
903 err_nd(e_x_2d, x_2d_des, x_2d_ref, k3_rm, n);
922 void rm_2nd(
float dt,
float* x_ref,
float* x_d_ref,
float* x_2d_ref,
float x_des,
float k1_rm,
float k2_rm){
923 float e_x = k1_rm * (x_des- *x_ref);
924 float e_x_d = k2_rm * (e_x- *x_d_ref);
926 *x_d_ref = (*x_d_ref + dt * (*x_2d_ref));
927 *x_ref = (*x_ref + dt * (*x_d_ref ));
945 static float ec_3rd(
float x_ref,
float x_d_ref,
float x_2d_ref,
float x_3d_ref,
float x,
float x_d,
float x_2d,
float k1_e,
float k2_e,
float k3_e){
946 float y_4d = k1_e*(x_ref-x)+k2_e*(x_d_ref-x_d)+k3_e*(x_2d_ref-x_2d)+x_3d_ref;
949 void ec_3rd_pos(
float y_4d[],
float x_ref[],
float x_d_ref[],
float x_2d_ref[],
float x_3d_ref[],
float x[],
float x_d[],
float x_2d[],
float k1_e[],
float k2_e[],
float k3_e[],
float x_d_bound,
float x_2d_bound,
float x_3d_bound,
int n){
953 err_sum_nd(e_x_d, x_ref, x, k1_e, x_d_ref, n);
956 err_sum_nd(e_x_2d, e_x_d, x_d, k2_e, x_2d_ref, n);
959 err_sum_nd(y_4d, e_x_2d, x_2d, k3_e, x_3d_ref, n);
977 void ec_3rd_att(
float y_4d[3],
float x_ref[3],
float x_d_ref[3],
float x_2d_ref[3],
float x_3d_ref[3],
float x[3],
float x_d[3],
float x_2d[3],
float k1_e[3],
float k2_e[3],
float k3_e[3],
float max_ang_jerk){
981 err_nd(y_4d_1, x_ref, x, k1_e, 3);
982 float temp_diff = x_ref[2] - x[2];
983 NormRadAngle(temp_diff);
984 float e_x = temp_diff;
985 y_4d_1[2] = k1_e[2] * e_x;
986 err_nd(y_4d_2, x_d_ref, x_d, k2_e, 3);
987 err_nd(y_4d_3, x_2d_ref, x_2d, k3_e, 3);
1002 static float w_approx(
float p1,
float p2,
float p3,
float rm_k){
1007 float tao = (p1*p2+p1*p3+p2*p3)/(p1*p2*p3)/(rm_k);
1019 static float ec_poles(
float p_rm,
float slow_pole,
float k){
1023 float omega_n = (2*p_rm*slow_pole*k)/(3*slow_pole-p_rm);
1032 float slow_pole = 22.0;
1051 float slow_pole = 22.0;
1074 #ifdef ONELOOP_ANDI_POLES_POS_OMEGA_N
1085 #ifdef ONELOOP_ANDI_POLES_ALT_OMEGA_N
1104 float max_wind = 20.0;
1212 cf->tau = 1/(2*M_PI*
cf->freq);
1223 cf->tau = 1/(2*M_PI*
cf->freq);
1244 if(
cf->freq !=
cf->freq_set || reinit){
1245 cf->freq =
cf->freq_set;
1246 cf->tau = 1/(2*M_PI*
cf->freq);
1253 if(
cf->freq !=
cf->freq_set || reinit){
1254 cf->freq =
cf->freq_set;
1255 cf->tau = 1/(2*M_PI*
cf->freq);
1277 #ifdef ONELOOP_ANDI_ROLL_STRUCTURAL_MODE_FREQ
1282 #ifdef ONELOOP_ANDI_PITCH_STRUCTURAL_MODE_FREQ
1287 #ifdef ONELOOP_ANDI_YAW_STRUCTURAL_MODE_FREQ
1325 #define USE_YAW_NOTCH
1326 float temp_p_dot = (body_rates->
p-
cf.
p.
feedback)*PERIODIC_FREQUENCY;
1327 float temp_q_dot = (body_rates->
q-
cf.
q.
feedback)*PERIODIC_FREQUENCY;
1328 float temp_r_dot = (body_rates->
r-
cf.
r.
feedback)*PERIODIC_FREQUENCY;
1329 #ifdef USE_ROLL_NOTCH
1334 #ifdef USE_PITCH_NOTCH
1339 #ifdef USE_YAW_NOTCH
1396 Bound(airspeed_meas, 0.0, 30.0);
1437 #if PERIODIC_TELEMETRY
1499 float thrust_cmd_1l = 0.0;
1516 BoundAbs(des_r,
max_r);
1517 float delta_psi_des_rad = des_r *
dt_1l;
1519 NormRadAngle(delta_psi_rad);
1520 if (fabs(delta_psi_rad) > RadOfDeg(30.0)){
1521 delta_psi_des_rad = 0.0;
1526 if (!in_flight_oneloop){
1538 rm_3rd_attitude(
dt_1l,
oneloop_andi.
sta_ref.
att,
oneloop_andi.
sta_ref.
att_d,
oneloop_andi.
sta_ref.
att_2d,
oneloop_andi.
sta_ref.
att_3d, att_des,
false,
psi_vec,
k_att_rm.
k1,
k_att_rm.
k2,
k_att_rm.
k3,
max_j_ang);
1544 if (rm_order_h == 3){
1545 rm_3rd_pos(
dt_1l,
oneloop_andi.
gui_ref.
pos,
oneloop_andi.
gui_ref.
vel,
oneloop_andi.
gui_ref.
acc,
oneloop_andi.
gui_ref.
jer,
nav_target,
k_pos_rm.
k1,
k_pos_rm.
k2,
k_pos_rm.
k3,
max_v_nav,
max_a_nav,
max_j_nav, 2);
1546 }
else if (rm_order_h == 2){
1552 }
else if (rm_order_h == 1){
1567 if (ref_mag_vel > 3.0){
1570 NormRadAngle(delta_des_gs);
1571 if (fabs(delta_des_gs) > RadOfDeg(60.0)){
1572 delta_des_gs *= RadOfDeg(60.0)/fabs(delta_des_gs);
1579 if (!in_flight_oneloop){
1589 float single_value_nav_target[1] = {
nav_target[2]};
1590 float single_value_k1_rm[1] = {
k_pos_rm.
k1[2]};
1591 float single_value_k2_rm[1] = {
k_pos_rm.
k2[2]};
1592 float single_value_k3_rm[1] = {
k_pos_rm.
k3[2]};
1593 if (rm_order_v == 3){
1594 rm_3rd_pos(
dt_1l, single_value_ref, single_value_d_ref, single_value_2d_ref, single_value_3d_ref, single_value_nav_target, single_value_k1_rm, single_value_k2_rm, single_value_k3_rm,
max_v_nav_v,
max_a_nav,
max_j_nav, 1);
1599 }
else if (rm_order_v == 2){
1600 rm_2nd_pos(
dt_1l, single_value_d_ref, single_value_2d_ref, single_value_3d_ref, single_value_nav_target, single_value_k2_rm, single_value_k3_rm,
max_a_nav,
max_j_nav, 1);
1605 }
else if (rm_order_v == 1){
1606 rm_1st_pos(
dt_1l, single_value_2d_ref, single_value_3d_ref, single_value_nav_target, single_value_k3_rm,
max_j_nav, 1);
1613 chirp_call(&
chirp_on, &
chirp_first_call, &
t_0_chirp, &
time_elapsed_chirp,
f0_chirp,
f1_chirp,
t_chirp,
A_chirp,
chirp_axis, att_des[2],
oneloop_andi.
gui_ref.
pos,
oneloop_andi.
gui_ref.
vel,
oneloop_andi.
gui_ref.
acc,
oneloop_andi.
gui_ref.
jer,
p_ref_0);
1616 bool ow_psi =
false;
1617 rm_3rd_attitude(
dt_1l,
oneloop_andi.
sta_ref.
att,
oneloop_andi.
sta_ref.
att_d,
oneloop_andi.
sta_ref.
att_2d,
oneloop_andi.
sta_ref.
att_3d, att_des, ow_psi,
psi_vec,
k_att_rm.
k1,
k_att_rm.
k2,
k_att_rm.
k3,
max_j_ang);
1644 bool in_flight_oneloop =
false;
1647 in_flight_oneloop =
true;
1650 in_flight_oneloop =
false;
1688 oneloop_andi_RM(half_loop, PSA_des, rm_order_h, rm_order_v, in_flight_oneloop);
1697 ec_3rd_pos(
nu,
oneloop_andi.
gui_ref.
pos,
oneloop_andi.
gui_ref.
vel,
oneloop_andi.
gui_ref.
acc,
oneloop_andi.
gui_ref.
jer,
oneloop_andi.
gui_state.
pos,
oneloop_andi.
gui_state.
vel,
oneloop_andi.
gui_state.
acc,
k_pos_e.
k1,
k_pos_e.
k2,
k_pos_e.
k3,
max_v_nav,
max_a_nav,
max_j_nav, 3);
1710 ec_3rd_att(y_4d_att,
oneloop_andi.
sta_ref.
att,
oneloop_andi.
sta_ref.
att_d,
oneloop_andi.
sta_ref.
att_2d,
oneloop_andi.
sta_ref.
att_3d,
oneloop_andi.
sta_state.
att,
oneloop_andi.
sta_state.
att_d,
oneloop_andi.
sta_state.
att_2d,
k_att_e.
k1,
k_att_e.
k2,
k_att_e.
k3,
max_j_ang);
1712 float dummy0[3] = {0.0, 0.0, 0.0};
1713 ec_3rd_att(y_4d_att,
oneloop_andi.
sta_ref.
att,
oneloop_andi.
sta_ref.
att_d,
oneloop_andi.
sta_ref.
att_2d, dummy0,
oneloop_andi.
sta_state.
att,
oneloop_andi.
sta_state.
att_d,
oneloop_andi.
sta_state.
att_2d,
k_att_e_indi.
k1,
k_att_e_indi.
k2,
k_att_e_indi.
k3,
max_j_ang);
1715 nu[3] = y_4d_att[0];
1716 nu[4] = y_4d_att[1];
1727 case COMMAND_MOTOR_FRONT:
1728 case COMMAND_MOTOR_RIGHT:
1729 case COMMAND_MOTOR_BACK:
1730 case COMMAND_MOTOR_LEFT: {
1732 Bound(skew_bound,70.0,90.0);
1746 case COMMAND_MOTOR_PUSHER:
1747 case COMMAND_RUDDER:
1752 case COMMAND_AILERONS:
1772 case COMMAND_ELEVATOR:
1803 if (in_flight_oneloop) {
1814 #ifdef COMMAND_MOTOR_PUSHER
1830 commands[COMMAND_MOTOR_PUSHER] = 0;
1855 float prev_actuator_state_1l;
1876 case (COMMAND_MOTOR_FRONT):
1877 case (COMMAND_MOTOR_RIGHT):
1878 case (COMMAND_MOTOR_BACK):
1879 case (COMMAND_MOTOR_LEFT):
1880 case (COMMAND_MOTOR_PUSHER):
1881 case (COMMAND_ELEVATOR):
1882 case (COMMAND_RUDDER):
1883 case (COMMAND_AILERONS):
1884 case (COMMAND_FLAPS):
1891 case (COMMAND_ROLL):
1892 case (COMMAND_PITCH):
1909 if (turn_quad_off && i < 4){
1937 ratio_u_un[i] = ratio_numerator/ratio_denominator;
1942 float ratio_denominator = 1.0;
1948 ratio_vn_v[i] = ratio_numerator/ratio_denominator;
1954 ratio_vn_v[i] = ratio_numerator/ratio_denominator;
1985 cf.
ax.
model = -(cpsi * stheta + ctheta * sphi * spsi) *
T + (cpsi * ctheta - sphi * spsi * stheta) *
P - sphi * spsi * L;
1986 cf.
ay.
model = -(spsi * stheta - cpsi * ctheta * sphi) *
T + (ctheta * spsi + cpsi * sphi * stheta) *
P + cpsi * sphi * L;
1987 cf.
az.
model =
g - cphi * ctheta *
T - cphi * stheta *
P - cphi * L;
1988 float model_pqr_dot[3] = {0.0, 0.0, 0.0};
1989 for (i = 0; i < 3; i++){
1991 if(j == COMMAND_ELEVATOR){
2049 Bound(airspeed_turn, 1.0f, 30.0f);
2056 BoundAbs(coordinated_turn_roll, max_phi);
2057 omega =
g / airspeed_turn * tanf(coordinated_turn_roll);
2058 #ifdef FWD_SIDESLIP_GAIN
2067 float p_ref_fun = sinf(delta_t * M_PI * (f0 + k * delta_t) * 2.0);
2068 return (
A * p_ref_fun);
2072 float v_ref_fun = cosf(delta_t * M_PI * (f0 + k * delta_t) * 2.0) * (M_PI * (f0 + k * delta_t) * 2.0 + k * delta_t * M_PI * 2.0);
2073 return (
A * v_ref_fun);
2077 float a_ref_fun = -sinf(delta_t * M_PI * (f0 + k * delta_t) * 2.0) * pow((M_PI * (f0 + k * delta_t) * 2.0 + k * delta_t * M_PI * 2.0), 2) + k * M_PI * cosf(delta_t * M_PI * (f0 + k * delta_t) * 2.0) * 4.0;
2078 return (
A * a_ref_fun);
2082 float j_ref_fun = -cosf(delta_t * M_PI * (f0 + k * delta_t) * 2.0) * pow((M_PI * (f0 + k * delta_t) * 2.0 + k * delta_t * M_PI * 2.0), 3) - k * M_PI * sinf(delta_t * M_PI * (f0 + k * delta_t) * 2.0) * (M_PI * (f0 + k * delta_t) * 2.0 + k * delta_t * M_PI * 2.0) * 1.2e+1;
2083 return (
A * j_ref_fun);
2097 void chirp_pos(
float time_elapsed,
float f0,
float f1,
float t_chirp,
float A,
int8_t n,
float psi,
float p_ref[],
float v_ref[],
float a_ref[],
float j_ref[],
float p_ref_0[]) {
2102 if ((f1-f0) < -FLT_EPSILON){
2113 float k = (f1 - f0) /
t_chirp;
2119 float spsi = sinf(psi);
2120 float cpsi = cosf(psi);
2139 p_ref[2] =
p_ref_0[2] + p_ref_chirp * mult_2;
2140 v_ref[2] = v_ref_chirp * mult_2;
2141 a_ref[2] = a_ref_chirp * mult_2;
2142 j_ref[2] = j_ref_chirp * mult_2;
2144 p_ref[0] =
p_ref_0[0] + p_ref_chirp * mult_0;
2145 p_ref[1] =
p_ref_0[1] + p_ref_chirp * mult_1;
2146 v_ref[0] = v_ref_chirp * mult_0;
2147 v_ref[1] = v_ref_chirp * mult_1;
2148 a_ref[0] = a_ref_chirp * mult_0;
2149 a_ref[1] = a_ref_chirp * mult_1;
2150 j_ref[0] = j_ref_chirp * mult_0;
2151 j_ref[1] = j_ref_chirp * mult_1;
2155 float pitch_offset = RadOfDeg(5.0);
2161 void chirp_call(
bool *
chirp_on,
bool *
chirp_first_call,
float* t_0,
float* time_elapsed,
float f0,
float f1,
float t_chirp,
float A,
int8_t n,
float psi,
float p_ref[],
float v_ref[],
float a_ref[],
float j_ref[],
float p_ref_0[]){
2164 *time_elapsed = 0.0;
2173 chirp_pos(*time_elapsed, f0, f1,
t_chirp,
A, n, psi, p_ref, v_ref, a_ref, j_ref,
p_ref_0);
2177 *time_elapsed = 0.0;
2193 float cpsi = cosf(psi);
2194 float spsi = sinf(psi);
2197 struct FloatVect2 airspeed_v = { cpsi * airspeed, spsi * airspeed };
2203 VECT2_DIFF(windspeed, groundspeed, airspeed_v);
2208 if (norm_des_as <
min_as) {
2215 float groundspeed_factor = 0.0f;
2217 float av = NT_v_NE.
x * NT_v_NE.
x + NT_v_NE.
y * NT_v_NE.
y;
2218 float bv = -2.f * (windspeed.
x * NT_v_NE.
x + windspeed.
y * NT_v_NE.
y);
2219 float cv = windspeed.
x * windspeed.
x + windspeed.
y * windspeed.
y -
max_as *
max_as;
2220 float dv = bv * bv - 4.0f * av * cv;
2225 float d_sqrt = sqrtf(dv);
2226 groundspeed_factor = (-bv + d_sqrt) / (2.0f * av);
2228 des_as_NE.
x = groundspeed_factor * NT_v_NE.
x - windspeed.
x;
2229 des_as_NE.
y = groundspeed_factor * NT_v_NE.
y - windspeed.
y;
2230 NT_v_NE.
x = groundspeed_factor * NT_v_NE.
x;
2231 NT_v_NE.
y = groundspeed_factor * NT_v_NE.
y;
2234 des_as_B.
x = norm_des_as;
2237 float delta_psi = atan2f(des_as_NE.
y, des_as_NE.
x) - psi;
2239 des_acc_B.
y = delta_psi * 5.0;
2240 des_acc_B.
x = (des_as_B.
x - airspeed) *
k_pos_rm.
k2[0];
Main include for ABI (AirBorneInterface).
struct pprz_autopilot autopilot
Global autopilot structure.
bool autopilot_get_motors_on(void)
get motors status
pprz_t throttle
throttle level as will be displayed in GCS
uint8_t mode
current autopilot mode
pprz_t commands[COMMANDS_NB]
Hardware independent code for commands handling.
static const float scale[]
float G2_RW[EFF_MAT_COLS_NB]
float EFF_MAT_RW[EFF_MAT_ROWS_NB][EFF_MAT_COLS_NB]
Device independent GPS code (interface)
#define FLOAT_ANGLE_NORMALIZE(_a)
static void float_vect_sum(float *o, const float *a, const float *b, const int n)
o = a + b
static void float_vect_zero(float *a, const int n)
a = 0
static void float_vect_copy(float *a, const float *b, const int n)
a = b
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
static float float_vect_norm(const float *a, const int n)
||a||
#define FLOAT_VECT2_NORM(_v)
#define VECT2_DIFF(_c, _a, _b)
#define POS_FLOAT_OF_BFP(_ai)
#define SPEED_FLOAT_OF_BFP(_ai)
#define POS_BFP_OF_REAL(_af)
#define ACCEL_FLOAT_OF_BFP(_ai)
#define SPEED_BFP_OF_REAL(_af)
static struct NedCoor_f * stateGetAccelNed_f(void)
Get acceleration in NED coordinates (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 FloatRates * stateGetBodyRates_f(void)
Get vehicle body angular rate (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).
bool force_forward
forward flight for hybrid nav
Integrated Navigation System interface.
Simple first order low pass filter with bilinear transform.
struct SecondOrderLowPass lp2
static float get_butterworth_2_low_pass(Butterworth2LowPass *filter)
Get current value of the second order Butterworth low pass filter.
static float get_butterworth_4_low_pass(Butterworth4LowPass *filter)
Get current value of the fourth order Butterworth low pass filter.
static void init_butterworth_4_low_pass(Butterworth4LowPass *filter, float tau, float sample_time, float value)
Init a fourth order Butterworth filter.
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.
static float update_butterworth_4_low_pass(Butterworth4LowPass *filter, float value)
Update fourth order Butterworth low pass filter state with a new value.
Second order low pass filter structure.
Hardware independent API for actuators (servos, motor controllers).
#define NAV_HYBRID_MAX_AIRSPEED
float nav_hybrid_max_bank
float nav_max_acceleration_sp
float nav_hybrid_pos_gain
#define NAV_HYBRID_MAX_DECELERATION
Specific navigation functions for hybrid aircraft.
static void notch_filter_update(struct SecondOrderNotchFilter *filter, int32_t *input_signal, int32_t *output_signal)
Notch filter propagate.
static void notch_filter_init(struct SecondOrderNotchFilter *filter, float cutoff_frequency, float bandwidth, uint16_t sample_frequency)
Initialize second order notch filter.
static float k_e_3_3_f_v2(float omega_n, float zeta, float p1)
void reinit_all_cf(bool reinit)
Reinitialize all the Complementary Filters.
static float w_approx(float p1, float p2, float p3, float rm_k)
Third Order to First Order Dynamics Approximation.
#define ONELOOP_ANDI_MAX_THETA
void init_poles(void)
Initialize Position of Poles.
struct PolePlacement p_pos_e
static float Wv_backup[ANDI_OUTPUTS]
void chirp_pos(float time_elapsed, float f0, float f1, float t_chirp, float A, int8_t n, float psi, float p_ref[], float v_ref[], float a_ref[], float j_ref[], float p_ref_0[])
Reference Model Definition for 3rd order system specific to positioning with bounds.
static Butterworth2LowPass accely_filt
float act_dynamics[ANDI_NUM_ACT_TOT]
float ratio_u_un[ANDI_NUM_ACT_TOT]
static float Wu_backup[ANDI_NUM_ACT_TOT]
void init_filter(void)
Initialize the filters.
struct PolePlacement p_head_rm
void oneloop_andi_RM(bool half_loop, struct FloatVect3 PSA_des, int rm_order_h, int rm_order_v, bool in_flight_oneloop)
Function to generate the reference signals for the oneloop controller.
void oneloop_andi_enter(bool half_loop_sp, int ctrl_type)
Function that resets important values upon engaging Oneloop ANDI.
static Butterworth2LowPass airspeed_filt
static float k_e_2_3_f_v2(float omega_n, float zeta, float p1)
static float k_e_1_2_f_v2(float omega, float zeta)
Error Controller Gain Design.
float act_max_norm[ANDI_NUM_ACT_TOT]
struct Gains3rdOrder k_att_rm
void float_euler_dot_of_rates_vec(float r[3], float e[3], float edot[3])
Attitude Euler to Rates Conversion Function.
float oneloop_andi_filt_cutoff_v
struct FloatEulers eulers_zxy_des
struct Int32Eulers stab_att_sp_euler_1l
struct PolePlacement p_att_rm
static float ec_3rd(float x_ref, float x_d_ref, float x_2d_ref, float x_3d_ref, float x, float x_d, float x_2d, float k1_e, float k2_e, float k3_e)
Error Controller Definition for 3rd order system.
static float k_rm_3_3_f(float omega_n, float zeta, float p1)
struct Gains3rdOrder k_att_e
float EFF_MAT_G[ANDI_OUTPUTS][ANDI_NUM_ACT_TOT]
void rm_1st_pos(float dt, float x_2d_ref[], float x_3d_ref[], float x_2d_des[], float k3_rm[], float x_3d_bound, int n)
Reference Model Definition for 3rd order system specific to positioning with bounds.
void oneloop_andi_propagate_filters(void)
Propagate the filters.
struct Gains3rdOrder k_pos_e
static Butterworth2LowPass filt_veloc_E
bool actuator_is_servo[ANDI_NUM_ACT_TOT]
float oneloop_andi_sideslip(void)
Function to calculate corrections for sideslip.
float num_thrusters_oneloop
static float act_dynamics_d[ANDI_NUM_ACT_TOT]
float act_min_norm[ANDI_NUM_ACT_TOT]
#define ONELOOP_ANDI_DEBUG_MODE
float oneloop_andi_filt_cutoff_q
float oneloop_andi_filt_cutoff_a
static float ec_poles(float p_rm, float slow_pole, float k)
Calculate EC poles given RM poles.
static void send_wls_u_oneloop(struct transport_tx *trans, struct link_device *dev)
static float chirp_pos_j_ref(float delta_t, float f0, float k, float A)
Function to calculate the jerk reference during the chirp.
#define ONELOOP_ANDI_MAX_PHI
void oneloop_from_nav(bool in_flight)
Function that maps navigation inputs to the oneloop controller for the generated autopilot.
struct PolePlacement p_alt_rm
void ec_3rd_att(float y_4d[3], float x_ref[3], float x_d_ref[3], float x_2d_ref[3], float x_3d_ref[3], float x[3], float x_d[3], float x_2d[3], float k1_e[3], float k2_e[3], float k3_e[3], float max_ang_jerk)
Error Controller Definition for 3rd order system specific to attitude.
static float positive_non_zero(float input)
Function to make sure that inputs are positive non zero vaues.
static void send_eff_mat_stab_oneloop_andi(struct transport_tx *trans, struct link_device *dev)
void guidance_set_min_max_airspeed(float min_airspeed, float max_airspeed)
void rm_3rd(float dt, float *x_ref, float *x_d_ref, float *x_2d_ref, float *x_3d_ref, float x_des, float k1_rm, float k2_rm, float k3_rm)
Reference Model Definition for 3rd order system.
float andi_u[ANDI_NUM_ACT_TOT]
void calc_normalization(void)
Calculate Normalization of actuators and discrete actuator dynamics
struct Gains3rdOrder k_pos_e_indi
void init_cf4(struct CF4_t *cf, float fc)
Initialize the Complementary Filters 4th Order Butterworth.
void oneloop_andi_run(bool in_flight, bool half_loop, struct FloatVect3 PSA_des, int rm_order_h, int rm_order_v)
Main function that runs the controller and performs control allocation.
struct PolePlacement p_att_e
static void send_eff_mat_guid_oneloop_andi(struct transport_tx *trans, struct link_device *dev)
static void debug_vect(struct transport_tx *trans, struct link_device *dev, char *name, float *data, int datasize)
struct PolePlacement p_alt_e
void rm_2nd_pos(float dt, float x_d_ref[], float x_2d_ref[], float x_3d_ref[], float x_d_des[], float k2_rm[], float k3_rm[], float x_2d_bound, float x_3d_bound, int n)
Reference Model Definition for 3rd order system specific to positioning with bounds.
float bound_v_from_a(float e_x[], float v_bound, float a_bound, int n)
Calculate velocity limit based on acceleration limit.
static float andi_du_n[ANDI_NUM_ACT_TOT]
void get_act_state_oneloop(void)
Function to reconstruct actuator state using first order dynamics.
struct PolePlacement p_head_e
static float chirp_pos_p_ref(float delta_t, float f0, float k, float A)
Function to calculate the position reference during the chirp.
float andi_du[ANDI_NUM_ACT_TOT]
static float chirp_pos_v_ref(float delta_t, float f0, float k, float A)
Function to calculate the velocity reference during the chirp.
void init_cf2(struct CF2_t *cf, float fc)
Initialize the Complementary Filters 2nd Order Butterworth.
struct Int32Quat stab_att_sp_quat_1l
static void send_wls_v_oneloop(struct transport_tx *trans, struct link_device *dev)
static float nav_target[3]
void err_nd(float err[], float a[], float b[], float k[], int n)
Calculate Scaled Error between two 3D arrays.
static float k_e_1_3_f_v2(float omega_n, UNUSED float zeta, float p1)
#define ONELOOP_ANDI_AIRSPEED_SWITCH_THRESHOLD
void calc_model(void)
Function that calculates the model prediction for the complementary filter.
struct OneloopGeneral oneloop_andi
struct Gains3rdOrder k_pos_rm
bool autopilot_in_flight_end_detection(bool motors_on UNUSED)
Quadplanes can still be in-flight with COMMAND_THRUST==0 and can even soar not descending in updrafts...
static float use_increment
void chirp_call(bool *chirp_on, bool *chirp_first_call, float *t_0_chirp, float *time_elapsed, float f0, float f1, float t_chirp, float A, int8_t n, float psi, float p_ref[], float v_ref[], float a_ref[], float j_ref[], float p_ref_0[])
void init_controller(void)
Initialize Controller Gains FIXME: Calculate the gains dynamically for transition.
void G1G2_oneloop(int ctrl_type)
Function that samples and scales the effectiveness matrix FIXME: make this function into a for loop t...
static void send_guidance_oneloop_andi(struct transport_tx *trans, struct link_device *dev)
float act_max[ANDI_NUM_ACT_TOT]
void rm_3rd_head(float dt, float *x_ref, float *x_d_ref, float *x_2d_ref, float *x_3d_ref, float x_des, float k1_rm, float k2_rm, float k3_rm)
Reference Model Definition for 3rd order system specific to the heading angle.
static Butterworth2LowPass filt_veloc_D
static Butterworth2LowPass filt_veloc_N
void normalize_nu(void)
Function to normalize the pseudo control vector.
void rm_3rd_pos(float dt, float x_ref[], float x_d_ref[], float x_2d_ref[], float x_3d_ref[], float x_des[], float k1_rm[], float k2_rm[], float k3_rm[], float x_d_bound, float x_2d_bound, float x_3d_bound, int n)
Reference Model Definition for 3rd order system specific to positioning with bounds.
struct FloatEulers eulers_zxy
void oneloop_andi_init(void)
Init function of Oneloop ANDI controller
void float_rates_of_euler_dot_vec(float r[3], float e[3], float edot[3])
Attitude Rates to Euler Conversion Function.
float oneloop_andi_filt_cutoff_p
static struct Oneloop_notch_t oneloop_notch
static float k_rm_1_3_f(float omega_n, float zeta, float p1)
Reference Model Gain Design.
static float k_e_2_2_f_v2(float omega, float zeta)
float gi_unbounded_airspeed_sp
float oneloop_andi_filt_cutoff_r
void init_poles_att(void)
Initialize Position of Poles.
struct PolePlacement p_pos_rm
float ratio_vn_v[ANDI_OUTPUTS]
void ec_3rd_pos(float y_4d[], float x_ref[], float x_d_ref[], float x_2d_ref[], float x_3d_ref[], float x[], float x_d[], float x_2d[], float k1_e[], float k2_e[], float k3_e[], float x_d_bound, float x_2d_bound, float x_3d_bound, int n)
static float chirp_pos_a_ref(float delta_t, float f0, float k, float A)
Function to calculate the acceleration reference during the chirp.
#define ONELOOP_ANDI_MAX_BANK
void vect_bound_nd(float vect[], float bound, int n)
Scale a 3D array to within a 3D bound.
void err_sum_nd(float err[], float a[], float b[], float k[], float c[], int n)
Calculate Scaled Error between two 3D arrays.
PRINT_CONFIG_VAR(ONELOOP_ANDI_FILT_CUTOFF)
void reinit_cf4(struct CF4_t *cf, bool reinit)
Reinitialize 4th Order CF if new frequency setting or if forced.
void integrate_nd(float dt, float a[], float a_dot[], int n)
Integrate in time 3D array.
static void send_oneloop_andi(struct transport_tx *trans, struct link_device *dev)
struct Gains3rdOrder k_att_e_indi
void rm_3rd_attitude(float dt, float x_ref[3], float x_d_ref[3], float x_2d_ref[3], float x_3d_ref[3], float x_des[3], bool ow_psi, float psi_overwrite[4], float k1_rm[3], float k2_rm[3], float k3_rm[3], float max_ang_jerk)
Reference Model Definition for 3rd order system with attitude conversion functions.
static void send_oneloop_debug(struct transport_tx *trans, struct link_device *dev)
float act_min[ANDI_NUM_ACT_TOT]
float actuator_state_1l[ANDI_NUM_ACT]
float oneloop_andi_filt_cutoff_pos
void rm_2nd(float dt, float *x_ref, float *x_d_ref, float *x_2d_ref, float x_des, float k1_rm, float k2_rm)
Reference Model Definition for 2nd order system.
void init_all_cf(void)
Initialize all the Complementary Filters.
void acc_body_bound(struct FloatVect2 *vect, float bound)
Scale a 3D array to within a 3D bound.
float * bwls_1l[ANDI_OUTPUTS]
void init_poles_pos(void)
static float k_rm_2_3_f(float omega_n, float zeta, float p1)
static float nav_target_new[3]
void reinit_cf2(struct CF2_t *cf, bool reinit)
Reinitialize 2nd Order CF if new frequency setting or if forced.
static float u_pref[ANDI_NUM_ACT_TOT]
float oneloop_andi_filt_cutoff
struct OneloopGuidanceState gui_state
struct OneloopStabilizationState sta_state
Butterworth2LowPass feedback_filt
Butterworth4LowPass feedback_filt
Butterworth4LowPass model_filt
struct OneloopGuidanceRef gui_ref
#define CTRL_ANDI
Control types.
struct OneloopStabilizationRef sta_ref
struct notch_axis_t pitch
struct SecondOrderNotchFilter filter
Butterworth2LowPass model_filt
Paparazzi floating point algebra.
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]
static pprz_t radio_control_get(uint8_t idx)
Get a radio control channel value.
#define RADIO_ROLL
Redefining RADIO_* Do not use with radio.h (ppm rc)
#define AP_MODE_ATTITUDE_DIRECT
struct RotorcraftNavigation nav
Rotorcraft navigation functions.
struct EnuCoor_f speed
speed setpoint (in m/s)
float climb
climb setpoint (in m/s)
#define NAV_SETPOINT_MODE_SPEED
#define NAV_VERTICAL_MODE_CLIMB
float nav_altitude
current altitude setpoint (in meters): might differ from fp_altitude depending on altitude shift from...
#define NAV_VERTICAL_MODE_ALT
#define NAV_SETPOINT_MODE_POS
Nav setpoint modes these modes correspond to submodes defined by navigation routines to tell which se...
struct EnuCoor_f target
final target position (in meters)
bool rotwing_state_hover_motors_running(void)
struct rotwing_state_t rotwing_state
enum rotwing_states_t state
bool hover_motors_enabled
@ ROTWING_STATE_FORCE_HOVER
struct Stabilization stabilization
int32_t cmd[COMMANDS_NB]
output command vector, range from [-MAX_PPRZ:MAX_PPRZ] (store for messages)
API to get/set the generic vehicle states.
static const struct usb_device_descriptor dev
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.
short int16_t
Typedef defining 16 bit short type.
signed char int8_t
Typedef defining 8 bit char type.
void send_wls_v(char *name, struct WLS_t *WLS_p, struct transport_tx *trans, struct link_device *dev)
void wls_alloc(struct WLS_t *WLS_p, float **B, float *u_guess, float *W_init, int imax)
active set algorithm for control allocation
void send_wls_u(char *name, struct WLS_t *WLS_p, struct transport_tx *trans, struct link_device *dev)
float u_pref[WLS_N_U_MAX]