Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
hf_float.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2008-2009 Antoine Drouin <poinix@gmail.com>
3 * Copyright (C) 2009 Felix Ruess <felix.ruess@gmail.com>
4 *
5 * This file is part of paparazzi.
6 *
7 * paparazzi is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
11 *
12 * paparazzi is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with paparazzi; see the file COPYING. If not, write to
19 * the Free Software Foundation, 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
21 */
22
31#include "modules/imu/imu.h"
32#include "state.h"
33#include "modules/gps/gps.h"
34#include <stdlib.h>
36#include "generated/airframe.h"
37
38#if PERIODIC_TELEMETRY
40#endif
41
42#ifdef SITL
43#include <stdio.h>
44#define DBG_LEVEL 1
45#define PRINT_DBG(_l, _p) { \
46 if (DBG_LEVEL >= _l) \
47 printf _p; \
48 }
49#else
50#define PRINT_DBG(_l, _p) {}
51#endif
52
53
54#ifndef AHRS_PROPAGATE_FREQUENCY
55#define AHRS_PROPAGATE_FREQUENCY PERIODIC_FREQUENCY
56#endif
57
58#ifndef HFF_PRESCALER
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
65#else
66#error "HFF_PRESCALER not set, needs to be a divisor of AHRS_PROPAGATE_FREQUENCY"
67#endif
68#endif
69
71#define HFF_FREQ (AHRS_PROPAGATE_FREQUENCY / HFF_PRESCALER)
72#define HFF_DT (1./HFF_FREQ)
73
75#define HFF_INIT_PXX 1.
77#ifndef HFF_ACCEL_NOISE
78#define HFF_ACCEL_NOISE 0.5
79#endif
80#define HFF_Q HFF_ACCEL_NOISE
81#define HFF_Qdotdot HFF_ACCEL_NOISE
82
83//TODO: proper measurement noise
84#ifndef HFF_R_POS
85#define HFF_R_POS 8.
86#endif
87#ifndef HFF_R_POS_MIN
88#define HFF_R_POS_MIN 3.
89#endif
90
91#ifndef HFF_R_GPS_SPEED
92#define HFF_R_GPS_SPEED 2.
93#endif
94#ifndef HFF_R_GPS_SPEED_MIN
95#define HFF_R_GPS_SPEED_MIN 0.25
96#endif
97
98#ifndef HFF_UPDATE_GPS_SPEED
99#define HFF_UPDATE_GPS_SPEED TRUE
100#endif
101
102#ifndef HFF_LOWPASS_CUTOFF_FREQUENCY
103#define HFF_LOWPASS_CUTOFF_FREQUENCY 14
104#endif
105
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."
108#endif
109
110/* low pass filter variables */
114
115/* gps measurement noise */
117
118/*
119 X_x = [ x xdot xbias ]
120 X_y = [ y ydot ybias ]
121*/
122
123/* output filter states */
125
126/* last acceleration measurement */
127static float hff_xdd_meas = 0;
128static float hff_ydd_meas = 0;
129
130/* last velocity measurement */
131static float hff_xd_meas = 0;
132static float hff_yd_meas = 0;
133
134/* last position measurement */
135static float hff_x_meas = 0;
136static float hff_y_meas = 0;
137
139static int hff_ps_counter;
140
141/* default parameters */
142#define HFF_Qbiasbias 1e-7
143
144/*
145 * For GPS lag compensation
146 *
147 */
148#ifdef GPS_LAG
149/*
150 * GPS_LAG is defined in seconds in airframe file
151 */
152
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))
160
161/* maximum number of past propagation steps to rerun per ap cycle
162 * make sure GPS_LAG_N/MAX_PP_STEPS < 128
163 * GPS_LAG_N/MAX_PP_STEPS/512 = seconds until re-propagation catches up with the present
164 */
165#define MAX_PP_STEPS 6
166
167/* variables for mean accel buffer */
168#define ACC_BUF_MAXN (GPS_LAG_N+10)
169#define INC_ACC_IDX(idx) { idx = (idx + 1) < ACC_BUF_MAXN ? (idx + 1) : 0; }
170
173
174static unsigned int acc_buf_r;
175static unsigned int acc_buf_w;
176static unsigned int acc_buf_n;
177
178
179/*
180 * stuff for ringbuffer to store past filter states
181 */
182#define HFF_RB_MAXN ((int) (GPS_LAG * 4))
183#define INC_RB_POINTER(ptr) { \
184 if (ptr == &hff_rb[HFF_RB_MAXN-1]) \
185 ptr = hff_rb; \
186 else \
187 ptr++; \
188 }
189
192struct HfilterFloat *hff_rb_put;
193#endif /* GPS_LAG */
194
196static int hff_rb_n;
197
198
201
205#define SAVE_NOW 0
206#define SAVING -1
207#define SAVE_DONE -2
208
209#define HFF_LOST_LIMIT 1000
212
213#ifdef GPS_LAG
214static void hff_get_past_accel(unsigned int back_n);
215static void hff_rb_put_state(struct HfilterFloat *source);
216static void hff_rb_drop_last(void);
217static void hff_set_state(struct HfilterFloat *dest, struct HfilterFloat *source);
218#endif
219
220static void hff_init_x(float init_x, float init_xdot, float init_xbias);
221static void hff_init_y(float init_y, float init_ydot, float init_ybias);
222
223static void hff_propagate_x(struct HfilterFloat *filt, float dt);
224static void hff_propagate_y(struct HfilterFloat *filt, float dt);
225
226static void hff_update_x(struct HfilterFloat *filt, float x_meas, float Rpos);
227static void hff_update_y(struct HfilterFloat *filt, float y_meas, float Rpos);
228
229static void hff_update_xdot(struct HfilterFloat *filt, float vel, float Rvel);
230static void hff_update_ydot(struct HfilterFloat *filt, float vel, float Rvel);
231
232#if PERIODIC_TELEMETRY
233
234static void send_hff(struct transport_tx *trans, struct link_device *dev)
235{
237 &hff.x,
238 &hff.y,
239 &hff.xdot,
240 &hff.ydot,
241 &hff.xdotdot,
242 &hff.ydotdot,
243 &hff.xbias,
244 &hff.ybias);
245}
246
247static void send_hff_debug(struct transport_tx *trans, struct link_device *dev)
248{
250 &hff_x_meas,
251 &hff_y_meas,
254 &hff.xP[0][0],
255 &hff.yP[0][0],
256 &hff.xP[1][1],
257 &hff.yP[1][1],
258 &hff.xP[2][2],
259 &hff.yP[2][2]);
260}
261
262#ifdef GPS_LAG
263static void send_hff_gps(struct transport_tx *trans, struct link_device *dev)
264{
268 &save_counter);
269}
270#endif
271
272#endif
273
274void hff_init(float init_x, float init_xdot, float init_y, float init_ydot)
275{
280#ifdef GPS_LAG
281 /* init buffer for past mean accel values */
282 acc_buf_r = 0;
283 acc_buf_w = 0;
284 acc_buf_n = 0;
287 hff_rb_last->rollback = false;
290#ifdef SITL
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);
296#endif
297#else
298 hff_rb_last = &hff;
299 hff.lag_counter = 0;
300#endif
301 hff_rb_n = 0;
302 hff.rollback = false;
303 lag_counter_err = 0;
304 save_counter = -1;
309 hff_ps_counter = 0;
310
311#if PERIODIC_TELEMETRY
314#ifdef GPS_LAG
316#endif
317#endif
318
322}
323
324static void hff_init_x(float init_x, float init_xdot, float init_xbias)
325{
326 hff.x = init_x;
329 int i, j;
330 for (i = 0; i < HFF_STATE_SIZE; i++) {
331 for (j = 0; j < HFF_STATE_SIZE; j++) {
332 hff.xP[i][j] = 0.;
333 }
334 hff.xP[i][i] = HFF_INIT_PXX;
335 }
336}
337
338static void hff_init_y(float init_y, float init_ydot, float init_ybias)
339{
340 hff.y = init_y;
343 int i, j;
344 for (i = 0; i < HFF_STATE_SIZE; i++) {
345 for (j = 0; j < HFF_STATE_SIZE; j++) {
346 hff.yP[i][j] = 0.;
347 }
348 hff.yP[i][i] = HFF_INIT_PXX;
349 }
350}
351
352#ifdef GPS_LAG
353static void hff_store_accel_ltp(float x, float y)
354{
358
359 if (acc_buf_n < ACC_BUF_MAXN) {
360 acc_buf_n++;
361 } else {
363 }
364}
365
366/* get the accel values from back_n steps ago */
367static void hff_get_past_accel(unsigned int back_n)
368{
369 int i;
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"));
375 return;
376 }
377 if ((int)(acc_buf_w - back_n) < 0) {
379 } else {
380 i = acc_buf_w - back_n;
381 }
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,
386}
387
388static void hff_rb_put_state(struct HfilterFloat *source)
389{
390 /* copy state from source into buffer */
391 hff_set_state(hff_rb_put, source);
392 hff_rb_put->lag_counter = 0;
393 hff_rb_put->rollback = false;
394
395 /* forward write pointer */
397
398 /* increase fill count and forward last pointer if neccessary */
399 if (hff_rb_n < HFF_RB_MAXN) {
400 hff_rb_n++;
401 } else {
403 }
404 PRINT_DBG(2, ("put state. fill count now: %d\n", hff_rb_n));
405}
406
407static void hff_rb_drop_last(void)
408{
409 if (hff_rb_n > 0) {
411 hff_rb_n--;
412 } else {
413 PRINT_DBG(2, ("hff ringbuffer empty!\n"));
415 hff_rb_last->rollback = false;
416 }
417 PRINT_DBG(2, ("drop last state. fill count now: %d\n", hff_rb_n));
418}
419
420/* copy source state to dest state */
421static void hff_set_state(struct HfilterFloat *dest, struct HfilterFloat *source)
422{
423 dest->x = source->x;
424 dest->xdot = source->xdot;
425 dest->xdotdot = source->xdotdot;
426 dest->y = source->y;
427 dest->ydot = source->ydot;
428 dest->ydotdot = source->ydotdot;
429 for (int i = 0; i < HFF_STATE_SIZE; i++) {
430 for (int j = 0; j < HFF_STATE_SIZE; j++) {
431 dest->xP[i][j] = source->xP[i][j];
432 dest->yP[i][j] = source->yP[i][j];
433 }
434 }
435}
436
437static void hff_propagate_past(struct HfilterFloat *filt_past)
438{
439 PRINT_DBG(1, ("enter propagate past: %d\n", hff_past->lag_counter));
440 /* run max MAX_PP_STEPS propagation steps */
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--;
448
449 if (past_save_counter > 0) {
451 PRINT_DBG(2, ("dec past_save_counter: %d\n", past_save_counter));
452 } else if (past_save_counter == SAVE_NOW) {
453 /* next GPS measurement valid at this state -> save */
454 PRINT_DBG(2, ("save past state\n"));
457 } else if (past_save_counter == SAVING) {
458 /* increase lag counter on if next state is already saved */
459 if (hff_past == &hff_rb[HFF_RB_MAXN - 1]) {
460 hff_rb[0].lag_counter++;
461 } else {
462 (hff_past + 1)->lag_counter++;
463 }
464 }
465 }
466
467 /* finished re-propagating the past values */
468 if (hff_past->lag_counter == 0) {
472 break;
473 }
474 }
475}
476#endif /* GPS_LAG */
477
478
480{
483 }
484
487 }
488
489#ifdef GPS_LAG
490 /* continue re-propagating to catch up with the present */
491 if (hff_rb_last->rollback) {
493 }
494#endif
495
496 /* rotate imu accel measurement to body frame and filter */
501
502 /* propagate current state if it is time */
504 hff_ps_counter = 0;
506 struct Int32RMat *ltp_to_body_rmat = stateGetNedToBodyRMat_i();
510
511#ifdef GPS_LAG
513#endif
515 /*
516 * propagate current state
517 */
520
521#ifdef GPS_LAG
522 /* increase lag counter on last saved state */
523 if (hff_rb_n > 0) {
525 }
526
527 /* save filter state if needed */
528 if (save_counter == 0) {
529 PRINT_DBG(1, ("save current state\n"));
531 save_counter = -1;
532 } else if (save_counter > 0) {
533 save_counter--;
534 }
535#endif
536 }
537 }
539}
540
542{
544
545#if USE_GPS_ACC4R
546 Rgps_pos = (float) gps.pacc / 100.;
547 if (Rgps_pos < HFF_R_POS_MIN) {
549 }
550
551 Rgps_vel = (float) gps.sacc / 100.;
554 }
555#endif
556
557#ifdef GPS_LAG
558 if (GPS_LAG_N == 0) {
559#endif
560
561 /* update filter state with measurement */
564#if HFF_UPDATE_GPS_SPEED
567#endif
568
569
570#ifdef GPS_LAG
571 } else if (hff_rb_n > 0) {
572 /* roll back if state was saved approx when GPS was valid */
574 PRINT_DBG(2, ("update. rb_n: %d lag_counter: %d lag_cnt_err: %d\n", hff_rb_n, hff_rb_last->lag_counter,
577 hff_rb_last->rollback = true;
580#if HFF_UPDATE_GPS_SPEED
583#endif
584 past_save_counter = GPS_DT_N - 1; // + lag_counter_err;
585 PRINT_DBG(2, ("gps updated. past_save_counter: %d\n", past_save_counter));
587 } else if (lag_counter_err >= GPS_DT_N - (GPS_LAG_TOL_N + 1)) {
588 /* apparently missed a GPS update, try next saved state */
589 PRINT_DBG(2, ("try next saved state\n"));
592 }
593 } else if (save_counter < 0) {
594 /* ringbuffer empty -> save output filter state at next GPS validity point in time */
596 PRINT_DBG(2, ("rb empty, save counter set: %d\n", save_counter));
597 }
598#endif /* GPS_LAG */
599}
600
601
602void hff_realign(struct FloatVect2 pos, struct FloatVect2 vel)
603{
604 hff.x = pos.x;
605 hff.y = pos.y;
606 hff.xdot = vel.x;
607 hff.ydot = vel.y;
608 hff.xbias = 0.f;
609 hff.ybias = 0.f;
610#ifdef GPS_LAG
611 while (hff_rb_n > 0) {
613 }
614 save_counter = -1;
616#endif
617}
618
619
638static void hff_propagate_x(struct HfilterFloat *filt, float dt)
639{
640 /* update state */
641 filt->xdotdot = hff_xdd_meas - filt->xbias;
642 filt->x = filt->x + filt->xdot * dt;// + filt->xdotdot * dt * dt / 2;
643 filt->xdot = filt->xdot + dt * filt->xdotdot;
644 /* update covariance */
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];
654
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;
659 filt->xP[1][1] = FPF11 + HFF_Qdotdot * dt;
660 filt->xP[1][2] = FPF12;
661 filt->xP[2][0] = FPF20;
662 filt->xP[2][1] = FPF21;
663 filt->xP[2][2] = FPF22 + HFF_Qbiasbias;
664}
665
666static void hff_propagate_y(struct HfilterFloat *filt, float dt)
667{
668 /* update state */
669 filt->ydotdot = hff_ydd_meas - filt->ybias;
670 filt->y = filt->y + dt * filt->ydot;// + filt->ydotdot * dt * dt / 2;
671 filt->ydot = filt->ydot + dt * filt->ydotdot;
672 /* update covariance */
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];
682
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;
687 filt->yP[1][1] = FPF11 + HFF_Qdotdot * dt;
688 filt->yP[1][2] = FPF12;
689 filt->yP[2][0] = FPF20;
690 filt->yP[2][1] = FPF21;
691 filt->yP[2][2] = FPF22 + HFF_Qbiasbias;
692}
693
694
711void hff_update_pos(struct FloatVect2 pos, struct FloatVect2 Rpos)
712{
714 hff_update_x(&hff, pos.x, Rpos.x);
715 hff_update_y(&hff, pos.y, Rpos.y);
716}
717
718static void hff_update_x(struct HfilterFloat *filt, float x_meas, float Rpos)
719{
721
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;
727
728 filt->x = filt->x + K1 * y;
729 filt->xdot = filt->xdot + K2 * y;
730 filt->xbias = filt->xbias + K3 * y;
731
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];
741
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;
751}
752
753static void hff_update_y(struct HfilterFloat *filt, float y_meas, float Rpos)
754{
756
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;
762
763 filt->y = filt->y + K1 * y;
764 filt->ydot = filt->ydot + K2 * y;
765 filt->ybias = filt->ybias + K3 * y;
766
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];
776
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;
786}
787
788
789/*
790 *
791 * Update velocity
792 *
793 * H = [0 1 0];
794 * R = 0.1;
795 * // state residual
796 * yd = vx - H * Xm;
797 * // covariance residual
798 * S = H*Pm*H' + R;
799 * // kalman gain
800 * K = Pm*H'*inv(S);
801 * // update state
802 * Xp = Xm + K*yd;
803 * // update covariance
804 * Pp = Pm - K*H*Pm;
805*/
806void hff_update_vel(struct FloatVect2 vel, struct FloatVect2 Rvel)
807{
808 if (Rvel.x >= 0.f) {
809 hff_update_xdot(&hff, vel.x, Rvel.x);
810 }
811 if (Rvel.y >= 0.f) {
812 hff_update_ydot(&hff, vel.y, Rvel.y);
813 }
814
815 if (Rvel.x >= 0.f || Rvel.y >= 0.f) {
817 }
818}
819
820static void hff_update_xdot(struct HfilterFloat *filt, float vel, float Rvel)
821{
822 hff_xd_meas = vel;
823
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;
829
830 filt->x = filt->x + K1 * yd;
831 filt->xdot = filt->xdot + K2 * yd;
832 filt->xbias = filt->xbias + K3 * yd;
833
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];
843
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;
853}
854
855static void hff_update_ydot(struct HfilterFloat *filt, float vel, float Rvel)
856{
857 hff_yd_meas = vel;
858
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;
864
865 filt->y = filt->y + K1 * yd;
866 filt->ydot = filt->ydot + K2 * yd;
867 filt->ybias = filt->ybias + K3 * yd;
868
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];
878
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;
888}
struct GpsState gps
global GPS state
Definition gps.c:74
Device independent GPS code (interface)
uint32_t sacc
speed accuracy in cm/s
Definition gps.h:103
uint32_t pacc
position accuracy in cm
Definition gps.h:100
void int32_rmat_transp_vmult(struct Int32Vect3 *vb, struct Int32RMat *m_b2a, struct Int32Vect3 *va)
rotate 3D vector by transposed rotation matrix.
#define ACCEL_FLOAT_OF_BFP(_ai)
rotation matrix
static struct Int32RMat * stateGetNedToBodyRMat_i(void)
Get vehicle body attitude rotation matrix (int).
Definition state.h:1282
static struct Int32Vect3 * stateGetAccelBody_i(void)
Get acceleration in Body coordinates (int).
Definition state.h:1094
#define HFF_Qdotdot
Definition hf_float.c:81
#define HFF_Qbiasbias
Definition hf_float.c:142
#define HFF_DT
Definition hf_float.c:72
#define HFF_R_GPS_SPEED
Definition hf_float.c:92
static int past_save_counter
Definition hf_float.c:204
struct HfilterFloat * hff_rb_last
ringbuffer read pointer
Definition hf_float.c:195
#define PRINT_DBG(_l, _p)
Definition hf_float.c:50
static float hff_y_meas
Definition hf_float.c:136
#define HFF_R_POS_MIN
Definition hf_float.c:88
static void hff_update_ydot(struct HfilterFloat *filt, float vel, float Rvel)
Definition hf_float.c:855
void hff_init(float init_x, float init_xdot, float init_y, float init_ydot)
Definition hf_float.c:274
Butterworth2LowPass_int filter_z
Definition hf_float.c:113
struct HfilterFloat hff
Definition hf_float.c:124
static uint16_t hff_lost_limit
Definition hf_float.c:210
#define SAVE_DONE
Definition hf_float.c:207
static void hff_update_x(struct HfilterFloat *filt, float x_meas, float Rpos)
Definition hf_float.c:718
#define HFF_LOST_LIMIT
Definition hf_float.c:209
static float hff_yd_meas
Definition hf_float.c:132
static void hff_init_y(float init_y, float init_ydot, float init_ybias)
Definition hf_float.c:338
static float hff_xd_meas
Definition hf_float.c:131
static int16_t lag_counter_err
by how many steps the estimated GPS validity point in time differed from GPS_LAG_N
Definition hf_float.c:200
static void hff_propagate_x(struct HfilterFloat *filt, float dt)
Propagate the filter in time.
Definition hf_float.c:638
static float hff_ydd_meas
Definition hf_float.c:128
Butterworth2LowPass_int filter_y
Definition hf_float.c:112
#define HFF_LOWPASS_CUTOFF_FREQUENCY
Definition hf_float.c:103
static void hff_update_y(struct HfilterFloat *filt, float y_meas, float Rpos)
Definition hf_float.c:753
void hff_update_gps(struct FloatVect2 *pos_ned, struct FloatVect2 *speed_ned)
Definition hf_float.c:541
static void hff_propagate_y(struct HfilterFloat *filt, float dt)
Definition hf_float.c:666
static void hff_init_x(float init_x, float init_xdot, float init_xbias)
Definition hf_float.c:324
#define AHRS_PROPAGATE_FREQUENCY
Definition hf_float.c:55
#define SAVING
Definition hf_float.c:206
static int16_t save_counter
counts down the propagation steps until the filter state is saved again
Definition hf_float.c:203
void hff_propagate(void)
Definition hf_float.c:479
#define HFF_R_GPS_SPEED_MIN
Definition hf_float.c:95
static void hff_update_xdot(struct HfilterFloat *filt, float vel, float Rvel)
Definition hf_float.c:820
void hff_update_vel(struct FloatVect2 vel, struct FloatVect2 Rvel)
Definition hf_float.c:806
#define HFF_Q
Definition hf_float.c:80
static void send_hff_debug(struct transport_tx *trans, struct link_device *dev)
Definition hf_float.c:247
static uint16_t hff_lost_counter
Definition hf_float.c:211
static void send_hff(struct transport_tx *trans, struct link_device *dev)
Definition hf_float.c:234
static float hff_xdd_meas
Definition hf_float.c:127
static float hff_x_meas
Definition hf_float.c:135
void hff_realign(struct FloatVect2 pos, struct FloatVect2 vel)
Definition hf_float.c:602
#define HFF_R_POS
Definition hf_float.c:85
#define HFF_INIT_PXX
initial covariance diagonal
Definition hf_float.c:75
static int hff_ps_counter
counter for hff propagation
Definition hf_float.c:139
#define SAVE_NOW
Definition hf_float.c:205
static int hff_rb_n
ringbuffer fill count
Definition hf_float.c:196
void hff_update_pos(struct FloatVect2 pos, struct FloatVect2 Rpos)
Update position.
Definition hf_float.c:711
float Rgps_pos
Definition hf_float.c:116
Butterworth2LowPass_int filter_x
Definition hf_float.c:111
float Rgps_vel
Definition hf_float.c:116
static uint16_t hff_speed_lost_counter
Definition hf_float.c:211
Horizontal filter (x,y) to estimate position and velocity.
float xdot
Definition hf_float.h:42
bool rollback
Definition hf_float.h:52
float yP[HFF_STATE_SIZE][HFF_STATE_SIZE]
Definition hf_float.h:50
float ydotdot
Definition hf_float.h:47
float xP[HFF_STATE_SIZE][HFF_STATE_SIZE]
Definition hf_float.h:49
float xdotdot
Definition hf_float.h:43
float xbias
Definition hf_float.h:44
float ydot
Definition hf_float.h:46
#define HFF_STATE_SIZE
Definition hf_float.h:38
uint16_t lag_counter
Definition hf_float.h:51
float ybias
Definition hf_float.h:48
Inertial Measurement Unit interface.
Simple first order low pass filter with bilinear transform.
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 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).
uint16_t foo
Definition main_demo5.c:58
API to get/set the generic vehicle states.
static const struct usb_device_descriptor dev
Definition usb_ser_hw.c:74
int8_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint8_t _id, telemetry_cb _cb)
Register a telemetry callback function.
Definition telemetry.c:51
Periodic telemetry system header (includes downlink utility and generated code).
#define DefaultPeriodic
Set default periodic telemetry.
Definition telemetry.h:66
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
short int16_t
Typedef defining 16 bit short type.
static uint8_t dest[]
Definition w5100.c:99