Skip to content

Commit

Permalink
Wind estimation (#2028)
Browse files Browse the repository at this point in the history
* [nps] add angle of attack and sideslip to NPS

* [module] extra_dl can work with nps

* [module] add sideslip sensor to aoa_pwm module and fix apogee board file

* [module] add wind estimation module

This module is an experimental wind estimation filter based on UKF that
aims at estimating all 3 local wind components in real-time.
It is based on ChibiOS as the algorithm runs in a dedicated thread.
The algorithm itself is generated from a Matlab/Simulink model.

* [tool] read Meso-NH meteo data and feed NPS with wind information

* [module] remove nps target from extra_dl, uart not well supported on FW

* [mesonh] remove unused UDP interface

* [chibios] add compilation error message for wind estimator module
  • Loading branch information
gautierhattenberger authored and podhrmic committed Mar 19, 2017
1 parent 12b01e2 commit 0e8b580
Show file tree
Hide file tree
Showing 28 changed files with 3,854 additions and 18 deletions.
2 changes: 2 additions & 0 deletions conf/firmwares/subsystems/shared/nps.makefile
Expand Up @@ -49,6 +49,8 @@ nps.srcs += \
$(NPSDIR)/nps_sensor_gps.c \
$(NPSDIR)/nps_sensor_airspeed.c \
$(NPSDIR)/nps_sensor_temperature.c \
$(NPSDIR)/nps_sensor_aoa.c \
$(NPSDIR)/nps_sensor_sideslip.c \
$(NPSDIR)/nps_electrical.c \
$(NPSDIR)/nps_atmosphere.c \
$(NPSDIR)/nps_ivy.c \
Expand Down
21 changes: 20 additions & 1 deletion conf/modules/AOA_pwm.xml
Expand Up @@ -2,7 +2,15 @@

<module name="AOA_pwm" dir="sensors">
<doc>
<description> Angle of Attack sensor using PWM input</description>
<description>
Angle of Attack sensor using PWM input

Driver for a PWM based angle of attack sensor
A second sensor can be defined for the sideslip angle
It is assumed that both sensors are the same, only sensitivity, offset and direction can differ.

Sensor example: US DIGITAL MA3-P12-125-B
</description>
<configure name="AOA_PWM_CHANNEL" value="PWM_INPUTX" description="Select PWM input channel for AOA sensor"/>
<define name="AOA_SENS" value="(2*3.14)/AOA_PWM_PERIOD" description="sensor sensitivity"/>
<define name="AOA_OFFSET" value="0." description="offset in radian that can be set from settings"/>
Expand All @@ -12,12 +20,19 @@
<define name="AOA_PWM_OFFSET" value="1" description="initial offset on the raw pwm signal if needed (default: 1usec)"/>
<define name="SEND_AOA" value="TRUE|FALSE" description="enable telemetry report (default: TRUE)"/>
<define name="LOG_AOA" value="TRUE|FALSE" description="enable logging on SD card (default: FALSE)"/>
<configure name="SSA_PWM_CHANNEL" value="PWM_INPUTX" description="Select PWM input channel for Sideslip sensor (optional)"/>
<define name="SSA_SENS" value="(2*3.14)/AOA_PWM_PERIOD" description="sensor sensitivity"/>
<define name="SSA_OFFSET" value="0." description="offset in radian that can be set from settings"/>
<define name="SSA_REVERSE" value="TRUE|FALSE" description="set to TRUE to reverse rotation direction"/>
</doc>
<settings>
<dl_settings>
<dl_settings NAME="AOA">
<dl_setting MAX="1" MIN="0" STEP="1" VAR="aoa_send_type" shortname="send type" module="modules/sensors/aoa_pwm" values="AOA|SIDESLIP"/>
<dl_setting MAX="180" MIN="-180" STEP="0.1" VAR="aoa_pwm.offset" shortname="AOA_offset" module="modules/sensors/aoa_pwm" param="AOA_OFFSET" unit="rad" alt_unit="deg"/>
<dl_setting MAX="0.95" MIN="0" STEP="0.001" VAR="aoa_pwm.filter" shortname="AOA_filter" module="modules/sensors/aoa_pwm" param="AOA_FILTER"/>
<dl_setting MAX="180" MIN="-180" STEP="0.1" VAR="ssa_pwm.offset" shortname="SSA_offset" module="modules/sensors/aoa_pwm" param="SSA_OFFSET" unit="rad" alt_unit="deg"/>
<dl_setting MAX="0.95" MIN="0" STEP="0.001" VAR="ssa_pwm.filter" shortname="SSA_filter" module="modules/sensors/aoa_pwm" param="SSA_FILTER"/>
</dl_settings>
</dl_settings>
</settings>
Expand All @@ -35,5 +50,9 @@
<define name="AOA_PWM_CHANNEL" value="$(AOA_PWM_CHANNEL)" cond="ifdef AOA_PWM_CHANNEL" />
<define name="$(AOA_PWM_CHANNEL)_TICKS_PER_USEC" value="1" />
<define name="USE_$(AOA_PWM_CHANNEL)" value="PWM_PULSE_TYPE_ACTIVE_LOW" />
<define name="SSA_PWM_CHANNEL" value="$(SSA_PWM_CHANNEL)" cond="ifdef SSA_PWM_CHANNEL" />
<define name="$(SSA_PWM_CHANNEL)_TICKS_PER_USEC" value="1" cond="ifdef SSA_PWM_CHANNEL" />
<define name="USE_$(SSA_PWM_CHANNEL)" value="PWM_PULSE_TYPE_ACTIVE_LOW" cond="ifdef SSA_PWM_CHANNEL" />
<define name="USE_SIDESLIP" cond="ifdef SSA_PWM_CHANNEL" />
</makefile>
</module>
2 changes: 2 additions & 0 deletions conf/modules/nps.xml
Expand Up @@ -55,6 +55,8 @@
<file name="nps_sensor_gps.c" dir="nps"/>
<file name="nps_sensor_airspeed.c" dir="nps"/>
<file name="nps_sensor_temperature.c" dir="nps"/>
<file name="nps_sensor_aoa.c" dir="nps"/>
<file name="nps_sensor_sideslip.c" dir="nps"/>
<file name="nps_electrical.c" dir="nps"/>
<file name="nps_atmosphere.c" dir="nps"/>
<file name="nps_ivy.c" dir="nps"/>
Expand Down
41 changes: 41 additions & 0 deletions conf/modules/wind_estimator.xml
@@ -0,0 +1,41 @@
<!DOCTYPE module SYSTEM "module.dtd">

<module name="wind_estimator" dir="meteo">
<doc>
<description>
Wind Estimator.
Using an UKF filter generated by MATLAB running in a CHibiOS thread
Requires:
- IMU for inertial data (rates and accel)
- GPS for ground speed vector
- magnetometer for true heading
- pitot for airspeed norm
- angle of attack probe (better and faster estimate of vertical component
</description>
</doc>
<settings>
<dl_settings>
<dl_settings name="wind">
<dl_setting MAX="1" MIN="1" STEP="1" values="RESET" module="modules/meteo/wind_estimator" VAR="wind_estimator.reset" shortname="reset"/>
<dl_setting MAX="2." MIN="0." STEP="0.01" module="modules/meteo/wind_estimator" VAR="wind_estimator.r_gs" shortname="R_GS" handler="Set_R_GS"/>
<dl_setting MAX="2." MIN="0." STEP="0.01" module="modules/meteo/wind_estimator" VAR="wind_estimator.r_va" shortname="R_VA" handler="Set_R_VA"/>
<dl_setting MAX="0.1" MIN="0." STEP="0.0001" module="modules/meteo/wind_estimator" VAR="wind_estimator.r_aoa" shortname="R_AOA" handler="Set_R_AOA"/>
<dl_setting MAX="0.1" MIN="0." STEP="0.0001" module="modules/meteo/wind_estimator" VAR="wind_estimator.r_ssa" shortname="R_SSA" handler="Set_R_SSA"/>
<dl_setting MAX="1." MIN="0." STEP="0.01" module="modules/meteo/wind_estimator" VAR="wind_estimator.q_va" shortname="Q_VA" handler="Set_Q_VA"/>
<dl_setting MAX="0.01" MIN="0." STEP="0.0001" module="modules/meteo/wind_estimator" VAR="wind_estimator.q_wind" shortname="Q_WIND" handler="Set_Q_WIND"/>
<dl_setting MAX="0.001" MIN="0." STEP="0.0001" module="modules/meteo/wind_estimator" VAR="wind_estimator.q_va_scale" shortname="Q_VA_SCALE" handler="Set_Q_VA_SCALE"/>
</dl_settings>
</dl_settings>
</settings>
<header>
<file name="wind_estimator.h"/>
</header>
<init fun="wind_estimator_init()"/>
<periodic fun="wind_estimator_periodic()" freq="10." autorun="TRUE"/>
<event fun="wind_estimator_event()"/>
<makefile target="ap|nps">
<file name="wind_estimator.c"/>
<file name="lib_ukf_wind_estimator/UKF_Wind_Estimator.c"/>
</makefile>
</module>

171 changes: 171 additions & 0 deletions conf/simulator/nps/nps_sensors_params_wind_estimator.h
@@ -0,0 +1,171 @@
/*
* Copyright (C) 2016 Gautier Hattenberger
*
* This file is part of paparazzi.
*
* paparazzi is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* paparazzi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/

#ifndef NPS_SENSORS_PARAMS_H
#define NPS_SENSORS_PARAMS_H

#include "generated/airframe.h"
#include "subsystems/imu.h"


#define NPS_BODY_TO_IMU_PHI IMU_BODY_TO_IMU_PHI
#define NPS_BODY_TO_IMU_THETA IMU_BODY_TO_IMU_THETA
#define NPS_BODY_TO_IMU_PSI IMU_BODY_TO_IMU_PSI

/*
* Accelerometer
*/
/* MPU60x0 has 16bit resolution */
#define NPS_ACCEL_MIN -32767
#define NPS_ACCEL_MAX 32767
/* ms-2 */
/* aka 2^10/ACCEL_X_SENS */
#define NPS_ACCEL_SENSITIVITY_XX (IMU_ACCEL_X_SIGN * ACCEL_BFP_OF_REAL(1./IMU_ACCEL_X_SENS))
#define NPS_ACCEL_SENSITIVITY_YY (IMU_ACCEL_Y_SIGN * ACCEL_BFP_OF_REAL(1./IMU_ACCEL_Y_SENS))
#define NPS_ACCEL_SENSITIVITY_ZZ (IMU_ACCEL_Z_SIGN * ACCEL_BFP_OF_REAL(1./IMU_ACCEL_Z_SENS))

#define NPS_ACCEL_NEUTRAL_X IMU_ACCEL_X_NEUTRAL
#define NPS_ACCEL_NEUTRAL_Y IMU_ACCEL_Y_NEUTRAL
#define NPS_ACCEL_NEUTRAL_Z IMU_ACCEL_Z_NEUTRAL
/* m2s-4 */
#define NPS_ACCEL_NOISE_STD_DEV_X 5.e-2
#define NPS_ACCEL_NOISE_STD_DEV_Y 5.e-2
#define NPS_ACCEL_NOISE_STD_DEV_Z 5.e-2
/* ms-2 */
#define NPS_ACCEL_BIAS_X 0
#define NPS_ACCEL_BIAS_Y 0
#define NPS_ACCEL_BIAS_Z 0
/* s */
#ifndef NPS_ACCEL_DT
#define NPS_ACCEL_DT (1./125.)
#endif



/*
* Gyrometer
*/
/* MPU60x0 has 16 bit resolution */
#define NPS_GYRO_MIN -32767
#define NPS_GYRO_MAX 32767

/* 2^12/GYRO_X_SENS */
#define NPS_GYRO_SENSITIVITY_PP (IMU_GYRO_P_SIGN * RATE_BFP_OF_REAL(1./IMU_GYRO_P_SENS))
#define NPS_GYRO_SENSITIVITY_QQ (IMU_GYRO_Q_SIGN * RATE_BFP_OF_REAL(1./IMU_GYRO_Q_SENS))
#define NPS_GYRO_SENSITIVITY_RR (IMU_GYRO_R_SIGN * RATE_BFP_OF_REAL(1./IMU_GYRO_R_SENS))

#define NPS_GYRO_NEUTRAL_P IMU_GYRO_P_NEUTRAL
#define NPS_GYRO_NEUTRAL_Q IMU_GYRO_Q_NEUTRAL
#define NPS_GYRO_NEUTRAL_R IMU_GYRO_R_NEUTRAL

#define NPS_GYRO_NOISE_STD_DEV_P RadOfDeg(0.)
#define NPS_GYRO_NOISE_STD_DEV_Q RadOfDeg(0.)
#define NPS_GYRO_NOISE_STD_DEV_R RadOfDeg(0.)

#define NPS_GYRO_BIAS_INITIAL_P RadOfDeg( 0.0)
#define NPS_GYRO_BIAS_INITIAL_Q RadOfDeg( 0.0)
#define NPS_GYRO_BIAS_INITIAL_R RadOfDeg( 0.0)

#define NPS_GYRO_BIAS_RANDOM_WALK_STD_DEV_P RadOfDeg(0.5)
#define NPS_GYRO_BIAS_RANDOM_WALK_STD_DEV_Q RadOfDeg(0.5)
#define NPS_GYRO_BIAS_RANDOM_WALK_STD_DEV_R RadOfDeg(0.5)
/* s */
#ifndef NPS_GYRO_DT
#define NPS_GYRO_DT (1./125.)
#endif



/*
* Magnetometer
*/
/* HMC5843 has 12 bit resolution */
#define NPS_MAG_MIN -2047
#define NPS_MAG_MAX 2047

#define NPS_MAG_IMU_TO_SENSOR_PHI 0.
#define NPS_MAG_IMU_TO_SENSOR_THETA 0.
#define NPS_MAG_IMU_TO_SENSOR_PSI 0.

#define NPS_MAG_SENSITIVITY_XX (IMU_MAG_X_SIGN * MAG_BFP_OF_REAL(1./IMU_MAG_X_SENS))
#define NPS_MAG_SENSITIVITY_YY (IMU_MAG_Y_SIGN * MAG_BFP_OF_REAL(1./IMU_MAG_Y_SENS))
#define NPS_MAG_SENSITIVITY_ZZ (IMU_MAG_Z_SIGN * MAG_BFP_OF_REAL(1./IMU_MAG_Z_SENS))

#define NPS_MAG_NEUTRAL_X IMU_MAG_X_NEUTRAL
#define NPS_MAG_NEUTRAL_Y IMU_MAG_Y_NEUTRAL
#define NPS_MAG_NEUTRAL_Z IMU_MAG_Z_NEUTRAL

#define NPS_MAG_NOISE_STD_DEV_X 2e-3
#define NPS_MAG_NOISE_STD_DEV_Y 2e-3
#define NPS_MAG_NOISE_STD_DEV_Z 2e-3

#define NPS_MAG_DT (1./60.)


/*
* Barometer
*/
/* m */
/* aka 2^8/INS_BARO_SENS */
#define NPS_BARO_QNH 1013.25
#define NPS_BARO_SENSITIVITY 4.0
#define NPS_BARO_DT (1./5.)
#define NPS_BARO_NOISE_STD_DEV 5.e-2

/*
* GPS
*/

#ifndef GPS_PERFECT
#define GPS_PERFECT 1
#endif

#if GPS_PERFECT

#define NPS_GPS_SPEED_NOISE_STD_DEV 0.
#define NPS_GPS_SPEED_LATENCY 0.
#define NPS_GPS_POS_NOISE_STD_DEV 0.001
#define NPS_GPS_POS_BIAS_INITIAL_X 0.
#define NPS_GPS_POS_BIAS_INITIAL_Y 0.
#define NPS_GPS_POS_BIAS_INITIAL_Z 0.
#define NPS_GPS_POS_BIAS_RANDOM_WALK_STD_DEV_X 0.
#define NPS_GPS_POS_BIAS_RANDOM_WALK_STD_DEV_Y 0.
#define NPS_GPS_POS_BIAS_RANDOM_WALK_STD_DEV_Z 0.
#define NPS_GPS_POS_LATENCY 0.

#else

#define NPS_GPS_SPEED_NOISE_STD_DEV 0.5
#define NPS_GPS_SPEED_LATENCY 0.2
#define NPS_GPS_POS_NOISE_STD_DEV 2
#define NPS_GPS_POS_BIAS_INITIAL_X 0e-1
#define NPS_GPS_POS_BIAS_INITIAL_Y -0e-1
#define NPS_GPS_POS_BIAS_INITIAL_Z -0e-1
#define NPS_GPS_POS_BIAS_RANDOM_WALK_STD_DEV_X 1e-3
#define NPS_GPS_POS_BIAS_RANDOM_WALK_STD_DEV_Y 1e-3
#define NPS_GPS_POS_BIAS_RANDOM_WALK_STD_DEV_Z 1e-3
#define NPS_GPS_POS_LATENCY 0.2

#endif /* GPS_PERFECT */

#define NPS_GPS_DT (1./5.)

#endif /* NPS_SENSORS_PARAMS_H */
1 change: 1 addition & 0 deletions conf/telemetry/fixedwing_flight_recorder.xml
Expand Up @@ -137,6 +137,7 @@
<message name="DATALINK_REPORT" period="1.0"/>
<message name="ESC" period="0.1"/>
<message name="ADC_GENERIC" period="0.05"/>
<message name="WIND_INFO_RET" period="0.1"/>
</mode>
</process>
</telemetry>
2 changes: 1 addition & 1 deletion sw/airborne/boards/apogee/chibios/v1.0/board.h
Expand Up @@ -932,7 +932,7 @@
#if (USE_PWM1 && USE_PWM_INPUT2)
#error "PW1 and PWM_INPUT2 are not compatible"
#endif
#define PWM_INPUT2_ICU ICUD2
#define PWM_INPUT2_ICU ICUD9
#define PWM_INPUT2_CHANNEL ICU_CHANNEL_1
#define PWM_INPUT2_GPIO_PORT GPIOA
#define PWM_INPUT2_GPIO_PIN GPIO2
Expand Down
4 changes: 0 additions & 4 deletions sw/airborne/boards/apogee/chibios/v1.0/mcuconf.h
Expand Up @@ -194,11 +194,7 @@
* ICU driver system settings.
*/
#define STM32_ICU_USE_TIM1 TRUE
#ifdef USE_PWM_INPUT2
#define STM32_ICU_USE_TIM2 TRUE
#else
#define STM32_ICU_USE_TIM2 FALSE
#endif
#define STM32_ICU_USE_TIM3 FALSE
#define STM32_ICU_USE_TIM4 FALSE
#define STM32_ICU_USE_TIM5 FALSE
Expand Down

0 comments on commit 0e8b580

Please sign in to comment.