36 #include "generated/airframe.h"
38 #if PERIODIC_TELEMETRY
45 #define PRINT_DBG(_l, _p) { \
46 if (DBG_LEVEL >= _l) \
50 #define PRINT_DBG(_l, _p) {}
54 #ifndef AHRS_PROPAGATE_FREQUENCY
55 #define AHRS_PROPAGATE_FREQUENCY PERIODIC_FREQUENCY
59 #if AHRS_PROPAGATE_FREQUENCY == 512
60 #define HFF_PRESCALER 16
61 #elif AHRS_PROPAGATE_FREQUENCY == 500
62 #define HFF_PRESCALER 10
63 #elif AHRS_PROPAGATE_FREQUENCY == 200
64 #define HFF_PRESCALER 6
66 #error "HFF_PRESCALER not set, needs to be a divisor of AHRS_PROPAGATE_FREQUENCY"
71 #define HFF_FREQ (AHRS_PROPAGATE_FREQUENCY / HFF_PRESCALER)
72 #define HFF_DT (1./HFF_FREQ)
75 #define HFF_INIT_PXX 1.
77 #ifndef HFF_ACCEL_NOISE
78 #define HFF_ACCEL_NOISE 0.5
80 #define HFF_Q HFF_ACCEL_NOISE
81 #define HFF_Qdotdot HFF_ACCEL_NOISE
88 #define HFF_R_POS_MIN 3.
91 #ifndef HFF_R_GPS_SPEED
92 #define HFF_R_GPS_SPEED 2.
94 #ifndef HFF_R_GPS_SPEED_MIN
95 #define HFF_R_GPS_SPEED_MIN 0.25
98 #ifndef HFF_UPDATE_GPS_SPEED
99 #define HFF_UPDATE_GPS_SPEED TRUE
102 #ifndef HFF_LOWPASS_CUTOFF_FREQUENCY
103 #define HFF_LOWPASS_CUTOFF_FREQUENCY 14
106 #if HFF_LOWPASS_CUTOFF_FREQUENCY < 8
107 #error "It is not allowed to use a cutoff frequency lower than 8Hz due to overflow issues."
142 #define HFF_Qbiasbias 1e-7
154 #define GPS_LAG_N ((int) (GPS_LAG * HFF_FREQ + 0.5))
156 #define GPS_DT_N ((int) (HFF_FREQ / 4))
158 #define GPS_LAG_TOLERANCE 0.08
159 #define GPS_LAG_TOL_N ((int) (GPS_LAG_TOLERANCE * HFF_FREQ + 0.5))
165 #define MAX_PP_STEPS 6
168 #define ACC_BUF_MAXN (GPS_LAG_N+10)
169 #define INC_ACC_IDX(idx) { idx = (idx + 1) < ACC_BUF_MAXN ? (idx + 1) : 0; }
174 static unsigned int acc_buf_r;
175 static unsigned int acc_buf_w;
176 static unsigned int acc_buf_n;
182 #define HFF_RB_MAXN ((int) (GPS_LAG * 4))
183 #define INC_RB_POINTER(ptr) { \
184 if (ptr == &hff_rb[HFF_RB_MAXN-1]) \
209 #define HFF_LOST_LIMIT 1000
214 static void hff_get_past_accel(
unsigned int back_n);
215 static void hff_rb_put_state(
struct HfilterFloat *source);
216 static void hff_rb_drop_last(
void);
220 static void hff_init_x(
float init_x,
float init_xdot,
float init_xbias);
221 static void hff_init_y(
float init_y,
float init_ydot,
float init_ybias);
232 #if PERIODIC_TELEMETRY
234 static void send_hff(
struct transport_tx *trans,
struct link_device *
dev)
236 pprz_msg_send_HFF(trans, dev, AC_ID,
249 pprz_msg_send_HFF_DBG(trans, dev, AC_ID,
263 static void send_hff_gps(
struct transport_tx *trans,
struct link_device *
dev)
265 pprz_msg_send_HFF_GPS(trans, dev, AC_ID,
274 void hff_init(
float init_x,
float init_xdot,
float init_y,
float init_ydot)
286 hff_rb_last = hff_rb;
291 printf(
"GPS_LAG: %f\n", GPS_LAG);
292 printf(
"GPS_LAG_N: %d\n", GPS_LAG_N);
293 printf(
"GPS_DT_N: %d\n", GPS_DT_N);
294 printf(
"HFF_DT: %f\n",
HFF_DT);
295 printf(
"GPS_LAG_TOL_N: %i\n", GPS_LAG_TOL_N);
311 #if PERIODIC_TELEMETRY
324 static void hff_init_x(
float init_x,
float init_xdot,
float init_xbias)
338 static void hff_init_y(
float init_y,
float init_ydot,
float init_ybias)
353 static void hff_store_accel_ltp(
float x,
float y)
355 past_accel[acc_buf_w].x =
x;
356 past_accel[acc_buf_w].y =
y;
357 INC_ACC_IDX(acc_buf_w);
359 if (acc_buf_n < ACC_BUF_MAXN) {
362 INC_ACC_IDX(acc_buf_r);
367 static void hff_get_past_accel(
unsigned int back_n)
370 if (back_n > acc_buf_n) {
371 PRINT_DBG(1, (
"Cannot go back %d steps, going back only %d instead!\n", back_n, acc_buf_n));
373 }
else if (back_n == 0) {
374 PRINT_DBG(1, (
"Cannot go back zero steps!\n"));
377 if ((
int)(acc_buf_w - back_n) < 0) {
378 i = acc_buf_w - back_n + ACC_BUF_MAXN;
380 i = acc_buf_w - back_n;
384 PRINT_DBG(3, (
"get past accel. buf_n: %2d \tbuf_w: %2d \tback_n: %2d \ti: %2d \txdd: %f \tydd: %f\n", acc_buf_n,
388 static void hff_rb_put_state(
struct HfilterFloat *source)
391 hff_set_state(hff_rb_put, source);
396 INC_RB_POINTER(hff_rb_put);
402 INC_RB_POINTER(hff_rb_last);
407 static void hff_rb_drop_last(
void)
410 INC_RB_POINTER(hff_rb_last);
413 PRINT_DBG(2, (
"hff ringbuffer empty!\n"));
431 dest->
xP[i][j] = source->
xP[i][j];
432 dest->
yP[i][j] = source->
yP[i][j];
437 static void hff_propagate_past(
struct HfilterFloat *filt_past)
439 PRINT_DBG(1, (
"enter propagate past: %d\n", hff_past->lag_counter));
441 for (
int i = 0; i < MAX_PP_STEPS; i++) {
442 if (hff_past->lag_counter > 0) {
443 hff_get_past_accel(hff_past->lag_counter);
444 PRINT_DBG(2, (
"propagate past: %d\n", hff_past->lag_counter));
447 hff_past->lag_counter--;
455 hff_rb_put_state(hff_past);
459 if (hff_past == &hff_rb[HFF_RB_MAXN - 1]) {
460 hff_rb[0].lag_counter++;
468 if (hff_past->lag_counter == 0) {
469 hff_set_state(&
hff, hff_past);
492 hff_propagate_past(hff_rb_last);
530 hff_rb_put_state(&
hff);
558 if (GPS_LAG_N == 0) {
564 #if HFF_UPDATE_GPS_SPEED
580 #if HFF_UPDATE_GPS_SPEED
586 hff_propagate_past(hff_rb_last);
589 PRINT_DBG(2, (
"try next saved state\n"));
642 filt->
x = filt->
x + filt->
xdot * dt;
645 const float FPF00 = filt->
xP[0][0] + dt * (filt->
xP[1][0] + filt->
xP[0][1] + dt * filt->
xP[1][1]);
646 const float FPF01 = filt->
xP[0][1] + dt * (filt->
xP[1][1] - filt->
xP[0][2] - dt * filt->
xP[1][2]);
647 const float FPF02 = filt->
xP[0][2] + dt * (filt->
xP[1][2]);
648 const float FPF10 = filt->
xP[1][0] + dt * (-filt->
xP[2][0] + filt->
xP[1][1] - dt * filt->
xP[2][1]);
649 const float FPF11 = filt->
xP[1][1] + dt * (-filt->
xP[2][1] - filt->
xP[1][2] + dt * filt->
xP[2][2]);
650 const float FPF12 = filt->
xP[1][2] + dt * (-filt->
xP[2][2]);
651 const float FPF20 = filt->
xP[2][0] + dt * (filt->
xP[2][1]);
652 const float FPF21 = filt->
xP[2][1] + dt * (-filt->
xP[2][2]);
653 const float FPF22 = filt->
xP[2][2];
655 filt->
xP[0][0] = FPF00 +
HFF_Q * dt * dt / 2.;
656 filt->
xP[0][1] = FPF01;
657 filt->
xP[0][2] = FPF02;
658 filt->
xP[1][0] = FPF10;
660 filt->
xP[1][2] = FPF12;
661 filt->
xP[2][0] = FPF20;
662 filt->
xP[2][1] = FPF21;
670 filt->
y = filt->
y + dt * filt->
ydot;
673 const float FPF00 = filt->
yP[0][0] + dt * (filt->
yP[1][0] + filt->
yP[0][1] + dt * filt->
yP[1][1]);
674 const float FPF01 = filt->
yP[0][1] + dt * (filt->
yP[1][1] - filt->
yP[0][2] - dt * filt->
yP[1][2]);
675 const float FPF02 = filt->
yP[0][2] + dt * (filt->
yP[1][2]);
676 const float FPF10 = filt->
yP[1][0] + dt * (-filt->
yP[2][0] + filt->
yP[1][1] - dt * filt->
yP[2][1]);
677 const float FPF11 = filt->
yP[1][1] + dt * (-filt->
yP[2][1] - filt->
yP[1][2] + dt * filt->
yP[2][2]);
678 const float FPF12 = filt->
yP[1][2] + dt * (-filt->
yP[2][2]);
679 const float FPF20 = filt->
yP[2][0] + dt * (filt->
yP[2][1]);
680 const float FPF21 = filt->
yP[2][1] + dt * (-filt->
yP[2][2]);
681 const float FPF22 = filt->
yP[2][2];
683 filt->
yP[0][0] = FPF00 +
HFF_Q * dt * dt / 2.;
684 filt->
yP[0][1] = FPF01;
685 filt->
yP[0][2] = FPF02;
686 filt->
yP[1][0] = FPF10;
688 filt->
yP[1][2] = FPF12;
689 filt->
yP[2][0] = FPF20;
690 filt->
yP[2][1] = FPF21;
722 const float y = x_meas - filt->
x;
723 const float S = filt->
xP[0][0] + Rpos;
724 const float K1 = filt->
xP[0][0] * 1 / S;
725 const float K2 = filt->
xP[1][0] * 1 / S;
726 const float K3 = filt->
xP[2][0] * 1 / S;
728 filt->
x = filt->
x + K1 * y;
732 const float P11 = (1. - K1) * filt->
xP[0][0];
733 const float P12 = (1. - K1) * filt->
xP[0][1];
734 const float P13 = (1. - K1) * filt->
xP[0][2];
735 const float P21 = -K2 * filt->
xP[0][0] + filt->
xP[1][0];
736 const float P22 = -K2 * filt->
xP[0][1] + filt->
xP[1][1];
737 const float P23 = -K2 * filt->
xP[0][2] + filt->
xP[1][2];
738 const float P31 = -K3 * filt->
xP[0][0] + filt->
xP[2][0];
739 const float P32 = -K3 * filt->
xP[0][1] + filt->
xP[2][1];
740 const float P33 = -K3 * filt->
xP[0][2] + filt->
xP[2][2];
742 filt->
xP[0][0] = P11;
743 filt->
xP[0][1] = P12;
744 filt->
xP[0][2] = P13;
745 filt->
xP[1][0] = P21;
746 filt->
xP[1][1] = P22;
747 filt->
xP[1][2] = P23;
748 filt->
xP[2][0] = P31;
749 filt->
xP[2][1] = P32;
750 filt->
xP[2][2] = P33;
757 const float y = y_meas - filt->
y;
758 const float S = filt->
yP[0][0] + Rpos;
759 const float K1 = filt->
yP[0][0] * 1 / S;
760 const float K2 = filt->
yP[1][0] * 1 / S;
761 const float K3 = filt->
yP[2][0] * 1 / S;
763 filt->
y = filt->
y + K1 * y;
767 const float P11 = (1. - K1) * filt->
yP[0][0];
768 const float P12 = (1. - K1) * filt->
yP[0][1];
769 const float P13 = (1. - K1) * filt->
yP[0][2];
770 const float P21 = -K2 * filt->
yP[0][0] + filt->
yP[1][0];
771 const float P22 = -K2 * filt->
yP[0][1] + filt->
yP[1][1];
772 const float P23 = -K2 * filt->
yP[0][2] + filt->
yP[1][2];
773 const float P31 = -K3 * filt->
yP[0][0] + filt->
yP[2][0];
774 const float P32 = -K3 * filt->
yP[0][1] + filt->
yP[2][1];
775 const float P33 = -K3 * filt->
yP[0][2] + filt->
yP[2][2];
777 filt->
yP[0][0] = P11;
778 filt->
yP[0][1] = P12;
779 filt->
yP[0][2] = P13;
780 filt->
yP[1][0] = P21;
781 filt->
yP[1][1] = P22;
782 filt->
yP[1][2] = P23;
783 filt->
yP[2][0] = P31;
784 filt->
yP[2][1] = P32;
785 filt->
yP[2][2] = P33;
815 if (Rvel.
x >= 0.f || Rvel.
y >= 0.f) {
824 const float yd = vel - filt->
xdot;
825 const float S = filt->
xP[1][1] + Rvel;
826 const float K1 = filt->
xP[0][1] * 1 / S;
827 const float K2 = filt->
xP[1][1] * 1 / S;
828 const float K3 = filt->
xP[2][1] * 1 / S;
830 filt->
x = filt->
x + K1 * yd;
834 const float P11 = -K1 * filt->
xP[1][0] + filt->
xP[0][0];
835 const float P12 = -K1 * filt->
xP[1][1] + filt->
xP[0][1];
836 const float P13 = -K1 * filt->
xP[1][2] + filt->
xP[0][2];
837 const float P21 = (1. - K2) * filt->
xP[1][0];
838 const float P22 = (1. - K2) * filt->
xP[1][1];
839 const float P23 = (1. - K2) * filt->
xP[1][2];
840 const float P31 = -K3 * filt->
xP[1][0] + filt->
xP[2][0];
841 const float P32 = -K3 * filt->
xP[1][1] + filt->
xP[2][1];
842 const float P33 = -K3 * filt->
xP[1][2] + filt->
xP[2][2];
844 filt->
xP[0][0] = P11;
845 filt->
xP[0][1] = P12;
846 filt->
xP[0][2] = P13;
847 filt->
xP[1][0] = P21;
848 filt->
xP[1][1] = P22;
849 filt->
xP[1][2] = P23;
850 filt->
xP[2][0] = P31;
851 filt->
xP[2][1] = P32;
852 filt->
xP[2][2] = P33;
859 const float yd = vel - filt->
ydot;
860 const float S = filt->
yP[1][1] + Rvel;
861 const float K1 = filt->
yP[0][1] * 1 / S;
862 const float K2 = filt->
yP[1][1] * 1 / S;
863 const float K3 = filt->
yP[2][1] * 1 / S;
865 filt->
y = filt->
y + K1 * yd;
869 const float P11 = -K1 * filt->
yP[1][0] + filt->
yP[0][0];
870 const float P12 = -K1 * filt->
yP[1][1] + filt->
yP[0][1];
871 const float P13 = -K1 * filt->
yP[1][2] + filt->
yP[0][2];
872 const float P21 = (1. - K2) * filt->
yP[1][0];
873 const float P22 = (1. - K2) * filt->
yP[1][1];
874 const float P23 = (1. - K2) * filt->
yP[1][2];
875 const float P31 = -K3 * filt->
yP[1][0] + filt->
yP[2][0];
876 const float P32 = -K3 * filt->
yP[1][1] + filt->
yP[2][1];
877 const float P33 = -K3 * filt->
yP[1][2] + filt->
yP[2][2];
879 filt->
yP[0][0] = P11;
880 filt->
yP[0][1] = P12;
881 filt->
yP[0][2] = P13;
882 filt->
yP[1][0] = P21;
883 filt->
yP[1][1] = P22;
884 filt->
yP[1][2] = P23;
885 filt->
yP[2][0] = P31;
886 filt->
yP[2][1] = P32;
887 filt->
yP[2][2] = P33;
static void hff_init_y(float init_y, float init_ydot, float init_ybias)
static struct Int32Vect3 * stateGetAccelBody_i(void)
Get acceleration in Body coordinates (int).
static void hff_propagate_y(struct HfilterFloat *filt, float dt)
uint32_t pacc
position accuracy in cm
Horizontal filter (x,y) to estimate position and velocity.
#define AHRS_PROPAGATE_FREQUENCY
static int hff_ps_counter
counter for hff propagation
static int16_t lag_counter_err
by how many steps the estimated GPS validity point in time differed from GPS_LAG_N ...
Periodic telemetry system header (includes downlink utility and generated code).
static struct Int32RMat * stateGetNedToBodyRMat_i(void)
Get vehicle body attitude rotation matrix (int).
static void hff_update_y(struct HfilterFloat *filt, float y_meas, float Rpos)
Simple first order low pass filter with bilinear transform.
static float hff_ydd_meas
void hff_realign(struct FloatVect2 pos, struct FloatVect2 vel)
Butterworth2LowPass_int filter_y
#define HFF_LOWPASS_CUTOFF_FREQUENCY
static uint16_t hff_lost_limit
static void init_butterworth_2_low_pass_int(Butterworth2LowPass_int *filter, float cut_off, float sample_time, int32_t value)
Init a second order Butterworth filter.
static void hff_update_ydot(struct HfilterFloat *filt, float vel, float Rvel)
static void hff_init_x(float init_x, float init_xdot, float init_xbias)
uint32_t sacc
speed accuracy in cm/s
static void hff_update_x(struct HfilterFloat *filt, float x_meas, float Rpos)
#define PRINT_DBG(_l, _p)
static void send_hff_debug(struct transport_tx *trans, struct link_device *dev)
void hff_update_vel(struct FloatVect2 vel, struct FloatVect2 Rvel)
static uint16_t hff_lost_counter
Device independent GPS code (interface)
#define ACCEL_FLOAT_OF_BFP(_ai)
#define DefaultPeriodic
Set default periodic telemetry.
static int32_t update_butterworth_2_low_pass_int(Butterworth2LowPass_int *filter, int32_t value)
Update second order Butterworth low pass filter state with a new value(fixed point version)...
static uint16_t hff_speed_lost_counter
static float hff_xdd_meas
Inertial Measurement Unit interface.
float yP[HFF_STATE_SIZE][HFF_STATE_SIZE]
void hff_update_pos(struct FloatVect2 pos, struct FloatVect2 Rpos)
Update position.
static const struct usb_device_descriptor dev
static int past_save_counter
static void hff_update_xdot(struct HfilterFloat *filt, float vel, float Rvel)
void hff_init(float init_x, float init_xdot, float init_y, float init_ydot)
API to get/set the generic vehicle states.
#define HFF_R_GPS_SPEED_MIN
void int32_rmat_transp_vmult(struct Int32Vect3 *vb, struct Int32RMat *m_b2a, struct Int32Vect3 *va)
rotate 3D vector by transposed rotation matrix.
static void send_hff(struct transport_tx *trans, struct link_device *dev)
Butterworth2LowPass_int filter_x
void hff_update_gps(struct FloatVect2 *pos_ned, struct FloatVect2 *speed_ned)
#define HFF_INIT_PXX
initial covariance diagonal
static void hff_propagate_x(struct HfilterFloat *filt, float dt)
Propagate the filter in time.
struct GpsState gps
global GPS state
static int hff_rb_n
ringbuffer fill count
struct HfilterFloat * hff_rb_last
ringbuffer read pointer
Butterworth2LowPass_int filter_z
int8_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint8_t _id, telemetry_cb _cb)
Register a telemetry callback function.
float xP[HFF_STATE_SIZE][HFF_STATE_SIZE]
static int16_t save_counter
counts down the propagation steps until the filter state is saved again