[ahrs] dual ahrs working with icq and mlkf

This commit is contained in:
Felix Ruess
2015-03-06 16:44:34 +01:00
parent f92ce926e8
commit d25486c579
12 changed files with 182 additions and 45 deletions
@@ -5,30 +5,43 @@
USE_MAGNETOMETER ?= 1 USE_MAGNETOMETER ?= 1
AHRS_ALIGNER_LED ?= none AHRS_ALIGNER_LED ?= none
AHRS_CFLAGS = -DUSE_AHRS AHRS_MLKF_CFLAGS = -DUSE_AHRS
AHRS_CFLAGS += -DUSE_AHRS_ALIGNER AHRS_MLKF_CFLAGS += -DUSE_AHRS_ALIGNER
ifeq (,$(findstring $(USE_MAGNETOMETER),0 FALSE)) ifeq (,$(findstring $(USE_MAGNETOMETER),0 FALSE))
AHRS_CFLAGS += -DUSE_MAGNETOMETER AHRS_MLKF_CFLAGS += -DUSE_MAGNETOMETER
else else
$(error ahrs_float_mlkf needs a magnetometer) $(error ahrs_float_mlkf needs a magnetometer)
endif endif
ifneq ($(AHRS_ALIGNER_LED),none) ifneq ($(AHRS_ALIGNER_LED),none)
AHRS_CFLAGS += -DAHRS_ALIGNER_LED=$(AHRS_ALIGNER_LED) AHRS_MLKF_CFLAGS += -DAHRS_ALIGNER_LED=$(AHRS_ALIGNER_LED)
endif endif
AHRS_CFLAGS += -DAHRS_TYPE_H=\"subsystems/ahrs/ahrs_float_mlkf_wrapper.h\" ifdef SECONDARY_AHRS
AHRS_SRCS += subsystems/ahrs.c ifneq (,$(findstring $(SECONDARY_AHRS), mlkf))
AHRS_SRCS += subsystems/ahrs/ahrs_float_mlkf.c AHRS_MLKF_SEC = ahrs_mlkf
AHRS_SRCS += subsystems/ahrs/ahrs_float_mlkf_wrapper.c endif
AHRS_SRCS += subsystems/ahrs/ahrs_aligner.c endif
ap.CFLAGS += $(AHRS_CFLAGS) ifdef AHRS_MLKF_SEC
ap.srcs += $(AHRS_SRCS) AHRS_MLKF_CFLAGS += -DAHRS_SECONDARY_TYPE_H=\"subsystems/ahrs/ahrs_float_mlkf_wrapper.h\"
AHRS_MLKF_CFLAGS += -DSECONDARY_AHRS=ahrs_mlkf
AHRS_MLKF_CFLAGS += -DAHRS_MLKF_OUTPUT_ENABLED=FALSE
else
AHRS_MLKF_CFLAGS += -DAHRS_TYPE_H=\"subsystems/ahrs/ahrs_float_mlkf_wrapper.h\"
AHRS_MLKF_CFLAGS += -DPRIMARY_AHRS=ahrs_mlkf
endif
AHRS_MLKF_SRCS += subsystems/ahrs.c
AHRS_MLKF_SRCS += subsystems/ahrs/ahrs_float_mlkf.c
AHRS_MLKF_SRCS += subsystems/ahrs/ahrs_float_mlkf_wrapper.c
AHRS_MLKF_SRCS += subsystems/ahrs/ahrs_aligner.c
nps.CFLAGS += $(AHRS_CFLAGS) ap.CFLAGS += $(AHRS_MLKF_CFLAGS)
nps.srcs += $(AHRS_SRCS) ap.srcs += $(AHRS_MLKF_SRCS)
test_ahrs.CFLAGS += $(AHRS_CFLAGS) nps.CFLAGS += $(AHRS_MLKF_CFLAGS)
test_ahrs.srcs += $(AHRS_SRCS) nps.srcs += $(AHRS_MLKF_SRCS)
test_ahrs.CFLAGS += $(AHRS_MLKF_CFLAGS)
test_ahrs.srcs += $(AHRS_MLKF_SRCS)
@@ -19,7 +19,20 @@ ifneq ($(AHRS_ALIGNER_LED),none)
AHRS_CFLAGS += -DAHRS_ALIGNER_LED=$(AHRS_ALIGNER_LED) AHRS_CFLAGS += -DAHRS_ALIGNER_LED=$(AHRS_ALIGNER_LED)
endif endif
ifdef SECONDARY_AHRS
ifneq (,$(findstring $(SECONDARY_AHRS),ahrs_icq int_cmpl_quat))
AHRS_ICQ_SEC = ahrs_icq
endif
endif
ifdef AHRS_ICQ_SEC
AHRS_CFLAGS += -DAHRS_SECONDARY_TYPE_H=\"subsystems/ahrs/ahrs_int_cmpl_quat_wrapper.h\"
AHRS_CFLAGS += -DSECONDARY_AHRS=ahrs_icq
AHRS_CFLAGS += -DAHRS_ICQ_OUTPUT_ENABLED=FALSE
else
AHRS_CFLAGS += -DAHRS_TYPE_H=\"subsystems/ahrs/ahrs_int_cmpl_quat_wrapper.h\" AHRS_CFLAGS += -DAHRS_TYPE_H=\"subsystems/ahrs/ahrs_int_cmpl_quat_wrapper.h\"
AHRS_CFLAGS += -DPRIMARY_AHRS=ahrs_icq
endif
AHRS_SRCS += subsystems/ahrs.c AHRS_SRCS += subsystems/ahrs.c
AHRS_SRCS += subsystems/ahrs/ahrs_int_cmpl_quat.c AHRS_SRCS += subsystems/ahrs/ahrs_int_cmpl_quat.c
AHRS_SRCS += subsystems/ahrs/ahrs_int_cmpl_quat_wrapper.c AHRS_SRCS += subsystems/ahrs/ahrs_int_cmpl_quat_wrapper.c
@@ -0,0 +1,11 @@
<!DOCTYPE settings SYSTEM "../settings.dtd">
<settings>
<dl_settings>
<dl_settings NAME="AHRS">
<dl_setting var="ahrs_output_idx" min="0" step="1" max="1" module="subsystems/ahrs" shortname="ahrs_idx" handler="switch"/>
</dl_settings>
</dl_settings>
</settings>
+54 -18
View File
@@ -27,35 +27,71 @@
#include "subsystems/ahrs.h" #include "subsystems/ahrs.h"
#ifndef DefaultAhrsImpl #ifndef PRIMARY_AHRS
#warning "DefaultAhrsImpl not set!" #error "PRIMARY_AHRS not set!"
#else #else
PRINT_CONFIG_VAR(DefaultAhrsImpl) PRINT_CONFIG_VAR(PRIMARY_AHRS)
#endif #endif
#define __DefaultAhrsRegister(_x) _x ## _register() #ifdef SECONDARY_AHRS
#define _DefaultAhrsRegister(_x) __DefaultAhrsRegister(_x) PRINT_CONFIG_VAR(SECONDARY_AHRS)
#define DefaultAhrsRegister() _DefaultAhrsRegister(DefaultAhrsImpl) #endif
/** Attitude and Heading Reference System state */ #define __RegisterAhrs(_x) _x ## _register()
struct Ahrs { #define _RegisterAhrs(_x) __RegisterAhrs(_x)
/* function pointers to actual implementation, set by ahrs_register_impl */ #define RegisterAhrs(_x) _RegisterAhrs(_x)
AhrsInit init;
/** maximum number of AHRS implementations that can register */
#ifndef AHRS_NB_IMPL
#define AHRS_NB_IMPL 2
#endif
/** references a registered AHRS implementation */
struct AhrsImpl {
AhrsEnableOutput enable;
}; };
struct Ahrs ahrs; struct AhrsImpl ahrs_impls[AHRS_NB_IMPL];
uint8_t ahrs_output_idx;
void ahrs_register_impl(AhrsInit init) void ahrs_register_impl(AhrsEnableOutput enable)
{ {
ahrs.init = init; int i;
for (i=0; i < AHRS_NB_IMPL; i++) {
ahrs.init(); if (ahrs_impls[i].enable == NULL) {
ahrs_impls[i].enable = enable;
break;
}
}
} }
void ahrs_init(void) void ahrs_init(void)
{ {
ahrs.init = NULL; int i;
#ifdef DefaultAhrsImpl for (i=0; i < AHRS_NB_IMPL; i++) {
DefaultAhrsRegister(); ahrs_impls[i].enable = NULL;
}
ahrs_output_idx = 0;
RegisterAhrs(PRIMARY_AHRS);
#ifdef SECONDARY_AHRS
RegisterAhrs(SECONDARY_AHRS);
#endif #endif
} }
int ahrs_switch(uint8_t idx)
{
if (idx >= AHRS_NB_IMPL) { return -1; }
if (ahrs_impls[idx].enable == NULL) { return -1; }
/* first disable other AHRS output */
int i;
for (i=0; i < AHRS_NB_IMPL; i++) {
if (ahrs_impls[i].enable != NULL) {
ahrs_impls[i].enable(FALSE);
}
}
/* enable requested AHRS */
ahrs_impls[idx].enable(TRUE);
ahrs_output_idx = idx;
return ahrs_output_idx;
}
+23 -4
View File
@@ -29,18 +29,37 @@
#include "std.h" #include "std.h"
/* underlying includes (needed for parameters) */ /* include actual (primary) implementation header */
#ifdef AHRS_TYPE_H #ifdef AHRS_TYPE_H
#include AHRS_TYPE_H #include AHRS_TYPE_H
#endif #endif
typedef void (*AhrsInit)(void); /* include secondary implementation header */
#ifdef AHRS_SECONDARY_TYPE_H
#include AHRS_SECONDARY_TYPE_H
#endif
extern void ahrs_register_impl(AhrsInit init); typedef bool_t (*AhrsEnableOutput)(bool_t);
/* for settings when using secondary AHRS */
extern uint8_t ahrs_output_idx;
/**
* Register an AHRS implementation.
* Adds it to an internal list.
* @param enable pointer to function to enable/disable the output of registering AHRS
*/
extern void ahrs_register_impl(AhrsEnableOutput enable);
/** AHRS initialization. Called at startup. /** AHRS initialization. Called at startup.
* Initialized the global AHRS struct. * Registers/initializes the default AHRS.
*/ */
extern void ahrs_init(void); extern void ahrs_init(void);
/**
* Switch to the output of another AHRS impl.
* @param idx index of the AHRS impl (0 = PRIMARY_AHRS, 1 = SECONDARY_AHRS).
*/
extern int ahrs_switch(uint8_t idx);
#endif /* AHRS_H */ #endif /* AHRS_H */
+18 -2
View File
@@ -42,6 +42,11 @@
//#include <stdio.h> //#include <stdio.h>
#ifndef AHRS_MLKF_OUTPUT_ENABLED
#define AHRS_MLKF_OUTPUT_ENABLED TRUE
#endif
PRINT_CONFIG_VAR(AHRS_MLKF_OUTPUT_ENABLED)
#ifndef AHRS_MAG_NOISE_X #ifndef AHRS_MAG_NOISE_X
#define AHRS_MAG_NOISE_X 0.2 #define AHRS_MAG_NOISE_X 0.2
#define AHRS_MAG_NOISE_Y 0.2 #define AHRS_MAG_NOISE_Y 0.2
@@ -66,6 +71,7 @@ void ahrs_mlkf_init(void)
{ {
ahrs_mlkf.is_aligned = FALSE; ahrs_mlkf.is_aligned = FALSE;
ahrs_mlkf.output_enabled = AHRS_MLKF_OUTPUT_ENABLED;
/* init ltp_to_imu quaternion as zero/identity rotation */ /* init ltp_to_imu quaternion as zero/identity rotation */
float_quat_identity(&ahrs_mlkf.ltp_to_imu_quat); float_quat_identity(&ahrs_mlkf.ltp_to_imu_quat);
@@ -116,7 +122,9 @@ bool_t ahrs_mlkf_align(struct Int32Rates *lp_gyro, struct Int32Vect3 *lp_accel,
ahrs_float_get_quat_from_accel_mag(&ahrs_mlkf.ltp_to_imu_quat, lp_accel, lp_mag); ahrs_float_get_quat_from_accel_mag(&ahrs_mlkf.ltp_to_imu_quat, lp_accel, lp_mag);
/* set initial body orientation */ /* set initial body orientation */
set_body_state_from_quat(); if (ahrs_mlkf.output_enabled) {
set_body_state_from_quat();
}
/* used averaged gyro as initial value for bias */ /* used averaged gyro as initial value for bias */
struct Int32Rates bias0; struct Int32Rates bias0;
@@ -132,7 +140,9 @@ void ahrs_mlkf_propagate(struct Int32Rates *gyro, float dt)
{ {
propagate_ref(gyro, dt); propagate_ref(gyro, dt);
propagate_state(dt); propagate_state(dt);
set_body_state_from_quat(); if (ahrs_mlkf.output_enabled) {
set_body_state_from_quat();
}
} }
void ahrs_mlkf_update_accel(struct Int32Vect3 *accel) void ahrs_mlkf_update_accel(struct Int32Vect3 *accel)
@@ -147,6 +157,9 @@ void ahrs_mlkf_update_accel(struct Int32Vect3 *accel)
struct FloatVect3 g_noise = {1. + dn, 1. + dn, 1. + dn}; struct FloatVect3 g_noise = {1. + dn, 1. + dn, 1. + dn};
update_state(&earth_g, &imu_g, &g_noise); update_state(&earth_g, &imu_g, &g_noise);
reset_state(); reset_state();
if (ahrs_mlkf.output_enabled) {
set_body_state_from_quat();
}
} }
void ahrs_mlkf_update_mag(struct Int32Vect3 *mag) void ahrs_mlkf_update_mag(struct Int32Vect3 *mag)
@@ -156,6 +169,9 @@ void ahrs_mlkf_update_mag(struct Int32Vect3 *mag)
#else #else
ahrs_mlkf_update_mag_2d(mag); ahrs_mlkf_update_mag_2d(mag);
#endif #endif
if (ahrs_mlkf.output_enabled) {
set_body_state_from_quat();
}
} }
void ahrs_mlkf_update_mag_2d(struct Int32Vect3 *mag) void ahrs_mlkf_update_mag_2d(struct Int32Vect3 *mag)
@@ -59,6 +59,7 @@ struct AhrsMlkf {
enum AhrsMlkfStatus status; enum AhrsMlkfStatus status;
bool_t is_aligned; bool_t is_aligned;
bool_t output_enabled; ///< if TRUE with push the estimation results to the state interface
}; };
extern struct AhrsMlkf ahrs_mlkf; extern struct AhrsMlkf ahrs_mlkf;
@@ -135,9 +135,16 @@ static void geo_mag_cb(uint8_t sender_id __attribute__((unused)), struct FloatVe
memcpy(&ahrs_mlkf.mag_h, h, sizeof(struct FloatVect3)); memcpy(&ahrs_mlkf.mag_h, h, sizeof(struct FloatVect3));
} }
static bool_t ahrs_mlkf_enable_output(bool_t enable)
{
ahrs_mlkf.output_enabled = enable;
return ahrs_mlkf.output_enabled;
}
void ahrs_mlkf_register(void) void ahrs_mlkf_register(void)
{ {
ahrs_register_impl(ahrs_mlkf_init); ahrs_mlkf_init();
ahrs_register_impl(ahrs_mlkf_enable_output);
/* /*
* Subscribe to scaled IMU measurements and attach callbacks * Subscribe to scaled IMU measurements and attach callbacks
@@ -60,6 +60,10 @@ PRINT_CONFIG_MSG("LOW PASS FILTER ON GYRO RATES")
#error "AHRS_USE_GPS_HEADING needs USE_GPS to be TRUE" #error "AHRS_USE_GPS_HEADING needs USE_GPS to be TRUE"
#endif #endif
#ifndef AHRS_ICQ_OUTPUT_ENABLED
#define AHRS_ICQ_OUTPUT_ENABLED TRUE
#endif
PRINT_CONFIG_VAR(AHRS_ICQ_OUTPUT_ENABLED)
/* /*
* default gains for correcting attitude and bias from accel/mag * default gains for correcting attitude and bias from accel/mag
@@ -112,6 +116,7 @@ void ahrs_icq_init(void)
{ {
ahrs_icq.status = AHRS_ICQ_UNINIT; ahrs_icq.status = AHRS_ICQ_UNINIT;
ahrs_icq.output_enabled = AHRS_ICQ_OUTPUT_ENABLED;
ahrs_icq.is_aligned = FALSE; ahrs_icq.is_aligned = FALSE;
ahrs_icq.ltp_vel_norm_valid = FALSE; ahrs_icq.ltp_vel_norm_valid = FALSE;
@@ -168,7 +173,9 @@ bool_t ahrs_icq_align(struct Int32Rates *lp_gyro, struct Int32Vect3 *lp_accel,
lp_mag = lp_mag; lp_mag = lp_mag;
#endif #endif
set_body_state_from_quat(); if (ahrs_icq.output_enabled) {
set_body_state_from_quat();
}
/* Use low passed gyro value as initial bias */ /* Use low passed gyro value as initial bias */
RATES_COPY(ahrs_icq.gyro_bias, *lp_gyro); RATES_COPY(ahrs_icq.gyro_bias, *lp_gyro);
@@ -209,7 +216,9 @@ void ahrs_icq_propagate(struct Int32Rates *gyro, float dt)
&omega, freq); &omega, freq);
int32_quat_normalize(&ahrs_icq.ltp_to_imu_quat); int32_quat_normalize(&ahrs_icq.ltp_to_imu_quat);
set_body_state_from_quat(); if (ahrs_icq.output_enabled) {
set_body_state_from_quat();
}
// increase accel and mag propagation counters // increase accel and mag propagation counters
ahrs_icq.accel_cnt++; ahrs_icq.accel_cnt++;
@@ -639,7 +648,9 @@ void ahrs_icq_realign_heading(int32_t heading)
int32_quat_comp(&ahrs_icq.ltp_to_imu_quat, &ltp_to_body_quat, body_to_imu_quat); int32_quat_comp(&ahrs_icq.ltp_to_imu_quat, &ltp_to_body_quat, body_to_imu_quat);
/* Set state */ /* Set state */
stateSetNedToBodyQuat_i(&ltp_to_body_quat); if (ahrs_icq.output_enabled) {
stateSetNedToBodyQuat_i(&ltp_to_body_quat);
}
ahrs_icq.heading_aligned = TRUE; ahrs_icq.heading_aligned = TRUE;
} }
@@ -102,6 +102,7 @@ struct AhrsIntCmplQuat {
enum AhrsICQStatus status; ///< status of the AHRS, AHRS_ICQ_UNINIT or AHRS_ICQ_RUNNING enum AhrsICQStatus status; ///< status of the AHRS, AHRS_ICQ_UNINIT or AHRS_ICQ_RUNNING
bool_t is_aligned; bool_t is_aligned;
bool_t output_enabled; ///< if TRUE with push the estimation results to the state interface
}; };
extern struct AhrsIntCmplQuat ahrs_icq; extern struct AhrsIntCmplQuat ahrs_icq;
@@ -209,9 +209,16 @@ static void gps_cb(uint8_t sender_id __attribute__((unused)),
ahrs_icq_update_gps(gps_s); ahrs_icq_update_gps(gps_s);
} }
static bool_t ahrs_icq_enable_output(bool_t enable)
{
ahrs_icq.output_enabled = enable;
return ahrs_icq.output_enabled;
}
void ahrs_icq_register(void) void ahrs_icq_register(void)
{ {
ahrs_register_impl(ahrs_icq_init); ahrs_icq_init();
ahrs_register_impl(ahrs_icq_enable_output);
/* /*
* Subscribe to scaled IMU measurements and attach callbacks * Subscribe to scaled IMU measurements and attach callbacks
@@ -29,7 +29,9 @@
#include "subsystems/ahrs/ahrs_int_cmpl_quat.h" #include "subsystems/ahrs/ahrs_int_cmpl_quat.h"
#define DefaultAhrsImpl ahrs_icq #ifndef PRIMARY_AHRS
#define PRIMARY_AHRS ahrs_icq
#endif
extern void ahrs_icq_register(void); extern void ahrs_icq_register(void);