paparazzi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[paparazzi-commits] [4035] simple horizontal filter with GPS lag compens


From: Felix Ruess
Subject: [paparazzi-commits] [4035] simple horizontal filter with GPS lag compensation.
Date: Mon, 31 Aug 2009 18:47:02 +0000

Revision: 4035
          http://svn.sv.gnu.org/viewvc/?view=rev&root=paparazzi&revision=4035
Author:   flixr
Date:     2009-08-31 18:46:59 +0000 (Mon, 31 Aug 2009)
Log Message:
-----------
simple horizontal filter with GPS lag compensation.
include booz2_ins_hff.makefile to use the filter and define GPS_LAG in
seconds: e.g. -DGPS_LAG=0.8
removed bias estimation in hff since that was plain wrong

Modified Paths:
--------------
    paparazzi3/trunk/conf/airframes/booz2_flixr.xml
    paparazzi3/trunk/conf/autopilot/booz2_autopilot.makefile
    paparazzi3/trunk/conf/autopilot/booz2_simulator_nps.makefile
    paparazzi3/trunk/conf/messages.xml
    paparazzi3/trunk/sw/airborne/booz/booz2_ins.c
    paparazzi3/trunk/sw/airborne/booz/booz2_ins.h
    paparazzi3/trunk/sw/airborne/booz/booz2_telemetry.h
    paparazzi3/trunk/sw/airborne/booz/ins/booz2_hf_float.c
    paparazzi3/trunk/sw/airborne/booz/ins/booz2_hf_float.h

Added Paths:
-----------
    paparazzi3/trunk/conf/autopilot/subsystems/booz2_ins_hff.makefile

Modified: paparazzi3/trunk/conf/airframes/booz2_flixr.xml
===================================================================
--- paparazzi3/trunk/conf/airframes/booz2_flixr.xml     2009-08-31 18:46:44 UTC 
(rev 4034)
+++ paparazzi3/trunk/conf/airframes/booz2_flixr.xml     2009-08-31 18:46:59 UTC 
(rev 4035)
@@ -203,8 +203,9 @@
 
                include $(CFG_BOOZ)/subsystems/booz2_ahrs_cmpl.makefile
 
-               #enable horizontal filter
-               ap.CFLAGS += -DUSE_HFF -DHFF_PRESCALER=16 -DGPS_LAG=0.2
+               include $(CFG_BOOZ)/subsystems/booz2_ins_hff.makefile
+               #set GPS lag for horizontal filter
+               ap.CFLAGS += -DGPS_LAG=0.8
 
   </makefile>
 

Modified: paparazzi3/trunk/conf/autopilot/booz2_autopilot.makefile
===================================================================
--- paparazzi3/trunk/conf/autopilot/booz2_autopilot.makefile    2009-08-31 
18:46:44 UTC (rev 4034)
+++ paparazzi3/trunk/conf/autopilot/booz2_autopilot.makefile    2009-08-31 
18:46:59 UTC (rev 4035)
@@ -130,8 +130,15 @@
 
 ap.srcs += $(SRC_BOOZ)/booz2_ins.c
 ap.srcs += math/pprz_geodetic_int.c math/pprz_geodetic_float.c
-# horizontal filter float version
-ap.srcs += $(SRC_BOOZ)/ins/booz2_hf_float.c
+
+#
+# INS choice
+#
+# include booz2_ins_hff.makefile
+# or
+# nothing
+#
+
 #  vertical filter float version
 ap.srcs += $(SRC_BOOZ)/ins/booz2_vf_float.c
 ap.CFLAGS += -DUSE_VFF -DDT_VFILTER="(1./512.)" -DFLOAT_T=float

Modified: paparazzi3/trunk/conf/autopilot/booz2_simulator_nps.makefile
===================================================================
--- paparazzi3/trunk/conf/autopilot/booz2_simulator_nps.makefile        
2009-08-31 18:46:44 UTC (rev 4034)
+++ paparazzi3/trunk/conf/autopilot/booz2_simulator_nps.makefile        
2009-08-31 18:46:59 UTC (rev 4035)
@@ -138,8 +138,14 @@
 #  vertical filter float version
 sim.srcs += $(SRC_BOOZ)/ins/booz2_vf_float.c
 sim.CFLAGS += -DUSE_VFF -DDT_VFILTER="(1./512.)"
-sim.srcs += $(SRC_BOOZ)/ins/booz2_hf_float.c
 
+#
+# INS choice
+#
+# include booz2_ins_hff.makefile
+# or
+# nothing
+#
 
 
 sim.srcs += $(SRC_BOOZ)/booz2_navigation.c

Added: paparazzi3/trunk/conf/autopilot/subsystems/booz2_ins_hff.makefile
===================================================================
--- paparazzi3/trunk/conf/autopilot/subsystems/booz2_ins_hff.makefile           
                (rev 0)
+++ paparazzi3/trunk/conf/autopilot/subsystems/booz2_ins_hff.makefile   
2009-08-31 18:46:59 UTC (rev 4035)
@@ -0,0 +1,9 @@
+#
+# simple horizontal filter for INS
+#
+
+ap.CFLAGS += -DUSE_HFF
+ap.srcs += $(SRC_BOOZ)/ins/booz2_hf_float.c
+
+sim.CFLAGS += -DUSE_HFF
+sim.srcs += $(SRC_BOOZ)/ins/booz2_hf_float.c

Modified: paparazzi3/trunk/conf/messages.xml
===================================================================
--- paparazzi3/trunk/conf/messages.xml  2009-08-31 18:46:44 UTC (rev 4034)
+++ paparazzi3/trunk/conf/messages.xml  2009-08-31 18:46:59 UTC (rev 4035)
@@ -1069,10 +1069,8 @@
          <field name="xdd"            type="float"/>
       <field name="x"              type="float"/>
       <field name="xd"             type="float"/>
-      <field name="xbias"          type="float"/>
       <field name="Pxx"            type="float"/>
       <field name="Pxdxd"          type="float"/>
-      <field name="Pbb"            type="float"/>
   </message>
 
   <message name="BOOZ2_HFF_Y" id="165">
@@ -1080,10 +1078,8 @@
          <field name="ydd"            type="float"/>
       <field name="y"              type="float"/>
       <field name="yd"             type="float"/>
-      <field name="ybias"          type="float"/>
       <field name="Pyy"            type="float"/>
       <field name="Pydyd"          type="float"/>
-      <field name="Pbb"            type="float"/>
   </message>
 
   <message name="BOOZ2_HFF_GPS" id="166">

Modified: paparazzi3/trunk/sw/airborne/booz/booz2_ins.c
===================================================================
--- paparazzi3/trunk/sw/airborne/booz/booz2_ins.c       2009-08-31 18:46:44 UTC 
(rev 4034)
+++ paparazzi3/trunk/sw/airborne/booz/booz2_ins.c       2009-08-31 18:46:59 UTC 
(rev 4035)
@@ -52,9 +52,11 @@
          bool_t  booz_ins_ltp_initialised;
 struct NedCoor_i booz_ins_gps_pos_cm_ned;
 struct NedCoor_i booz_ins_gps_speed_cm_s_ned;
+#ifdef USE_HFF
 /* horizontal gps transformed to NED in meters as float */
 struct FloatVect2 booz_ins_gps_pos_m_ned;
 struct FloatVect2 booz_ins_gps_speed_m_s_ned;
+#endif
 
 /* barometer                   */
 #ifdef USE_VFF
@@ -72,12 +74,7 @@
 struct EnuCoor_i booz_ins_enu_speed;
 struct EnuCoor_i booz_ins_enu_accel;
 
-#ifdef USE_HFF
-/* counter for hff propagation*/
-uint8_t b2_hff_ps_counter;
-#endif
 
-
 void booz_ins_init() {
 #ifdef USE_NAV_INS_INIT
   booz_ins_ltp_initialised  = TRUE;
@@ -93,8 +90,7 @@
   b2_vff_init(0., 0., 0.);
 #endif
 #ifdef USE_HFF
-  b2_hff_init(0., 0., 0., 0., 0., 0.);
-  b2_hff_ps_counter = 1;
+  b2_hff_init(0., 0., 0., 0.);
 #endif
   INT32_VECT3_ZERO(booz_ins_ltp_pos);
   INT32_VECT3_ZERO(booz_ins_ltp_speed);
@@ -135,34 +131,18 @@
 #endif /* USE_VFF */
 
 #ifdef USE_HFF
-  if (b2_hff_ps_counter == HFF_PRESCALER) {
-       b2_hff_ps_counter = 1;
-       if (booz_ahrs.status == BOOZ_AHRS_RUNNING ) {
-         /* compute float ltp mean acceleration */
-         booz_ahrs_compute_accel_mean(HFF_PRESCALER);
-         struct Int32Vect3 mean_accel_body;
-         INT32_RMAT_TRANSP_VMULT(mean_accel_body, booz_imu.body_to_imu_rmat, 
booz_ahrs_accel_mean);
-         struct Int32Vect3 mean_accel_ltp;
-         INT32_RMAT_TRANSP_VMULT(mean_accel_ltp, booz_ahrs.ltp_to_body_rmat, 
mean_accel_body);
-         float x_accel_mean_f = ACCEL_FLOAT_OF_BFP(mean_accel_ltp.x);
-         float y_accel_mean_f = ACCEL_FLOAT_OF_BFP(mean_accel_ltp.y);
-#ifdef GPS_LAG
-         b2_hff_store_accel(x_accel_mean_f, y_accel_mean_f);
-#endif
-         if ( booz_ins_ltp_initialised ) {
-               /* propagate horizontal filter */
-               b2_hff_propagate(x_accel_mean_f, y_accel_mean_f);
-               /* update ins state from horizontal filter */
-               booz_ins_ltp_accel.x = ACCEL_BFP_OF_REAL(b2_hff_state.xdotdot);
-               booz_ins_ltp_accel.y = ACCEL_BFP_OF_REAL(b2_hff_state.ydotdot);
-               booz_ins_ltp_speed.x = SPEED_BFP_OF_REAL(b2_hff_state.xdot);
-               booz_ins_ltp_speed.y = SPEED_BFP_OF_REAL(b2_hff_state.ydot);
-               booz_ins_ltp_pos.x   = POS_BFP_OF_REAL(b2_hff_state.x);
-               booz_ins_ltp_pos.y   = POS_BFP_OF_REAL(b2_hff_state.y);
-         }
+  if (booz_ahrs.status == BOOZ_AHRS_RUNNING ) {
+       /* propagate horizontal filter */
+       b2_hff_propagate();
+       if ( booz_ins_ltp_initialised ) {
+         /* update ins state from horizontal filter */
+         booz_ins_ltp_accel.x = ACCEL_BFP_OF_REAL(b2_hff_state.xdotdot);
+         booz_ins_ltp_accel.y = ACCEL_BFP_OF_REAL(b2_hff_state.ydotdot);
+         booz_ins_ltp_speed.x = SPEED_BFP_OF_REAL(b2_hff_state.xdot);
+         booz_ins_ltp_speed.y = SPEED_BFP_OF_REAL(b2_hff_state.ydot);
+         booz_ins_ltp_pos.x   = POS_BFP_OF_REAL(b2_hff_state.x);
+         booz_ins_ltp_pos.y   = POS_BFP_OF_REAL(b2_hff_state.y);
        }
-  } else {
-       b2_hff_ps_counter++;
   }
 #else
   booz_ins_ltp_accel.x = accel_ltp.x;
@@ -208,13 +188,13 @@
       booz_ins_ltp_initialised = TRUE;
     }
     ned_of_ecef_point_i(&booz_ins_gps_pos_cm_ned, &booz_ins_ltp_def, 
&booz_gps_state.ecef_pos);
+    ned_of_ecef_vect_i(&booz_ins_gps_speed_cm_s_ned, &booz_ins_ltp_def, 
&booz_gps_state.ecef_vel);
+
+#ifdef USE_HFF
        VECT2_ASSIGN(booz_ins_gps_pos_m_ned, booz_ins_gps_pos_cm_ned.x, 
booz_ins_gps_pos_cm_ned.y);
        VECT2_SDIV(booz_ins_gps_pos_m_ned, booz_ins_gps_pos_m_ned, 100.);
-    ned_of_ecef_vect_i(&booz_ins_gps_speed_cm_s_ned, &booz_ins_ltp_def, 
&booz_gps_state.ecef_vel);
        VECT2_ASSIGN(booz_ins_gps_speed_m_s_ned, booz_ins_gps_speed_cm_s_ned.x, 
booz_ins_gps_speed_cm_s_ned.y);
     VECT2_SDIV(booz_ins_gps_speed_m_s_ned, booz_ins_gps_speed_m_s_ned, 100.);
-       
-#ifdef USE_HFF
        b2_hff_update_gps();
     booz_ins_ltp_accel.x = ACCEL_BFP_OF_REAL(b2_hff_state.xdotdot);
     booz_ins_ltp_accel.y = ACCEL_BFP_OF_REAL(b2_hff_state.ydotdot);

Modified: paparazzi3/trunk/sw/airborne/booz/booz2_ins.h
===================================================================
--- paparazzi3/trunk/sw/airborne/booz/booz2_ins.h       2009-08-31 18:46:44 UTC 
(rev 4034)
+++ paparazzi3/trunk/sw/airborne/booz/booz2_ins.h       2009-08-31 18:46:59 UTC 
(rev 4035)
@@ -50,9 +50,11 @@
 extern struct EnuCoor_i booz_ins_enu_pos;
 extern struct EnuCoor_i booz_ins_enu_speed;
 extern struct EnuCoor_i booz_ins_enu_accel;
+#ifdef USE_HFF
 /* horizontal gps transformed to NED in meters as float */
 extern struct FloatVect2 booz_ins_gps_pos_m_ned;
 extern struct FloatVect2 booz_ins_gps_speed_m_s_ned;
+#endif
 
 extern void booz_ins_init( void );
 extern void booz_ins_periodic( void );

Modified: paparazzi3/trunk/sw/airborne/booz/booz2_telemetry.h
===================================================================
--- paparazzi3/trunk/sw/airborne/booz/booz2_telemetry.h 2009-08-31 18:46:44 UTC 
(rev 4034)
+++ paparazzi3/trunk/sw/airborne/booz/booz2_telemetry.h 2009-08-31 18:46:59 UTC 
(rev 4035)
@@ -454,31 +454,27 @@
 
 #ifdef USE_HFF
 #include "ins/booz2_hf_float.h"
-#define PERIODIC_SEND_BOOZ2_HFF_X(_chan) {             \
-    DOWNLINK_SEND_BOOZ2_HFF_X(_chan,                   \
-                           &b2_hff_x_meas,             \
-                   &b2_hff_state.xdotdot,    \
+#define PERIODIC_SEND_BOOZ2_HFF_X(_chan) {     \
+    DOWNLINK_SEND_BOOZ2_HFF_X(_chan,           \
+                           &b2_hff_x_meas,                     \
+                   &b2_hff_state.xdotdot,      \
                            &b2_hff_state.x,                    \
-                           &b2_hff_state.xdot,         \
-                           &b2_hff_state.xbias,                \
+                           &b2_hff_state.xdot,             \
                            &b2_hff_state.xP[0][0],             \
-                           &b2_hff_state.xP[1][1],             \
-                           &b2_hff_state.xP[2][2]);            \
+                               &b2_hff_state.xP[1][1]);        \
   }
-#define PERIODIC_SEND_BOOZ2_HFF_Y(_chan) {             \
-    DOWNLINK_SEND_BOOZ2_HFF_Y(_chan,                   \
-                           &b2_hff_y_meas,             \
-                   &b2_hff_state.ydotdot,    \
+#define PERIODIC_SEND_BOOZ2_HFF_Y(_chan) {     \
+    DOWNLINK_SEND_BOOZ2_HFF_Y(_chan,           \
+                           &b2_hff_y_meas,                     \
+                   &b2_hff_state.ydotdot,      \
                            &b2_hff_state.y,                    \
-                           &b2_hff_state.ydot,         \
-                           &b2_hff_state.ybias,                \
-                           &b2_hff_state.yP[0][0],                             
                                \
-                           &b2_hff_state.yP[1][1],             \
-                           &b2_hff_state.yP[2][2]);            \
+                           &b2_hff_state.ydot,             \
+                           &b2_hff_state.yP[0][0],             \
+                               &b2_hff_state.yP[1][1]);        \
   }
 #define PERIODIC_SEND_BOOZ2_HFF_GPS(_chan) {   \
     DOWNLINK_SEND_BOOZ2_HFF_GPS(_chan,                 \
-                                                         
&b2_hff_save.lag_counter,             \
+                                                         
&b2_hff_rb_last->lag_counter,         \
                                                          &lag_counter_err,     
\
                                                          &save_counter);       
\
   }

Modified: paparazzi3/trunk/sw/airborne/booz/ins/booz2_hf_float.c
===================================================================
--- paparazzi3/trunk/sw/airborne/booz/ins/booz2_hf_float.c      2009-08-31 
18:46:44 UTC (rev 4034)
+++ paparazzi3/trunk/sw/airborne/booz/ins/booz2_hf_float.c      2009-08-31 
18:46:59 UTC (rev 4035)
@@ -24,380 +24,425 @@
 
 #include "booz2_hf_float.h"
 #include "booz2_ins.h"
+#include "booz_imu.h"
+#include "booz_ahrs.h"
 #include <stdlib.h>
 
-/*
 
-X_x = [ x xdot xbias ]
-X_y = [ y ydot ybias ]
 
-
-*/
-
 /* horizontal filter propagation frequency */
 #define HFF_FREQ 512./HFF_PRESCALER
 #define DT_HFILTER 1./HFF_FREQ
 
 /* initial covariance diagonal */
 #define INIT_PXX 1.
-#define INIT_PXX_BIAS 0.1
 /* process noise (is the same for x and y)*/
 #define ACCEL_NOISE 0.5
 #define Q       ACCEL_NOISE*DT_HFILTER*DT_HFILTER/2.
 #define Qdotdot ACCEL_NOISE*DT_HFILTER
-#define Qbiasbias 1e-7*HFF_PRESCALER
 //TODO: proper measurement noise
 #define Rpos   5.
 #define Rspeed 1.
 
+/*
+
+  X_x = [ x xdot]
+  X_y = [ y ydot]
+
+
+*/
 /* output filter states */
-struct hfilter_f b2_hff_state;
-/* saved state when gps was valid */
-struct hfilter_f b2_hff_save;
+struct HfilterFloat b2_hff_state;
 /* pointer to filter states to operate on */
-struct hfilter_f *b2_hff_work;
+//struct HfilterFloat *b2_hff_work;
 
-/* float b2_hff_x; */
-/* float b2_hff_xbias; */
-/* float b2_hff_xdot; */
-/* float b2_hff_xdotdot; */
 
-/* float b2_hff_y; */
-/* float b2_hff_ybias; */
-/* float b2_hff_ydot; */
-/* float b2_hff_ydotdot; */
 
-/* filter covariance matrices */
-/* float b2_hff_xP[B2_HFF_STATE_SIZE][B2_HFF_STATE_SIZE]; */
-/* float b2_hff_yP[B2_HFF_STATE_SIZE][B2_HFF_STATE_SIZE]; */
+/* acceleration used in propagation step */
+float b2_hff_xaccel;
+float b2_hff_yaccel;
 
+/* last position measurement */
+float b2_hff_x_meas;
+float b2_hff_y_meas;
+
+/* counter for hff propagation*/
+int b2_hff_ps_counter;
+
+
+/*
+ * For GPS lag compensation
+ *
+ *
+ *
+ */
+
 #ifdef GPS_LAG
-/* GPS_LAG is defined in seconds
- * GPS_LAG_PS in multiple of prescaler
+/*
+ * GPS_LAG is defined in seconds in airframe file
  */
+
 /* number of propagaton steps to redo according to GPS_LAG */
-#define GPS_LAG_N (int) (GPS_LAG * 512. / HFF_PRESCALER + 0.5)
+#define GPS_LAG_N ((int) (GPS_LAG * HFF_FREQ + 0.5))
+/* number of propagation steps between two GPS updates */
+#define GPS_DT_N ((int) (HFF_FREQ / 4))
 
-/* state and covariance when GPS was valid */
-/* float b2_hff_x_sav; */
-/* float b2_hff_xbias_sav; */
-/* float b2_hff_xdot_sav; */
-/* float b2_hff_xdotdot_sav; */
-/* float b2_hff_y_sav; */
-/* float b2_hff_ybias_sav; */
-/* float b2_hff_ydot_sav; */
-/* float b2_hff_ydotdot_sav; */
-/* float b2_hff_xP_sav[B2_HFF_STATE_SIZE][B2_HFF_STATE_SIZE]; */
-/* float b2_hff_yP_sav[B2_HFF_STATE_SIZE][B2_HFF_STATE_SIZE]; */
+/* maximum number of past propagation steps to rerun per ap cycle
+ * make sure GPS_LAG_N/MAX_PP_STEPS < GPS_DT_N
+ */
+#define MAX_PP_STEPS 6
 
-#define BUF_MAXN GPS_LAG_N+2
-/* buffer with past mean accel values for redoing the propagation */
-struct FloatVect2 past_accel[BUF_MAXN];
-
 /* variables for accel buffer */
-uint8_t buf_r; /* pos to read from, oldest measurement */
-uint8_t buf_w; /* pos to write to */
-uint8_t buf_n; /* number of elements in buffer */
+#define ACC_BUF_MAXN GPS_LAG_N+10
+struct FloatVect2 past_accel[ACC_BUF_MAXN]; /* buffer with past mean accel 
values for redoing the propagation */
+uint8_t acc_buf_r; /* pos to read from, oldest measurement */
+uint8_t acc_buf_w; /* pos to write to */
+uint8_t acc_buf_n; /* number of elements in buffer */
 
-/* number of propagation steps since state was saved */
-/* uint8_t lag_counter; */
+
+/*
+ * stuff for ringbuffer to store past filter states
+ */
+#define HFF_RB_MAXN ((int) (GPS_LAG * 4))
+#define INC_RB_POINTER(ptr) {                                  \
+       if (ptr == &b2_hff_rb[HFF_RB_MAXN-1])           \
+       ptr = b2_hff_rb;                                                        
\
+  else                                                                         
        \
+       ptr++;                                                                  
        \
+  }
+
+struct HfilterFloat b2_hff_rb[HFF_RB_MAXN]; /* ringbuffer with state and 
covariance when GPS was valid */
+struct HfilterFloat *b2_hff_rb_put; /* write pointer */
+#endif /* GPS_LAG */
+
+struct HfilterFloat *b2_hff_rb_last; /* read pointer */
+int b2_hff_rb_n; /* fill count */
+
+
 /* by how many steps the estimated GPS validity point in time differed from 
GPS_LAG_N */
 int8_t lag_counter_err;
 
 /* counts down the propagation steps until the filter state is saved again */
 int8_t save_counter;
+int8_t past_save_counter;
 
+#ifdef GPS_LAG
 static inline void b2_hff_get_past_accel(int back_n);
-static inline void b2_hff_rollback_filter(void);
-static inline void b2_hff_save_filter(void);
-#endif /* GPS_LAG */
+static inline void b2_hff_rb_put_state(struct HfilterFloat* source);
+static inline void b2_hff_rb_next(void);
+static inline void b2_hff_set_state(struct HfilterFloat* dest, struct 
HfilterFloat* source);
+#endif
 
-/* acceleration used in propagation step */
-float b2_hff_xaccel;
-float b2_hff_yaccel;
 
-/* last position measurement */
-float b2_hff_x_meas;
-float b2_hff_y_meas;
 
+static inline void b2_hff_init_x(float init_x, float init_xdot);
+static inline void b2_hff_init_y(float init_y, float init_ydot);
 
-static inline void b2_hff_init_x(float init_x, float init_xdot, float 
init_xbias);
-static inline void b2_hff_init_y(float init_y, float init_ydot, float 
init_ybias);
+static inline void b2_hff_propagate_x(struct HfilterFloat* hff_work);
+static inline void b2_hff_propagate_y(struct HfilterFloat* hff_work);
 
-static inline void b2_hff_propagate_x(void);
-static inline void b2_hff_propagate_y(void);
+static inline void b2_hff_update_x(struct HfilterFloat* hff_work, float 
x_meas);
+static inline void b2_hff_update_y(struct HfilterFloat* hff_work, float 
y_meas);
 
-static inline void b2_hff_update_x(float x_meas);
-static inline void b2_hff_update_y(float y_meas);
+static inline void b2_hff_update_xdot(struct HfilterFloat* hff_work, float v);
+static inline void b2_hff_update_ydot(struct HfilterFloat* hff_work, float v);
 
-static inline void b2_hff_update_xdot(float v);
-static inline void b2_hff_update_ydot(float v);
 
 
-
-void b2_hff_init(float init_x, float init_xdot, float init_xbias, float 
init_y, float init_ydot, float init_ybias) {
-  b2_hff_init_x(init_x, init_xdot, init_xbias);
-  b2_hff_init_y(init_y, init_ydot, init_ybias);
-  b2_hff_work = &b2_hff_state;
+void b2_hff_init(float init_x, float init_xdot, float init_y, float init_ydot) 
{
+  b2_hff_init_x(init_x, init_xdot);
+  b2_hff_init_y(init_y, init_ydot);
 #ifdef GPS_LAG
-  buf_r = 0;
-  buf_w = 0;
-  buf_n = 0;
-  b2_hff_save.lag_counter = 0;
+  acc_buf_r = 0;
+  acc_buf_w = 0;
+  acc_buf_n = 0;
+  b2_hff_rb_put = b2_hff_rb;
+  b2_hff_rb_last = b2_hff_rb;
   b2_hff_state.lag_counter = GPS_LAG_N;
-  lag_counter_err = 0;
+#else
+  b2_hff_rb_last = NULL;
+  b2_hff_state.lag_counter = 0;
 #endif
+  b2_hff_rb_n = 0;
+  b2_hff_state.rollback = 0;
+  lag_counter_err = 0;
+  b2_hff_ps_counter = 1;
 }
 
-static inline void b2_hff_init_x(float init_x, float init_xdot, float 
init_xbias) {
+static inline void b2_hff_init_x(float init_x, float init_xdot) {
   b2_hff_state.x     = init_x;
   b2_hff_state.xdot  = init_xdot;
-  b2_hff_state.xbias = init_xbias;
   int i, j;
   for (i=0; i<B2_HFF_STATE_SIZE; i++) {
     for (j=0; j<B2_HFF_STATE_SIZE; j++)
       b2_hff_state.xP[i][j] = 0.;
-       if (i < 2)
-         b2_hff_state.xP[i][i] = INIT_PXX;
-       else
-         b2_hff_state.xP[i][i] = INIT_PXX_BIAS;
+       b2_hff_state.xP[i][i] = INIT_PXX;
   }
 
 }
 
-static inline void b2_hff_init_y(float init_y, float init_ydot, float 
init_ybias) {
+static inline void b2_hff_init_y(float init_y, float init_ydot) {
   b2_hff_state.y     = init_y;
   b2_hff_state.ydot  = init_ydot;
-  b2_hff_state.ybias = init_ybias;
   int i, j;
   for (i=0; i<B2_HFF_STATE_SIZE; i++) {
     for (j=0; j<B2_HFF_STATE_SIZE; j++)
       b2_hff_state.yP[i][j] = 0.;
-       if (i < 2)
-         b2_hff_state.yP[i][i] = INIT_PXX;
-       else
-         b2_hff_state.yP[i][i] = INIT_PXX_BIAS;
+       b2_hff_state.yP[i][i] = INIT_PXX;
   }
 }
 
 #ifdef GPS_LAG
 void b2_hff_store_accel(float x, float y) {
-  past_accel[buf_w].x = x;
-  past_accel[buf_w].y = y;
-  buf_w = (buf_w + 1) < BUF_MAXN ? (buf_w + 1) : 0;
+  past_accel[acc_buf_w].x = x;
+  past_accel[acc_buf_w].y = y;
+  acc_buf_w = (acc_buf_w + 1) < ACC_BUF_MAXN ? (acc_buf_w + 1) : 0;
 
-  if (buf_n < BUF_MAXN) {
-       buf_n++;
+  if (acc_buf_n < ACC_BUF_MAXN) {
+       acc_buf_n++;
   } else {
-       buf_r = (buf_r + 1) < BUF_MAXN ? (buf_r + 1) : 0;
+       acc_buf_r = (acc_buf_r + 1) < ACC_BUF_MAXN ? (acc_buf_r + 1) : 0;
   }
 }
 
 /* get the accel values from back_n steps ago */
 static inline void b2_hff_get_past_accel(int back_n) {
   int i;
-  if (back_n > buf_n) {
-       //printf("Cannot go back %d steps, going back only %d instead!\n", 
back_n, buf_n);
-       back_n = buf_n;
+  if (back_n > acc_buf_n) {
+       //printf("Cannot go back %d steps, going back only %d instead!\n", 
back_n, acc_buf_n);
+       back_n = acc_buf_n;
+  } else if (back_n <= 0) {
+       //printf("Cannot go back %d steps, not getting past accel value!\n", 
back_n);
+       return;
   }
-  //i = (buf_r + n) < BUF_MAXN ? (buf_r + n) : (buf_r + n - BUF_MAXN);
-  i = (buf_w-1 - back_n) > 0 ? (buf_w-1 - back_n) : (buf_w-1 + BUF_MAXN - 
back_n);
+  i = (acc_buf_w - back_n) > 0 ? (acc_buf_w - back_n) : (acc_buf_w + 
ACC_BUF_MAXN - back_n);
   b2_hff_xaccel = past_accel[i].x;
   b2_hff_yaccel = past_accel[i].y;
 }
 
-/* rollback the state and covariance matrix to time when last saved */
-static inline void b2_hff_rollback_filter(void) {
-  /* b2_hff_x = b2_hff_x_sav; */
-/*   b2_hff_xbias = b2_hff_xbias_sav; */
-/*   b2_hff_xdot = b2_hff_xdot_sav; */
-/*   b2_hff_xdotdot = b2_hff_xdotdot_sav; */
-/*   b2_hff_y = b2_hff_y_sav; */
-/*   b2_hff_ybias = b2_hff_ybias_sav; */
-/*   b2_hff_ydot = b2_hff_ydot_sav; */
-/*   b2_hff_ydotdot = b2_hff_ydotdot_sav; */
-/*   for (int i=0; i < B2_HFF_STATE_SIZE; i++) { */
-/*     for (int j=0; j < B2_HFF_STATE_SIZE; j++) { */
-/*       b2_hff_xP[i][j] = b2_hff_xP_sav[i][j]; */
-/*       b2_hff_yP[i][j] = b2_hff_yP_sav[i][j]; */
-/*     } */
-/*   } */
-  b2_hff_work = &b2_hff_save;
+static inline void b2_hff_rb_put_state(struct HfilterFloat* source) {
+  /* copy state from source into buffer */
+  b2_hff_set_state(b2_hff_rb_put, source);
+  b2_hff_rb_put->lag_counter = 0;
+  b2_hff_rb_put->rollback = 0;
+
+  /* forward write pointer */
+  INC_RB_POINTER(b2_hff_rb_put);
+
+  /* increase fill count and forward last pointer if neccessary */
+  if (b2_hff_rb_n < HFF_RB_MAXN) {
+       b2_hff_rb_n++;
+  } else {
+       INC_RB_POINTER(b2_hff_rb_last);
+  }
 }
 
-/* save current state for later rollback */
-static inline void b2_hff_save_filter(void) {
-  b2_hff_save.x       = b2_hff_state.x;
-  b2_hff_save.xbias   = b2_hff_state.xbias;
-  b2_hff_save.xdot    = b2_hff_state.xdot;
-  b2_hff_save.xdotdot = b2_hff_state.xdotdot;
-  b2_hff_save.y       = b2_hff_state.y;
-  b2_hff_save.ybias   = b2_hff_state.ybias;
-  b2_hff_save.ydot    = b2_hff_state.ydot;
-  b2_hff_save.ydotdot = b2_hff_state.ydotdot;
-  for (int i=0; i < B2_HFF_STATE_SIZE; i++) {
-       for (int j=0; j < B2_HFF_STATE_SIZE; j++) {
-         b2_hff_save.xP[i][j] = b2_hff_state.xP[i][j];
-         b2_hff_save.yP[i][j] = b2_hff_state.yP[i][j];
-       }
+static inline void b2_hff_rb_next(void) {
+  if (b2_hff_rb_n > 0) {
+       INC_RB_POINTER(b2_hff_rb_last);
+       b2_hff_rb_n--;
+  } else {
+       //printf("hff ringbuffer empty!\n");
   }
-  b2_hff_save.lag_counter = 0;
 }
 
-/* copy working state to output state */
-static inline void b2_hff_set_state(struct hfilter_f* source) {
-  b2_hff_state.x       = source->x;
-  b2_hff_state.xbias   = source->xbias;
-  b2_hff_state.xdot    = source->xdot;
-  b2_hff_state.xdotdot = source->xdotdot;
-  b2_hff_state.y       = source->y;
-  b2_hff_state.ybias   = source->ybias;
-  b2_hff_state.ydot    = source->ydot;
-  b2_hff_state.ydotdot = source->ydotdot;
+
+/* copy source state to dest state */
+static inline void b2_hff_set_state(struct HfilterFloat* dest, struct 
HfilterFloat* source) {
+  dest->x       = source->x;
+  dest->xdot    = source->xdot;
+  dest->xdotdot = source->xdotdot;
+  dest->y       = source->y;
+  dest->ydot    = source->ydot;
+  dest->ydotdot = source->ydotdot;
   for (int i=0; i < B2_HFF_STATE_SIZE; i++) {
        for (int j=0; j < B2_HFF_STATE_SIZE; j++) {
-         b2_hff_state.xP[i][j] = source->xP[i][j];
-         b2_hff_state.yP[i][j] = source->yP[i][j];
+         dest->xP[i][j] = source->xP[i][j];
+         dest->yP[i][j] = source->yP[i][j];
        }
   }
 }
-#endif
 
-/*
+static inline void b2_hff_propagate_past(struct HfilterFloat* hff_past) {
+  /* run max MAX_PP_STEPS propagation steps */
+  for (int i=0; i < MAX_PP_STEPS; i++) {
+       b2_hff_get_past_accel(hff_past->lag_counter);
+       b2_hff_propagate_x(hff_past);
+       b2_hff_propagate_y(hff_past);
+       hff_past->lag_counter--;
 
- F = [ 1 dt -dt^2/2
-       0  1 -dt
-       0  0   1     ];
+       if (past_save_counter == 0) {
+         /* next GPS measurement valid at this state -> save */
+         b2_hff_rb_put_state(hff_past);
+         past_save_counter = -1;
+       } else if (save_counter > 0) {
+         past_save_counter--;
+       }
 
- B = [ dt^2/2 dt 0]';
+       if (hff_past->lag_counter == 0) {
+         b2_hff_set_state(&b2_hff_state, hff_past);
+         b2_hff_rb_next();
+         break;
+       }
+  }
+}
+#endif
 
- Q = [ 0.01  0     0
-       0     0.01  0
-       0     0     0.001 ];
 
- Xk1 = F * Xk0 + B * accel;
 
- Pk1 = F * Pk0 * F' + Q;
-
-*/
-void b2_hff_propagate(float xaccel, float yaccel) {
+void b2_hff_propagate(void) {
 #ifdef GPS_LAG
-  /* save filter if now is the estimated GPS validity point in time */
-  if (save_counter == 0) {
-       b2_hff_save_filter();
-       save_counter = -1;
-  } else if (save_counter > 0) {
-       save_counter--;
+  /* continue to redo the propagation to catch up with the present */
+  if (b2_hff_rb_last->rollback) {
+       b2_hff_propagate_past(b2_hff_rb_last);
   }
 #endif
 
-  b2_hff_xaccel = xaccel;
-  b2_hff_yaccel = yaccel;
-  b2_hff_propagate_x();
-  b2_hff_propagate_y();
+  /* propagate current state if it is time */
+  if (b2_hff_ps_counter == HFF_PRESCALER) {
+       b2_hff_ps_counter = 1;
 
+       /* compute float ltp mean acceleration */
+       booz_ahrs_compute_accel_mean(HFF_PRESCALER);
+       struct Int32Vect3 mean_accel_body;
+       INT32_RMAT_TRANSP_VMULT(mean_accel_body, booz_imu.body_to_imu_rmat, 
booz_ahrs_accel_mean);
+       struct Int32Vect3 mean_accel_ltp;
+       INT32_RMAT_TRANSP_VMULT(mean_accel_ltp, booz_ahrs.ltp_to_body_rmat, 
mean_accel_body);
+       b2_hff_xaccel = ACCEL_FLOAT_OF_BFP(mean_accel_ltp.x);
+       b2_hff_yaccel = ACCEL_FLOAT_OF_BFP(mean_accel_ltp.y);
+
+       /*
+        * propagate current state
+        */
+       if ( booz_ins_ltp_initialised ) {
+         b2_hff_propagate_x(&b2_hff_state);
+         b2_hff_propagate_y(&b2_hff_state);
+       }
 #ifdef GPS_LAG
-  if (b2_hff_save.lag_counter < 2*GPS_LAG_N) // prevent from overflowing if no 
gps available
-       b2_hff_save.lag_counter++;
+       b2_hff_store_accel(b2_hff_xaccel, b2_hff_yaccel);
+       /* increase all lag counters */
+       for (int i=0; i < b2_hff_rb_n; i++ ) {
+         (b2_hff_rb_last+i)->lag_counter++;
+       }
+
+       /* save filter state if ringbuffer is empty */
+       if (save_counter == 0) {
+         b2_hff_rb_put_state(&b2_hff_state);
+         save_counter = -1;
+       } else if (save_counter > 0) {
+         save_counter--;
+       }
 #endif
-}
 
-static inline void b2_hff_propagate_x(void) {
-  /* update state */
-  b2_hff_work->xdotdot = b2_hff_xaccel - b2_hff_work->xbias;
-  b2_hff_work->x = b2_hff_work->x + DT_HFILTER * b2_hff_work->xdot + 
DT_HFILTER * DT_HFILTER / 2 * b2_hff_work->xdotdot;
-  b2_hff_work->xdot = b2_hff_work->xdot + DT_HFILTER * b2_hff_work->xdotdot;
-  /* update covariance */
-  const float FPF00 = b2_hff_work->xP[0][0] + DT_HFILTER * ( 
b2_hff_work->xP[1][0] + b2_hff_work->xP[0][1] + DT_HFILTER * 
b2_hff_work->xP[1][1] );
-  const float FPF01 = b2_hff_work->xP[0][1] + DT_HFILTER * ( 
b2_hff_work->xP[1][1] - b2_hff_work->xP[0][2] - DT_HFILTER * 
b2_hff_work->xP[1][2] );
-  const float FPF02 = b2_hff_work->xP[0][2] + DT_HFILTER * ( 
b2_hff_work->xP[1][2] );
-  const float FPF10 = b2_hff_work->xP[1][0] + DT_HFILTER * 
(-b2_hff_work->xP[2][0] + b2_hff_work->xP[1][1] - DT_HFILTER * 
b2_hff_work->xP[2][1] );
-  const float FPF11 = b2_hff_work->xP[1][1] + DT_HFILTER * 
(-b2_hff_work->xP[2][1] - b2_hff_work->xP[1][2] + DT_HFILTER * 
b2_hff_work->xP[2][2] );
-  const float FPF12 = b2_hff_work->xP[1][2] + DT_HFILTER * 
(-b2_hff_work->xP[2][2] );
-  const float FPF20 = b2_hff_work->xP[2][0] + DT_HFILTER * ( 
b2_hff_work->xP[2][1] );
-  const float FPF21 = b2_hff_work->xP[2][1] + DT_HFILTER * 
(-b2_hff_work->xP[2][2] );
-  const float FPF22 = b2_hff_work->xP[2][2];
-
-  b2_hff_work->xP[0][0] = FPF00 + Q;
-  b2_hff_work->xP[0][1] = FPF01;
-  b2_hff_work->xP[0][2] = FPF02;
-  b2_hff_work->xP[1][0] = FPF10;
-  b2_hff_work->xP[1][1] = FPF11 + Qdotdot;
-  b2_hff_work->xP[1][2] = FPF12;
-  b2_hff_work->xP[2][0] = FPF20;
-  b2_hff_work->xP[2][1] = FPF21;
-  b2_hff_work->xP[2][2] = FPF22 + Qbiasbias;
-
+  } else {
+       b2_hff_ps_counter++;
+  }
 }
 
-static inline void b2_hff_propagate_y(void) {
-  /* update state */
-  b2_hff_work->ydotdot = b2_hff_yaccel - b2_hff_work->ybias;
-  b2_hff_work->y = b2_hff_work->y + DT_HFILTER * b2_hff_work->ydot;
-  b2_hff_work->ydot = b2_hff_work->ydot + DT_HFILTER * b2_hff_work->ydotdot;
-  /* update covariance */
-  const float FPF00 = b2_hff_work->yP[0][0] + DT_HFILTER * ( 
b2_hff_work->yP[1][0] + b2_hff_work->yP[0][1] + DT_HFILTER * 
b2_hff_work->yP[1][1] );
-  const float FPF01 = b2_hff_work->yP[0][1] + DT_HFILTER * ( 
b2_hff_work->yP[1][1] - b2_hff_work->yP[0][2] - DT_HFILTER * 
b2_hff_work->yP[1][2] );
-  const float FPF02 = b2_hff_work->yP[0][2] + DT_HFILTER * ( 
b2_hff_work->yP[1][2] );
-  const float FPF10 = b2_hff_work->yP[1][0] + DT_HFILTER * 
(-b2_hff_work->yP[2][0] + b2_hff_work->yP[1][1] - DT_HFILTER * 
b2_hff_work->yP[2][1] );
-  const float FPF11 = b2_hff_work->yP[1][1] + DT_HFILTER * 
(-b2_hff_work->yP[2][1] - b2_hff_work->yP[1][2] + DT_HFILTER * 
b2_hff_work->yP[2][2] );
-  const float FPF12 = b2_hff_work->yP[1][2] + DT_HFILTER * 
(-b2_hff_work->yP[2][2] );
-  const float FPF20 = b2_hff_work->yP[2][0] + DT_HFILTER * ( 
b2_hff_work->yP[2][1] );
-  const float FPF21 = b2_hff_work->yP[2][1] + DT_HFILTER * 
(-b2_hff_work->yP[2][2] );
-  const float FPF22 = b2_hff_work->yP[2][2];
 
-  b2_hff_work->yP[0][0] = FPF00 + Q;
-  b2_hff_work->yP[0][1] = FPF01;
-  b2_hff_work->yP[0][2] = FPF02;
-  b2_hff_work->yP[1][0] = FPF10;
-  b2_hff_work->yP[1][1] = FPF11 + Qdotdot;
-  b2_hff_work->yP[1][2] = FPF12;
-  b2_hff_work->yP[2][0] = FPF20;
-  b2_hff_work->yP[2][1] = FPF21;
-  b2_hff_work->yP[2][2] = FPF22 + Qbiasbias;
 
-}
 
-
 void b2_hff_update_gps(void) {
 #ifdef GPS_LAG
-  lag_counter_err = b2_hff_save.lag_counter - GPS_LAG_N;
-  /* roll back if state was saved approx when GPS was valid */
-  if (abs(lag_counter_err) < 3) {
-       b2_hff_rollback_filter();
-  }
-#endif
 
-#ifdef B2_HFF_UPDATE_POS
-  b2_hff_update_x(booz_ins_gps_pos_m_ned.x);
-  b2_hff_update_y(booz_ins_gps_pos_m_ned.y);
-#endif
+  if (b2_hff_rb_n > 0) {
+       /* roll back if state was saved approx when GPS was valid */
+       lag_counter_err = b2_hff_rb_last->lag_counter - GPS_LAG_N;
+       if (abs(lag_counter_err) < 3) {
+         b2_hff_rb_last->rollback = 1;
+         b2_hff_update_x(b2_hff_rb_last, booz_ins_gps_pos_m_ned.x);
+         b2_hff_update_y(b2_hff_rb_last, booz_ins_gps_pos_m_ned.y);
 #ifdef B2_HFF_UPDATE_SPEED
-  b2_hff_update_xdot(booz_ins_gps_speed_m_s_ned.x);
-  b2_hff_update_ydot(booz_ins_gps_speed_m_s_ned.y);
+         b2_hff_update_xdot(b2_hff_rb_last, booz_ins_gps_speed_m_s_ned.x);
+         b2_hff_update_ydot(b2_hff_rb_last, booz_ins_gps_speed_m_s_ned.y);
 #endif
-
-#ifdef GPS_LAG
-  /* roll back if state was saved approx when GPS was valid */
-  if (abs(lag_counter_err) < 3) {
-       /* redo all propagation steps since GPS update */
-       for (int i=b2_hff_save.lag_counter-1; i >= 0; i--) {
-         b2_hff_get_past_accel(i);
-         b2_hff_propagate_x();
-         b2_hff_propagate_y();
+         past_save_counter = GPS_DT_N + lag_counter_err;
+         b2_hff_propagate_past(b2_hff_rb_last);
+       } else if (lag_counter_err >= GPS_DT_N-2) {
+         /* apparently missed a GPS update, try next saved state */
+         b2_hff_rb_next();
+         b2_hff_update_gps();
        }
-       b2_hff_set_state(b2_hff_work);
-       b2_hff_work = &b2_hff_state;
+  } else {
+       /* ringbuffer empty -> save output filter state at next GPS validity 
point in time */
+       save_counter = GPS_DT_N - (GPS_LAG_N % GPS_DT_N);
   }
 
-  /* reset save counter */
-  save_counter = (int)(HFF_FREQ / 4) % GPS_LAG_N;
+#else /* GPS_LAG */
+
+  b2_hff_update_x(&b2_hff_state, booz_ins_gps_pos_m_ned.x);
+  b2_hff_update_y(&b2_hff_state, booz_ins_gps_pos_m_ned.y);
+#ifdef B2_HFF_UPDATE_SPEED
+  b2_hff_update_xdot(&b2_hff_state, booz_ins_gps_speed_m_s_ned.x);
+  b2_hff_update_ydot(&b2_hff_state, booz_ins_gps_speed_m_s_ned.y);
 #endif
+
+#endif/* GPS_LAG */
 }
 
 
+
 /*
-  H = [1 0 0];
+ *
+ * Propagation
+ *
+ *
+
+  F = [ 1 dt
+        0  1 ];
+
+  B = [ dt^2/2 dt]';
+
+  Q = [ 0.01  0
+        0     0.01];
+
+  Xk1 = F * Xk0 + B * accel;
+
+  Pk1 = F * Pk0 * F' + Q;
+
+*/
+static inline void b2_hff_propagate_x(struct HfilterFloat* hff_work) {
+  /* update state */
+  hff_work->xdotdot = b2_hff_xaccel;
+  hff_work->x = hff_work->x + DT_HFILTER * hff_work->xdot;
+  hff_work->xdot = hff_work->xdot + DT_HFILTER * hff_work->xdotdot;
+  /* update covariance */
+  const float FPF00 = hff_work->xP[0][0] + DT_HFILTER * ( hff_work->xP[1][0] + 
hff_work->xP[0][1] + DT_HFILTER * hff_work->xP[1][1] );
+  const float FPF01 = hff_work->xP[0][1] + DT_HFILTER * hff_work->xP[1][1];
+  const float FPF10 = hff_work->xP[1][0] + DT_HFILTER * hff_work->xP[1][1];
+  const float FPF11 = hff_work->xP[1][1];
+
+  hff_work->xP[0][0] = FPF00 + Q;
+  hff_work->xP[0][1] = FPF01;
+  hff_work->xP[1][0] = FPF10;
+  hff_work->xP[1][1] = FPF11 + Qdotdot;
+}
+
+static inline void b2_hff_propagate_y(struct HfilterFloat* hff_work) {
+  /* update state */
+  hff_work->ydotdot = b2_hff_yaccel;
+  hff_work->y = hff_work->y + DT_HFILTER * hff_work->ydot;
+  hff_work->ydot = hff_work->ydot + DT_HFILTER * hff_work->ydotdot;
+  /* update covariance */
+  const float FPF00 = hff_work->yP[0][0] + DT_HFILTER * ( hff_work->yP[1][0] + 
hff_work->yP[0][1] + DT_HFILTER * hff_work->yP[1][1] );
+  const float FPF01 = hff_work->yP[0][1] + DT_HFILTER * hff_work->yP[1][1];
+  const float FPF10 = hff_work->yP[1][0] + DT_HFILTER * hff_work->yP[1][1];
+  const float FPF11 = hff_work->yP[1][1];
+
+  hff_work->yP[0][0] = FPF00 + Q;
+  hff_work->yP[0][1] = FPF01;
+  hff_work->yP[1][0] = FPF10;
+  hff_work->yP[1][1] = FPF11 + Qdotdot;
+}
+
+
+/*
+ *
+ * Update position
+ *
+ *
+
+  H = [1 0];
   R = 0.1;
   // state residual
   y = pos_measurement - H * Xm;
@@ -411,85 +456,64 @@
   Pp = Pm - K*H*Pm;
 */
 void b2_hff_update_pos (float posx, float posy) {
-    b2_hff_update_x(posx);
-    b2_hff_update_y(posy);
+  b2_hff_update_x(&b2_hff_state, posx);
+  b2_hff_update_y(&b2_hff_state, posy);
 }
 
-static inline void b2_hff_update_x(float x_meas) {
+static inline void b2_hff_update_x(struct HfilterFloat* hff_work, float 
x_meas) {
   b2_hff_x_meas = x_meas;
 
-  const float y = x_meas - b2_hff_work->x;
-  const float S  = b2_hff_work->xP[0][0] + Rpos;
-  const float K1 = b2_hff_work->xP[0][0] * 1/S;
-  const float K2 = b2_hff_work->xP[1][0] * 1/S;
-  const float K3 = b2_hff_work->xP[2][0] * 1/S;
+  const float y  = x_meas - hff_work->x;
+  const float S  = hff_work->xP[0][0] + Rpos;
+  const float K1 = hff_work->xP[0][0] * 1/S;
+  const float K2 = hff_work->xP[1][0] * 1/S;
 
-  b2_hff_work->x     = b2_hff_work->x     + K1 * y;
-  b2_hff_work->xdot  = b2_hff_work->xdot  + K2 * y;
-  b2_hff_work->xbias = b2_hff_work->xbias + K3 * y;
+  hff_work->x     = hff_work->x     + K1 * y;
+  hff_work->xdot  = hff_work->xdot  + K2 * y;
 
-  const float P11 = (1. - K1) * b2_hff_work->xP[0][0];
-  const float P12 = (1. - K1) * b2_hff_work->xP[0][1];
-  const float P13 = (1. - K1) * b2_hff_work->xP[0][2];
-  const float P21 = -K2 * b2_hff_work->xP[0][0] + b2_hff_work->xP[1][0];
-  const float P22 = -K2 * b2_hff_work->xP[0][1] + b2_hff_work->xP[1][1];
-  const float P23 = -K2 * b2_hff_work->xP[0][2] + b2_hff_work->xP[1][2];
-  const float P31 = -K3 * b2_hff_work->xP[0][0] + b2_hff_work->xP[2][0];
-  const float P32 = -K3 * b2_hff_work->xP[0][1] + b2_hff_work->xP[2][1];
-  const float P33 = -K3 * b2_hff_work->xP[0][2] + b2_hff_work->xP[2][2];
+  const float P11 = (1. - K1) * hff_work->xP[0][0];
+  const float P12 = (1. - K1) * hff_work->xP[0][1];
+  const float P21 = -K2 * hff_work->xP[0][0] + hff_work->xP[1][0];
+  const float P22 = -K2 * hff_work->xP[0][1] + hff_work->xP[1][1];
 
-  b2_hff_work->xP[0][0] = P11;
-  b2_hff_work->xP[0][1] = P12;
-  b2_hff_work->xP[0][2] = P13;
-  b2_hff_work->xP[1][0] = P21;
-  b2_hff_work->xP[1][1] = P22;
-  b2_hff_work->xP[1][2] = P23;
-  b2_hff_work->xP[2][0] = P31;
-  b2_hff_work->xP[2][1] = P32;
-  b2_hff_work->xP[2][2] = P33;
-
+  hff_work->xP[0][0] = P11;
+  hff_work->xP[0][1] = P12;
+  hff_work->xP[1][0] = P21;
+  hff_work->xP[1][1] = P22;
 }
 
-static inline void b2_hff_update_y(float y_meas) {
+static inline void b2_hff_update_y(struct HfilterFloat* hff_work, float 
y_meas) {
   b2_hff_y_meas = y_meas;
 
-  const float y = y_meas - b2_hff_work->y;
-  const float S  = b2_hff_work->yP[0][0] + Rpos;
-  const float K1 = b2_hff_work->yP[0][0] * 1/S;
-  const float K2 = b2_hff_work->yP[1][0] * 1/S;
-  const float K3 = b2_hff_work->yP[2][0] * 1/S;
+  const float y  = y_meas - hff_work->y;
+  const float S  = hff_work->yP[0][0] + Rpos;
+  const float K1 = hff_work->yP[0][0] * 1/S;
+  const float K2 = hff_work->yP[1][0] * 1/S;
 
-  b2_hff_work->y     = b2_hff_work->y     + K1 * y;
-  b2_hff_work->ydot  = b2_hff_work->ydot  + K2 * y;
-  b2_hff_work->ybias = b2_hff_work->ybias + K3 * y;
+  hff_work->y     = hff_work->y     + K1 * y;
+  hff_work->ydot  = hff_work->ydot  + K2 * y;
 
-  const float P11 = (1. - K1) * b2_hff_work->yP[0][0];
-  const float P12 = (1. - K1) * b2_hff_work->yP[0][1];
-  const float P13 = (1. - K1) * b2_hff_work->yP[0][2];
-  const float P21 = -K2 * b2_hff_work->yP[0][0] + b2_hff_work->yP[1][0];
-  const float P22 = -K2 * b2_hff_work->yP[0][1] + b2_hff_work->yP[1][1];
-  const float P23 = -K2 * b2_hff_work->yP[0][2] + b2_hff_work->yP[1][2];
-  const float P31 = -K3 * b2_hff_work->yP[0][0] + b2_hff_work->yP[2][0];
-  const float P32 = -K3 * b2_hff_work->yP[0][1] + b2_hff_work->yP[2][1];
-  const float P33 = -K3 * b2_hff_work->yP[0][2] + b2_hff_work->yP[2][2];
+  const float P11 = (1. - K1) * hff_work->yP[0][0];
+  const float P12 = (1. - K1) * hff_work->yP[0][1];
+  const float P21 = -K2 * hff_work->yP[0][0] + hff_work->yP[1][0];
+  const float P22 = -K2 * hff_work->yP[0][1] + hff_work->yP[1][1];
 
-  b2_hff_work->yP[0][0] = P11;
-  b2_hff_work->yP[0][1] = P12;
-  b2_hff_work->yP[0][2] = P13;
-  b2_hff_work->yP[1][0] = P21;
-  b2_hff_work->yP[1][1] = P22;
-  b2_hff_work->yP[1][2] = P23;
-  b2_hff_work->yP[2][0] = P31;
-  b2_hff_work->yP[2][1] = P32;
-  b2_hff_work->yP[2][2] = P33;
-
+  hff_work->yP[0][0] = P11;
+  hff_work->yP[0][1] = P12;
+  hff_work->yP[1][0] = P21;
+  hff_work->yP[1][1] = P22;
 }
 
 
 
 
 /*
-  H = [0 1 0];
+ *
+ * Update speed
+ *
+ *
+
+  H = [0 1];
   R = 0.1;
   // state residual
   yd = vx - H * Xm;
@@ -503,74 +527,48 @@
   Pp = Pm - K*H*Pm;
 */
 void b2_hff_update_v(float xspeed, float yspeed) {
-    b2_hff_update_xdot(xspeed);
-    b2_hff_update_ydot(yspeed);
+  b2_hff_update_xdot(&b2_hff_state, xspeed);
+  b2_hff_update_ydot(&b2_hff_state, yspeed);
 }
 
-static inline void b2_hff_update_xdot(float v) {
-  const float yd = v - b2_hff_work->xdot;
-  const float S  = b2_hff_work->xP[1][1] + Rspeed;
-  const float K1 = b2_hff_work->xP[0][1] * 1/S;
-  const float K2 = b2_hff_work->xP[1][1] * 1/S;
-  const float K3 = b2_hff_work->xP[2][1] * 1/S;
+static inline void b2_hff_update_xdot(struct HfilterFloat* hff_work, float v) {
+  const float yd = v - hff_work->xdot;
+  const float S  = hff_work->xP[1][1] + Rspeed;
+  const float K1 = hff_work->xP[0][1] * 1/S;
+  const float K2 = hff_work->xP[1][1] * 1/S;
 
-  b2_hff_work->x     = b2_hff_work->x     + K1 * yd;
-  b2_hff_work->xdot  = b2_hff_work->xdot  + K2 * yd;
-  b2_hff_work->xbias = b2_hff_work->xbias + K3 * yd;
+  hff_work->x     = hff_work->x     + K1 * yd;
+  hff_work->xdot  = hff_work->xdot  + K2 * yd;
 
-  const float P11 = -K1 * b2_hff_work->xP[1][0] + b2_hff_work->xP[0][0];
-  const float P12 = -K1 * b2_hff_work->xP[1][1] + b2_hff_work->xP[0][1];
-  const float P13 = -K1 * b2_hff_work->xP[1][2] + b2_hff_work->xP[0][2];
-  const float P21 = (1. - K2) * b2_hff_work->xP[1][0];
-  const float P22 = (1. - K2) * b2_hff_work->xP[1][1];
-  const float P23 = (1. - K2) * b2_hff_work->xP[1][2];
-  const float P31 = -K3 * b2_hff_work->xP[1][0] + b2_hff_work->xP[2][0];
-  const float P32 = -K3 * b2_hff_work->xP[1][1] + b2_hff_work->xP[2][1];
-  const float P33 = -K3 * b2_hff_work->xP[1][2] + b2_hff_work->xP[2][2];
+  const float P11 = -K1 * hff_work->xP[1][0] + hff_work->xP[0][0];
+  const float P12 = -K1 * hff_work->xP[1][1] + hff_work->xP[0][1];
+  const float P21 = (1. - K2) * hff_work->xP[1][0];
+  const float P22 = (1. - K2) * hff_work->xP[1][1];
 
-  b2_hff_work->xP[0][0] = P11;
-  b2_hff_work->xP[0][1] = P12;
-  b2_hff_work->xP[0][2] = P13;
-  b2_hff_work->xP[1][0] = P21;
-  b2_hff_work->xP[1][1] = P22;
-  b2_hff_work->xP[1][2] = P23;
-  b2_hff_work->xP[2][0] = P31;
-  b2_hff_work->xP[2][1] = P32;
-  b2_hff_work->xP[2][2] = P33;
-
+  hff_work->xP[0][0] = P11;
+  hff_work->xP[0][1] = P12;
+  hff_work->xP[1][0] = P21;
+  hff_work->xP[1][1] = P22;
 }
 
-static inline void b2_hff_update_ydot(float v) {
-  const float yd = v - b2_hff_work->ydot;
-  const float S  = b2_hff_work->yP[1][1] + Rspeed;
-  const float K1 = b2_hff_work->yP[0][1] * 1/S;
-  const float K2 = b2_hff_work->yP[1][1] * 1/S;
-  const float K3 = b2_hff_work->yP[2][1] * 1/S;
+static inline void b2_hff_update_ydot(struct HfilterFloat* hff_work, float v) {
+  const float yd = v - hff_work->ydot;
+  const float S  = hff_work->yP[1][1] + Rspeed;
+  const float K1 = hff_work->yP[0][1] * 1/S;
+  const float K2 = hff_work->yP[1][1] * 1/S;
 
-  b2_hff_work->y     = b2_hff_work->y     + K1 * yd;
-  b2_hff_work->ydot  = b2_hff_work->ydot  + K2 * yd;
-  b2_hff_work->ybias = b2_hff_work->ybias + K3 * yd;
+  hff_work->y     = hff_work->y     + K1 * yd;
+  hff_work->ydot  = hff_work->ydot  + K2 * yd;
 
-  const float P11 = -K1 * b2_hff_work->yP[1][0] + b2_hff_work->yP[0][0];
-  const float P12 = -K1 * b2_hff_work->yP[1][1] + b2_hff_work->yP[0][1];
-  const float P13 = -K1 * b2_hff_work->yP[1][2] + b2_hff_work->yP[0][2];
-  const float P21 = (1. - K2) * b2_hff_work->yP[1][0];
-  const float P22 = (1. - K2) * b2_hff_work->yP[1][1];
-  const float P23 = (1. - K2) * b2_hff_work->yP[1][2];
-  const float P31 = -K3 * b2_hff_work->yP[1][0] + b2_hff_work->yP[2][0];
-  const float P32 = -K3 * b2_hff_work->yP[1][1] + b2_hff_work->yP[2][1];
-  const float P33 = -K3 * b2_hff_work->yP[1][2] + b2_hff_work->yP[2][2];
+  const float P11 = -K1 * hff_work->yP[1][0] + hff_work->yP[0][0];
+  const float P12 = -K1 * hff_work->yP[1][1] + hff_work->yP[0][1];
+  const float P21 = (1. - K2) * hff_work->yP[1][0];
+  const float P22 = (1. - K2) * hff_work->yP[1][1];
 
-  b2_hff_work->yP[0][0] = P11;
-  b2_hff_work->yP[0][1] = P12;
-  b2_hff_work->yP[0][2] = P13;
-  b2_hff_work->yP[1][0] = P21;
-  b2_hff_work->yP[1][1] = P22;
-  b2_hff_work->yP[1][2] = P23;
-  b2_hff_work->yP[2][0] = P31;
-  b2_hff_work->yP[2][1] = P32;
-  b2_hff_work->yP[2][2] = P33;
-
+  hff_work->yP[0][0] = P11;
+  hff_work->yP[0][1] = P12;
+  hff_work->yP[1][0] = P21;
+  hff_work->yP[1][1] = P22;
 }
 
 

Modified: paparazzi3/trunk/sw/airborne/booz/ins/booz2_hf_float.h
===================================================================
--- paparazzi3/trunk/sw/airborne/booz/ins/booz2_hf_float.h      2009-08-31 
18:46:44 UTC (rev 4034)
+++ paparazzi3/trunk/sw/airborne/booz/ins/booz2_hf_float.h      2009-08-31 
18:46:59 UTC (rev 4035)
@@ -33,9 +33,8 @@
 #endif
 
 #define B2_HFF_UPDATE_SPEED
-#define B2_HFF_UPDATE_POS
 
-struct hfilter_f {
+struct HfilterFloat {
   float x;
   float xbias;
   float xdot;
@@ -47,40 +46,26 @@
   float xP[B2_HFF_STATE_SIZE][B2_HFF_STATE_SIZE];
   float yP[B2_HFF_STATE_SIZE][B2_HFF_STATE_SIZE];
   uint8_t lag_counter;
+  uint8_t rollback;
 };
 
-extern struct hfilter_f b2_hff_state;
-extern struct hfilter_f b2_hff_save;
-extern struct hfilter_f *b2_hff_work;
+extern struct HfilterFloat b2_hff_state;
 
-/* extern float b2_hff_x; */
-/* extern float b2_hff_xbias; */
-/* extern float b2_hff_xdot; */
-/* extern float b2_hff_xdotdot; */
-
-/* extern float b2_hff_y; */
-/* extern float b2_hff_ybias; */
-/* extern float b2_hff_ydot; */
-/* extern float b2_hff_ydotdot; */
-
-/* extern float b2_hff_xP[B2_HFF_STATE_SIZE][B2_HFF_STATE_SIZE]; */
-/* extern float b2_hff_yP[B2_HFF_STATE_SIZE][B2_HFF_STATE_SIZE]; */
-
 extern float b2_hff_x_meas;
 extern float b2_hff_y_meas;
 
-extern void b2_hff_init(float init_x, float init_xdot, float init_xbias, float 
init_y, float init_ydot, float init_ybias);
-extern void b2_hff_propagate(float xaccel, float yaccel);
+extern void b2_hff_init(float init_x, float init_xdot, float init_y, float 
init_ydot);
+extern void b2_hff_propagate(void);
 extern void b2_hff_update_gps(void);
 extern void b2_hff_update_pos(float xpos, float ypos);
 extern void b2_hff_update_v(float xspeed, float yspeed);
 
 #ifdef GPS_LAG
 extern void b2_hff_store_accel(float x, float y);
-/* extern uint8_t lag_counter; */
+#endif
+extern struct HfilterFloat *b2_hff_rb_last;
 extern int8_t lag_counter_err;
 extern int8_t save_counter;
-#endif
 
 #endif /* BOOZ2_HF_FLOAT_H */
 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]