diff --git a/conf/modules/airspeed_sdp3x.xml b/conf/modules/airspeed_sdp3x.xml index 5f42fe5c0f..408157fc0e 100644 --- a/conf/modules/airspeed_sdp3x.xml +++ b/conf/modules/airspeed_sdp3x.xml @@ -8,15 +8,18 @@ - - + + + + + diff --git a/sw/airborne/modules/sensors/airspeed_sdp3x.c b/sw/airborne/modules/sensors/airspeed_sdp3x.c index 25a4011265..0381377844 100644 --- a/sw/airborne/modules/sensors/airspeed_sdp3x.c +++ b/sw/airborne/modules/sensors/airspeed_sdp3x.c @@ -25,6 +25,7 @@ #include "std.h" #include "mcu_periph/i2c.h" #include "modules/sensors/airspeed_sdp3x.h" +#include "filters/low_pass_filter.h" #include "subsystems/abi.h" #include "mcu_periph/uart.h" @@ -35,6 +36,19 @@ #include "subsystems/datalink/telemetry.h" #endif +#ifndef USE_AIRSPEED_SDP3X +#if USE_AIRSPEED +#define USE_AIRSPEED_SDP3X TRUE +PRINT_CONFIG_MSG("USE_AIRSPEED_SDP3X set to TRUE since this is set USE_AIRSPEED") +#endif +#endif + +/** Use low pass filter on pressure values + */ +#ifndef USE_AIRSPEED_LOWPASS_FILTER +#define USE_AIRSPEED_LOWPASS_FILTER TRUE +#endif + /** Commands and scales */ #define SDP3X_SCALE_TEMPERATURE 200.0f @@ -91,9 +105,20 @@ PRINT_CONFIG_VAR(SDP3X_PRESSURE_OFFSET) #define SDP3X_AIRSPEED_SCALE 1.6327 #endif +/** Time constant for second order Butterworth low pass filter + * Default of 0.15 should give cut-off freq of 1/(2*pi*tau) ~= 1Hz + */ +#ifndef SDP3X_LOWPASS_TAU +#define SDP3X_LOWPASS_TAU 0.15 +#endif + struct AirspeedSdp3x sdp3x; static struct i2c_transaction sdp3x_trans; +#ifdef USE_AIRSPEED_LOWPASS_FILTER +static Butterworth2LowPass sdp3x_filter; +#endif + static bool sdp3x_crc(const uint8_t data[], unsigned size, uint8_t checksum) { uint8_t crc_value = 0xff; @@ -127,17 +152,22 @@ static void sdp3x_downlink(struct transport_tx *trans, struct link_device *dev) void sdp3x_init(void) { - sdp3x.pressure = 0.; - sdp3x.temperature = 0; - sdp3x.airspeed = 0.; + sdp3x.pressure = 0.f; + sdp3x.temperature = 0.f; + sdp3x.airspeed = 0.f; sdp3x.pressure_scale = SDP3X_PRESSURE_SCALE; sdp3x.pressure_offset = SDP3X_PRESSURE_OFFSET; sdp3x.airspeed_scale = SDP3X_AIRSPEED_SCALE; + sdp3x.autoset_offset = false; sdp3x.sync_send = SDP3X_SYNC_SEND; sdp3x.initialized = false; sdp3x_trans.status = I2CTransDone; // setup low pass filter with time constant and 100Hz sampling freq +#ifdef USE_AIRSPEED_LOWPASS_FILTER + init_butterworth_2_low_pass(&sdp3x_filter, SDP3X_LOWPASS_TAU, + SDP3X_PERIODIC_PERIOD, 0); +#endif #if PERIODIC_TELEMETRY register_periodic_telemetry(DefaultPeriodic, PPRZ_MSG_ID_AIRSPEED_MS45XX, sdp3x_downlink); // FIXME @@ -163,13 +193,16 @@ void sdp3x_periodic(void) } } +#define AUTOSET_NB_MAX 20 + void sdp3x_event(void) { /* Check if transaction is succesfull */ if (sdp3x_trans.status == I2CTransSuccess) { if (sdp3x.initialized) { - // make local copy of buffer + static int autoset_nb = 0; + static float autoset_offset = 0.f; uint8_t buf[6]; for (uint8_t i = 0; i < 6; i++) { buf[i] = sdp3x_trans.buf[i]; @@ -183,7 +216,26 @@ void sdp3x_event(void) } int16_t p_raw = ((int16_t)(buf[0]) << 8) | (int16_t)(buf[1]); - sdp3x.pressure = ((float)p_raw / sdp3x.pressure_scale) - sdp3x.pressure_offset; + + float p_out = ((float)p_raw / sdp3x.pressure_scale) - sdp3x.pressure_offset; + +#ifdef USE_AIRSPEED_LOWPASS_FILTER + sdp3x.pressure = update_butterworth_2_low_pass(&sdp3x_filter, p_out); +#else + sdp3x.pressure = p_out; +#endif + + if (sdp3x.autoset_offset) { + if (autoset_nb < AUTOSET_NB_MAX) { + autoset_offset += p_raw * sdp3x.pressure_scale; + autoset_nb++; + } else { + sdp3x.pressure_offset = autoset_offset / (float)autoset_nb; + autoset_offset = 0.f; + autoset_nb = 0; + sdp3x.autoset_offset = false; + } + } int16_t t_raw = ((int16_t)(buf[3]) << 8) | (int16_t)(buf[4]); sdp3x.temperature = (float)t_raw / SDP3X_SCALE_TEMPERATURE; @@ -195,6 +247,9 @@ void sdp3x_event(void) // Compute airspeed sdp3x.airspeed = sqrtf(Max(sdp3x.pressure * sdp3x.airspeed_scale, 0)); +#if USE_AIRSPEED_SDP3X + AbiSendMsgAIRSPEED(AIRSPEED_SDP3X_ID, sdp3x.airspeed); +#endif if (sdp3x.sync_send) { sdp3x_downlink(&(DefaultChannel).trans_tx, &(DefaultDevice).device); } diff --git a/sw/airborne/modules/sensors/airspeed_sdp3x.h b/sw/airborne/modules/sensors/airspeed_sdp3x.h index 24efa4dcff..9b801ad1ef 100644 --- a/sw/airborne/modules/sensors/airspeed_sdp3x.h +++ b/sw/airborne/modules/sensors/airspeed_sdp3x.h @@ -34,6 +34,7 @@ struct AirspeedSdp3x { float airspeed_scale; ///< Quadratic scale factor to convert (differential) pressure to airspeed float pressure_scale; ///< Scaling factor from raw measurement to Pascal float pressure_offset; ///< Offset in Pascal + bool autoset_offset; ///< Set offset value from current filtered value bool sync_send; ///< Flag to enable sending every new measurement via telemetry for debugging purpose bool initialized; ///< init flag }; diff --git a/sw/airborne/subsystems/abi_sender_ids.h b/sw/airborne/subsystems/abi_sender_ids.h index ed0cf3daf6..e8cdf7dd67 100644 --- a/sw/airborne/subsystems/abi_sender_ids.h +++ b/sw/airborne/subsystems/abi_sender_ids.h @@ -103,6 +103,10 @@ #define AIRSPEED_ADC_ID 2 #endif +#ifndef AIRSPEED_SDP3X_ID +#define AIRSPEED_SDP3X_ID 3 +#endif + /* * IDs of Incidence angles (message 24) */