diff --git a/Makefile b/Makefile index b46b46b178..2a34d96ddb 100644 --- a/Makefile +++ b/Makefile @@ -82,6 +82,7 @@ SUBDIRS = $(PPRZCENTER) $(MISC) $(LOGALIZER) # xml files used as input for header generation # MESSAGES_XML = $(CONF)/messages.xml +ABI_XML = $(CONF)/abi.xml UBX_XML = $(CONF)/ubx.xml MTK_XML = $(CONF)/mtk.xml XSENS_XML = $(CONF)/xsens_MTi-G.xml @@ -218,7 +219,7 @@ $(DL_PROTOCOL2_H) : $(MESSAGES_XML) tools $(Q)mv $($@_TMP) $@ $(Q)chmod a+r $@ -$(ABI_MESSAGES_H) : $(MESSAGES_XML) tools +$(ABI_MESSAGES_H) : $(ABI_XML) tools @echo GENERATE $@ $(eval $@_TMP := $(shell $(MKTEMP))) $(Q)PAPARAZZI_SRC=$(PAPARAZZI_SRC) PAPARAZZI_HOME=$(PAPARAZZI_HOME) $(TOOLS)/gen_abi.out $< airborne > $($@_TMP) diff --git a/README.md b/README.md index 86ced4a95d..4cd013f77b 100644 --- a/README.md +++ b/README.md @@ -18,11 +18,12 @@ Installation is described in the wiki (http://paparazzi.enac.fr/wiki/Installatio For Ubuntu users, required packages are available in the [paparazzi-uav PPA] (https://launchpad.net/~paparazzi-uav/+archive/ppa), Debian users can use http://paparazzi.enac.fr/debian - +Debian/Ubuntu packages: - **paparazzi-dev** is the meta-package that depends on everything needed to compile and run the ground segment and the simulator. -- **paparazzi-arm-multilib** ARM cross-compiling toolchain for LPC21 and STM32 based boards. - **paparazzi-jsbsim** is needed for using JSBSim as flight dynamic model for the simulator. +Recommended cross compiling toolchain: https://launchpad.net/gcc-arm-embedded + Directories quick and dirty description: ---------------------------------------- diff --git a/conf/Makefile.omap b/conf/Makefile.omap index e567d0c314..9cc359d7cd 100644 --- a/conf/Makefile.omap +++ b/conf/Makefile.omap @@ -81,6 +81,38 @@ load upload program: $(OBJDIR)/$(TARGET).elf # Kill the application -echo "killall -9 $(TARGET).elf" | telnet $(HOST) + # Make the target dir and edit the config + -{ \ + echo "mkdir -p $(TARGET_DIR)"; \ + } | telnet $(HOST) + + # Upload the drivers and new application + { \ + echo "binary"; \ + echo "put $(PAPARAZZI_SRC)/sw/ext/ardrone2_drivers/cdc-acm.ko /$(SUB_DIR)/cdc-acm.ko"; \ + echo "put $(OBJDIR)/$(TARGET).elf /$(SUB_DIR)/$(TARGET).elf"; \ + echo "quit"; \ + } | ftp -n $(HOST) + + # Upload the modules and start the application + -{ \ + echo "insmod $(TARGET_DIR)/cdc-acm.ko"; \ + echo "chmod 777 $(TARGET_DIR)/$(TARGET).elf"; \ + echo "$(TARGET_DIR)/$(TARGET).elf > /dev/null 2>&1 &"; \ + } | telnet $(HOST) + +ifeq ($(ARDRONE2_REBOOT),1) + -{ \ + echo "reboot"; \ + } | telnet $(HOST) +endif + +# Program the device and start it. +load2 upload2 program2: $(OBJDIR)/$(TARGET).elf + + # Kill the application + -echo "killall -9 $(TARGET).elf" | telnet $(HOST) + # Make the target dir and edit the config -{ \ echo "mkdir -p $(TARGET_DIR)"; \ @@ -111,7 +143,7 @@ load upload program: $(OBJDIR)/$(TARGET).elf echo "chmod 777 $(TARGET_DIR)/$(TARGET).elf"; \ echo "$(TARGET_DIR)/$(TARGET).elf > /dev/null 2>&1 &"; \ } | telnet $(HOST) - + ifeq ($(ARDRONE2_REBOOT),1) -{ \ echo "reboot"; \ @@ -119,6 +151,8 @@ ifeq ($(ARDRONE2_REBOOT),1) endif + + # Link: create ELF output file from object files. .SECONDARY : $(OBJDIR)/$(TARGET).elf .PRECIOUS : $(OBJ_C_OMAP) $(OBJ_CPP_OMAP) @@ -140,6 +174,7 @@ $(OBJDIR)/%.o : %.cpp $(OBJDIR)/../Makefile.ac $(Q)test -d $(dir $@) || mkdir -p $(dir $@) $(Q)$(CXX) -c $(CXXFLAGS) $< -o $@ + # Listing of phony targets. .PHONY : all build elf clean clean_list diff --git a/conf/abi.xml b/conf/abi.xml new file mode 100644 index 0000000000..896761d545 --- /dev/null +++ b/conf/abi.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + diff --git a/conf/airframes/CDW/asctec_cdw.xml b/conf/airframes/CDW/asctec_cdw.xml index 830c176d2f..b5ca327b07 100644 --- a/conf/airframes/CDW/asctec_cdw.xml +++ b/conf/airframes/CDW/asctec_cdw.xml @@ -124,7 +124,6 @@
-
@@ -182,10 +181,6 @@ - - - - diff --git a/conf/airframes/CDW/tricopter_cdw.xml b/conf/airframes/CDW/tricopter_cdw.xml index 86946f11f3..3585eac907 100644 --- a/conf/airframes/CDW/tricopter_cdw.xml +++ b/conf/airframes/CDW/tricopter_cdw.xml @@ -121,7 +121,6 @@ LiPo/LiIo-Zellen: 2-3
-
@@ -179,10 +178,6 @@ LiPo/LiIo-Zellen: 2-3 - - - -
diff --git a/conf/airframes/ENAC/fixed-wing/firestorm.xml b/conf/airframes/ENAC/fixed-wing/firestorm.xml index 222712c259..4f9abc4b4c 100644 --- a/conf/airframes/ENAC/fixed-wing/firestorm.xml +++ b/conf/airframes/ENAC/fixed-wing/firestorm.xml @@ -124,7 +124,6 @@
-
diff --git a/conf/airframes/ENAC/fixed-wing/funjet2.xml b/conf/airframes/ENAC/fixed-wing/funjet2.xml index 56455152a5..670c51f99a 100644 --- a/conf/airframes/ENAC/fixed-wing/funjet2.xml +++ b/conf/airframes/ENAC/fixed-wing/funjet2.xml @@ -15,9 +15,6 @@ - diff --git a/conf/airframes/ENAC/fixed-wing/mythe.xml b/conf/airframes/ENAC/fixed-wing/mythe.xml index f6c226b11b..58d0beaac0 100644 --- a/conf/airframes/ENAC/fixed-wing/mythe.xml +++ b/conf/airframes/ENAC/fixed-wing/mythe.xml @@ -9,7 +9,6 @@ - diff --git a/conf/airframes/ENAC/fixed-wing/weasel.xml b/conf/airframes/ENAC/fixed-wing/weasel.xml index f15a4b5c41..91d220785e 100644 --- a/conf/airframes/ENAC/fixed-wing/weasel.xml +++ b/conf/airframes/ENAC/fixed-wing/weasel.xml @@ -120,7 +120,6 @@
-
diff --git a/conf/airframes/ENAC/quadrotor/blender.xml b/conf/airframes/ENAC/quadrotor/blender.xml index 2dce3cc671..c1a5406c3d 100644 --- a/conf/airframes/ENAC/quadrotor/blender.xml +++ b/conf/airframes/ENAC/quadrotor/blender.xml @@ -142,7 +142,6 @@
- @@ -225,9 +224,7 @@ - -
diff --git a/conf/airframes/ENAC/quadrotor/booz2_g1.xml b/conf/airframes/ENAC/quadrotor/booz2_g1.xml index 834132e720..1d1a729e9a 100644 --- a/conf/airframes/ENAC/quadrotor/booz2_g1.xml +++ b/conf/airframes/ENAC/quadrotor/booz2_g1.xml @@ -177,7 +177,6 @@
- @@ -199,9 +198,7 @@ - -
diff --git a/conf/airframes/ENAC/quadrotor/hen1.xml b/conf/airframes/ENAC/quadrotor/hen1.xml index 2c0bdb49ae..2b5fa5b811 100644 --- a/conf/airframes/ENAC/quadrotor/hen1.xml +++ b/conf/airframes/ENAC/quadrotor/hen1.xml @@ -127,7 +127,6 @@
-
@@ -205,9 +204,7 @@ - -
diff --git a/conf/airframes/TUDelft/IMAV2013/ardrone2_raw.xml b/conf/airframes/TUDelft/IMAV2013/ardrone2_raw.xml index cf2739449c..0542c01425 100644 --- a/conf/airframes/TUDelft/IMAV2013/ardrone2_raw.xml +++ b/conf/airframes/TUDelft/IMAV2013/ardrone2_raw.xml @@ -174,10 +174,6 @@ - - - -
diff --git a/conf/airframes/TUDelft/IMAV2013/chouchou_lisa_s.xml b/conf/airframes/TUDelft/IMAV2013/chouchou_lisa_s.xml index 7a870f3b9c..4ce0305ecf 100644 --- a/conf/airframes/TUDelft/IMAV2013/chouchou_lisa_s.xml +++ b/conf/airframes/TUDelft/IMAV2013/chouchou_lisa_s.xml @@ -145,7 +145,6 @@
-
@@ -157,10 +156,6 @@ - - - -
diff --git a/conf/airframes/TUDelft/IMAV2013/quadrotor_lisa_s.xml b/conf/airframes/TUDelft/IMAV2013/quadrotor_lisa_s.xml index 064c01ae5a..6e5b38afe9 100644 --- a/conf/airframes/TUDelft/IMAV2013/quadrotor_lisa_s.xml +++ b/conf/airframes/TUDelft/IMAV2013/quadrotor_lisa_s.xml @@ -147,7 +147,6 @@
-
@@ -159,10 +158,6 @@ - - - -
diff --git a/conf/airframes/TUDelft/IMAV2013/walkera_V120D02S.xml b/conf/airframes/TUDelft/IMAV2013/walkera_V120D02S.xml index 2ee2d7548e..f28c89cdd5 100644 --- a/conf/airframes/TUDelft/IMAV2013/walkera_V120D02S.xml +++ b/conf/airframes/TUDelft/IMAV2013/walkera_V120D02S.xml @@ -129,7 +129,6 @@
-
@@ -141,10 +140,6 @@ - - - -
diff --git a/conf/airframes/TUDelft/IMAV2013/walkera_genius_v1.xml b/conf/airframes/TUDelft/IMAV2013/walkera_genius_v1.xml index 4e7dda0a2e..d06a6cbdee 100644 --- a/conf/airframes/TUDelft/IMAV2013/walkera_genius_v1.xml +++ b/conf/airframes/TUDelft/IMAV2013/walkera_genius_v1.xml @@ -134,7 +134,6 @@
-
@@ -146,10 +145,6 @@ - - - -
diff --git a/conf/airframes/TestHardware/LisaL_v1.1_aspirin_v1.5_rc.xml b/conf/airframes/TestHardware/LisaL_v1.1_aspirin_v1.5_rc.xml index ee9e0848ac..af754f073d 100644 --- a/conf/airframes/TestHardware/LisaL_v1.1_aspirin_v1.5_rc.xml +++ b/conf/airframes/TestHardware/LisaL_v1.1_aspirin_v1.5_rc.xml @@ -221,7 +221,6 @@
-
@@ -234,10 +233,6 @@ - - - -
diff --git a/conf/airframes/TestHardware/LisaL_v1.1_b2_v1.2_rc.xml b/conf/airframes/TestHardware/LisaL_v1.1_b2_v1.2_rc.xml index 06f2f97307..a474774180 100644 --- a/conf/airframes/TestHardware/LisaL_v1.1_b2_v1.2_rc.xml +++ b/conf/airframes/TestHardware/LisaL_v1.1_b2_v1.2_rc.xml @@ -221,7 +221,6 @@
-
@@ -234,10 +233,6 @@ - - - -
diff --git a/conf/airframes/ardrone2_raw.xml b/conf/airframes/ardrone2_raw.xml index 99265a1638..4378808f12 100644 --- a/conf/airframes/ardrone2_raw.xml +++ b/conf/airframes/ardrone2_raw.xml @@ -5,7 +5,6 @@ - @@ -20,15 +19,14 @@ + - - @@ -39,7 +37,7 @@ - + @@ -55,11 +53,12 @@ + - - - - + + + + @@ -71,40 +70,45 @@
- - - + + + + - - - - - - - - - + + + + + + + + + + + +
- - +
- -
- +
- + + + + + +
-
@@ -132,7 +136,6 @@
-
@@ -195,10 +198,13 @@
+ + + - +
@@ -221,5 +227,4 @@
- diff --git a/conf/airframes/ardrone2_sdk.xml b/conf/airframes/ardrone2_sdk.xml index 73c21af476..792c0bc74f 100644 --- a/conf/airframes/ardrone2_sdk.xml +++ b/conf/airframes/ardrone2_sdk.xml @@ -81,10 +81,6 @@ - - - - diff --git a/conf/airframes/esden/cocto_lm2a2.xml b/conf/airframes/esden/cocto_lm2a2.xml index 609e7295bd..692ba0ecb6 100644 --- a/conf/airframes/esden/cocto_lm2a2.xml +++ b/conf/airframes/esden/cocto_lm2a2.xml @@ -170,7 +170,6 @@ B2L -> CW
-
@@ -182,10 +181,6 @@ B2L -> CW - - - -
diff --git a/conf/airframes/esden/gain_scheduling_example.xml b/conf/airframes/esden/gain_scheduling_example.xml index 02f574bd9f..c169f8c314 100644 --- a/conf/airframes/esden/gain_scheduling_example.xml +++ b/conf/airframes/esden/gain_scheduling_example.xml @@ -153,7 +153,6 @@
-
@@ -165,8 +164,6 @@ - -
diff --git a/conf/airframes/esden/hexy_ll11a2pwm.xml b/conf/airframes/esden/hexy_ll11a2pwm.xml index f796f42c68..c7cc5ce652 100644 --- a/conf/airframes/esden/hexy_ll11a2pwm.xml +++ b/conf/airframes/esden/hexy_ll11a2pwm.xml @@ -167,7 +167,6 @@
-
@@ -179,10 +178,6 @@ - - - -
diff --git a/conf/airframes/esden/hexy_lm2a2pwm.xml b/conf/airframes/esden/hexy_lm2a2pwm.xml index 73554f3209..7eb3cd3420 100644 --- a/conf/airframes/esden/hexy_lm2a2pwm.xml +++ b/conf/airframes/esden/hexy_lm2a2pwm.xml @@ -128,7 +128,6 @@
-
@@ -140,10 +139,6 @@ - - - -
diff --git a/conf/airframes/esden/lisa2_hex.xml b/conf/airframes/esden/lisa2_hex.xml index b21dddffcb..a8c786cc69 100644 --- a/conf/airframes/esden/lisa2_hex.xml +++ b/conf/airframes/esden/lisa2_hex.xml @@ -135,7 +135,6 @@
-
@@ -147,10 +146,6 @@ - - - -
diff --git a/conf/airframes/esden/qs_asp22.xml b/conf/airframes/esden/qs_asp22.xml index c4ef62b938..120cb296c8 100644 --- a/conf/airframes/esden/qs_asp22.xml +++ b/conf/airframes/esden/qs_asp22.xml @@ -161,7 +161,6 @@
-
@@ -173,8 +172,6 @@ - -
diff --git a/conf/airframes/esden/quady_ll11a2pwm.xml b/conf/airframes/esden/quady_ll11a2pwm.xml index ca80e5a5d2..d4337f236c 100644 --- a/conf/airframes/esden/quady_ll11a2pwm.xml +++ b/conf/airframes/esden/quady_ll11a2pwm.xml @@ -163,7 +163,6 @@
-
@@ -175,10 +174,6 @@ - - - -
diff --git a/conf/airframes/esden/quady_lm1a1pwm.xml b/conf/airframes/esden/quady_lm1a1pwm.xml index 406734e757..517dad5dd2 100644 --- a/conf/airframes/esden/quady_lm1a1pwm.xml +++ b/conf/airframes/esden/quady_lm1a1pwm.xml @@ -124,7 +124,6 @@
-
@@ -136,10 +135,6 @@ - - - -
diff --git a/conf/airframes/esden/quady_lm2a2pwm.xml b/conf/airframes/esden/quady_lm2a2pwm.xml index e87c817b3e..b23eb2c303 100644 --- a/conf/airframes/esden/quady_lm2a2pwm.xml +++ b/conf/airframes/esden/quady_lm2a2pwm.xml @@ -127,7 +127,6 @@
-
@@ -139,10 +138,6 @@ - - - -
diff --git a/conf/airframes/esden/quady_lm2a2pwmppm.xml b/conf/airframes/esden/quady_lm2a2pwmppm.xml index 31fd65c39d..bb11c56f1d 100644 --- a/conf/airframes/esden/quady_lm2a2pwmppm.xml +++ b/conf/airframes/esden/quady_lm2a2pwmppm.xml @@ -124,7 +124,6 @@
-
@@ -136,10 +135,6 @@ - - - -
diff --git a/conf/airframes/esden/quady_ls01pwm.xml b/conf/airframes/esden/quady_ls01pwm.xml index 4a3a194c39..00b255d544 100644 --- a/conf/airframes/esden/quady_ls01pwm.xml +++ b/conf/airframes/esden/quady_ls01pwm.xml @@ -127,7 +127,6 @@
-
@@ -139,10 +138,6 @@ - - - -
diff --git a/conf/airframes/examples/Twinstar_energyadaptive.xml b/conf/airframes/examples/Twinstar_energyadaptive.xml index d58dbd1fb1..c5afbe19cf 100644 --- a/conf/airframes/examples/Twinstar_energyadaptive.xml +++ b/conf/airframes/examples/Twinstar_energyadaptive.xml @@ -12,7 +12,6 @@ twog_1.0 + aspirin + ETS baro + ETS speed - @@ -22,6 +21,9 @@ twog_1.0 + aspirin + ETS baro + ETS speed + + + @@ -50,12 +52,11 @@ twog_1.0 + aspirin + ETS baro + ETS speed - + + - - - + @@ -124,7 +125,6 @@ twog_1.0 + aspirin + ETS baro + ETS speed
-
diff --git a/conf/airframes/examples/booz2.xml b/conf/airframes/examples/booz2.xml index e93ccf9d2c..72a05e09bc 100644 --- a/conf/airframes/examples/booz2.xml +++ b/conf/airframes/examples/booz2.xml @@ -148,7 +148,6 @@
-
@@ -160,10 +159,6 @@ - - - -
diff --git a/conf/airframes/examples/easystar_ets.xml b/conf/airframes/examples/easystar_ets.xml index a66406c0c7..4f23f35360 100644 --- a/conf/airframes/examples/easystar_ets.xml +++ b/conf/airframes/examples/easystar_ets.xml @@ -19,7 +19,6 @@ - @@ -37,9 +36,6 @@ - - - diff --git a/conf/airframes/examples/h_hex.xml b/conf/airframes/examples/h_hex.xml index 5faaedebe3..8bb83004de 100644 --- a/conf/airframes/examples/h_hex.xml +++ b/conf/airframes/examples/h_hex.xml @@ -147,7 +147,6 @@
-
@@ -159,10 +158,6 @@ - - - -
diff --git a/conf/airframes/examples/krooz_sd/krooz_sd_hexa_mkk.xml b/conf/airframes/examples/krooz_sd/krooz_sd_hexa_mkk.xml index 44f2681826..6de9a1cd82 100644 --- a/conf/airframes/examples/krooz_sd/krooz_sd_hexa_mkk.xml +++ b/conf/airframes/examples/krooz_sd/krooz_sd_hexa_mkk.xml @@ -112,14 +112,13 @@
- +
-
@@ -206,9 +205,7 @@ - -
diff --git a/conf/airframes/examples/krooz_sd/krooz_sd_okto_mkk.xml b/conf/airframes/examples/krooz_sd/krooz_sd_okto_mkk.xml index 4bf55eeb9f..a01191d274 100644 --- a/conf/airframes/examples/krooz_sd/krooz_sd_okto_mkk.xml +++ b/conf/airframes/examples/krooz_sd/krooz_sd_okto_mkk.xml @@ -115,14 +115,13 @@
- +
-
@@ -209,9 +208,7 @@ - -
diff --git a/conf/airframes/examples/krooz_sd/krooz_sd_quad_mkk.xml b/conf/airframes/examples/krooz_sd/krooz_sd_quad_mkk.xml index ebdda35837..ffdede1e73 100644 --- a/conf/airframes/examples/krooz_sd/krooz_sd_quad_mkk.xml +++ b/conf/airframes/examples/krooz_sd/krooz_sd_quad_mkk.xml @@ -24,8 +24,6 @@ - - @@ -105,14 +103,14 @@
- + +
-
@@ -145,35 +143,35 @@ - + - - - - + + + + - - - - + + + + - + - - + + - - - + + + - - - + + + @@ -182,7 +180,7 @@ - +
@@ -191,16 +189,14 @@ - - - - - - + + + + + + + - - -
@@ -209,9 +205,8 @@ - - +
@@ -229,8 +224,8 @@
- - + +
diff --git a/conf/airframes/examples/krooz_sd/krooz_sd_quad_pwm.xml b/conf/airframes/examples/krooz_sd/krooz_sd_quad_pwm.xml index cf85a484c0..4a3944ecb8 100644 --- a/conf/airframes/examples/krooz_sd/krooz_sd_quad_pwm.xml +++ b/conf/airframes/examples/krooz_sd/krooz_sd_quad_pwm.xml @@ -101,14 +101,13 @@
- +
-
@@ -194,9 +193,7 @@ - -
diff --git a/conf/airframes/examples/lisa_asctec.xml b/conf/airframes/examples/lisa_asctec.xml index 5e4869cb87..1440ea0781 100644 --- a/conf/airframes/examples/lisa_asctec.xml +++ b/conf/airframes/examples/lisa_asctec.xml @@ -146,7 +146,6 @@
-
@@ -158,10 +157,6 @@ - - - -
diff --git a/conf/airframes/examples/quadrotor_lisa_m_2_pwm_spektrum.xml b/conf/airframes/examples/quadrotor_lisa_m_2_pwm_spektrum.xml index 4d68ce1534..b332a0c730 100644 --- a/conf/airframes/examples/quadrotor_lisa_m_2_pwm_spektrum.xml +++ b/conf/airframes/examples/quadrotor_lisa_m_2_pwm_spektrum.xml @@ -35,7 +35,7 @@ - + @@ -102,7 +102,6 @@
-
@@ -184,16 +183,13 @@ - - - -
+ diff --git a/conf/airframes/examples/quadrotor_lisa_m_2_pwm_spektrum_geo_mag.xml b/conf/airframes/examples/quadrotor_lisa_m_2_pwm_spektrum_geo_mag.xml index 9f7210bd3e..136a0b1d02 100644 --- a/conf/airframes/examples/quadrotor_lisa_m_2_pwm_spektrum_geo_mag.xml +++ b/conf/airframes/examples/quadrotor_lisa_m_2_pwm_spektrum_geo_mag.xml @@ -104,7 +104,6 @@
-
@@ -187,10 +186,6 @@ - - - -
diff --git a/conf/airframes/examples/quadrotor_lisa_m_mkk.xml b/conf/airframes/examples/quadrotor_lisa_m_mkk.xml index 4746f8f78d..016537f4f4 100644 --- a/conf/airframes/examples/quadrotor_lisa_m_mkk.xml +++ b/conf/airframes/examples/quadrotor_lisa_m_mkk.xml @@ -94,7 +94,6 @@
-
@@ -176,10 +175,6 @@ - - - -
diff --git a/conf/airframes/examples/quadrotor_lisa_s.xml b/conf/airframes/examples/quadrotor_lisa_s.xml index bc0ffa17be..c963633c5e 100644 --- a/conf/airframes/examples/quadrotor_lisa_s.xml +++ b/conf/airframes/examples/quadrotor_lisa_s.xml @@ -147,7 +147,6 @@
-
@@ -159,10 +158,6 @@ - - - -
diff --git a/conf/airframes/examples/quadrotor_mlkf.xml b/conf/airframes/examples/quadrotor_mlkf.xml index 781cbd771a..5c264fc3a7 100644 --- a/conf/airframes/examples/quadrotor_mlkf.xml +++ b/conf/airframes/examples/quadrotor_mlkf.xml @@ -27,9 +27,7 @@ - - - +
@@ -100,7 +98,6 @@
-
@@ -186,10 +183,6 @@ - - - -
diff --git a/conf/airframes/examples/quadrotor_navgo.xml b/conf/airframes/examples/quadrotor_navgo.xml index 98df961abd..3316eec5ff 100644 --- a/conf/airframes/examples/quadrotor_navgo.xml +++ b/conf/airframes/examples/quadrotor_navgo.xml @@ -36,6 +36,8 @@ + +
@@ -117,7 +119,6 @@
- @@ -127,7 +128,6 @@
- @@ -208,9 +208,7 @@ - -
diff --git a/conf/airframes/examples/quadrotor_px4fmu.xml b/conf/airframes/examples/quadrotor_px4fmu.xml index fb02773791..b189c2c8e6 100644 --- a/conf/airframes/examples/quadrotor_px4fmu.xml +++ b/conf/airframes/examples/quadrotor_px4fmu.xml @@ -98,7 +98,6 @@
-
@@ -180,10 +179,6 @@ - - - -
diff --git a/conf/airframes/examples/quadshot_asp21_spektrum.xml b/conf/airframes/examples/quadshot_asp21_spektrum.xml index d5fc8439fd..d1bbc5525d 100644 --- a/conf/airframes/examples/quadshot_asp21_spektrum.xml +++ b/conf/airframes/examples/quadshot_asp21_spektrum.xml @@ -184,7 +184,6 @@ More information on the Quadshot can be found at transition-robotics.com -->
-
@@ -197,8 +196,6 @@ More information on the Quadshot can be found at transition-robotics.com --> - - diff --git a/conf/airframes/examples/stm32f4_discovery_test.xml b/conf/airframes/examples/stm32f4_discovery_test.xml index ed339e5a4a..6735c16ec3 100644 --- a/conf/airframes/examples/stm32f4_discovery_test.xml +++ b/conf/airframes/examples/stm32f4_discovery_test.xml @@ -24,20 +24,18 @@ - + - + + - - - @@ -100,7 +98,6 @@
-
@@ -182,10 +179,6 @@ - - - -
diff --git a/conf/airframes/fraser_lisa_m_rotorcraft.xml b/conf/airframes/fraser_lisa_m_rotorcraft.xml index a347658ee8..9139db0e35 100644 --- a/conf/airframes/fraser_lisa_m_rotorcraft.xml +++ b/conf/airframes/fraser_lisa_m_rotorcraft.xml @@ -30,7 +30,7 @@ - + @@ -138,7 +138,6 @@
-
@@ -220,16 +219,13 @@ - - - -
- + + diff --git a/conf/airframes/obsolete/ENAC/g1_vision.xml b/conf/airframes/obsolete/ENAC/g1_vision.xml index d24b588c2e..988b66025f 100644 --- a/conf/airframes/obsolete/ENAC/g1_vision.xml +++ b/conf/airframes/obsolete/ENAC/g1_vision.xml @@ -130,7 +130,6 @@
-
@@ -156,9 +155,7 @@ - - diff --git a/conf/airframes/obsolete/ENAC/mkk1-vision.xml b/conf/airframes/obsolete/ENAC/mkk1-vision.xml index 4d78dbd80b..dc44ffc4bc 100644 --- a/conf/airframes/obsolete/ENAC/mkk1-vision.xml +++ b/conf/airframes/obsolete/ENAC/mkk1-vision.xml @@ -163,7 +163,6 @@
-
@@ -189,10 +188,6 @@ - - - - diff --git a/conf/airframes/obsolete/ENAC/mkk1.xml b/conf/airframes/obsolete/ENAC/mkk1.xml index 18a9742bc7..e1b71b9eb3 100644 --- a/conf/airframes/obsolete/ENAC/mkk1.xml +++ b/conf/airframes/obsolete/ENAC/mkk1.xml @@ -193,7 +193,6 @@
-
@@ -209,10 +208,6 @@ - - - -
diff --git a/conf/airframes/obsolete/ENAC/nova1.xml b/conf/airframes/obsolete/ENAC/nova1.xml index 0ef106ba39..7824e3e3a3 100644 --- a/conf/airframes/obsolete/ENAC/nova1.xml +++ b/conf/airframes/obsolete/ENAC/nova1.xml @@ -164,7 +164,6 @@
-
@@ -180,10 +179,6 @@ - - - -
diff --git a/conf/airframes/NoVa_L.xml b/conf/airframes/obsolete/NoVa_L.xml similarity index 97% rename from conf/airframes/NoVa_L.xml rename to conf/airframes/obsolete/NoVa_L.xml index aaf45e3e27..890f626200 100644 --- a/conf/airframes/NoVa_L.xml +++ b/conf/airframes/obsolete/NoVa_L.xml @@ -189,7 +189,6 @@
-
@@ -208,10 +207,6 @@ --> - - - -
diff --git a/conf/airframes/obsolete/PPZUAV/quadrotor/ppzuav_booz2_asctec_example.xml b/conf/airframes/obsolete/PPZUAV/quadrotor/ppzuav_booz2_asctec_example.xml index 0c2cfe06c0..3a16d424a6 100644 --- a/conf/airframes/obsolete/PPZUAV/quadrotor/ppzuav_booz2_asctec_example.xml +++ b/conf/airframes/obsolete/PPZUAV/quadrotor/ppzuav_booz2_asctec_example.xml @@ -149,7 +149,6 @@
-
@@ -164,9 +163,7 @@ - - diff --git a/conf/airframes/obsolete/PPZUAV/quadrotor/ppzuav_booz2_mkk_example.xml b/conf/airframes/obsolete/PPZUAV/quadrotor/ppzuav_booz2_mkk_example.xml index 6d60135e55..6c37dde48e 100644 --- a/conf/airframes/obsolete/PPZUAV/quadrotor/ppzuav_booz2_mkk_example.xml +++ b/conf/airframes/obsolete/PPZUAV/quadrotor/ppzuav_booz2_mkk_example.xml @@ -166,7 +166,6 @@
-
@@ -182,9 +181,7 @@ - - diff --git a/conf/airframes/obsolete/Poine/booz2_a1.xml b/conf/airframes/obsolete/Poine/booz2_a1.xml index 5823e29e03..c57175d1ca 100644 --- a/conf/airframes/obsolete/Poine/booz2_a1.xml +++ b/conf/airframes/obsolete/Poine/booz2_a1.xml @@ -142,7 +142,6 @@
-
@@ -154,10 +153,6 @@ - - - -
diff --git a/conf/airframes/obsolete/Poine/booz2_a7.xml b/conf/airframes/obsolete/Poine/booz2_a7.xml index d3f23c31fd..ebaa87a22b 100644 --- a/conf/airframes/obsolete/Poine/booz2_a7.xml +++ b/conf/airframes/obsolete/Poine/booz2_a7.xml @@ -161,7 +161,6 @@
-
@@ -180,10 +179,6 @@ - - - -
diff --git a/conf/airframes/obsolete/Poine/h_hex.xml b/conf/airframes/obsolete/Poine/h_hex.xml index 252cdacf33..3551f55043 100644 --- a/conf/airframes/obsolete/Poine/h_hex.xml +++ b/conf/airframes/obsolete/Poine/h_hex.xml @@ -128,7 +128,6 @@
-
@@ -140,10 +139,6 @@ - - - -
diff --git a/conf/airframes/obsolete/UofAdelaide/A1000_BOOZ.xml b/conf/airframes/obsolete/UofAdelaide/A1000_BOOZ.xml index 10b61e41a0..70be3d2a50 100644 --- a/conf/airframes/obsolete/UofAdelaide/A1000_BOOZ.xml +++ b/conf/airframes/obsolete/UofAdelaide/A1000_BOOZ.xml @@ -216,7 +216,6 @@ second attempt
-
@@ -228,10 +227,6 @@ second attempt - - - -
diff --git a/conf/airframes/obsolete/UofAdelaide/A1000_LISA.xml b/conf/airframes/obsolete/UofAdelaide/A1000_LISA.xml index 5f3ee2a945..ead16fa04c 100644 --- a/conf/airframes/obsolete/UofAdelaide/A1000_LISA.xml +++ b/conf/airframes/obsolete/UofAdelaide/A1000_LISA.xml @@ -153,7 +153,6 @@
-
@@ -165,10 +164,6 @@ - - - -
diff --git a/conf/airframes/obsolete/UofAdelaide/A1000_NOVA.xml b/conf/airframes/obsolete/UofAdelaide/A1000_NOVA.xml index 406d6de2c0..aaae07223d 100644 --- a/conf/airframes/obsolete/UofAdelaide/A1000_NOVA.xml +++ b/conf/airframes/obsolete/UofAdelaide/A1000_NOVA.xml @@ -171,7 +171,6 @@
-
@@ -189,9 +188,7 @@ - - diff --git a/conf/airframes/obsolete/UofAdelaide/booz2_NoVa_001_1000.xml b/conf/airframes/obsolete/UofAdelaide/booz2_NoVa_001_1000.xml index 3328cc4b18..03d5cc45d3 100644 --- a/conf/airframes/obsolete/UofAdelaide/booz2_NoVa_001_1000.xml +++ b/conf/airframes/obsolete/UofAdelaide/booz2_NoVa_001_1000.xml @@ -171,7 +171,6 @@
-
@@ -189,9 +188,7 @@ - - diff --git a/conf/airframes/obsolete/UofAdelaide/booz2_a1000.xml b/conf/airframes/obsolete/UofAdelaide/booz2_a1000.xml index 82f499852b..abdc4df4dd 100644 --- a/conf/airframes/obsolete/UofAdelaide/booz2_a1000.xml +++ b/conf/airframes/obsolete/UofAdelaide/booz2_a1000.xml @@ -217,7 +217,6 @@ second attempt
-
@@ -229,10 +228,6 @@ second attempt - - - -
diff --git a/conf/airframes/obsolete/UofAdelaide/lisa_a1000.xml b/conf/airframes/obsolete/UofAdelaide/lisa_a1000.xml index 0cecb4fdb2..cfccc53017 100644 --- a/conf/airframes/obsolete/UofAdelaide/lisa_a1000.xml +++ b/conf/airframes/obsolete/UofAdelaide/lisa_a1000.xml @@ -132,7 +132,6 @@
-
@@ -144,10 +143,6 @@ - - - -
diff --git a/conf/airframes/obsolete/booz2_Aron.xml b/conf/airframes/obsolete/booz2_Aron.xml index a5a48f5295..426c2a1991 100644 --- a/conf/airframes/obsolete/booz2_Aron.xml +++ b/conf/airframes/obsolete/booz2_Aron.xml @@ -134,7 +134,6 @@
-
@@ -149,9 +148,7 @@ - -
diff --git a/conf/airframes/obsolete/booz2_NoVa.xml b/conf/airframes/obsolete/booz2_NoVa.xml index aa12a6dfdd..11aa351569 100644 --- a/conf/airframes/obsolete/booz2_NoVa.xml +++ b/conf/airframes/obsolete/booz2_NoVa.xml @@ -171,7 +171,6 @@
-
@@ -189,9 +188,7 @@ - - diff --git a/conf/airframes/obsolete/booz2_NoVa_001.xml b/conf/airframes/obsolete/booz2_NoVa_001.xml index 81c9021e83..8b303bb013 100644 --- a/conf/airframes/obsolete/booz2_NoVa_001.xml +++ b/conf/airframes/obsolete/booz2_NoVa_001.xml @@ -171,7 +171,6 @@
-
@@ -189,9 +188,7 @@ - - diff --git a/conf/airframes/obsolete/booz2_NoVa_002.xml b/conf/airframes/obsolete/booz2_NoVa_002.xml index ed879fb742..d0e286b964 100644 --- a/conf/airframes/obsolete/booz2_NoVa_002.xml +++ b/conf/airframes/obsolete/booz2_NoVa_002.xml @@ -171,7 +171,6 @@
-
@@ -189,9 +188,7 @@ - - diff --git a/conf/airframes/obsolete/booz2_a1p.xml b/conf/airframes/obsolete/booz2_a1p.xml index 18ff3d98f8..743dd891d9 100644 --- a/conf/airframes/obsolete/booz2_a1p.xml +++ b/conf/airframes/obsolete/booz2_a1p.xml @@ -146,7 +146,6 @@
-
@@ -158,10 +157,6 @@ - - - -
diff --git a/conf/airframes/obsolete/booz2_a2.xml b/conf/airframes/obsolete/booz2_a2.xml index d0f9361638..88ffa59789 100644 --- a/conf/airframes/obsolete/booz2_a2.xml +++ b/conf/airframes/obsolete/booz2_a2.xml @@ -134,7 +134,6 @@
-
@@ -149,9 +148,7 @@ - -
diff --git a/conf/airframes/obsolete/booz2_a3.xml b/conf/airframes/obsolete/booz2_a3.xml index 0635e3ce89..c234c2b1a7 100644 --- a/conf/airframes/obsolete/booz2_a3.xml +++ b/conf/airframes/obsolete/booz2_a3.xml @@ -121,7 +121,6 @@
-
@@ -134,9 +133,7 @@ - -
diff --git a/conf/airframes/obsolete/booz2_a4.xml b/conf/airframes/obsolete/booz2_a4.xml index e9cc7ede69..776ed8f12b 100644 --- a/conf/airframes/obsolete/booz2_a4.xml +++ b/conf/airframes/obsolete/booz2_a4.xml @@ -99,7 +99,6 @@
-
@@ -112,9 +111,7 @@ - -
diff --git a/conf/airframes/obsolete/booz2_a5.xml b/conf/airframes/obsolete/booz2_a5.xml index 6fc2fe07eb..3f79fb0e75 100644 --- a/conf/airframes/obsolete/booz2_a5.xml +++ b/conf/airframes/obsolete/booz2_a5.xml @@ -138,7 +138,6 @@
-
@@ -150,10 +149,6 @@ - - - -
diff --git a/conf/airframes/booz2_flixr.xml b/conf/airframes/obsolete/booz2_flixr.xml similarity index 98% rename from conf/airframes/booz2_flixr.xml rename to conf/airframes/obsolete/booz2_flixr.xml index a62ace8aee..b3a8cab4f5 100644 --- a/conf/airframes/booz2_flixr.xml +++ b/conf/airframes/obsolete/booz2_flixr.xml @@ -190,7 +190,6 @@
-
@@ -204,9 +203,7 @@ - - diff --git a/conf/airframes/booz2_ppzuav.xml b/conf/airframes/obsolete/booz2_ppzuav.xml similarity index 98% rename from conf/airframes/booz2_ppzuav.xml rename to conf/airframes/obsolete/booz2_ppzuav.xml index af532c20f2..6915b576da 100644 --- a/conf/airframes/booz2_ppzuav.xml +++ b/conf/airframes/obsolete/booz2_ppzuav.xml @@ -164,9 +164,7 @@ - -
@@ -188,7 +186,6 @@
-
diff --git a/conf/airframes/obsolete/booz2_s1.xml b/conf/airframes/obsolete/booz2_s1.xml index 4cf6bb4bbe..54d25a357e 100644 --- a/conf/airframes/obsolete/booz2_s1.xml +++ b/conf/airframes/obsolete/booz2_s1.xml @@ -130,7 +130,6 @@
-
@@ -142,9 +141,7 @@ - -
diff --git a/conf/airframes/obsolete/booz2_x1.xml b/conf/airframes/obsolete/booz2_x1.xml index 370920cd85..97fc3920ba 100644 --- a/conf/airframes/obsolete/booz2_x1.xml +++ b/conf/airframes/obsolete/booz2_x1.xml @@ -141,7 +141,6 @@
-
@@ -154,9 +153,7 @@ - -
diff --git a/conf/airframes/obsolete/example_heli_lisam.xml b/conf/airframes/obsolete/example_heli_lisam.xml index 79e8d519ac..33e8073432 100644 --- a/conf/airframes/obsolete/example_heli_lisam.xml +++ b/conf/airframes/obsolete/example_heli_lisam.xml @@ -181,7 +181,6 @@ AP_MODE_NAV
-
@@ -193,10 +192,6 @@ AP_MODE_NAV - - - -
diff --git a/conf/airframes/mentor_tum.xml b/conf/airframes/obsolete/mentor_tum.xml similarity index 100% rename from conf/airframes/mentor_tum.xml rename to conf/airframes/obsolete/mentor_tum.xml diff --git a/conf/airframes/obsolete/mm/rotor/qmk1.xml b/conf/airframes/obsolete/mm/rotor/qmk1.xml index 37b3b6c07a..a593c6aec1 100644 --- a/conf/airframes/obsolete/mm/rotor/qmk1.xml +++ b/conf/airframes/obsolete/mm/rotor/qmk1.xml @@ -141,8 +141,6 @@
- -
@@ -154,10 +152,6 @@ - - - -
diff --git a/conf/airframes/obsolete/mm/rotor/quadrotor_lisa_l_mkk.xml b/conf/airframes/obsolete/mm/rotor/quadrotor_lisa_l_mkk.xml index 5d1b3e397d..154bce55bf 100644 --- a/conf/airframes/obsolete/mm/rotor/quadrotor_lisa_l_mkk.xml +++ b/conf/airframes/obsolete/mm/rotor/quadrotor_lisa_l_mkk.xml @@ -119,7 +119,6 @@
-
@@ -201,10 +200,6 @@ - - - -
diff --git a/conf/airframes/obsolete/mm/rotor/quadrotor_lisa_m_1_pwm.xml b/conf/airframes/obsolete/mm/rotor/quadrotor_lisa_m_1_pwm.xml index 5343031357..5fd31a6e33 100644 --- a/conf/airframes/obsolete/mm/rotor/quadrotor_lisa_m_1_pwm.xml +++ b/conf/airframes/obsolete/mm/rotor/quadrotor_lisa_m_1_pwm.xml @@ -82,7 +82,6 @@
-
@@ -164,10 +163,6 @@ - - - -
diff --git a/conf/airframes/obsolete/mm/rotor/quadrotor_lisa_m_2_pwm.xml b/conf/airframes/obsolete/mm/rotor/quadrotor_lisa_m_2_pwm.xml index 2ba487a784..32b121c0f6 100644 --- a/conf/airframes/obsolete/mm/rotor/quadrotor_lisa_m_2_pwm.xml +++ b/conf/airframes/obsolete/mm/rotor/quadrotor_lisa_m_2_pwm.xml @@ -89,7 +89,6 @@
-
@@ -171,10 +170,6 @@ - - - -
diff --git a/conf/boards/stm32f4_discovery.makefile b/conf/boards/stm32f4_discovery.makefile index f00700c783..1961c9c387 100644 --- a/conf/boards/stm32f4_discovery.makefile +++ b/conf/boards/stm32f4_discovery.makefile @@ -28,8 +28,8 @@ DFU_UTIL ?= y # RADIO_CONTROL_LED ?= 4 BARO_LED ?= none -AHRS_ALIGNER_LED ?= none -GPS_LED ?= none +AHRS_ALIGNER_LED ?= 5 +GPS_LED ?= 6 SYS_TIME_LED ?= 3 # @@ -39,7 +39,7 @@ SYS_TIME_LED ?= 3 MODEM_PORT ?= UART6 MODEM_BAUD ?= B57600 -GPS_PORT ?= UART4 +GPS_PORT ?= UART3 GPS_BAUD ?= B38400 RADIO_CONTROL_SPEKTRUM_PRIMARY_PORT ?= UART2 diff --git a/conf/conf_example.xml b/conf/conf_example.xml index 893aba9cec..e8ed823458 100644 --- a/conf/conf_example.xml +++ b/conf/conf_example.xml @@ -41,7 +41,7 @@ radio="radios/cockpitSX.xml" telemetry="telemetry/default_rotorcraft.xml" flight_plan="flight_plans/rotorcraft_basic.xml" - settings="settings/rotorcraft_basic.xml settings/control/rotorcraft_guidance.xml settings/control/stabilization_att_int.xml settings/control/stabilization_rate.xml" + settings="settings/rotorcraft_basic.xml settings/control/rotorcraft_guidance.xml settings/control/stabilization_att_int.xml settings/control/stabilization_rate.xml settings/estimation/ahrs_int_cmpl_quat.xml" gui_color="white" /> + +USE_BARO_BOARD ?= TRUE +ifeq ($(USE_BARO_BOARD), TRUE) + +# booz baro +ifeq ($(BOARD), booz) + ap.srcs += $(SRC_BOARD)/baro_board.c + +# Lisa/L +else ifeq ($(BOARD), lisa_l) + ap.CFLAGS += -DUSE_I2C2 + ap.srcs += $(SRC_BOARD)/baro_board.c + +# Ardrone baro +else ifeq ($(BOARD)$(BOARD_TYPE), ardroneraw) + ap.srcs += $(SRC_BOARD)/baro_board.c + +# Lisa/M baro +else ifeq ($(BOARD), lisa_m) +# defaults to i2c baro bmp085 on the board +LISA_M_BARO ?= BARO_BOARD_BMP085 + ifeq ($(LISA_M_BARO), BARO_MS5611_SPI) + include $(CFG_SHARED)/spi_master.makefile + ap.CFLAGS += -DUSE_SPI2 -DUSE_SPI_SLAVE3 + ap.CFLAGS += -DBB_MS5611_SPI_DEV=spi2 + ap.CFLAGS += -DBB_MS5611_SLAVE_IDX=SPI_SLAVE3 + ap.srcs += peripherals/ms5611.c + ap.srcs += peripherals/ms5611_spi.c + ap.srcs += boards/baro_board_ms5611_spi.c + else ifeq ($(LISA_M_BARO), BARO_MS5611_I2C) + ap.CFLAGS += -DUSE_I2C2 + ap.CFLAGS += -DBB_MS5611_I2C_DEV=i2c2 + ap.srcs += peripherals/ms5611.c + ap.srcs += peripherals/ms5611_i2c.c + ap.srcs += boards/baro_board_ms5611_i2c.c + else ifeq ($(LISA_M_BARO), BARO_BOARD_BMP085) + ap.CFLAGS += -DUSE_I2C2 + ap.srcs += peripherals/bmp085.c + ap.srcs += $(SRC_BOARD)/baro_board.c + endif + +# Lisa/S baro +else ifeq ($(BOARD), lisa_s) +# defaults to SPI baro MS5611 on the board + include $(CFG_SHARED)/spi_master.makefile + ap.CFLAGS += -DUSE_SPI1 -DUSE_SPI_SLAVE1 + ap.CFLAGS += -DBB_MS5611_SPI_DEV=spi1 + ap.CFLAGS += -DBB_MS5611_SLAVE_IDX=SPI_SLAVE1 + ap.srcs += peripherals/ms5611.c + ap.srcs += peripherals/ms5611_spi.c + ap.srcs += boards/baro_board_ms5611_spi.c + +# Lia baro (no bmp onboard) +else ifeq ($(BOARD), lia) +# fixme, reuse the baro drivers in lisa_m dir +LIA_BARO ?= BARO_MS5611_SPI + ifeq ($(LIA_BARO), BARO_MS5611_SPI) + include $(CFG_SHARED)/spi_master.makefile + ap.CFLAGS += -DUSE_SPI2 -DUSE_SPI_SLAVE3 + ap.CFLAGS += -DBB_MS5611_SPI_DEV=spi2 + ap.CFLAGS += -DBB_MS5611_SLAVE_IDX=SPI_SLAVE3 + ap.srcs += peripherals/ms5611.c + ap.srcs += peripherals/ms5611_spi.c + ap.srcs += boards/baro_board_ms5611_spi.c + else ifeq ($(LIA_BARO), BARO_MS5611_I2C) + ap.CFLAGS += -DUSE_I2C2 + ap.CFLAGS += -DBB_MS5611_I2C_DEV=i2c2 + ap.srcs += peripherals/ms5611.c + ap.srcs += peripherals/ms5611_i2c.c + ap.srcs += boards/baro_board_ms5611_i2c.c + endif + +# navgo baro +else ifeq ($(BOARD), navgo) + include $(CFG_SHARED)/spi_master.makefile + ap.CFLAGS += -DUSE_SPI_SLAVE0 + ap.CFLAGS += -DUSE_SPI1 + ap.srcs += peripherals/mcp355x.c + ap.srcs += $(SRC_BOARD)/baro_board.c + +# krooz baro +else ifeq ($(BOARD), krooz) + ap.CFLAGS += -DBB_MS5611_I2C_DEV=i2c2 + ap.CFLAGS += -DBB_MS5611_SLAVE_ADDR=0xEC + ap.srcs += peripherals/ms5611.c + ap.srcs += peripherals/ms5611_i2c.c + ap.srcs += boards/baro_board_ms5611_i2c.c + +# PX4FMU +else ifeq ($(BOARD), px4fmu) + ap.CFLAGS += -DUSE_I2C2 + ap.CFLAGS += -DBB_MS5611_I2C_DEV=i2c2 + ap.srcs += peripherals/ms5611.c + ap.srcs += peripherals/ms5611_i2c.c + ap.srcs += boards/baro_board_ms5611_i2c.c + +# apogee baro +else ifeq ($(BOARD), apogee) + ap.CFLAGS += -DUSE_I2C1 + ap.srcs += peripherals/mpl3115.c + ap.srcs += $(SRC_BOARD)/baro_board.c + +# Umarim +else ifeq ($(BOARD), umarim) + ifeq ($(BOARD_VERSION), 1.0) + ap.CFLAGS += -DUSE_I2C1 -DUSE_ADS1114_1 + ap.CFLAGS += -DADS1114_I2C_DEV=i2c1 + ap.srcs += peripherals/ads1114.c + ap.srcs += boards/umarim/baro_board.c + endif + +endif # check board + +ifneq ($(BARO_LED),none) +ap.CFLAGS += -DBARO_LED=$(BARO_LED) +endif + +# +# add it for simulators +# +# only NPS for now... +#sim.srcs += $(SRC_BOARD)/baro_board.c +#jsbsim.srcs += $(SRC_BOARD)/baro_board.c +nps.srcs += $(SRC_BOARD)/baro_board.c + + +else # USE_BARO_BOARD is not TRUE, was explicitly disabled + +$(TARGET).CFLAGS += -DUSE_BARO_BOARD=FALSE + +endif # check USE_BARO_BOARD diff --git a/conf/flight_plans/flight_plan.dtd b/conf/flight_plans/flight_plan.dtd index 7d1fbdeb12..fb18d5ce0e 100644 --- a/conf/flight_plans/flight_plan.dtd +++ b/conf/flight_plans/flight_plan.dtd @@ -159,7 +159,8 @@ var CDATA #REQUIRED value CDATA #REQUIRED> +fun CDATA #REQUIRED +until CDATA #IMPLIED> grid CDATA #REQUIRED orientation CDATA #IMPLIED wp1 CDATA #REQUIRED -wp2 CDATA #REQUIRED> +wp2 CDATA #REQUIRED +until CDATA #IMPLIED> + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/conf/messages.xml b/conf/messages.xml index e3d06e6d30..d876a5d04c 100644 --- a/conf/messages.xml +++ b/conf/messages.xml @@ -1345,7 +1345,7 @@ - + @@ -1377,6 +1377,7 @@ + @@ -1890,8 +1891,8 @@ - - + + @@ -2256,6 +2257,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2589,15 +2723,6 @@ - - - - - - - - - diff --git a/conf/modules/baro_amsys.xml b/conf/modules/baro_amsys.xml index 2b94bb226c..7b7f72f3d4 100644 --- a/conf/modules/baro_amsys.xml +++ b/conf/modules/baro_amsys.xml @@ -20,7 +20,7 @@ - + diff --git a/conf/modules/baro_board.xml b/conf/modules/baro_board.xml deleted file mode 100644 index b5c56db26f..0000000000 --- a/conf/modules/baro_board.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - Baro board wrapper. - Allows to use baro interface on fixedwing with external barometers. - - -
- -
- - - - -
- diff --git a/conf/modules/baro_ets.xml b/conf/modules/baro_ets.xml index 0b59c2a45b..ec53f74a56 100644 --- a/conf/modules/baro_ets.xml +++ b/conf/modules/baro_ets.xml @@ -19,7 +19,9 @@ - + + + @@ -31,7 +33,7 @@ - + diff --git a/conf/modules/baro_hca.xml b/conf/modules/baro_hca.xml index d874c6388c..3a368f48d8 100644 --- a/conf/modules/baro_hca.xml +++ b/conf/modules/baro_hca.xml @@ -13,7 +13,7 @@ - + diff --git a/conf/modules/baro_mpl3115.xml b/conf/modules/baro_mpl3115.xml index 81151291fb..13225e56c0 100644 --- a/conf/modules/baro_mpl3115.xml +++ b/conf/modules/baro_mpl3115.xml @@ -3,7 +3,10 @@ Baro MPL3115A2 (I2C) - + + + +
@@ -13,7 +16,7 @@ - + diff --git a/conf/modules/baro_ms5611_spi.xml b/conf/modules/baro_ms5611_spi.xml index 2ec153e554..281bc6f94f 100644 --- a/conf/modules/baro_ms5611_spi.xml +++ b/conf/modules/baro_ms5611_spi.xml @@ -7,7 +7,7 @@ Measurement Specialties MS5611-01BA pressure sensor (SPI) - +
diff --git a/conf/modules/baro_sim.xml b/conf/modules/baro_sim.xml new file mode 100644 index 0000000000..ca694bb582 --- /dev/null +++ b/conf/modules/baro_sim.xml @@ -0,0 +1,22 @@ + + + + + + Simulated barometer. + Sends the BARO_ABS ABI message with gps.hmsl converted to absolute pressure. + + + +
+ +
+ + + + + + + + +
diff --git a/conf/modules/mission_fw.xml b/conf/modules/mission_fw.xml new file mode 100644 index 0000000000..096e896394 --- /dev/null +++ b/conf/modules/mission_fw.xml @@ -0,0 +1,32 @@ + + + + + + Interface for mission control of fixed wing aircraft. + This module parse datalink commands for basic navigation routines + and store them in a queue. + + +
+ +
+ + + + + + + + + + + + + + + + + + +
diff --git a/conf/settings/control/rotorcraft_guidance.xml b/conf/settings/control/rotorcraft_guidance.xml index 45c73a958b..c44ecb0069 100644 --- a/conf/settings/control/rotorcraft_guidance.xml +++ b/conf/settings/control/rotorcraft_guidance.xml @@ -15,6 +15,7 @@ + diff --git a/conf/settings/estimation/ahrs_float_cmpl.xml b/conf/settings/estimation/ahrs_float_cmpl.xml new file mode 100644 index 0000000000..950b651e70 --- /dev/null +++ b/conf/settings/estimation/ahrs_float_cmpl.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/conf/settings/estimation/ahrs_int_cmpl_quat.xml b/conf/settings/estimation/ahrs_int_cmpl_quat.xml index 920f3c0dc5..600de04e88 100644 --- a/conf/settings/estimation/ahrs_int_cmpl_quat.xml +++ b/conf/settings/estimation/ahrs_int_cmpl_quat.xml @@ -4,7 +4,11 @@ - + + + + + diff --git a/conf/settings/nps.xml b/conf/settings/nps.xml index ba8aa8f8c6..fd58df0a73 100644 --- a/conf/settings/nps.xml +++ b/conf/settings/nps.xml @@ -4,8 +4,8 @@ - - + + diff --git a/conf/simulator/nps/nps_sensors_params_aspirin_1.5.h b/conf/simulator/nps/nps_sensors_params_aspirin_1.5.h index 678a33833a..d9ae3d501f 100644 --- a/conf/simulator/nps/nps_sensors_params_aspirin_1.5.h +++ b/conf/simulator/nps/nps_sensors_params_aspirin_1.5.h @@ -131,14 +131,11 @@ /* - * Barometer + * Barometer (pressure and std dev in Pascal) */ -/* m */ -/* aka 2^8/INS_BARO_SENS */ -#define NPS_BARO_QNH 900. -#define NPS_BARO_SENSITIVITY 17.066667 -#define NPS_BARO_DT (1./100.) -#define NPS_BARO_NOISE_STD_DEV 5.e-2 +#define NPS_BARO_DT (1./50.) +#define NPS_BARO_NOISE_STD_DEV 2 + /* * GPS diff --git a/conf/simulator/nps/nps_sensors_params_booz2_a1.h b/conf/simulator/nps/nps_sensors_params_booz2_a1.h index 3464326aa8..f815d77033 100644 --- a/conf/simulator/nps/nps_sensors_params_booz2_a1.h +++ b/conf/simulator/nps/nps_sensors_params_booz2_a1.h @@ -130,14 +130,11 @@ /* - * Barometer + * Barometer (pressure and std dev in Pascal) */ -/* m */ -/* aka 2^8/INS_BARO_SENS */ -#define NPS_BARO_QNH 900. -#define NPS_BARO_SENSITIVITY 17.066667 -#define NPS_BARO_DT (1./100.) -#define NPS_BARO_NOISE_STD_DEV 5.e-2 +#define NPS_BARO_DT (1./50.) +#define NPS_BARO_NOISE_STD_DEV 2 + /* * GPS diff --git a/conf/simulator/nps/nps_sensors_params_booz2_a1p.h b/conf/simulator/nps/nps_sensors_params_booz2_a1p.h index 3edb61d98f..7e4e88fa38 100644 --- a/conf/simulator/nps/nps_sensors_params_booz2_a1p.h +++ b/conf/simulator/nps/nps_sensors_params_booz2_a1p.h @@ -130,14 +130,11 @@ /* - * Barometer + * Barometer (pressure and std dev in Pascal) */ -/* m */ -/* aka 2^8/INS_BARO_SENS */ -#define NPS_BARO_QNH 900. -#define NPS_BARO_SENSITIVITY 17.066667 -#define NPS_BARO_DT (1./100.) -#define NPS_BARO_NOISE_STD_DEV 5.e-2 +#define NPS_BARO_DT (1./50.) +#define NPS_BARO_NOISE_STD_DEV 2 + /* * GPS diff --git a/conf/simulator/nps/nps_sensors_params_default.h b/conf/simulator/nps/nps_sensors_params_default.h index 1874378859..d0be213c4e 100644 --- a/conf/simulator/nps/nps_sensors_params_default.h +++ b/conf/simulator/nps/nps_sensors_params_default.h @@ -126,14 +126,10 @@ /* - * Barometer + * Barometer (pressure and std dev in Pascal) */ -/* m */ -/* aka 2^8/INS_BARO_SENS */ -#define NPS_BARO_QNH 900. -#define NPS_BARO_SENSITIVITY 17.066667 -#define NPS_BARO_DT (1./100.) -#define NPS_BARO_NOISE_STD_DEV 5.e-2 +#define NPS_BARO_DT (1./50.) +#define NPS_BARO_NOISE_STD_DEV 2 /* * GPS diff --git a/sw/airborne/arch/sim/sim_baro.c b/sw/airborne/arch/sim/sim_baro.c deleted file mode 100644 index cf6221bb29..0000000000 --- a/sw/airborne/arch/sim/sim_baro.c +++ /dev/null @@ -1,37 +0,0 @@ -#include -#include "state.h" -#include "subsystems/nav.h" -#include "subsystems/gps.h" -#include "baro_MS5534A.h" - -bool_t alt_baro_enabled; -bool_t spi_message_received; -bool_t baro_MS5534A_available; -uint32_t baro_MS5534A_pressure; -uint32_t baro_MS5534A_ground_pressure; -uint16_t baro_MS5534A_temp; -float baro_MS5534A_r; -float baro_MS5534A_sigma2; -float baro_MS5534A_z; - -void baro_MS5534A_init(void) { - baro_MS5534A_ground_pressure = 100000; - - baro_MS5534A_r = 10.; - baro_MS5534A_sigma2 = 1; -} - -// void baro_MS5534A_reset(void); - -void baro_MS5534A_send(void) { - static bool_t even = FALSE; - even = !even; - - spi_message_received = even; -} - -void baro_MS5534A_event_task( void ) { - baro_MS5534A_pressure = baro_MS5534A_ground_pressure - (gps.hmsl/1000.-ground_alt) / 0.08 + ((10.*random()) / RAND_MAX); - baro_MS5534A_temp = 10 + stateGetPositionUtm_f()->alt; - baro_MS5534A_available = TRUE; -} diff --git a/sw/airborne/boards/apogee/baro_board.c b/sw/airborne/boards/apogee/baro_board.c index cfabf3b2a5..27aabe4bfe 100644 --- a/sw/airborne/boards/apogee/baro_board.c +++ b/sw/airborne/boards/apogee/baro_board.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ENAC + * Copyright (C) 2013 Gautier Hattenberger (ENAC) * * This file is part of paparazzi. * @@ -26,40 +26,59 @@ * integrated barometer for Apogee boards (mpl3115) */ +#include "std.h" #include "subsystems/sensors/baro.h" +#include "peripherals/mpl3115.h" // to get MPU status #include "boards/apogee/imu_apogee.h" - -/* Common Baro struct */ -struct Baro baro; +#include "subsystems/abi.h" +#include "led.h" /** Counter to init ads1114 at startup */ #define BARO_STARTUP_COUNTER 200 uint16_t startup_cnt; +struct Mpl3115 apogee_baro; + void baro_init( void ) { - mpl3115_init(); - baro.status = BS_UNINITIALIZED; - baro.absolute = 0; - baro.differential = 1; /* not handled on this board, use extra module */ + mpl3115_init(&apogee_baro, &i2c1, MPL3115_I2C_ADDR); +#ifdef BARO_LED + LED_OFF(BARO_LED); +#endif startup_cnt = BARO_STARTUP_COUNTER; } void baro_periodic( void ) { - if (baro.status == BS_UNINITIALIZED && mpl3115_data_available) { - // Run some loops to get correct readings from the adc - --startup_cnt; - mpl3115_data_available = FALSE; - if (startup_cnt == 0) { - baro.status = BS_RUNNING; - } - } - // Baro is slave of the MPU, only start reading it after MPU is configured - if (imu_apogee.mpu.config.initialized) - Mpl3115Periodic(); + if (imu_apogee.mpu.config.initialized) { + + if (startup_cnt > 0 && apogee_baro.data_available) { + // Run some loops to get correct readings from the adc + --startup_cnt; + apogee_baro.data_available = FALSE; +#ifdef BARO_LED + LED_TOGGLE(BARO_LED); + if (startup_cnt == 0) { + LED_ON(BARO_LED); + } +#endif + } + // Read the sensor + mpl3115_periodic(&apogee_baro); + } +} + +void apogee_baro_event(void) { + mpl3115_event(&apogee_baro); + if (apogee_baro.data_available) { + if (startup_cnt == 0) { + float pressure = ((float)apogee_baro.pressure/(1<<2)); + AbiSendMsgBARO_ABS(BARO_BOARD_SENDER_ID, &pressure); + } + apogee_baro.data_available = FALSE; + } } diff --git a/sw/airborne/boards/apogee/baro_board.h b/sw/airborne/boards/apogee/baro_board.h index c820fd1cb1..595a8a90cb 100644 --- a/sw/airborne/boards/apogee/baro_board.h +++ b/sw/airborne/boards/apogee/baro_board.h @@ -29,32 +29,7 @@ #ifndef BOARDS_APOGEE_BARO_H #define BOARDS_APOGEE_BARO_H -#include "std.h" -#include "peripherals/mpl3115.h" - -/* There is no differential pressure on the board but - * it can be available from an external sensor - * */ - -#define BaroAbs(_handler) { \ - mpl3115_event(); \ - if (mpl3115_data_available) { \ - baro.absolute = mpl3115_pressure; \ - if (baro.status == BS_RUNNING) { \ - _handler(); \ - mpl3115_data_available = FALSE; \ - } \ - } \ -} - -// TODO handle baro diff -#ifndef BaroDiff -#define BaroDiff(_h) {} -#endif - -#define BaroEvent(_b_abs_handler, _b_diff_handler) { \ - BaroAbs(_b_abs_handler); \ - BaroDiff(_b_diff_handler); \ -} +extern void apogee_baro_event(void); +#define BaroEvent apogee_baro_event #endif // BOARDS_APOGEE_BARO_H diff --git a/sw/airborne/boards/apogee/imu_apogee.c b/sw/airborne/boards/apogee/imu_apogee.c index 6617c90d8b..47f004fc29 100644 --- a/sw/airborne/boards/apogee/imu_apogee.c +++ b/sw/airborne/boards/apogee/imu_apogee.c @@ -58,6 +58,13 @@ PRINT_CONFIG_VAR(APOGEE_ACCEL_RANGE) struct ImuApogee imu_apogee; +// baro config will be done later in bypass mode +bool_t configure_baro_slave(Mpu60x0ConfigSet mpu_set, void* mpu); + +bool_t configure_baro_slave(Mpu60x0ConfigSet mpu_set __attribute__ ((unused)), void* mpu __attribute__ ((unused))) { + return TRUE; +} + void imu_impl_init(void) { ///////////////////////////////////////////////////////////////////// @@ -68,6 +75,10 @@ void imu_impl_init(void) imu_apogee.mpu.config.dlpf_cfg = APOGEE_LOWPASS_FILTER; imu_apogee.mpu.config.gyro_range = APOGEE_GYRO_RANGE; imu_apogee.mpu.config.accel_range = APOGEE_ACCEL_RANGE; + // set MPU in bypass mode for the baro + imu_apogee.mpu.config.nb_slaves = 1; + imu_apogee.mpu.config.slaves[0].configure = &configure_baro_slave; + imu_apogee.mpu.config.i2c_bypass = TRUE; imu_apogee.gyr_valid = FALSE; imu_apogee.acc_valid = FALSE; diff --git a/sw/airborne/boards/apogee_0.99.h b/sw/airborne/boards/apogee_0.99.h index 8a79bdc24b..6e22c73192 100644 --- a/sw/airborne/boards/apogee_0.99.h +++ b/sw/airborne/boards/apogee_0.99.h @@ -183,8 +183,10 @@ //#define SPI_SELECT_SLAVE5_PORT GPIOC //#define SPI_SELECT_SLAVE5_PIN GPIO4 -/* Activate onboard baro */ -#define BOARD_HAS_BARO 1 +/* by default activate onboard baro */ +#ifndef USE_BARO_BOARD +#define USE_BARO_BOARD 1 +#endif /* PWM */ #define PWM_USE_TIM2 1 diff --git a/sw/airborne/boards/apogee_1.0.h b/sw/airborne/boards/apogee_1.0.h index 343c514eca..7fc32b63d0 100644 --- a/sw/airborne/boards/apogee_1.0.h +++ b/sw/airborne/boards/apogee_1.0.h @@ -253,8 +253,11 @@ #define I2C2_GPIO_SDA GPIO11 -/* Activate onboard baro */ -#define BOARD_HAS_BARO 1 +/* by default activate onboard baro */ +#ifndef USE_BARO_BOARD +#define USE_BARO_BOARD 1 +#endif + /* PWM */ #define PWM_USE_TIM2 1 diff --git a/sw/airborne/boards/ardrone/baro_board.c b/sw/airborne/boards/ardrone/baro_board.c index 9b05dad93a..73c33868f3 100644 --- a/sw/airborne/boards/ardrone/baro_board.c +++ b/sw/airborne/boards/ardrone/baro_board.c @@ -27,18 +27,16 @@ */ #include "subsystems/sensors/baro.h" +#include "subsystems/abi.h" #include "baro_board.h" #include "navdata.h" -struct Baro baro; #define BMP180_OSS 0 // Parrot ARDrone uses no oversampling -void baro_init(void) { - baro.status = BS_UNINITIALIZED; - baro.absolute = 0; - baro.differential = 0; -} +void baro_init(void) {} + +void baro_periodic(void) {} static inline int32_t baro_apply_calibration(int32_t raw) { @@ -69,20 +67,16 @@ static inline int32_t baro_apply_calibration_temp(int32_t tmp_raw) return (baro_calibration.b5 + 8) >> 4; } -void baro_periodic(void) +void ardrone_baro_event(void) { -} - -void process_ardrone_baro(void) -{ - if(baro.status == BS_RUNNING) { - // first read temperature because pressure calibration depends on temperature - baro.differential = baro_apply_calibration_temp(navdata.temperature_pressure); // We store the temperature in Baro-Diff - baro.absolute = baro_apply_calibration(navdata.pressure); - } - else { - if (baro_calibrated == TRUE) { - baro.status = BS_RUNNING; + if (navdata_baro_available) { + if (baro_calibrated) { + // first read temperature because pressure calibration depends on temperature + // TODO send Temperature message + baro_apply_calibration_temp(navdata.temperature_pressure); + float pressure = (float)baro_apply_calibration(navdata.pressure); + AbiSendMsgBARO_ABS(BARO_BOARD_SENDER_ID, &pressure); } + navdata_baro_available = FALSE; } } diff --git a/sw/airborne/boards/ardrone/baro_board.h b/sw/airborne/boards/ardrone/baro_board.h index d98a771108..443e94b476 100644 --- a/sw/airborne/boards/ardrone/baro_board.h +++ b/sw/airborne/boards/ardrone/baro_board.h @@ -30,26 +30,7 @@ #ifndef BOARDS_ARDRONE2_BARO_H #define BOARDS_ARDRONE2_BARO_H -#if BOARD_HAS_BARO -#include "navdata.h" - -void process_ardrone_baro(void); - - -static inline void baro_event(void (*b_abs_handler)(void), void (*b_diff_handler)(void)){ - if (navdata_baro_available) - { - navdata_baro_available = 0; - process_ardrone_baro(); - b_abs_handler(); - } -} - -#define BaroEvent(_b_abs_handler, _b_diff_handler) {\ - baro_event(_b_abs_handler,_b_diff_handler);\ -} -#else -#define BaroEvent(_b_abs_handler, _b_diff_handler) {} -#endif +extern void ardrone_baro_event(void); +#define BaroEvent ardrone_baro_event #endif /* BOARDS_ARDRONE2_BARO_H */ diff --git a/sw/airborne/boards/ardrone/baro_board_dummy.c b/sw/airborne/boards/ardrone/baro_board_dummy.c deleted file mode 100644 index 8487675af7..0000000000 --- a/sw/airborne/boards/ardrone/baro_board_dummy.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2013 Dino Hensen - * - * 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. - */ - -/** - * @file boards/ardrone/baro_board_dummy.c - * Dummy Baro Board. - * - * These functions are mostly empty because this is a dummy. - */ - -#include "subsystems/sensors/baro.h" - -struct Baro baro; - -void baro_init(void) { - baro.status = BS_UNINITIALIZED; - baro.absolute = 0; - baro.differential = 0; -} - -void baro_periodic(void) { -} diff --git a/sw/airborne/boards/ardrone2_raw.h b/sw/airborne/boards/ardrone2_raw.h index 6200042285..b60b41efc4 100644 --- a/sw/airborne/boards/ardrone2_raw.h +++ b/sw/airborne/boards/ardrone2_raw.h @@ -9,6 +9,10 @@ #define ActuatorsDefaultInit() ActuatorsArdroneInit() #define ActuatorsDefaultCommit() ActuatorsArdroneCommit() -#define BOARD_HAS_BARO 1 + +/* by default activate onboard baro */ +#ifndef USE_BARO_BOARD +#define USE_BARO_BOARD 1 +#endif #endif /* CONFIG_ARDRONE2_RAW */ diff --git a/sw/airborne/boards/ardrone2_sdk.h b/sw/airborne/boards/ardrone2_sdk.h index 01bb97452d..923cc22037 100644 --- a/sw/airborne/boards/ardrone2_sdk.h +++ b/sw/airborne/boards/ardrone2_sdk.h @@ -15,6 +15,6 @@ #define ActuatorsDefaultInit() {} #define ActuatorsDefaultCommit() {} -#define BOARD_HAS_BARO 0 +#define USE_BARO_BOARD 0 #endif /* CONFIG_ARDRONE2_SDK */ diff --git a/sw/airborne/boards/baro_board_ms5611_i2c.c b/sw/airborne/boards/baro_board_ms5611_i2c.c new file mode 100644 index 0000000000..3cd631019b --- /dev/null +++ b/sw/airborne/boards/baro_board_ms5611_i2c.c @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2011-2013 The Paparazzi Team + * + * 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. + * + */ + +/** + * @file boards/baro_board_ms5611_i2c.c + * + * Driver for onboard MS5611 baro via I2C. + * + */ + +#include "subsystems/sensors/baro.h" +#include "peripherals/ms5611_i2c.h" + +#include "mcu_periph/sys_time.h" +#include "led.h" +#include "std.h" +#include "subsystems/abi.h" + +#ifndef DOWNLINK_DEVICE +#define DOWNLINK_DEVICE DOWNLINK_AP_DEVICE +#endif +#include "mcu_periph/uart.h" +#include "messages.h" +#include "subsystems/datalink/downlink.h" + + +/* default i2c address + * when CSB is set to GND addr is 0xEE + * when CSB is set to VCC addr is 0xEC + * + * Note: Aspirin 2.1 has CSB bound to GND. + */ +#ifndef BB_MS5611_SLAVE_ADDR +#define BB_MS5611_SLAVE_ADDR 0xEE +#endif + + +struct Ms5611_I2c bb_ms5611; + + +void baro_init(void) { + ms5611_i2c_init(&bb_ms5611, &BB_MS5611_I2C_DEV, BB_MS5611_SLAVE_ADDR); + +#ifdef BARO_LED + LED_OFF(BARO_LED); +#endif +} + +void baro_periodic(void) { + if (sys_time.nb_sec > 1) { + + /* call the convenience periodic that initializes the sensor and starts reading*/ + ms5611_i2c_periodic(&bb_ms5611); + +#if DEBUG + if (bb_ms5611.initialized) + RunOnceEvery((50*30), DOWNLINK_SEND_MS5611_COEFF(DefaultChannel, DefaultDevice, + &bb_ms5611.data.c[0], + &bb_ms5611.data.c[1], + &bb_ms5611.data.c[2], + &bb_ms5611.data.c[3], + &bb_ms5611.data.c[4], + &bb_ms5611.data.c[5], + &bb_ms5611.data.c[6], + &bb_ms5611.data.c[7]); +#endif + } +} + +void baro_event(void){ + if (sys_time.nb_sec > 1) { + ms5611_i2c_event(&bb_ms5611); + + if (bb_ms5611.data_available) { + float pressure = (float)bb_ms5611.data.pressure; + AbiSendMsgBARO_ABS(BARO_BOARD_SENDER_ID, &pressure); + bb_ms5611.data_available = FALSE; + +#ifdef BARO_LED + RunOnceEvery(10,LED_TOGGLE(BARO_LED)); +#endif + +#if DEBUG + float ftempms = bb_ms5611.data.temperature / 100.; + float fbaroms = bb_ms5611.data.pressure / 100.; + DOWNLINK_SEND_BARO_MS5611(DefaultChannel, DefaultDevice, + &bb_ms5611.data.d1, &bb_ms5611.data.d2, + &fbaroms, &ftempms); +#endif + } + } +} diff --git a/sw/airborne/boards/baro_board_ms5611_spi.c b/sw/airborne/boards/baro_board_ms5611_spi.c new file mode 100644 index 0000000000..61b0396d78 --- /dev/null +++ b/sw/airborne/boards/baro_board_ms5611_spi.c @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2011-2013 The Paparazzi Team + * + * 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. + * + */ + +/** + * @file boards/baro_board_ms5611_spi.c + * + * Driver for onboard MS5611 baro via SPI. + * + */ + +#include "subsystems/sensors/baro.h" +#include "peripherals/ms5611_spi.h" + +#include "mcu_periph/sys_time.h" +#include "led.h" +#include "std.h" +#include "subsystems/abi.h" + +#ifndef DOWNLINK_DEVICE +#define DOWNLINK_DEVICE DOWNLINK_AP_DEVICE +#endif +#include "mcu_periph/uart.h" +#include "messages.h" +#include "subsystems/datalink/downlink.h" + + +struct Ms5611_Spi bb_ms5611; + + +void baro_init(void) { + ms5611_spi_init(&bb_ms5611, &BB_MS5611_SPI_DEV, BB_MS5611_SLAVE_IDX); + +#ifdef BARO_LED + LED_OFF(BARO_LED); +#endif +} + +void baro_periodic(void) { + if (sys_time.nb_sec > 1) { + + /* call the convenience periodic that initializes the sensor and starts reading*/ + ms5611_spi_periodic(&bb_ms5611); + +#if DEBUG + if (bb_ms5611.initialized) + RunOnceEvery((50*30), DOWNLINK_SEND_MS5611_COEFF(DefaultChannel, DefaultDevice, + &bb_ms5611.data.c[0], + &bb_ms5611.data.c[1], + &bb_ms5611.data.c[2], + &bb_ms5611.data.c[3], + &bb_ms5611.data.c[4], + &bb_ms5611.data.c[5], + &bb_ms5611.data.c[6], + &bb_ms5611.data.c[7]); +#endif + } +} + +void baro_event(){ + if (sys_time.nb_sec > 1) { + ms5611_spi_event(&bb_ms5611); + + if (bb_ms5611.data_available) { + float pressure = (float)bb_ms5611.data.pressure; + AbiSendMsgBARO_ABS(BARO_BOARD_SENDER_ID, &pressure); + bb_ms5611.data_available = FALSE; + +#ifdef BARO_LED + RunOnceEvery(10,LED_TOGGLE(BARO_LED)); +#endif + +#if DEBUG + float ftempms = bb_ms5611.data.temperature / 100.; + float fbaroms = bb_ms5611.data.pressure / 100.; + DOWNLINK_SEND_BARO_MS5611(DefaultChannel, DefaultDevice, + &bb_ms5611.data.d1, &bb_ms5611.data.d2, + &fbaroms, &ftempms); +#endif + } + } +} diff --git a/sw/airborne/boards/booz/baro_board.c b/sw/airborne/boards/booz/baro_board.c index cfcbc8b5b2..e7d955ecdb 100644 --- a/sw/airborne/boards/booz/baro_board.c +++ b/sw/airborne/boards/booz/baro_board.c @@ -1,5 +1,4 @@ -/* $Id$ - * +/* * Copyright (C) 2010 The Paparazzi Team * * This file is part of paparazzi. @@ -20,48 +19,74 @@ * Boston, MA 02111-1307, USA. */ +/** + * @file boards/booz/baro_board.c + * + */ + #include "subsystems/sensors/baro.h" #include "generated/airframe.h" +#include "subsystems/abi.h" #include "led.h" -/* threshold >0 && <1023 */ + +/** threshold >0 && <1023 */ #ifndef BOOZ_ANALOG_BARO_THRESHOLD #define BOOZ_ANALOG_BARO_THRESHOLD 850 #endif -struct Baro baro; -struct BaroBoard baro_board; +/** scale factor to convert raw ADC measurement to pressure in Pascal. + * + * Sensor Sensitivity -> SS = 0.045 mv / Pa + * Sensor Gain -> G = 94.25 + * Sensitivity -> S = SS*G = 4.24125 mV / Pa + * 10 bit ADC -> A = 3.3 V / 1024 = 3.223 mV / LSB + * Total Sensitivity SENS = A / S = 0.759837 + * + * For the real pressure you also need to take into account the (variable) offset + * + * supply voltage Vs = 5V + * real sensor sensitivity Vout = Vs * (0.009 P - 0.095) + * voltage variable offset Voff(DAC) = Vs / 69.23 + (DAC * 3.3 / 1024) / 21.77 + * ADC voltage at init Vadc = 3.3*BARO_THRESHOLD/1024 = Vout - Voff + * + * => Inverting these formulas can give the 'real' pressure + * + * since we don't care that much in this case, we can take a fixed offset of 101325 Pa + */ +#ifndef BOOZ_BARO_SENS +#define BOOZ_BARO_SENS 0.759837 +#endif +struct BaroBoard baro_board; void baro_init( void ) { adc_buf_channel(ADC_CHANNEL_BARO, &baro_board.buf, DEFAULT_AV_NB_SAMPLE); - baro.status = BS_UNINITIALIZED; - baro.absolute = 0; - baro.differential = 0; /* not handled on this board */ - + baro_board.status = BB_UNINITIALIZED; + baro_board.absolute = 0; baro_board.offset = 1023; DACSet(baro_board.offset); - baro_board.value_filtered = 0; - baro_board.data_available = FALSE; -#ifdef ROTORCRAFT_BARO_LED - LED_OFF(ROTORCRAFT_BARO_LED); +#ifdef BARO_LED + LED_OFF(BARO_LED); #endif } void baro_periodic(void) { - baro.absolute = baro_board.buf.sum/baro_board.buf.av_nb_sample; - baro_board.value_filtered = (3*baro_board.value_filtered + baro.absolute)/4; - if (baro.status == BS_UNINITIALIZED) { + baro_board.absolute = baro_board.buf.sum/baro_board.buf.av_nb_sample; + baro_board.value_filtered = (3*baro_board.value_filtered + baro_board.absolute)/4; + if (baro_board.status == BB_UNINITIALIZED) { RunOnceEvery(10, { baro_board_calibrate();}); } - /* else */ - baro_board.data_available = TRUE; + else { + float pressure = 101325.0 - BOOZ_BARO_SENS*(BOOZ_ANALOG_BARO_THRESHOLD - baro_board.absolute); + AbiSendMsgBARO_ABS(BARO_BOARD_SENDER_ID, &pressure); + } } /* decrement offset until adc reading is over a threshold */ @@ -72,18 +97,15 @@ void baro_board_calibrate(void) { else baro_board.offset--; DACSet(baro_board.offset); -#ifdef ROTORCRAFT_BARO_LED - LED_TOGGLE(ROTORCRAFT_BARO_LED); +#ifdef BARO_LED + LED_TOGGLE(BARO_LED); #endif } else { - baro.status = BS_RUNNING; -#ifdef ROTORCRAFT_BARO_LED - LED_ON(ROTORCRAFT_BARO_LED); + baro_board.status = BB_RUNNING; +#ifdef BARO_LED + LED_ON(BARO_LED); #endif } } - - - diff --git a/sw/airborne/boards/booz/baro_board.h b/sw/airborne/boards/booz/baro_board.h index 902aef2db1..f47abe700b 100644 --- a/sw/airborne/boards/booz/baro_board.h +++ b/sw/airborne/boards/booz/baro_board.h @@ -1,3 +1,30 @@ + /* + * Copyright (C) 2010-2013 Antoine Drouin, 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. + * + */ + +/** + * @file boards/booz/baro_board.h + * + */ + #ifndef BOARDS_BOOZ_BARO_H #define BOARDS_BOOZ_BARO_H @@ -7,24 +34,23 @@ #include "mcu_periph/adc.h" #include "mcu_periph/dac.h" +enum BaroBoardStatus { + BB_UNINITIALIZED, + BB_RUNNING +}; struct BaroBoard { + enum BaroBoardStatus status; + int32_t absolute; uint16_t offset; uint16_t value_filtered; - bool_t data_available; struct adc_buf buf; }; extern struct BaroBoard baro_board; extern void baro_board_calibrate(void); - -#define BaroEvent(_b_abs_handler, _b_diff_handler) { \ - if (baro_board.data_available) { \ - _b_abs_handler(); \ - baro_board.data_available = FALSE; \ - } \ - } +#define BaroEvent() {} static inline void baro_board_SetOffset(uint16_t _o) { baro_board.offset = _o; diff --git a/sw/airborne/boards/booz_1.0.h b/sw/airborne/boards/booz_1.0.h index 1bb2007977..70fc889bc3 100644 --- a/sw/airborne/boards/booz_1.0.h +++ b/sw/airborne/boards/booz_1.0.h @@ -182,6 +182,9 @@ #endif -#define BOARD_HAS_BARO 1 +/* by default enable onboard baro */ +#ifndef USE_BARO_BOARD +#define USE_BARO_BOARD 1 +#endif #endif /* CONFIG_BOOZ2_V1_0_H */ diff --git a/sw/airborne/boards/krooz/baro_board.h b/sw/airborne/boards/krooz/baro_board.h index 5f47ad650e..c12e63138c 100644 --- a/sw/airborne/boards/krooz/baro_board.h +++ b/sw/airborne/boards/krooz/baro_board.h @@ -8,7 +8,7 @@ #ifndef BOARDS_KROOZ_BARO_H #define BOARDS_KROOZ_BARO_H -extern void baro_event(void (*b_abs_handler)(void)); -#define BaroEvent(_b_abs_handler, _b_diff_handler) baro_event(_b_abs_handler) +extern void baro_event(void); +#define BaroEvent baro_event #endif /* BOARDS_KROOZ_SD_BARO_H */ diff --git a/sw/airborne/boards/krooz_sd.h b/sw/airborne/boards/krooz_sd.h index 1ecd270753..5c12ecef7e 100644 --- a/sw/airborne/boards/krooz_sd.h +++ b/sw/airborne/boards/krooz_sd.h @@ -224,8 +224,12 @@ } #endif // USE_AD1 -/* Activate onboard baro */ -#define BOARD_HAS_BARO 1 + +/* by default activate onboard baro */ +#ifndef USE_BARO_BOARD +#define USE_BARO_BOARD 1 +#endif + /* PWM */ #define PWM_USE_TIM3 1 diff --git a/sw/airborne/boards/lia/baro_board.h b/sw/airborne/boards/lia/baro_board.h deleted file mode 100644 index 59782132c8..0000000000 --- a/sw/airborne/boards/lia/baro_board.h +++ /dev/null @@ -1,16 +0,0 @@ - -/* - * FIXME, fake baro board header for BaroEvent - * - */ - -#ifndef BOARDS_LIA_BARO_H -#define BOARDS_LIA_BARO_H - -#include "std.h" - -extern void baro_event(void (*b_abs_handler)(void)); - -#define BaroEvent(_b_abs_handler, _b_diff_handler) baro_event(_b_abs_handler) - -#endif /* BOARDS_LIA_BARO_H */ diff --git a/sw/airborne/boards/lia_1.1.h b/sw/airborne/boards/lia_1.1.h index 3b9c1bf419..31260f054d 100644 --- a/sw/airborne/boards/lia_1.1.h +++ b/sw/airborne/boards/lia_1.1.h @@ -166,7 +166,7 @@ // FIXME, using baro_board right now to include the appropriate header -#define BOARD_HAS_BARO 0 +#define USE_BARO_BOARD 0 #endif /* CONFIG_LIA_1_1_H */ diff --git a/sw/airborne/boards/lisa_l/baro_board.c b/sw/airborne/boards/lisa_l/baro_board.c index 9e0d825c5e..a7a6a7834b 100644 --- a/sw/airborne/boards/lisa_l/baro_board.c +++ b/sw/airborne/boards/lisa_l/baro_board.c @@ -1,10 +1,57 @@ +/* + * Copyright (C) 2010-2013 The Paparazzi Team + * + * 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. + * + */ +#include "std.h" #include "subsystems/sensors/baro.h" +#include "mcu_periph/i2c.h" +#include "subsystems/abi.h" +#include "led.h" + +enum LisaBaroStatus { + LBS_UNINITIALIZED, + LBS_RESETED, + LBS_INITIALIZING_ABS, + LBS_INITIALIZING_ABS_1, + LBS_INITIALIZING_DIFF, + LBS_INITIALIZING_DIFF_1, + LBS_IDLE, + LBS_READING_ABS, + LBS_READ_ABS, + LBS_READING_DIFF, + LBS_READ_DIFF +}; + +struct BaroBoard { + enum LisaBaroStatus status; + bool_t running; +}; + -struct Baro baro; struct BaroBoard baro_board; struct i2c_transaction baro_trans; +static inline void baro_board_send_reset(void); +static inline void baro_board_send_config_abs(void); +static inline void baro_board_send_config_diff(void); static inline void baro_board_write_to_register(uint8_t baro_addr, uint8_t reg_addr, uint8_t val_msb, uint8_t val_lsb); static inline void baro_board_read_from_register(uint8_t baro_addr, uint8_t reg_addr); static inline void baro_board_set_current_register(uint8_t baro_addr, uint8_t reg_addr); @@ -15,11 +62,21 @@ static inline void baro_board_read_from_current_register(uint8_t baro_addr); // differential #define BARO_DIFF_ADDR 0x92 +// FIXME +#ifndef LISA_L_BARO_SENS +#define LISA_L_BARO_SENS 1.0 +#endif + +#ifndef LISA_L_DIFF_SENS +#define LISA_L_DIFF_SENS 1.0 +#endif + void baro_init(void) { - baro.status = BS_UNINITIALIZED; - baro.absolute = 0; - baro.differential = 0; +#ifdef BARO_LED + LED_OFF(BARO_LED); +#endif baro_board.status = LBS_UNINITIALIZED; + baro_board.running = FALSE; } @@ -50,7 +107,7 @@ void baro_periodic(void) { // baro_board.status = LBS_UNINITIALIZED; break; case LBS_INITIALIZING_DIFF_1: - baro.status = BS_RUNNING; + baro_board.running = TRUE; case LBS_READ_DIFF: baro_board_read_from_current_register(BARO_ABS_ADDR); baro_board.status = LBS_READING_ABS; @@ -63,10 +120,38 @@ void baro_periodic(void) { break; } +#ifdef BARO_LED + if (baro_board.running == TRUE) { + LED_ON(BARO_LED); + } + else { + LED_TOGGLE(BARO_LED); + } +#endif } +void lisa_l_baro_event(void) { + if (baro_board.status == LBS_READING_ABS && + baro_trans.status != I2CTransPending) { + baro_board.status = LBS_READ_ABS; + if (baro_trans.status == I2CTransSuccess) { + int16_t tmp = baro_trans.buf[0]<<8 | baro_trans.buf[1]; + float pressure = LISA_L_BARO_SENS*(float)tmp; + AbiSendMsgBARO_ABS(BARO_BOARD_SENDER_ID, &pressure); + } + } + else if (baro_board.status == LBS_READING_DIFF && + baro_trans.status != I2CTransPending) { + baro_board.status = LBS_READ_DIFF; + if (baro_trans.status == I2CTransSuccess) { + int16_t tmp = baro_trans.buf[0]<<8 | baro_trans.buf[1]; + float diff = LISA_L_DIFF_SENS*(float)tmp; + AbiSendMsgBARO_DIFF(BARO_BOARD_SENDER_ID, &diff); + } + } +} -void baro_board_send_config_abs(void) { +static inline void baro_board_send_config_abs(void) { #ifndef BARO_LOW_GAIN INFO("Using High LisaL Baro Gain: Do not use below 1000hPa") baro_board_write_to_register(BARO_ABS_ADDR, 0x01, 0x86, 0x83); @@ -77,11 +162,11 @@ INFO("Using Low LisaL Baro Gain, capable of measuring below 1000hPa or more") #endif } -void baro_board_send_config_diff(void) { +static inline void baro_board_send_config_diff(void) { baro_board_write_to_register(BARO_DIFF_ADDR, 0x01, 0x84, 0x83); } -void baro_board_send_reset(void) { +static inline void baro_board_send_reset(void) { baro_trans.type = I2CTransTx; baro_trans.slave_addr = 0x00; baro_trans.len_w = 1; diff --git a/sw/airborne/boards/lisa_l/baro_board.h b/sw/airborne/boards/lisa_l/baro_board.h index 4eec5cfdee..5a39dc8ef8 100644 --- a/sw/airborne/boards/lisa_l/baro_board.h +++ b/sw/airborne/boards/lisa_l/baro_board.h @@ -1,5 +1,29 @@ +/* + * Copyright (C) 2013 Gautier Hattenberger (ENAC) + * + * 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. + * + */ + /* + * @file boards/lisa_l/baro_board.h + * * board specific fonctions for the lisa_l board * */ @@ -7,56 +31,7 @@ #ifndef BOARDS_LISA_L_BARO_H #define BOARDS_LISA_L_BARO_H -#include "std.h" -#include "mcu_periph/i2c.h" - -enum LisaBaroStatus { - LBS_UNINITIALIZED, - LBS_RESETED, - LBS_INITIALIZING_ABS, - LBS_INITIALIZING_ABS_1, - LBS_INITIALIZING_DIFF, - LBS_INITIALIZING_DIFF_1, - LBS_IDLE, - LBS_READING_ABS, - LBS_READ_ABS, - LBS_READING_DIFF, - LBS_READ_DIFF -}; - -struct BaroBoard { - enum LisaBaroStatus status; -}; - -extern struct BaroBoard baro_board; -extern struct i2c_transaction baro_trans; - -extern void baro_board_send_reset(void); -extern void baro_board_send_config_abs(void); -extern void baro_board_send_config_diff(void); - -#define BaroEvent(_b_abs_handler, _b_diff_handler) { \ - if (baro_board.status == LBS_READING_ABS && \ - baro_trans.status != I2CTransPending) { \ - baro_board.status = LBS_READ_ABS; \ - if (baro_trans.status == I2CTransSuccess) { \ - int16_t tmp = baro_trans.buf[0]<<8 | baro_trans.buf[1]; \ - baro.absolute = tmp; \ - _b_abs_handler(); \ - } \ - } \ - else if (baro_board.status == LBS_READING_DIFF && \ - baro_trans.status != I2CTransPending) { \ - baro_board.status = LBS_READ_DIFF; \ - if (baro_trans.status == I2CTransSuccess) { \ - int16_t tmp = baro_trans.buf[0]<<8 | baro_trans.buf[1]; \ - baro.differential = tmp; \ - _b_diff_handler(); \ - } \ - } \ - } - - - +extern void lisa_l_baro_event(void); +#define BaroEvent lisa_l_baro_event #endif /* BOARDS_LISA_L_BARO_H */ diff --git a/sw/airborne/boards/lisa_l_1.0.h b/sw/airborne/boards/lisa_l_1.0.h index f18b7d34eb..bb21346971 100644 --- a/sw/airborne/boards/lisa_l_1.0.h +++ b/sw/airborne/boards/lisa_l_1.0.h @@ -156,7 +156,11 @@ #define BOARD_ADC_CHANNEL_3 0 #define BOARD_ADC_CHANNEL_4 15 -#define BOARD_HAS_BARO 1 + +/* by default activate onboard baro */ +#ifndef USE_BARO_BOARD +#define USE_BARO_BOARD 1 +#endif /* Default actuators driver */ diff --git a/sw/airborne/boards/lisa_m/baro_board.c b/sw/airborne/boards/lisa_m/baro_board.c index 9c09b97d90..5a6aa9a489 100644 --- a/sw/airborne/boards/lisa_m/baro_board.c +++ b/sw/airborne/boards/lisa_m/baro_board.c @@ -23,13 +23,17 @@ * Baro board interface for Bosch BMP085 on LisaM I2C2 with EOC check. */ +#include "std.h" + #include "subsystems/sensors/baro.h" +#include "peripherals/bmp085.h" #include "peripherals/bmp085_regs.h" #include +#include "subsystems/abi.h" #include "led.h" -struct Baro baro; + struct Bmp085 baro_bmp085; static bool_t baro_eoc(void) @@ -38,10 +42,6 @@ static bool_t baro_eoc(void) } void baro_init(void) { - baro.status = BS_UNINITIALIZED; - baro.absolute = 0; - baro.differential = 0; - bmp085_init(&baro_bmp085, &i2c2, BMP085_SLAVE_ADDR); /* setup eoc check function */ @@ -50,32 +50,34 @@ void baro_init(void) { gpio_clear(GPIOB, GPIO0); gpio_set_mode(GPIOB, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO0); + +#ifdef BARO_LED + LED_OFF(BARO_LED); +#endif } void baro_periodic(void) { - if (baro_bmp085.initialized) { - baro.status = BS_RUNNING; bmp085_periodic(&baro_bmp085); } - else + else { bmp085_read_eeprom_calib(&baro_bmp085); + } } -void baro_event(void (*b_abs_handler)(void)) +void baro_event(void) { bmp085_event(&baro_bmp085); if (baro_bmp085.data_available) { - baro.absolute = baro_bmp085.pressure; - b_abs_handler(); + float pressure = (float)baro_bmp085.pressure; + AbiSendMsgBARO_ABS(BARO_BOARD_SENDER_ID, &pressure); baro_bmp085.data_available = FALSE; - -#ifdef ROTORCRAFT_BARO_LED - RunOnceEvery(10,LED_TOGGLE(ROTORCRAFT_BARO_LED)); +#ifdef BARO_LED + RunOnceEvery(10,LED_TOGGLE(BARO_LED)); #endif } } diff --git a/sw/airborne/boards/lisa_m/baro_board.h b/sw/airborne/boards/lisa_m/baro_board.h index b84a11a7da..bb080094ab 100644 --- a/sw/airborne/boards/lisa_m/baro_board.h +++ b/sw/airborne/boards/lisa_m/baro_board.h @@ -7,20 +7,9 @@ #ifndef BOARDS_LISA_M_BARO_H #define BOARDS_LISA_M_BARO_H -#include "std.h" - // for right now we abuse this file for the ms5611 baro on aspirin as well -#if !BARO_MS5611_I2C && !BARO_MS5611 -#include "peripherals/bmp085.h" - -extern struct Bmp085 baro_bmp085; - - -#endif // !BARO_MS5611_xx - -extern void baro_event(void (*b_abs_handler)(void)); - -#define BaroEvent(_b_abs_handler, _b_diff_handler) baro_event(_b_abs_handler) +extern void baro_event(void); +#define BaroEvent baro_event #endif /* BOARDS_LISA_M_BARO_H */ diff --git a/sw/airborne/boards/lisa_m_1.0.h b/sw/airborne/boards/lisa_m_1.0.h index a2b1b2e88d..e4f48c3ab2 100644 --- a/sw/airborne/boards/lisa_m_1.0.h +++ b/sw/airborne/boards/lisa_m_1.0.h @@ -111,7 +111,7 @@ #endif /* GPIO mapping for ADC1 pins, overwrites the default in arch/stm32/mcu_periph/adc_arch.c */ -// FIXME, this is not very nice, is also stm lib specific +// FIXME, this is not very nice, is also libopencm3 lib specific #ifdef USE_AD1 #define ADC1_GPIO_INIT(gpio) { \ gpio_set_mode(GPIOC, GPIO_MODE_INPUT, \ @@ -120,6 +120,10 @@ } #endif // USE_AD1 -#define BOARD_HAS_BARO 1 + +/* by default enable onboard baro */ +#ifndef USE_BARO_BOARD +#define USE_BARO_BOARD 1 +#endif #endif /* CONFIG_LISA_M_1_0_H */ diff --git a/sw/airborne/boards/lisa_m_2.0.h b/sw/airborne/boards/lisa_m_2.0.h index 3f09b51a8d..de0664a950 100644 --- a/sw/airborne/boards/lisa_m_2.0.h +++ b/sw/airborne/boards/lisa_m_2.0.h @@ -165,6 +165,9 @@ #endif // USE_AD1 -#define BOARD_HAS_BARO 1 +/* by default activate onboard baro */ +#ifndef USE_BARO_BOARD +#define USE_BARO_BOARD 1 +#endif #endif /* CONFIG_LISA_M_2_0_H */ diff --git a/sw/airborne/boards/lisa_s/baro_board.h b/sw/airborne/boards/lisa_s/baro_board.h index 7581ef4de3..8f41c8e3ca 100644 --- a/sw/airborne/boards/lisa_s/baro_board.h +++ b/sw/airborne/boards/lisa_s/baro_board.h @@ -4,13 +4,13 @@ * */ -#ifndef BOARDS_LISA_M_BARO_H -#define BOARDS_LISA_M_BARO_H +#ifndef BOARDS_LISA_S_BARO_H +#define BOARDS_LISA_S_BARO_H #include "std.h" -extern void baro_event(void (*b_abs_handler)(void)); +extern void baro_event(void); -#define BaroEvent(_b_abs_handler, _b_diff_handler) baro_event(_b_abs_handler) +#define BaroEvent baro_event -#endif /* BOARDS_LISA_M_BARO_H */ +#endif /* BOARDS_LISA_S_BARO_H */ diff --git a/sw/airborne/boards/navgo/baro_board.c b/sw/airborne/boards/navgo/baro_board.c index 898878070e..fd99a5c6ca 100644 --- a/sw/airborne/boards/navgo/baro_board.c +++ b/sw/airborne/boards/navgo/baro_board.c @@ -25,12 +25,30 @@ * Navarro & Gorraz & Hattenberger */ +#include "std.h" +#include "baro_board.h" #include "subsystems/sensors/baro.h" +#include "peripherals/mcp355x.h" +#include "subsystems/abi.h" #include "led.h" -#include "mcu_periph/spi.h" -/* Common Baro struct */ -struct Baro baro; +/** scale factor to convert raw ADC measurement to pressure in Pascal. + * + * supply voltage Vs = 5V + * real sensor sensitivity Vout = Vs * (0.009 P - 0.095) with P in kPa + * 22 bit signed ADC -> only 21 useful bits ADC = 5/2^21 = 2.384e-6 V / LSB + * + * offset = 5*0.095/2.384e-6 = 199229 (LSB) + * sensitivity = (1000/0.009)*2.384e-6/5 = 0.05298 Pa/LSB + * + */ +#ifndef NAVGO_BARO_SENS +#define NAVGO_BARO_SENS 0.05298 +#endif + +#ifndef NAVGO_BARO_OFFSET +#define NAVGO_BARO_OFFSET 199229 +#endif /* Counter to init mcp355x at startup */ #define BARO_STARTUP_COUNTER 200 @@ -38,31 +56,35 @@ uint16_t startup_cnt; void baro_init( void ) { mcp355x_init(); - baro.status = BS_UNINITIALIZED; - baro.absolute = 0; - baro.differential = 0; /* not handled on this board */ -#ifdef ROTORCRAFT_BARO_LED - LED_OFF(ROTORCRAFT_BARO_LED); +#ifdef BARO_LED + LED_OFF(BARO_LED); #endif startup_cnt = BARO_STARTUP_COUNTER; } void baro_periodic( void ) { - - if (baro.status == BS_UNINITIALIZED) { - // Run some loops to get correct readings from the adc + // Run some loops to get correct readings from the adc + if (startup_cnt > 0) { --startup_cnt; -#ifdef ROTORCRAFT_BARO_LED - LED_TOGGLE(ROTORCRAFT_BARO_LED); -#endif +#ifdef BARO_LED + LED_TOGGLE(BARO_LED); if (startup_cnt == 0) { - baro.status = BS_RUNNING; -#ifdef ROTORCRAFT_BARO_LED - LED_ON(ROTORCRAFT_BARO_LED); -#endif + LED_ON(BARO_LED); } +#endif } // Read the ADC (at 50/4 Hz, conversion time is 68 ms) RunOnceEvery(4,mcp355x_read()); } +void navgo_baro_event(void) { + mcp355x_event(); + if (mcp355x_data_available) { + if (startup_cnt == 0) { + // Send data when init phase is done + float pressure = NAVGO_BARO_SENS*(mcp355x_data+NAVGO_BARO_OFFSET); + AbiSendMsgBARO_ABS(BARO_BOARD_SENDER_ID, &pressure); + } + mcp355x_data_available = FALSE; + } +} diff --git a/sw/airborne/boards/navgo/baro_board.h b/sw/airborne/boards/navgo/baro_board.h index 56137a6806..bbd56ba3f7 100644 --- a/sw/airborne/boards/navgo/baro_board.h +++ b/sw/airborne/boards/navgo/baro_board.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2012 Gautier Hattenberger + * Copyright (C) 2011-2013 Gautier Hattenberger * * This file is part of paparazzi. * @@ -29,17 +29,9 @@ #ifndef BOARDS_NAVGO_BARO_H #define BOARDS_NAVGO_BARO_H +extern void navgo_baro_event(void); -#include "std.h" -#include "peripherals/mcp355x.h" - -#define BaroEvent(_b_abs_handler, _b_diff_handler) { \ - mcp355x_event(); \ - if (mcp355x_data_available) { \ - baro.absolute = mcp355x_data; \ - _b_abs_handler(); \ - mcp355x_data_available = FALSE; \ - } \ -} +// define BaroEvent macro +#define BaroEvent navgo_baro_event #endif // BOARDS_NAVGO_BARO_H diff --git a/sw/airborne/boards/navgo_1.0.h b/sw/airborne/boards/navgo_1.0.h index 015b51d428..8cdfd75591 100644 --- a/sw/airborne/boards/navgo_1.0.h +++ b/sw/airborne/boards/navgo_1.0.h @@ -105,6 +105,10 @@ #define SERVO_REG_1 PWMMR5 #endif -#define BOARD_HAS_BARO 1 + +/* by default activate onboard baro */ +#ifndef USE_BARO_BOARD +#define USE_BARO_BOARD 1 +#endif #endif /* CONFIG_NAVGO_V1_0_H */ diff --git a/sw/airborne/boards/pc/baro_board.c b/sw/airborne/boards/pc/baro_board.c index 52f3cb19fe..d65be929b8 100644 --- a/sw/airborne/boards/pc/baro_board.c +++ b/sw/airborne/boards/pc/baro_board.c @@ -1,17 +1,41 @@ +/* + * Copyright (C) 2010-2013 Paparazzi Team + * + * 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. + * + */ +/** + * @file boards/pc/baro_board.h + * + * board specific fonction for the PC board ( simulator ) + * + */ #include "subsystems/sensors/baro.h" +#include "subsystems/abi.h" -struct Baro baro; +void baro_init(void) {} -bool_t baro_pc_available; - -void baro_init(void) {baro_pc_available=FALSE;} - -void baro_periodic(void) {baro.status = BS_RUNNING;} +void baro_periodic(void) {} void baro_feed_value(double value) { - baro.absolute = (int32_t) value; - baro_pc_available = TRUE; + float pressure = (float) value; + AbiSendMsgBARO_ABS(BARO_BOARD_SENDER_ID, &pressure); } diff --git a/sw/airborne/boards/pc/baro_board.h b/sw/airborne/boards/pc/baro_board.h index 54d902730b..e9ede28b60 100644 --- a/sw/airborne/boards/pc/baro_board.h +++ b/sw/airborne/boards/pc/baro_board.h @@ -1,4 +1,28 @@ /* + * Copyright (C) 2010-2013 Paparazzi Team + * + * 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. + * + */ + +/* + * @file boards/pc/baro_board.c + * * board specific fonction for the PC board ( simulator ) * */ @@ -6,15 +30,7 @@ #ifndef BOARDS_PC_BARO_H #define BOARDS_PC_BARO_H -#define BaroEvent(_b_abs_handler, _b_diff_handler) { \ - if (baro_pc_available) { \ - _b_abs_handler(); \ - baro_pc_available = FALSE; \ - } \ - } - - -extern bool_t baro_pc_available; +#define BaroEvent() {} extern void baro_feed_value(double value); diff --git a/sw/airborne/boards/pc_sim.h b/sw/airborne/boards/pc_sim.h index 2b80d2f632..f2ac35ef1f 100644 --- a/sw/airborne/boards/pc_sim.h +++ b/sw/airborne/boards/pc_sim.h @@ -11,7 +11,12 @@ #define DefaultVoltageOfAdc(adc) (1.0*adc) - -#define BOARD_HAS_BARO 1 +#ifndef USE_BARO_BOARD +#if USE_NPS +#define USE_BARO_BOARD 1 +#else +#define USE_BARO_BOARD 0 +#endif +#endif #endif /* CONFIG_PC_SIM_H */ diff --git a/sw/airborne/boards/px4fmu/baro_board.h b/sw/airborne/boards/px4fmu/baro_board.h index 4aff1cc1c7..8ef2dacaea 100644 --- a/sw/airborne/boards/px4fmu/baro_board.h +++ b/sw/airborne/boards/px4fmu/baro_board.h @@ -7,8 +7,8 @@ #ifndef BOARDS_PX4FMU_BARO_H #define BOARDS_PX4FMU_BARO_H -extern void baro_event(void (*b_abs_handler)(void)); +extern void baro_event(void); -#define BaroEvent(_b_abs_handler, _b_diff_handler) baro_event(_b_abs_handler) +#define BaroEvent baro_event #endif /* BOARDS_PX4FMU_BARO_H */ diff --git a/sw/airborne/boards/stm32f4_discovery.h b/sw/airborne/boards/stm32f4_discovery.h index 288385d132..49c2fdc26f 100755 --- a/sw/airborne/boards/stm32f4_discovery.h +++ b/sw/airborne/boards/stm32f4_discovery.h @@ -1,3 +1,96 @@ +/* + * STM32F4 DISCOVERY BOARD DEFINITIONS FOR THE PAPARAZZI AUTOPILOT. + * + * DISCOVERY USED FOR THE AUTOPILOT PINS + * PA0 = PWM9 + user-wake up button switch b1 normaly open. + * PA1 = PWM8 + * PA2 = PWM7 + * PA3 = PWM6 + * PA4 = ADC_4 (ADC12 IN 4)+CS43L22 DAC out, capacitively coupled+100Kohm, should not interfere. + * PA5 = FREE + * PA6 = CANNOT BE USED + * PA7 = FREE + * PA8 = SPECTRUM BIND + * PA9 = FREE (ONLY if usb is not active during runtime, PC0 must be high or input ) + * PA10 = UART2 (Spektrum input) + * PA11 = FREE if usb is not active during runtime + * PA12 = FREE if usb is not active during runtime + * PA13 = FREE + * PA14 = FREE + * PA15 = FREE + * + * PB0 = FREE + * PB1 = ADC_1 (ADC12 IN 9) + * PB2 = FREE + * PB3 = SPI1 SCL + * PB4 = SPI1 MISO + * PB5 = SPI1 MOSI + * PB6 = UART1 TX + 4K7 Ohm pull up resistor normaly used for i2c + * PB7 = UART1 RX + * PB8 = I2C1 SCL + * PB9 = I2C1 SDA + 4K7 Ohm pull up resistor normaly used for i2c + * PB10 = I2C2 SCL + MP45DT02 MEMS MIC clock in + * PB11 = I2C2 SDA + * PB12 = FREE + * PB13 = SPI2 SCL + * PB14 = PWM 10 OR SPI2 MISO + * PB15 = PWM 11 OR SPI2 MOSI + * + * PC0 = CANNOT BE USED, pulled up to 3.3v (10Kohm), low = usb power on directly applied to PA9) + * PC1 = ADC_5 (ADC123 IN 11) + * PC2 = ADC_6 (ADC123 IN 12) + * PC3 = CANNOT BE USED (MEMS microphone output) + * PC4 = ADC_3 (ADC12 IN 14) + * PC5 = ADC_2 (ADC12 IN 15) + * PC6 = UART6 TX + * PC7 = UART6 RX + * PC8 = FREE + * PC9 = PPM INPUT FROM RC RECEIVER + * PC10 = UART4 TX OR SPI3 SCL + * PC11 = UART4 RX OR SPI3 MISO + * PC12 = UART5 TX OR SPI3 MOSI + * PC13 = FREE max 3ma sink + * PC14 = FREE max 3ma sink, short circuit the relevant PCB bridge with solder to activate + * PC15 = FREE max 3ma sink, short circuit the relevant PCB bridge with solder to activate + * + * PD0 = FREE + * PD1 = FREE + * PD2 = UART5 RX + * PD3 = FREE + * PD4 = FREE + * PD5 = UART2 TX (usb power management fault output open drain) + * PD6 = UART2 RX + * PD7 = FREE + * PD8 = UART3 TX + * PD9 = UART3 RX + * PD10 = FREE + * PD11 = FREE + * PD12 = LED_3 + * PD13 = LED_4 + * PD14 = LED_5 + * PD15 = LED_6 + * + * PE0 = CANNOT BE USED (Accel int output) + * PE1 = CANNOT BE USED (Accel int output) + * PE2 = SPI SLAVE 0 + * PE3 = FREE (Needs some testing as it is used for the accel spi/i2c select pin) + * PE4 = FREE + * PE5 = PWM4 + * PE6 = PWM5 + * PE7 = SPI SLAVE 1 + * PE8 = FREE + * PE9 = PWM0 + * PE10 = FREE + * PE11 = PWM1 + * PE12 = FREE + * PE13 = PWM2 + * PE14 = PWM3 + * PE15 = FREE + * + * PH0 = CRYSTAL - OSC IN + * PH1 = CRYSTAL - OSC OUT + */ + #ifndef CONFIG_STM32F4_DISCOVERY_H #define CONFIG_STM32F4_DISCOVERY_H @@ -17,7 +110,7 @@ #endif #define LED_3_GPIO GPIOD #define LED_3_GPIO_CLK RCC_AHB1ENR_IOPDEN -#define LED_3_GPIO_PIN GPIO13 +#define LED_3_GPIO_PIN GPIO12 #define LED_3_AFIO_REMAP ((void)0) #define LED_3_GPIO_ON gpio_set #define LED_3_GPIO_OFF gpio_clear @@ -28,7 +121,7 @@ #endif #define LED_4_GPIO GPIOD #define LED_4_GPIO_CLK RCC_AHB1ENR_IOPDEN -#define LED_4_GPIO_PIN GPIO12 +#define LED_4_GPIO_PIN GPIO13 #define LED_4_AFIO_REMAP ((void)0) #define LED_4_GPIO_ON gpio_set #define LED_4_GPIO_OFF gpio_clear @@ -56,46 +149,107 @@ #define LED_6_GPIO_OFF gpio_clear -/* UART */ + +/* +// LED 9 (Green) of the STM32F4 discovery board same as USB power (VBUS). +#ifndef USE_LED_9 +#define USE_LED_9 1 +#endif +#define LED_9_GPIO GPIOA +#define LED_9_GPIO_CLK RCC_AHB1ENR_IOPAEN +#define LED_9_GPIO_PIN GPIO9 +#define LED_9_AFIO_REMAP ((void)0) +#define LED_9_GPIO_ON gpio_set +#define LED_9_GPIO_OFF gpio_clear +*/ + + +/***************************************************************************************************/ +/************************************** UART *************************************************/ +/***************************************************************************************************/ + +// If you don't need all those uarts comment a uart block out to free pins. #define UART1_GPIO_AF GPIO_AF7 -#define UART1_GPIO_PORT_RX GPIOA -#define UART1_GPIO_RX GPIO10 #define UART1_GPIO_PORT_TX GPIOB #define UART1_GPIO_TX GPIO6 +#define UART1_GPIO_PORT_RX GPIOB +#define UART1_GPIO_RX GPIO7 +// UART2 is used for the Spectrum rx input also #define UART2_GPIO_AF GPIO_AF7 -#define UART2_GPIO_PORT_RX GPIOA -#define UART2_GPIO_RX GPIO3 -#define UART2_GPIO_PORT_TX GPIOA -#define UART2_GPIO_TX GPIO2 +#define UART2_GPIO_PORT_TX GPIOD +#define UART2_GPIO_TX GPIO5 +#define UART2_GPIO_PORT_RX GPIOD +#define UART2_GPIO_RX GPIO6 +#define UART3_GPIO_AF GPIO_AF7 +#define UART3_GPIO_PORT_TX GPIOD +#define UART3_GPIO_TX GPIO8 +#define UART3_GPIO_PORT_RX GPIOD +#define UART3_GPIO_RX GPIO9 + +// UARTS 4 AND 5 CANT BE USED IF SPI3 IS NEEDED +#if !USE_SPI3 #define UART4_GPIO_AF GPIO_AF8 -#define UART4_GPIO_PORT_RX GPIOA -#define UART4_GPIO_RX GPIO1 -#define UART4_GPIO_PORT_TX GPIOA -#define UART4_GPIO_TX GPIO0 +#define UART4_GPIO_PORT_TX GPIOC +#define UART4_GPIO_TX GPIO10 +#define UART4_GPIO_PORT_RX GPIOC +#define UART4_GPIO_RX GPIO11 + +#define UART5_GPIO_AF GPIO_AF8 +#define UART5_GPIO_PORT_TX GPIOC +#define UART5_GPIO_TX GPIO12 +#define UART5_GPIO_PORT_RX GPIOD +#define UART5_GPIO_RX GPIO2 +#endif #define UART6_GPIO_AF GPIO_AF8 -#define UART6_GPIO_PORT_RX GPIOC -#define UART6_GPIO_RX GPIO7 #define UART6_GPIO_PORT_TX GPIOC #define UART6_GPIO_TX GPIO6 +#define UART6_GPIO_PORT_RX GPIOC +#define UART6_GPIO_RX GPIO7 -/* SPI */ +/***************************************************************************************************/ +/************************************** SPI *************************************************/ +/***************************************************************************************************/ + #define SPI1_GPIO_AF GPIO_AF5 -#define SPI1_GPIO_PORT_MISO GPIOA -#define SPI1_GPIO_MISO GPIO6 -#define SPI1_GPIO_PORT_MOSI GPIOA -#define SPI1_GPIO_MOSI GPIO7 -#define SPI1_GPIO_PORT_SCK GPIOA -#define SPI1_GPIO_SCK GPIO5 - -#define SPI_SELECT_SLAVE0_PORT GPIOB -#define SPI_SELECT_SLAVE0_PIN GPIO9 +#define SPI1_GPIO_PORT_SCK GPIOB +#define SPI1_GPIO_SCK GPIO3 +#define SPI1_GPIO_PORT_MISO GPIOB +#define SPI1_GPIO_MISO GPIO4 +#define SPI1_GPIO_PORT_MOSI GPIOB +#define SPI1_GPIO_MOSI GPIO5 -/* I2C mapping */ +/* CANNOT BE USED IF PWM CHANNELS 10 & 11 ARE ACTIVE !!! */ +#define SPI2_GPIO_AF GPIO_AF5 +#define SPI2_GPIO_PORT_SCK GPIOB +#define SPI2_GPIO_SCK GPIO13 +#define SPI2_GPIO_PORT_MISO GPIOB +#define SPI2_GPIO_MISO GPIO14 +#define SPI2_GPIO_PORT_MOSI GPIOB +#define SPI2_GPIO_MOSI GPIO15 + +/* CANNOT BE USED IF UARTS 4 & 5 ARE ACTIVE !!! */ +#define SPI3_GPIO_AF GPIO_AF6 +#define SPI3_GPIO_PORT_SCK GPIOC +#define SPI3_GPIO_SCK GPIO10 +#define SPI3_GPIO_PORT_MISO GPIOC +#define SPI3_GPIO_MISO GPIO11 +#define SPI3_GPIO_PORT_MOSI GPIOC +#define SPI3_GPIO_MOSI GPIO12 + +#define SPI_SELECT_SLAVE0_PORT GPIOE +#define SPI_SELECT_SLAVE0_PIN GPIO2 +#define SPI_SELECT_SLAVE1_PORT GPIOE +#define SPI_SELECT_SLAVE1_PIN GPIO7 + + +/***************************************************************************************************/ +/************************************** I2C *************************************************/ +/***************************************************************************************************/ #define I2C1_GPIO_PORT GPIOB #define I2C1_GPIO_SCL GPIO8 #define I2C1_GPIO_SDA GPIO9 @@ -104,47 +258,16 @@ #define I2C2_GPIO_SCL GPIO10 #define I2C2_GPIO_SDA GPIO11 -#define I2C3_GPIO_PORT_SCL GPIOA -#define I2C3_GPIO_PORT_SDA GPIOC -#define I2C3_GPIO_SCL GPIO8 -#define I2C3_GPIO_SDA GPIO9 +//#define I2C3_GPIO_PORT_SCL GPIOA +//#define I2C3_GPIO_SCL GPIO8 +//#define I2C3_GPIO_PORT_SDA GPIOC +//#define I2C3_GPIO_SDA GPIO9 -/* - * PPM - */ -#define USE_PPM_TIM1 1 +/***************************************************************************************************/ +/************************************** ADC *************************************************/ +/***************************************************************************************************/ -#define PPM_CHANNEL TIM_IC1 -#define PPM_TIMER_INPUT TIM_IC_IN_TI1 -#define PPM_IRQ NVIC_TIM1_CC_IRQ -#define PPM_IRQ2 NVIC_TIM1_UP_TIM10_IRQ -// Capture/Compare InteruptEnable and InterruptFlag -#define PPM_CC_IE TIM_DIER_CC1IE -#define PPM_CC_IF TIM_SR_CC1IF -#define PPM_GPIO_PORT GPIOA -#define PPM_GPIO_PIN GPIO8 -#define PPM_GPIO_AF GPIO_AF1 - - -/* - * Spektrum - */ -/* The line that is pulled low at power up to initiate the bind process */ -#define SPEKTRUM_BIND_PIN GPIO8 -#define SPEKTRUM_BIND_PIN_PORT GPIOA - -#define SPEKTRUM_UART2_RCC_REG &RCC_APB2ENR -#define SPEKTRUM_UART2_RCC_DEV RCC_APB2ENR_USART1EN -#define SPEKTRUM_UART2_BANK GPIOA -#define SPEKTRUM_UART2_PIN GPIO10 -#define SPEKTRUM_UART2_AF GPIO_AF7 -#define SPEKTRUM_UART2_IRQ NVIC_USART1_IRQ -#define SPEKTRUM_UART2_ISR usart1_isr -#define SPEKTRUM_UART2_DEV USART1 - - -/* Onboard ADCs */ #define USE_AD_TIM4 1 #define BOARD_ADC_CHANNEL_1 9 @@ -155,10 +278,12 @@ #ifndef USE_AD1 #define USE_AD1 1 #endif + /* provide defines that can be used to access the ADC_x in the code or airframe file * these directly map to the index number of the 4 adc channels defined above * 4th (index 3) is used for bat monitoring by default */ + // AUX 1 #define ADC_1 ADC1_C1 #ifdef USE_ADC_1 @@ -206,7 +331,7 @@ #endif #define USE_AD1_4 1 -/* allow to define ADC_CHANNEL_VSUPPLY in the airframe file*/ +/* allow to define ADC_CHANNEL_VSUPPLY in the airframe file */ #ifndef ADC_CHANNEL_VSUPPLY #define ADC_CHANNEL_VSUPPLY ADC_4 #endif @@ -226,6 +351,10 @@ #define DefaultVoltageOfAdc(adc) (0.00485*adc) +/***************************************************************************************************/ +/************************************ ACTUATORS ************************************************/ +/***************************************************************************************************/ + /* Default actuators driver */ #define DEFAULT_ACTUATORS "subsystems/actuators/actuators_pwm.h" #define ActuatorDefaultSet(_x,_y) ActuatorPwmSet(_x,_y) @@ -233,4 +362,248 @@ #define ActuatorsDefaultCommit() ActuatorsPwmCommit() +/***************************************************************************************************/ +/********************************** SERVO PWM *************************************************/ +/***************************************************************************************************/ + +#define PWM_USE_TIM1 1 +//#define PWM_USE_TIM3 1 +#define PWM_USE_TIM5 1 +#define PWM_USE_TIM9 1 +#define PWM_USE_TIM12 1 + +#define USE_PWM0 1 +#define USE_PWM1 1 +#define USE_PWM2 1 +#define USE_PWM3 1 +#define USE_PWM4 1 +#define USE_PWM5 1 +#define USE_PWM6 1 +#define USE_PWM7 1 +#define USE_PWM8 1 +#define USE_PWM9 1 +#if USE_SPI2 +#define USE_PWM10 0 +#define USE_PWM11 0 +#else +#define USE_PWM10 1 +#define USE_PWM11 1 +#endif + +#define ACTUATORS_PWM_NB 12 + +// PWM_SERVO_x is the index of the servo in the actuators_pwm_values array +#if USE_PWM0 +#define PWM_SERVO_0 0 +#define PWM_SERVO_0_TIMER TIM1 +#define PWM_SERVO_0_RCC_IOP RCC_AHB1ENR_IOPEEN +#define PWM_SERVO_0_GPIO GPIOE +#define PWM_SERVO_0_PIN GPIO9 +#define PWM_SERVO_0_AF GPIO_AF1 +#define PWM_SERVO_0_OC TIM_OC1 +#define PWM_SERVO_0_OC_BIT (1<<0) +#else +#define PWM_SERVO_0_OC_BIT 0 +#endif + +#if USE_PWM1 +#define PWM_SERVO_1 1 +#define PWM_SERVO_1_TIMER TIM1 +#define PWM_SERVO_1_RCC_IOP RCC_AHB1ENR_IOPEEN +#define PWM_SERVO_1_GPIO GPIOE +#define PWM_SERVO_1_PIN GPIO11 +#define PWM_SERVO_1_AF GPIO_AF1 +#define PWM_SERVO_1_OC TIM_OC2 +#define PWM_SERVO_1_OC_BIT (1<<1) +#else +#define PWM_SERVO_1_OC_BIT 0 +#endif + +#if USE_PWM2 +#define PWM_SERVO_2 2 +#define PWM_SERVO_2_TIMER TIM1 +#define PWM_SERVO_2_RCC_IOP RCC_AHB1ENR_IOPEEN +#define PWM_SERVO_2_GPIO GPIOE +#define PWM_SERVO_2_PIN GPIO13 +#define PWM_SERVO_2_AF GPIO_AF1 +#define PWM_SERVO_2_OC TIM_OC3 +#define PWM_SERVO_2_OC_BIT (1<<2) +#else +#define PWM_SERVO_2_OC_BIT 0 +#endif + +#if USE_PWM3 +#define PWM_SERVO_3 3 +#define PWM_SERVO_3_TIMER TIM1 +#define PWM_SERVO_3_RCC_IOP RCC_AHB1ENR_IOPEEN +#define PWM_SERVO_3_GPIO GPIOE +#define PWM_SERVO_3_PIN GPIO14 +#define PWM_SERVO_3_AF GPIO_AF1 +#define PWM_SERVO_3_OC TIM_OC4 +#define PWM_SERVO_3_OC_BIT (1<<3) +#else +#define PWM_SERVO_3_OC_BIT 0 +#endif + +#if USE_PWM4 +#define PWM_SERVO_4 4 +#define PWM_SERVO_4_TIMER TIM9 +#define PWM_SERVO_4_RCC_IOP RCC_AHB1ENR_IOPEEN +#define PWM_SERVO_4_GPIO GPIOE +#define PWM_SERVO_4_PIN GPIO5 +#define PWM_SERVO_4_AF GPIO_AF3 +#define PWM_SERVO_4_OC TIM_OC1 +#define PWM_SERVO_4_OC_BIT (1<<0) +#else +#define PWM_SERVO_4_OC_BIT 0 +#endif + +#if USE_PWM5 +#define PWM_SERVO_5 5 +#define PWM_SERVO_5_TIMER TIM9 +#define PWM_SERVO_5_RCC_IOP RCC_AHB1ENR_IOPEEN +#define PWM_SERVO_5_GPIO GPIOE +#define PWM_SERVO_5_PIN GPIO6 +#define PWM_SERVO_5_AF GPIO_AF3 +#define PWM_SERVO_5_OC TIM_OC2 +#define PWM_SERVO_5_OC_BIT (1<<1) +#else +#define PWM_SERVO_5_OC_BIT 0 +#endif + + +#if USE_PWM6 +#define PWM_SERVO_6 6 +#define PWM_SERVO_6_TIMER TIM5 +#define PWM_SERVO_6_RCC_IOP RCC_AHB1ENR_IOPAEN +#define PWM_SERVO_6_GPIO GPIOA +#define PWM_SERVO_6_PIN GPIO3 +#define PWM_SERVO_6_AF GPIO_AF2 +#define PWM_SERVO_6_OC TIM_OC4 +#define PWM_SERVO_6_OC_BIT (1<<3) +#else +#define PWM_SERVO_6_OC_BIT 0 +#endif + +#if USE_PWM7 +#define PWM_SERVO_7 7 +#define PWM_SERVO_7_TIMER TIM5 +#define PWM_SERVO_7_RCC_IOP RCC_AHB1ENR_IOPAEN +#define PWM_SERVO_7_GPIO GPIOA +#define PWM_SERVO_7_PIN GPIO2 +#define PWM_SERVO_7_AF GPIO_AF2 +#define PWM_SERVO_7_OC TIM_OC3 +#define PWM_SERVO_7_OC_BIT (1<<2) +#else +#define PWM_SERVO_7_OC_BIT 0 +#endif + +#if USE_PWM8 +#define PWM_SERVO_8 8 +#define PWM_SERVO_8_TIMER TIM5 +#define PWM_SERVO_8_RCC_IOP RCC_AHB1ENR_IOPAEN +#define PWM_SERVO_8_GPIO GPIOA +#define PWM_SERVO_8_PIN GPIO1 +#define PWM_SERVO_8_AF GPIO_AF2 +#define PWM_SERVO_8_OC TIM_OC2 +#define PWM_SERVO_8_OC_BIT (1<<1) +#else +#define PWM_SERVO_8_OC_BIT 0 +#endif + +#if USE_PWM9 +#define PWM_SERVO_9 9 +#define PWM_SERVO_9_TIMER TIM5 +#define PWM_SERVO_9_RCC_IOP RCC_AHB1ENR_IOPAEN +#define PWM_SERVO_9_GPIO GPIOA +#define PWM_SERVO_9_PIN GPIO0 +#define PWM_SERVO_9_AF GPIO_AF2 +#define PWM_SERVO_9_OC TIM_OC1 +#define PWM_SERVO_9_OC_BIT (1<<0) +#else +#define PWM_SERVO_9_OC_BIT 0 +#endif + +/* PWM10 AND PWM11 cannot be used if SPI2 is active. */ +#if USE_PWM10 +#define PWM_SERVO_10 10 +#define PWM_SERVO_10_TIMER TIM12 +#define PWM_SERVO_10_RCC_IOP RCC_AHB1ENR_IOPBEN +#define PWM_SERVO_10_GPIO GPIOB +#define PWM_SERVO_10_PIN GPIO14 +#define PWM_SERVO_10_AF GPIO_AF9 +#define PWM_SERVO_10_OC TIM_OC1 +#define PWM_SERVO_10_OC_BIT (1<<0) +#else +#define PWM_SERVO_10_OC_BIT 0 +#endif + +#if USE_PWM11 +#define PWM_SERVO_11 11 +#define PWM_SERVO_11_TIMER TIM12 +#define PWM_SERVO_11_RCC_IOP RCC_AHB1ENR_IOPBEN +#define PWM_SERVO_11_GPIO GPIOB +#define PWM_SERVO_11_PIN GPIO15 +#define PWM_SERVO_11_AF GPIO_AF9 +#define PWM_SERVO_11_OC TIM_OC2 +#define PWM_SERVO_11_OC_BIT (1<<1) +#else +#define PWM_SERVO_11_OC_BIT 0 +#endif + +#define PWM_TIM1_CHAN_MASK (PWM_SERVO_0_OC_BIT|PWM_SERVO_1_OC_BIT|PWM_SERVO_2_OC_BIT|PWM_SERVO_3_OC_BIT) +#define PWM_TIM9_CHAN_MASK (PWM_SERVO_4_OC_BIT|PWM_SERVO_5_OC_BIT) +#define PWM_TIM5_CHAN_MASK (PWM_SERVO_6_OC_BIT|PWM_SERVO_7_OC_BIT|PWM_SERVO_8_OC_BIT|PWM_SERVO_9_OC_BIT) +#define PWM_TIM12_CHAN_MASK (PWM_SERVO_10_OC_BIT|PWM_SERVO_11_OC_BIT) + +/***************************************************************************************************/ +/*********************************** PPM INPUT *************************************************/ +/***************************************************************************************************/ + +/* +#define USE_PPM_TIM1 1 + +#define PPM_CHANNEL TIM_IC1 +#define PPM_TIMER_INPUT TIM_IC_IN_TI1 +#define PPM_IRQ NVIC_TIM1_CC_IRQ +#define PPM_IRQ2 NVIC_TIM1_UP_TIM10_IRQ +// Capture/Compare InteruptEnable and InterruptFlag +#define PPM_CC_IE TIM_DIER_CC1IE +#define PPM_CC_IF TIM_SR_CC1IF +#define PPM_GPIO_PORT GPIOA +#define PPM_GPIO_PIN GPIO8 +#define PPM_GPIO_AF GPIO_AF1 +*/ + +#define USE_PPM_TIM8 1 + +#define PPM_CHANNEL TIM_IC4 +#define PPM_TIMER_INPUT TIM_IC_IN_TI4 +#define PPM_IRQ NVIC_TIM8_CC_IRQ +#define PPM_IRQ2 NVIC_TIM8_UP_TIM13_IRQ +// Capture/Compare InteruptEnable and InterruptFlag +#define PPM_CC_IE TIM_DIER_CC4IE +#define PPM_CC_IF TIM_SR_CC4IF +#define PPM_GPIO_PORT GPIOC +#define PPM_GPIO_PIN GPIO9 +#define PPM_GPIO_AF GPIO_AF3 + +/***************************************************************************************************/ +/********************************* SPECTRUM UART *************************************************/ +/***************************************************************************************************/ + +/* The line that is pulled low at power up to initiate the bind process */ +#define SPEKTRUM_BIND_PIN GPIO8 +#define SPEKTRUM_BIND_PIN_PORT GPIOA + +#define SPEKTRUM_UART2_RCC_REG &RCC_APB2ENR +#define SPEKTRUM_UART2_RCC_DEV RCC_APB2ENR_USART1EN +#define SPEKTRUM_UART2_BANK GPIOA +#define SPEKTRUM_UART2_PIN GPIO10 +#define SPEKTRUM_UART2_AF GPIO_AF7 +#define SPEKTRUM_UART2_IRQ NVIC_USART1_IRQ +#define SPEKTRUM_UART2_ISR usart1_isr +#define SPEKTRUM_UART2_DEV USART1 + + #endif /* CONFIG_STM32F4_DISCOVERY_H */ diff --git a/sw/airborne/boards/umarim/baro_board.c b/sw/airborne/boards/umarim/baro_board.c index c83675d17b..69f5866403 100644 --- a/sw/airborne/boards/umarim/baro_board.c +++ b/sw/airborne/boards/umarim/baro_board.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ENAC + * Copyright (C) 2010-2013 Gautier Hattenberger * * This file is part of paparazzi. * @@ -25,11 +25,22 @@ * Navarro & Gorraz & Hattenberger */ +#include "std.h" +#include "baro_board.h" #include "subsystems/sensors/baro.h" +#include "peripherals/ads1114.h" +#include "subsystems/abi.h" +#include "led.h" +// ADC for absolute pressure +#define BARO_ABS_ADS +#define BARO_ABS_ADS ads1114_1 +#endif -/* Common Baro struct */ -struct Baro baro; +// FIXME +#ifndef UMARIM_BARO_SENS +#define UMARIM_BARO_SENS 0.0274181 +#endif /* Counter to init ads1114 at startup */ #define BARO_STARTUP_COUNTER 200 @@ -37,23 +48,36 @@ uint16_t startup_cnt; void baro_init( void ) { ads1114_init(); - baro.status = BS_UNINITIALIZED; - baro.absolute = 0; - baro.differential = 0; /* not handled on this board, use extra module (ex: airspeed_ads1114) */ +#ifdef BARO_LED + LED_OFF(BARO_LED); +#endif startup_cnt = BARO_STARTUP_COUNTER; } void baro_periodic( void ) { - if (baro.status == BS_UNINITIALIZED && BARO_ABS_ADS.data_available) { - // Run some loops to get correct readings from the adc + // Run some loops to get correct readings from the adc + if (startup_cnt > 0) { --startup_cnt; - BARO_ABS_ADS.data_available = FALSE; +#ifdef BARO_LED + LED_TOGGLE(BARO_LED); if (startup_cnt == 0) { - baro.status = BS_RUNNING; + LED_ON(BARO_LED); } +#endif } // Read the ADC ads1114_read(&BARO_ABS_ADS); } +void umarim_baro_event(void) { + Ads1114Event(); + if (BARO_ABS_ADS.data_available) { + if (startup_cnt == 0) { + float pressure = UMARIM_BARO_SENS*Ads1114GetValue(BARO_ABS_ADS); + AbiSendMsgBARO_ABS(BARO_BOARD_SENDER_ID, &pressure); + } + BARO_ABS_ADS.data_available = FALSE; + } +} + diff --git a/sw/airborne/boards/umarim/baro_board.h b/sw/airborne/boards/umarim/baro_board.h index a296e6a28c..b340417909 100644 --- a/sw/airborne/boards/umarim/baro_board.h +++ b/sw/airborne/boards/umarim/baro_board.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2012 Gautier Hattenberger + * Copyright (C) 2010-2013 Gautier Hattenberger * * This file is part of paparazzi. * @@ -29,53 +29,7 @@ #ifndef BOARDS_UMARIM_BARO_H #define BOARDS_UMARIM_BARO_H - -#include "std.h" -#include "peripherals/ads1114.h" - -/* There is no differential pressure on the board but - * it can be available from an external sensor - * */ - -#define BARO_ABS_ADS ads1114_1 - -#define BaroAbs(_ads, _handler) { \ - if (_ads.data_available) { \ - baro.absolute = Ads1114GetValue(_ads); \ - if (baro.status == BS_RUNNING) { \ - _handler(); \ - _ads.data_available = FALSE; \ - } \ - } \ -} - -#ifndef BaroDiff // Allow custom redefinition ? - -#if USE_BARO_DIFF - -#ifndef BARO_DIFF_ADS -#define BARO_DIFF_ADS ads1114_2 -#endif -#define BaroDiff(_ads, _handler) { \ - if (_ads.data_available) { \ - baro.differential = Ads1114GetValue(_ads); \ - if (baro.status == BS_RUNNING) { \ - _handler(); \ - _ads.data_available = FALSE; \ - } \ - } \ -} - -#else // Not using differential with ADS1114 -#define BaroDiff(_a, _h) {} -#endif - -#endif // ifndef BaroDiff - -#define BaroEvent(_b_abs_handler, _b_diff_handler) { \ - Ads1114Event(); \ - BaroAbs(BARO_ABS_ADS,_b_abs_handler); \ - BaroDiff(BARO_DIFF_ADS,_b_diff_handler); \ -} +extern void umarim_baro_event(void); +#define BaroEvent umarim_baro_event #endif // BOARDS_UMARIM_BARO_H diff --git a/sw/airborne/boards/umarim_1.0.h b/sw/airborne/boards/umarim_1.0.h index d34ca18317..b3859e2897 100644 --- a/sw/airborne/boards/umarim_1.0.h +++ b/sw/airborne/boards/umarim_1.0.h @@ -114,6 +114,10 @@ #define SPI1_DRDY_EINT 0 #define SPI1_DRDY_VIC_IT VIC_EINT0 -#define BOARD_HAS_BARO 1 + +/* by default enable onboard baro */ +#ifndef USE_BARO_BOARD +#define USE_BARO_BOARD 1 +#endif #endif /* CONFIG_UMARIM_V1_0_H */ diff --git a/sw/airborne/firmwares/fixedwing/main_ap.c b/sw/airborne/firmwares/fixedwing/main_ap.c index 859b3bda08..9b7e5def6a 100644 --- a/sw/airborne/firmwares/fixedwing/main_ap.c +++ b/sw/airborne/firmwares/fixedwing/main_ap.c @@ -30,6 +30,8 @@ #define MODULES_C +#define ABI_C + #include #include "firmwares/fixedwing/main_ap.h" @@ -51,7 +53,8 @@ #if USE_AHRS_ALIGNER #include "subsystems/ahrs/ahrs_aligner.h" #endif -#if USE_BAROMETER +#include "subsystems/air_data.h" +#if USE_BARO_BOARD #include "subsystems/sensors/baro.h" #endif #include "subsystems/ins.h" @@ -81,11 +84,12 @@ #if defined RADIO_CONTROL || defined RADIO_CONTROL_AUTO1 #include "rc_settings.h" #endif +#include "subsystems/abi.h" #include "led.h" #ifdef USE_NPS -#include "nps_autopilot_fixedwing.h" +#include "nps_autopilot.h" #endif /* Default trim commands for roll, pitch and yaw */ @@ -148,11 +152,6 @@ static void send_fliter_status(void) { static inline void on_gps_solution( void ); #endif -#if USE_BAROMETER -static inline void on_baro_abs_event( void ); -static inline void on_baro_dif_event( void ); -#endif - // what version is this ???? static const uint16_t version = 1; @@ -202,7 +201,8 @@ void init_ap( void ) { register_periodic_telemetry(DefaultPeriodic, "STATE_FILTER_STATUS", send_fliter_status); #endif -#if USE_BAROMETER + air_data_init(); +#if USE_BARO_BOARD baro_init(); #endif @@ -593,7 +593,7 @@ void sensors_task( void ) { ahrs_propagate(); #endif -#if USE_BAROMETER +#if USE_BARO_BOARD baro_periodic(); #endif @@ -663,8 +663,8 @@ void event_task_ap( void ) { GpsEvent(on_gps_solution); #endif /* USE_GPS */ -#if USE_BAROMETER - BaroEvent(on_baro_abs_event, on_baro_dif_event); +#if USE_BARO_BOARD + BaroEvent(); #endif DatalinkEvent(); @@ -795,14 +795,3 @@ static inline void on_mag_event(void) #endif // USE_AHRS -#if USE_BAROMETER - -static inline void on_baro_abs_event( void ) { - ins_update_baro(); -} - -static inline void on_baro_dif_event( void ) { - -} - -#endif // USE_BAROMETER diff --git a/sw/airborne/firmwares/fixedwing/main_fbw.c b/sw/airborne/firmwares/fixedwing/main_fbw.c index 2e1e1f865d..5fc0844480 100644 --- a/sw/airborne/firmwares/fixedwing/main_fbw.c +++ b/sw/airborne/firmwares/fixedwing/main_fbw.c @@ -61,7 +61,7 @@ uint8_t fbw_mode; #include "inter_mcu.h" #ifdef USE_NPS -#include "nps_autopilot_fixedwing.h" +#include "nps_autopilot.h" #endif /** Trim commands for roll, pitch and yaw. diff --git a/sw/airborne/firmwares/rotorcraft/datalink.c b/sw/airborne/firmwares/rotorcraft/datalink.c index c463b3218d..96001f4198 100644 --- a/sw/airborne/firmwares/rotorcraft/datalink.c +++ b/sw/airborne/firmwares/rotorcraft/datalink.c @@ -49,7 +49,7 @@ #include "firmwares/rotorcraft/navigation.h" #include "math/pprz_geodetic_int.h" -#include "subsystems/ins.h" +#include "state.h" #define IdOfMsg(x) (x[1]) @@ -97,19 +97,18 @@ void dl_parse_msg(void) { { uint8_t ac_id = DL_MOVE_WP_ac_id(dl_buffer); if (ac_id != AC_ID) break; - uint8_t wp_id = DL_MOVE_WP_wp_id(dl_buffer); - struct LlaCoor_i lla; - struct EnuCoor_i enu; - lla.lat = INT32_RAD_OF_DEG(DL_MOVE_WP_lat(dl_buffer)); - lla.lon = INT32_RAD_OF_DEG(DL_MOVE_WP_lon(dl_buffer)); - /* WP_alt is in cm, lla.alt in mm */ - lla.alt = DL_MOVE_WP_alt(dl_buffer)*10 - ins_ltp_def.hmsl + ins_ltp_def.lla.alt; - enu_of_lla_point_i(&enu,&ins_ltp_def,&lla); - enu.x = POS_BFP_OF_REAL(enu.x)/100; - enu.y = POS_BFP_OF_REAL(enu.y)/100; - enu.z = POS_BFP_OF_REAL(enu.z)/100; - VECT3_ASSIGN(waypoints[wp_id], enu.x, enu.y, enu.z); - DOWNLINK_SEND_WP_MOVED_ENU(DefaultChannel, DefaultDevice, &wp_id, &enu.x, &enu.y, &enu.z); + if (stateIsLocalCoordinateValid()) { + uint8_t wp_id = DL_MOVE_WP_wp_id(dl_buffer); + struct LlaCoor_i lla; + lla.lat = INT32_RAD_OF_DEG(DL_MOVE_WP_lat(dl_buffer)); + lla.lon = INT32_RAD_OF_DEG(DL_MOVE_WP_lon(dl_buffer)); + /* WP_alt from message is alt above MSL in cm + * lla.alt is above ellipsoid in mm + */ + lla.alt = DL_MOVE_WP_alt(dl_buffer)*10 - state.ned_origin_i.hmsl + + state.ned_origin_i.lla.alt; + nav_move_waypoint_lla(wp_id, &lla); + } } break; #endif /* USE_NAVIGATION */ diff --git a/sw/airborne/firmwares/rotorcraft/guidance/guidance_h.c b/sw/airborne/firmwares/rotorcraft/guidance/guidance_h.c index 05d1757785..9ce4b59ed2 100644 --- a/sw/airborne/firmwares/rotorcraft/guidance/guidance_h.c +++ b/sw/airborne/firmwares/rotorcraft/guidance/guidance_h.c @@ -30,6 +30,9 @@ #include "firmwares/rotorcraft/stabilization/stabilization_attitude_rc_setpoint.h" #include "firmwares/rotorcraft/navigation.h" +/* for guidance_v_thrust_coeff */ +#include "firmwares/rotorcraft/guidance/guidance_v.h" + #include "state.h" #include "generated/airframe.h" @@ -55,24 +58,30 @@ PRINT_CONFIG_VAR(GUIDANCE_H_USE_REF) +#ifndef GUIDANCE_H_APPROX_FORCE_BY_THRUST +#define GUIDANCE_H_APPROX_FORCE_BY_THRUST FALSE +#endif + uint8_t guidance_h_mode; bool_t guidance_h_use_ref; +bool_t guidance_h_approx_force_by_thrust; struct Int32Vect2 guidance_h_pos_sp; struct Int32Vect2 guidance_h_pos_ref; struct Int32Vect2 guidance_h_speed_ref; struct Int32Vect2 guidance_h_accel_ref; - +#if GUIDANCE_H_USE_SPEED_REF +struct Int32Vect2 guidance_h_speed_sp; +#endif struct Int32Vect2 guidance_h_pos_err; struct Int32Vect2 guidance_h_speed_err; -struct Int32Vect2 guidance_h_pos_err_sum; +struct Int32Vect2 guidance_h_trim_att_integrator; struct Int32Vect2 guidance_h_nav_err; +struct Int32Vect2 guidance_h_cmd_earth; struct Int32Eulers guidance_h_rc_sp; -struct Int32Vect2 guidance_h_command_earth; -struct Int32Vect2 guidance_h_stick_earth_sp; -struct Int32Eulers guidance_h_command_body; +int32_t guidance_h_heading_sp; int32_t guidance_h_pgain; int32_t guidance_h_dgain; @@ -88,6 +97,7 @@ static void guidance_h_traj_run(bool_t in_flight); static void guidance_h_hover_enter(void); static void guidance_h_nav_enter(void); static inline void transition_run(void); +static void read_rc_setpoint_speed_i(struct Int32Vect2 *speed_sp, bool_t in_flight); #if DOWNLINK #include "subsystems/datalink/telemetry.h" @@ -153,11 +163,12 @@ void guidance_h_init(void) { guidance_h_mode = GUIDANCE_H_MODE_KILL; guidance_h_use_ref = GUIDANCE_H_USE_REF; + guidance_h_approx_force_by_thrust = GUIDANCE_H_APPROX_FORCE_BY_THRUST; INT_VECT2_ZERO(guidance_h_pos_sp); - INT_VECT2_ZERO(guidance_h_pos_err_sum); + INT_VECT2_ZERO(guidance_h_trim_att_integrator); INT_EULERS_ZERO(guidance_h_rc_sp); - INT_EULERS_ZERO(guidance_h_command_body); + guidance_h_heading_sp = 0; guidance_h_pgain = GUIDANCE_H_PGAIN; guidance_h_igain = GUIDANCE_H_IGAIN; guidance_h_dgain = GUIDANCE_H_DGAIN; @@ -179,7 +190,7 @@ static inline void reset_guidance_reference_from_current_position(void) { INT_VECT2_ZERO(guidance_h_accel_ref); gh_set_ref(guidance_h_pos_ref, guidance_h_speed_ref, guidance_h_accel_ref); - INT_VECT2_ZERO(guidance_h_pos_err_sum); + INT_VECT2_ZERO(guidance_h_trim_att_integrator); } void guidance_h_mode_changed(uint8_t new_mode) { @@ -268,6 +279,9 @@ void guidance_h_read_rc(bool_t in_flight) { case GUIDANCE_H_MODE_HOVER: stabilization_attitude_read_rc_setpoint_eulers(&guidance_h_rc_sp, in_flight); +#if GUIDANCE_H_USE_SPEED_REF + read_rc_setpoint_speed_i(&guidance_h_speed_sp, in_flight); +#endif break; case GUIDANCE_H_MODE_NAV: @@ -312,10 +326,12 @@ void guidance_h_run(bool_t in_flight) { guidance_h_update_reference(); /* set psi command */ - guidance_h_command_body.psi = guidance_h_rc_sp.psi; - /* compute roll and pitch commands and set final attitude setpoint */ + guidance_h_heading_sp = guidance_h_rc_sp.psi; + /* compute x,y earth commands */ guidance_h_traj_run(in_flight); - + /* set final attitude setpoint */ + stabilization_attitude_set_earth_cmd_i(&guidance_h_cmd_earth, + guidance_h_heading_sp); stabilization_attitude_run(in_flight); break; @@ -327,9 +343,11 @@ void guidance_h_run(bool_t in_flight) { struct Int32Eulers sp_cmd_i; sp_cmd_i.phi = nav_roll; sp_cmd_i.theta = nav_pitch; - /* FIXME: heading can't be set via attitude block yet, use current heading for now */ + /** @todo: heading can't be set via attitude block yet. + * use current euler psi for now, should be real heading + */ sp_cmd_i.psi = stateGetNedToBodyEulers_i()->psi; - stabilization_attitude_set_cmd_i(&sp_cmd_i); + stabilization_attitude_set_rpy_setpoint_i(&sp_cmd_i); } else { INT32_VECT2_NED_OF_ENU(guidance_h_pos_sp, navigation_carrot); @@ -337,10 +355,13 @@ void guidance_h_run(bool_t in_flight) { guidance_h_update_reference(); /* set psi command */ - guidance_h_command_body.psi = nav_heading; - INT32_ANGLE_NORMALIZE(guidance_h_command_body.psi); - /* compute roll and pitch commands and set final attitude setpoint */ + guidance_h_heading_sp = nav_heading; + INT32_ANGLE_NORMALIZE(guidance_h_heading_sp); + /* compute x,y earth commands */ guidance_h_traj_run(in_flight); + /* set final attitude setpoint */ + stabilization_attitude_set_earth_cmd_i(&guidance_h_cmd_earth, + guidance_h_heading_sp); } stabilization_attitude_run(in_flight); break; @@ -354,6 +375,11 @@ void guidance_h_run(bool_t in_flight) { static void guidance_h_update_reference(void) { /* compute reference even if usage temporarily disabled via guidance_h_use_ref */ #if GUIDANCE_H_USE_REF +#if GUIDANCE_H_USE_SPEED_REF + if(guidance_h_mode == GUIDANCE_H_MODE_HOVER) + gh_update_ref_from_speed_sp(guidance_h_speed_sp); + else +#endif gh_update_ref_from_pos_sp(guidance_h_pos_sp); #endif @@ -368,21 +394,31 @@ static void guidance_h_update_reference(void) { INT_VECT2_ZERO(guidance_h_speed_ref); INT_VECT2_ZERO(guidance_h_accel_ref); } + +#if GUIDANCE_H_USE_SPEED_REF + if(guidance_h_mode == GUIDANCE_H_MODE_HOVER) { + VECT2_COPY(guidance_h_pos_sp, guidance_h_pos_ref); // for display only + } +#endif } #define MAX_POS_ERR POS_BFP_OF_REAL(16.) #define MAX_SPEED_ERR SPEED_BFP_OF_REAL(16.) -#define MAX_POS_ERR_SUM ((int32_t)(MAX_POS_ERR)<< 12) + +#ifndef GUIDANCE_H_THRUST_CMD_FILTER +#define GUIDANCE_H_THRUST_CMD_FILTER 10 +#endif /* with a pgain of 100 and a scale of 2, * you get an angle of 5.6 degrees for 1m pos error */ #define GH_GAIN_SCALE 2 -/** maximum bank angle: default 20 deg */ -#define TRAJ_MAX_BANK BFP_OF_REAL(GUIDANCE_H_MAX_BANK, INT32_ANGLE_FRAC) - static void guidance_h_traj_run(bool_t in_flight) { + /* maximum bank angle: default 20 deg, max 40 deg*/ + static const int32_t traj_max_bank = Max(BFP_OF_REAL(GUIDANCE_H_MAX_BANK, INT32_ANGLE_FRAC), + BFP_OF_REAL(RadOfDeg(40), INT32_ANGLE_FRAC)); + static const int32_t total_max_bank = BFP_OF_REAL(RadOfDeg(45), INT32_ANGLE_FRAC); /* compute position error */ VECT2_DIFF(guidance_h_pos_err, guidance_h_pos_ref, *stateGetPositionNed_i()); @@ -394,48 +430,50 @@ static void guidance_h_traj_run(bool_t in_flight) { /* saturate it */ VECT2_STRIM(guidance_h_speed_err, -MAX_SPEED_ERR, MAX_SPEED_ERR); - /* update pos error integral, zero it if not in_flight */ + /* run PID */ + int32_t pd_x = + ((guidance_h_pgain * guidance_h_pos_err.x) >> (INT32_POS_FRAC - GH_GAIN_SCALE)) + + ((guidance_h_dgain * (guidance_h_speed_err.x >> 2)) >> (INT32_SPEED_FRAC - GH_GAIN_SCALE - 2)); + int32_t pd_y = + ((guidance_h_pgain * guidance_h_pos_err.y) >> (INT32_POS_FRAC - GH_GAIN_SCALE)) + + ((guidance_h_dgain * (guidance_h_speed_err.y >> 2)) >> (INT32_SPEED_FRAC - GH_GAIN_SCALE - 2)); + guidance_h_cmd_earth.x = + pd_x + + ((guidance_h_again * guidance_h_accel_ref.x) >> 8); /* acceleration feedforward gain */ + guidance_h_cmd_earth.y = + pd_y + + ((guidance_h_again * guidance_h_accel_ref.y) >> 8); /* acceleration feedforward gain */ + + /* trim max bank angle from PD */ + VECT2_STRIM(guidance_h_cmd_earth, -traj_max_bank, traj_max_bank); + + /* Update pos & speed error integral, zero it if not in_flight. + * Integrate twice as fast when not only POS but also SPEED are wrong, + * but do not integrate POS errors when the SPEED is already catching up. + */ if (in_flight) { - VECT2_ADD(guidance_h_pos_err_sum, guidance_h_pos_err); - /* saturate it */ - VECT2_STRIM(guidance_h_pos_err_sum, -MAX_POS_ERR_SUM, MAX_POS_ERR_SUM); + /* ANGLE_FRAC (12) * GAIN (8) * LOOP_FREQ (9) -> ANGLE_FRAX (12) */ + guidance_h_trim_att_integrator.x += ((guidance_h_igain * pd_x) >> (8)); + guidance_h_trim_att_integrator.y += ((guidance_h_igain * pd_y) >> (8)); + /* saturate it */ + VECT2_STRIM(guidance_h_trim_att_integrator, -(traj_max_bank << 12) , (traj_max_bank << 12)); + /* add it to the command */ + guidance_h_cmd_earth.x += guidance_h_trim_att_integrator.x >> 12; + guidance_h_cmd_earth.y += guidance_h_trim_att_integrator.y >> 12; } else { - INT_VECT2_ZERO(guidance_h_pos_err_sum); + INT_VECT2_ZERO(guidance_h_trim_att_integrator); } - /* run PID */ - guidance_h_command_earth.x = - ((guidance_h_pgain * guidance_h_pos_err.x) >> (INT32_POS_FRAC - GH_GAIN_SCALE)) + - ((guidance_h_dgain * (guidance_h_speed_err.x >> 2)) >> (INT32_SPEED_FRAC - GH_GAIN_SCALE - 2)) + - ((guidance_h_igain * (guidance_h_pos_err_sum.x >> 12)) >> (INT32_POS_FRAC - GH_GAIN_SCALE)) + - ((guidance_h_again * guidance_h_accel_ref.x) >> 8); /* feedforward gain */ - guidance_h_command_earth.y = - ((guidance_h_pgain * guidance_h_pos_err.y) >> (INT32_POS_FRAC - GH_GAIN_SCALE)) + - ((guidance_h_dgain * (guidance_h_speed_err.y >> 2)) >> (INT32_SPEED_FRAC - GH_GAIN_SCALE - 2)) + - ((guidance_h_igain * (guidance_h_pos_err_sum.y >> 12)) >> (INT32_POS_FRAC - GH_GAIN_SCALE)) + - ((guidance_h_again * guidance_h_accel_ref.y) >> 8); /* feedforward gain */ + /* compute a better approximation of force commands by taking thrust into account */ + if (guidance_h_approx_force_by_thrust && in_flight) { + static int32_t thrust_cmd_filt; + int32_t vertical_thrust = (stabilization_cmd[COMMAND_THRUST] * guidance_v_thrust_coeff) >> INT32_TRIG_FRAC; + thrust_cmd_filt = (thrust_cmd_filt * GUIDANCE_H_THRUST_CMD_FILTER + vertical_thrust) / (GUIDANCE_H_THRUST_CMD_FILTER + 1); + guidance_h_cmd_earth.x = ANGLE_BFP_OF_REAL(atan2f((guidance_h_cmd_earth.x * MAX_PPRZ / INT32_ANGLE_PI_2), thrust_cmd_filt)); + guidance_h_cmd_earth.y = ANGLE_BFP_OF_REAL(atan2f((guidance_h_cmd_earth.y * MAX_PPRZ / INT32_ANGLE_PI_2), thrust_cmd_filt)); + } - VECT2_STRIM(guidance_h_command_earth, -TRAJ_MAX_BANK, TRAJ_MAX_BANK); - - /* Rotate to body frame */ - int32_t s_psi, c_psi; - int32_t psi = stateGetNedToBodyEulers_i()->psi; - PPRZ_ITRIG_SIN(s_psi, psi); - PPRZ_ITRIG_COS(c_psi, psi); - - // Restore angle ref resolution after rotation - guidance_h_command_body.phi = - ( - s_psi * guidance_h_command_earth.x + c_psi * guidance_h_command_earth.y) >> INT32_TRIG_FRAC; - guidance_h_command_body.theta = - - ( c_psi * guidance_h_command_earth.x + s_psi * guidance_h_command_earth.y) >> INT32_TRIG_FRAC; - - - /* Add RC roll and pitch setpoints for emergency corrections */ - guidance_h_command_body.phi += guidance_h_rc_sp.phi; - guidance_h_command_body.theta += guidance_h_rc_sp.theta; - - /* Set attitude setpoint from pseudo-euler commands */ - stabilization_attitude_set_cmd_i(&guidance_h_command_body); + VECT2_STRIM(guidance_h_cmd_earth, -total_max_bank, total_max_bank); } static void guidance_h_hover_enter(void) { @@ -467,3 +505,34 @@ static inline void transition_run(void) { transition_theta_offset = INT_MULT_RSHIFT((transition_percentage<<(INT32_ANGLE_FRAC-INT32_PERCENTAGE_FRAC))/100, max_offset, INT32_ANGLE_FRAC); #endif } + +/// read speed setpoint from RC +static void read_rc_setpoint_speed_i(struct Int32Vect2 *speed_sp, bool_t in_flight) { + if(in_flight) { + // negative pitch is forward + int64_t rc_x = -radio_control.values[RADIO_PITCH]; + int64_t rc_y = radio_control.values[RADIO_ROLL]; + DeadBand(rc_x, MAX_PPRZ/20); + DeadBand(rc_y, MAX_PPRZ/20); + + // convert input from MAX_PPRZ range to SPEED_BFP + int32_t max_speed = SPEED_BFP_OF_REAL(GUIDANCE_H_REF_MAX_SPEED); + /// @todo calc proper scale while making sure a division by zero can't occur + //int32_t rc_norm = sqrtf(rc_x * rc_x + rc_y * rc_y); + //int32_t max_pprz = rc_norm * MAX_PPRZ / Max(abs(rc_x), abs(rc_y); + rc_x = rc_x * max_speed / MAX_PPRZ; + rc_y = rc_y * max_speed / MAX_PPRZ; + + /* Rotate from body to NED frame by negative psi angle */ + int32_t psi = -stateGetNedToBodyEulers_i()->psi; + int32_t s_psi, c_psi; + PPRZ_ITRIG_SIN(s_psi, psi); + PPRZ_ITRIG_COS(c_psi, psi); + speed_sp->x = (int32_t)(((int64_t)c_psi * rc_x - (int64_t)s_psi * rc_y) >> INT32_TRIG_FRAC); + speed_sp->y = (int32_t)(((int64_t)s_psi * rc_x + (int64_t)c_psi * rc_y) >> INT32_TRIG_FRAC); + } + else { + speed_sp->x = 0; + speed_sp->y = 0; + } +} diff --git a/sw/airborne/firmwares/rotorcraft/guidance/guidance_h.h b/sw/airborne/firmwares/rotorcraft/guidance/guidance_h.h index 5a136317d5..f8a934ce43 100644 --- a/sw/airborne/firmwares/rotorcraft/guidance/guidance_h.h +++ b/sw/airborne/firmwares/rotorcraft/guidance/guidance_h.h @@ -53,6 +53,7 @@ extern uint8_t guidance_h_mode; extern bool_t guidance_h_use_ref; +extern bool_t guidance_h_approx_force_by_thrust; /** horizontal position setpoint in NED. * fixed point representation: Q23.8 @@ -66,12 +67,17 @@ extern struct Int32Vect2 guidance_h_accel_ref; ///< with #INT32_ACCEL_FRAC extern struct Int32Vect2 guidance_h_pos_err; extern struct Int32Vect2 guidance_h_speed_err; -extern struct Int32Vect2 guidance_h_pos_err_sum; +extern struct Int32Vect2 guidance_h_trim_att_integrator; extern struct Int32Vect2 guidance_h_nav_err; + +/** horizontal guidance command. + * In north/east with #INT32_ANGLE_FRAC + * @todo convert to real force command + */ +extern struct Int32Vect2 guidance_h_cmd_earth; extern struct Int32Eulers guidance_h_rc_sp; ///< with #INT32_ANGLE_FRAC -extern struct Int32Vect2 guidance_h_command_earth; -extern struct Int32Eulers guidance_h_command_body; ///< with #INT32_ANGLE_FRAC +extern int32_t guidance_h_heading_sp; ///< with #INT32_ANGLE_FRAC extern int32_t guidance_h_pgain; extern int32_t guidance_h_dgain; @@ -89,7 +95,7 @@ extern void guidance_h_run(bool_t in_flight); #define guidance_h_SetKi(_val) { \ guidance_h_igain = _val; \ - INT_VECT2_ZERO(guidance_h_pos_err_sum); \ + INT_VECT2_ZERO(guidance_h_trim_att_integrator); \ } /* Make sure that ref can only be temporarily disabled for testing, diff --git a/sw/airborne/firmwares/rotorcraft/guidance/guidance_h_ref.c b/sw/airborne/firmwares/rotorcraft/guidance/guidance_h_ref.c index 34b23d212c..fb8be1fa67 100644 --- a/sw/airborne/firmwares/rotorcraft/guidance/guidance_h_ref.c +++ b/sw/airborne/firmwares/rotorcraft/guidance/guidance_h_ref.c @@ -47,18 +47,9 @@ struct Int32Vect2 gh_speed_ref; */ struct Int64Vect2 gh_pos_ref; -/** Accel saturation. - * tanf(RadOfDeg(30.))*9.81 = 5.66 - */ -#ifndef GUIDANCE_H_REF_MAX_ACCEL -#define GUIDANCE_H_REF_MAX_ACCEL 5.66 -#endif + static const int32_t gh_max_accel = BFP_OF_REAL(GUIDANCE_H_REF_MAX_ACCEL, GH_ACCEL_REF_FRAC); -/** Speed saturation */ -#ifndef GUIDANCE_H_REF_MAX_SPEED -#define GUIDANCE_H_REF_MAX_SPEED 5. -#endif /** @todo GH_MAX_SPEED must be limited to 2^14 to avoid overflow */ #define GH_MAX_SPEED_REF_FRAC 7 static const int32_t gh_max_speed = BFP_OF_REAL(GUIDANCE_H_REF_MAX_SPEED, GH_MAX_SPEED_REF_FRAC); diff --git a/sw/airborne/firmwares/rotorcraft/guidance/guidance_h_ref.h b/sw/airborne/firmwares/rotorcraft/guidance/guidance_h_ref.h index ab285baa11..179097db55 100644 --- a/sw/airborne/firmwares/rotorcraft/guidance/guidance_h_ref.h +++ b/sw/airborne/firmwares/rotorcraft/guidance/guidance_h_ref.h @@ -31,6 +31,18 @@ #include "math/pprz_algebra.h" #include "math/pprz_algebra_int.h" +/** Speed saturation */ +#ifndef GUIDANCE_H_REF_MAX_SPEED +#define GUIDANCE_H_REF_MAX_SPEED 5. +#endif + +/** Accel saturation. + * tanf(RadOfDeg(30.))*9.81 = 5.66 + */ +#ifndef GUIDANCE_H_REF_MAX_ACCEL +#define GUIDANCE_H_REF_MAX_ACCEL 5.66 +#endif + /** Update frequency */ #define GH_FREQ_FRAC 9 diff --git a/sw/airborne/firmwares/rotorcraft/guidance/guidance_v.c b/sw/airborne/firmwares/rotorcraft/guidance/guidance_v.c index 82e990fe8a..7385927dba 100644 --- a/sw/airborne/firmwares/rotorcraft/guidance/guidance_v.c +++ b/sw/airborne/firmwares/rotorcraft/guidance/guidance_v.c @@ -62,6 +62,19 @@ PRINT_CONFIG_VAR(GUIDANCE_V_NOMINAL_HOVER_THROTTLE) PRINT_CONFIG_VAR(GUIDANCE_V_ADAPT_THROTTLE_ENABLED) +#ifndef GUIDANCE_V_CLIMB_RC_DEADBAND +#define GUIDANCE_V_CLIMB_RC_DEADBAND MAX_PPRZ/10 +#endif + +#ifndef GUIDANCE_V_MAX_RC_CLIMB_SPEED +#define GUIDANCE_V_MAX_RC_CLIMB_SPEED GUIDANCE_V_REF_MIN_ZD +#endif + +#ifndef GUIDANCE_V_MAX_RC_DESCENT_SPEED +#define GUIDANCE_V_MAX_RC_DESCENT_SPEED GUIDANCE_V_REF_MAX_ZD +#endif + + uint8_t guidance_v_mode; int32_t guidance_v_ff_cmd; int32_t guidance_v_fb_cmd; @@ -94,14 +107,14 @@ int32_t guidance_v_ki; int32_t guidance_v_z_sum_err; -static int32_t guidance_v_thrust_coeff; +int32_t guidance_v_thrust_coeff; #define GuidanceVSetRef(_pos, _speed, _accel) { \ - gv_set_ref(_pos, _speed, _accel); \ - guidance_v_z_ref = _pos; \ - guidance_v_zd_ref = _speed; \ - guidance_v_zdd_ref = _accel; \ + gv_set_ref(_pos, _speed, _accel); \ + guidance_v_z_ref = _pos; \ + guidance_v_zd_ref = _speed; \ + guidance_v_zdd_ref = _accel; \ } static int32_t get_vertical_thrust_coeff(void); @@ -164,9 +177,18 @@ void guidance_v_read_rc(void) { guidance_v_rc_delta_t = (int32_t)radio_control.values[RADIO_THROTTLE]; /* used in RC_CLIMB */ - guidance_v_rc_zd_sp = ((MAX_PPRZ/2) - (int32_t)radio_control.values[RADIO_THROTTLE]) * GUIDANCE_V_RC_CLIMB_COEF; - DeadBand(guidance_v_rc_zd_sp, GUIDANCE_V_RC_CLIMB_DEAD_BAND); + guidance_v_rc_zd_sp = (MAX_PPRZ/2) - (int32_t)radio_control.values[RADIO_THROTTLE]; + DeadBand(guidance_v_rc_zd_sp, GUIDANCE_V_CLIMB_RC_DEADBAND); + static const int32_t climb_scale = ABS(SPEED_BFP_OF_REAL(GUIDANCE_V_MAX_RC_CLIMB_SPEED) / + (MAX_PPRZ/2 - GUIDANCE_V_CLIMB_RC_DEADBAND)); + static const int32_t descent_scale = ABS(SPEED_BFP_OF_REAL(GUIDANCE_V_MAX_RC_DESCENT_SPEED) / + (MAX_PPRZ/2 - GUIDANCE_V_CLIMB_RC_DEADBAND)); + + if(guidance_v_rc_zd_sp > 0) + guidance_v_rc_zd_sp *= descent_scale; + else + guidance_v_rc_zd_sp *= climb_scale; } void guidance_v_mode_changed(uint8_t new_mode) { diff --git a/sw/airborne/firmwares/rotorcraft/guidance/guidance_v.h b/sw/airborne/firmwares/rotorcraft/guidance/guidance_v.h index 4a94b4cfa8..93e0aeaa4d 100644 --- a/sw/airborne/firmwares/rotorcraft/guidance/guidance_v.h +++ b/sw/airborne/firmwares/rotorcraft/guidance/guidance_v.h @@ -91,6 +91,9 @@ extern float guidance_v_nominal_throttle; */ extern bool_t guidance_v_adapt_throttle_enabled; + +extern int32_t guidance_v_thrust_coeff; + extern int32_t guidance_v_kp; ///< vertical control P-gain extern int32_t guidance_v_kd; ///< vertical control D-gain extern int32_t guidance_v_ki; ///< vertical control I-gain diff --git a/sw/airborne/firmwares/rotorcraft/guidance/guidance_v_ref.c b/sw/airborne/firmwares/rotorcraft/guidance/guidance_v_ref.c index 281827bb0b..31d1e2c0e4 100644 --- a/sw/airborne/firmwares/rotorcraft/guidance/guidance_v_ref.c +++ b/sw/airborne/firmwares/rotorcraft/guidance/guidance_v_ref.c @@ -58,14 +58,7 @@ int64_t gv_z_ref; #endif #define GV_MAX_ZDD BFP_OF_REAL(GUIDANCE_V_REF_MAX_ZDD, GV_ZDD_REF_FRAC) -#ifndef GUIDANCE_V_REF_MIN_ZD -#define GUIDANCE_V_REF_MIN_ZD (-3.) -#endif #define GV_MIN_ZD BFP_OF_REAL(GUIDANCE_V_REF_MIN_ZD , GV_ZD_REF_FRAC) - -#ifndef GUIDANCE_V_REF_MAX_ZD -#define GUIDANCE_V_REF_MAX_ZD ( 3.) -#endif #define GV_MAX_ZD BFP_OF_REAL(GUIDANCE_V_REF_MAX_ZD , GV_ZD_REF_FRAC) /* second order model natural frequency and damping */ diff --git a/sw/airborne/firmwares/rotorcraft/guidance/guidance_v_ref.h b/sw/airborne/firmwares/rotorcraft/guidance/guidance_v_ref.h index f462a07a2b..3816a9031b 100644 --- a/sw/airborne/firmwares/rotorcraft/guidance/guidance_v_ref.h +++ b/sw/airborne/firmwares/rotorcraft/guidance/guidance_v_ref.h @@ -32,6 +32,16 @@ #include "math/pprz_algebra.h" #include "math/pprz_algebra_int.h" + +#ifndef GUIDANCE_V_REF_MIN_ZD +#define GUIDANCE_V_REF_MIN_ZD (-3.) +#endif + +#ifndef GUIDANCE_V_REF_MAX_ZD +#define GUIDANCE_V_REF_MAX_ZD ( 3.) +#endif + + /** Update frequency */ #define GV_FREQ_FRAC 9 diff --git a/sw/airborne/firmwares/rotorcraft/main.c b/sw/airborne/firmwares/rotorcraft/main.c index cbc7bef331..76ddcd9da7 100644 --- a/sw/airborne/firmwares/rotorcraft/main.c +++ b/sw/airborne/firmwares/rotorcraft/main.c @@ -28,6 +28,8 @@ #define MODULES_C +#define ABI_C + #include #include "mcu.h" #include "mcu_periph/sys_time.h" @@ -50,8 +52,11 @@ #include "subsystems/imu.h" #include "subsystems/gps.h" +#include "subsystems/air_data.h" +#if USE_BARO_BOARD #include "subsystems/sensors/baro.h" +#endif #include "subsystems/electrical.h" @@ -71,10 +76,11 @@ #include "firmwares/rotorcraft/main.h" #ifdef SITL -#include "nps_autopilot_rotorcraft.h" +#include "nps_autopilot.h" #endif #include "generated/modules.h" +#include "subsystems/abi.h" /* if PRINT_CONFIG is defined, print some config options */ @@ -98,8 +104,6 @@ PRINT_CONFIG_VAR(BARO_PERIODIC_FREQUENCY) static inline void on_gyro_event( void ); static inline void on_accel_event( void ); -static inline void on_baro_abs_event( void ); -static inline void on_baro_dif_event( void ); static inline void on_gps_event( void ); static inline void on_mag_event( void ); @@ -109,8 +113,10 @@ tid_t modules_tid; ///< id for modules_periodic_task() timer tid_t failsafe_tid; ///< id for failsafe_check() timer tid_t radio_control_tid; ///< id for radio_control_periodic_task() timer tid_t electrical_tid; ///< id for electrical_periodic() timer -tid_t baro_tid; ///< id for baro_periodic() timer tid_t telemetry_tid; ///< id for telemetry_periodic() timer +#if USE_BARO_BOARD +tid_t baro_tid; ///< id for baro_periodic() timer +#endif #ifndef SITL int main( void ) { @@ -139,7 +145,10 @@ STATIC_INLINE void main_init( void ) { radio_control_init(); + air_data_init(); +#if USE_BARO_BOARD baro_init(); +#endif imu_init(); #if USE_IMU_FLOAT imu_float_init(); @@ -175,8 +184,10 @@ STATIC_INLINE void main_init( void ) { radio_control_tid = sys_time_register_timer((1./60.), NULL); failsafe_tid = sys_time_register_timer(0.05, NULL); electrical_tid = sys_time_register_timer(0.1, NULL); - baro_tid = sys_time_register_timer(1./BARO_PERIODIC_FREQUENCY, NULL); telemetry_tid = sys_time_register_timer((1./TELEMETRY_FREQUENCY), NULL); +#if USE_BARO_BOARD + baro_tid = sys_time_register_timer(1./BARO_PERIODIC_FREQUENCY, NULL); +#endif } STATIC_INLINE void handle_periodic_tasks( void ) { @@ -190,10 +201,12 @@ STATIC_INLINE void handle_periodic_tasks( void ) { failsafe_check(); if (sys_time_check_and_ack_timer(electrical_tid)) electrical_periodic(); - if (sys_time_check_and_ack_timer(baro_tid)) - baro_periodic(); if (sys_time_check_and_ack_timer(telemetry_tid)) telemetry_periodic(); +#if USE_BARO_BOARD + if (sys_time_check_and_ack_timer(baro_tid)) + baro_periodic(); +#endif } STATIC_INLINE void main_periodic( void ) { @@ -260,7 +273,9 @@ STATIC_INLINE void main_event( void ) { ImuEvent(on_gyro_event, on_accel_event, on_mag_event); - BaroEvent(on_baro_abs_event, on_baro_dif_event); +#if USE_BARO_BOARD + BaroEvent(); +#endif #if USE_GPS GpsEvent(on_gps_event); @@ -297,26 +312,12 @@ static inline void on_gyro_event( void ) { if (nps_bypass_ahrs) sim_overwrite_ahrs(); #endif ins_propagate(); -#ifdef SITL - if (nps_bypass_ins) sim_overwrite_ins(); -#endif } #ifdef USE_VEHICLE_INTERFACE vi_notify_imu_available(); #endif } -static inline void on_baro_abs_event( void ) { - ins_update_baro(); -#ifdef USE_VEHICLE_INTERFACE - vi_notify_baro_abs_available(); -#endif -} - -static inline void on_baro_dif_event( void ) { - -} - static inline void on_gps_event(void) { ahrs_update_gps(); ins_update_gps(); diff --git a/sw/airborne/firmwares/rotorcraft/navigation.c b/sw/airborne/firmwares/rotorcraft/navigation.c index 30bcb9fd6b..2e99c54a76 100644 --- a/sw/airborne/firmwares/rotorcraft/navigation.c +++ b/sw/airborne/firmwares/rotorcraft/navigation.c @@ -44,6 +44,10 @@ #include "math/pprz_algebra_int.h" +#include "subsystems/datalink/downlink.h" +#include "messages.h" +#include "mcu_periph/uart.h" + const uint8_t nb_waypoint = NB_WAYPOINT; struct EnuCoor_i waypoints[NB_WAYPOINT]; @@ -179,13 +183,11 @@ static inline void nav_advance_carrot(void) { void nav_run(void) { -#if !GUIDANCE_H_USE_REF - PRINT_CONFIG_MSG("NOT using horizontal guidance reference :-(") - nav_advance_carrot(); -#else - PRINT_CONFIG_MSG("Using horizontal guidance reference :-)") - // if H_REF is used, CARROT_DIST is not used +#if GUIDANCE_H_USE_REF + // if GUIDANCE_H_USE_REF, CARROT_DIST is not used VECT2_COPY(navigation_carrot, navigation_target); +#else + nav_advance_carrot(); #endif nav_set_altitude(); @@ -305,7 +307,7 @@ static inline void nav_set_altitude( void ) { /** Reset the geographic reference to the current GPS fix */ unit_t nav_reset_reference( void ) { - ins_ltp_initialised = FALSE; + ins_impl.ltp_initialized = FALSE; ins.hf_realign = TRUE; ins.vf_realign = TRUE; return 0; @@ -315,9 +317,9 @@ unit_t nav_reset_alt( void ) { ins.vf_realign = TRUE; #if USE_GPS - ins_ltp_def.lla.alt = gps.lla_pos.alt; - ins_ltp_def.hmsl = gps.hmsl; - stateSetLocalOrigin_i(&ins_ltp_def); + ins_impl.ltp_def.lla.alt = gps.lla_pos.alt; + ins_impl.ltp_def.hmsl = gps.hmsl; + stateSetLocalOrigin_i(&ins_impl.ltp_def); #endif return 0; @@ -340,16 +342,25 @@ void nav_periodic_task() { /* run carrot loop */ nav_run(); - ground_alt = POS_BFP_OF_REAL((float)ins_ltp_def.hmsl / 1000.); + ground_alt = POS_BFP_OF_REAL((float)ins_impl.ltp_def.hmsl / 1000.); +} + +void nav_move_waypoint_lla(uint8_t wp_id, struct LlaCoor_i* new_lla_pos) { + if (stateIsLocalCoordinateValid()) { + struct EnuCoor_i enu; + enu_of_lla_point_i(&enu, &state.ned_origin_i, new_lla_pos); + enu.x = POS_BFP_OF_REAL(enu.x)/100; + enu.y = POS_BFP_OF_REAL(enu.y)/100; + enu.z = POS_BFP_OF_REAL(enu.z)/100; + nav_move_waypoint(wp_id, &enu); + } } -#include "subsystems/datalink/downlink.h" -#include "messages.h" -#include "mcu_periph/uart.h" void nav_move_waypoint(uint8_t wp_id, struct EnuCoor_i * new_pos) { if (wp_id < nb_waypoint) { INT32_VECT3_COPY(waypoints[wp_id],(*new_pos)); - DOWNLINK_SEND_WP_MOVED_ENU(DefaultChannel, DefaultDevice, &wp_id, &(new_pos->x), &(new_pos->y), &(new_pos->z)); + DOWNLINK_SEND_WP_MOVED_ENU(DefaultChannel, DefaultDevice, &wp_id, &(new_pos->x), + &(new_pos->y), &(new_pos->z)); } } diff --git a/sw/airborne/firmwares/rotorcraft/navigation.h b/sw/airborne/firmwares/rotorcraft/navigation.h index b8df4ee553..120e574de0 100644 --- a/sw/airborne/firmwares/rotorcraft/navigation.h +++ b/sw/airborne/firmwares/rotorcraft/navigation.h @@ -79,6 +79,7 @@ void compute_dist2_to_home(void); unit_t nav_reset_reference( void ) __attribute__ ((unused)); unit_t nav_reset_alt( void ) __attribute__ ((unused)); void nav_periodic_task(void); +void nav_move_waypoint_lla(uint8_t wp_id, struct LlaCoor_i* new_lla_pos); void nav_move_waypoint(uint8_t wp_id, struct EnuCoor_i * new_pos); bool_t nav_detect_ground(void); bool_t nav_is_in_flight(void); diff --git a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude.h b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude.h index 94b47466e4..8917a2d93c 100644 --- a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude.h +++ b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude.h @@ -34,8 +34,9 @@ extern void stabilization_attitude_init(void); extern void stabilization_attitude_read_rc(bool_t in_flight); extern void stabilization_attitude_enter(void); extern void stabilization_attitude_set_failsafe_setpoint(void); -extern void stabilization_attitude_set_cmd_i(struct Int32Eulers *sp_cmd); -extern void stabilization_attitude_run(bool_t in_flight); +extern void stabilization_attitude_set_rpy_setpoint_i(struct Int32Eulers *rpy); +extern void stabilization_attitude_set_earth_cmd_i(struct Int32Vect2 *cmd, int32_t heading); +extern void stabilization_attitude_run(bool_t in_flight); #endif /* STABILIZATION_ATTITUDE_H */ diff --git a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_euler_float.c b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_euler_float.c index f70a684093..d98e976f97 100644 --- a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_euler_float.c +++ b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_euler_float.c @@ -134,10 +134,23 @@ void stabilization_attitude_set_failsafe_setpoint(void) { stab_att_sp_euler.psi = stateGetNedToBodyEulers_f()->psi; } -void stabilization_attitude_set_cmd_i(struct Int32Eulers *sp_cmd) { - EULERS_FLOAT_OF_BFP(stab_att_sp_euler, *sp_cmd); +void stabilization_attitude_set_rpy_setpoint_i(struct Int32Eulers *rpy) { + EULERS_FLOAT_OF_BFP(stab_att_sp_euler, *rpy); } +void stabilization_attitude_set_earth_cmd_i(struct Int32Vect2 *cmd, int32_t heading) { + struct FloatVect2 cmd_f; + cmd_f.x = ANGLE_FLOAT_OF_BFP(cmd->x); + cmd_f.y = ANGLE_FLOAT_OF_BFP(cmd->y); + + /* Rotate horizontal commands to body frame by psi */ + float psi = stateGetNedToBodyEulers_f()->psi; + float s_psi = sinf(psi); + float c_psi = cosf(psi); + stab_att_sp_euler.phi = -s_psi * cmd_f.x + c_psi * cmd_f.y; + stab_att_sp_euler.theta = -c_psi * cmd_f.x - s_psi * cmd_f.y; + stab_att_sp_euler.psi = ANGLE_FLOAT_OF_BFP(heading); +} #define MAX_SUM_ERR RadOfDeg(56000) diff --git a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_euler_int.c b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_euler_int.c index 47260a4928..3f5fed125f 100644 --- a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_euler_int.c +++ b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_euler_int.c @@ -149,10 +149,20 @@ void stabilization_attitude_set_failsafe_setpoint(void) { stab_att_sp_euler.psi = stateGetNedToBodyEulers_i()->psi; } -void stabilization_attitude_set_cmd_i(struct Int32Eulers *sp_cmd) { - memcpy(&stab_att_sp_euler, sp_cmd, sizeof(struct Int32Eulers)); +void stabilization_attitude_set_rpy_setpoint_i(struct Int32Eulers *rpy) { + memcpy(&stab_att_sp_euler, rpy, sizeof(struct Int32Eulers)); } +void stabilization_attitude_set_earth_cmd_i(struct Int32Vect2 *cmd, int32_t heading) { + /* Rotate horizontal commands to body frame by psi */ + int32_t psi = stateGetNedToBodyEulers_i()->psi; + int32_t s_psi, c_psi; + PPRZ_ITRIG_SIN(s_psi, psi); + PPRZ_ITRIG_COS(c_psi, psi); + stab_att_sp_euler.phi = (-s_psi * cmd->x + c_psi * cmd->y) >> INT32_TRIG_FRAC; + stab_att_sp_euler.theta = -(c_psi * cmd->x + s_psi * cmd->y) >> INT32_TRIG_FRAC; + stab_att_sp_euler.psi = heading; +} #define OFFSET_AND_ROUND(_a, _b) (((_a)+(1<<((_b)-1)))>>(_b)) #define OFFSET_AND_ROUND2(_a, _b) (((_a)+(1<<((_b)-1))-((_a)<0?1:0))>>(_b)) diff --git a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_quat_float.c b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_quat_float.c index a5764fa859..ee7f42f067 100644 --- a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_quat_float.c +++ b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_quat_float.c @@ -25,6 +25,7 @@ #include "firmwares/rotorcraft/stabilization.h" #include "firmwares/rotorcraft/stabilization/stabilization_attitude_rc_setpoint.h" +#include "firmwares/rotorcraft/stabilization/stabilization_attitude_quat_transformations.h" #include #include "math/pprz_algebra_float.h" @@ -142,75 +143,21 @@ void stabilization_attitude_set_failsafe_setpoint(void) { stab_att_sp_quat.qz = sinf(heading2); } -void stabilization_attitude_set_cmd_i(struct Int32Eulers *sp_cmd) { - EULERS_FLOAT_OF_BFP(stab_att_sp_euler, *sp_cmd); +void stabilization_attitude_set_rpy_setpoint_i(struct Int32Eulers *rpy) { + // copy euler setpoint for debugging + EULERS_FLOAT_OF_BFP(stab_att_sp_euler, *rpy); - /* orientation vector describing simultaneous rotation of roll/pitch */ - struct FloatVect3 ov; - ov.x = stab_att_sp_euler.phi; - ov.y = stab_att_sp_euler.theta; - ov.z = 0.0; - /* quaternion from that orientation vector */ - struct FloatQuat q_rp; - FLOAT_QUAT_OF_ORIENTATION_VECT(q_rp, ov); + quat_from_rpy_cmd_f(&stab_att_sp_quat, &stab_att_sp_euler); +} - /// @todo optimize yaw angle calculation +void stabilization_attitude_set_earth_cmd_i(struct Int32Vect2 *cmd, int32_t heading) { + struct FloatVect2 cmd_f; + cmd_f.x = ANGLE_FLOAT_OF_BFP(cmd->x); + cmd_f.y = ANGLE_FLOAT_OF_BFP(cmd->y); + float heading_f; + heading_f = ANGLE_FLOAT_OF_BFP(heading); - /* - * Instead of using the psi setpoint angle to rotate around the body z-axis, - * calculate the real angle needed to align the projection of the body x-axis - * onto the horizontal plane with the psi setpoint. - * - * angle between two vectors a and b: - * angle = atan2(norm(cross(a,b)), dot(a,b)) * sign(dot(cross(a,b), n)) - * where n is the thrust vector (i.e. both a and b lie in that plane) - */ - const struct FloatVect3 xaxis = {1.0, 0.0, 0.0}; - const struct FloatVect3 zaxis = {0.0, 0.0, 1.0}; - struct FloatVect3 a; - FLOAT_QUAT_VMULT(a, q_rp, xaxis); - - // desired heading vect in earth x-y plane - struct FloatVect3 psi_vect; - psi_vect.x = cosf(stab_att_sp_euler.psi); - psi_vect.y = sinf(stab_att_sp_euler.psi); - psi_vect.z = 0.0; - // normal is the direction of the thrust vector - struct FloatVect3 normal; - FLOAT_QUAT_VMULT(normal, q_rp, zaxis); - - // projection of desired heading onto body x-y plane - // b = v - dot(v,n)*n - float dot = FLOAT_VECT3_DOT_PRODUCT(psi_vect, normal); - struct FloatVect3 dotn; - FLOAT_VECT3_SMUL(dotn, normal, dot); - - // b = v - dot(v,n)*n - struct FloatVect3 b; - FLOAT_VECT3_DIFF(b, psi_vect, dotn); - dot = FLOAT_VECT3_DOT_PRODUCT(a, b); - struct FloatVect3 cross; - VECT3_CROSS_PRODUCT(cross, a, b); - // norm of the cross product - float nc = FLOAT_VECT3_NORM(cross); - // angle = atan2(norm(cross(a,b)), dot(a,b)) - float yaw2 = atan2(nc, dot) / 2.0; - - // negative angle if needed - // sign(dot(cross(a,b), n) - float dot_cross_ab = FLOAT_VECT3_DOT_PRODUCT(cross, normal); - if (dot_cross_ab < 0) { - yaw2 = -yaw2; - } - - /* quaternion with yaw command */ - struct FloatQuat q_yaw; - QUAT_ASSIGN(q_yaw, cosf(yaw2), 0.0, 0.0, sinf(yaw2)); - - /* final setpoint: apply roll/pitch, then yaw around resulting body z-axis */ - FLOAT_QUAT_COMP(stab_att_sp_quat, q_yaw, q_rp); - FLOAT_QUAT_NORMALIZE(stab_att_sp_quat); - FLOAT_QUAT_WRAP_SHORTEST(stab_att_sp_quat); + quat_from_earth_cmd_f(&stab_att_sp_quat, &cmd_f, heading_f); } #ifndef GAIN_PRESCALER_FF diff --git a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_quat_float.h b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_quat_float.h index 9077bbd8cb..8655fc23ac 100644 --- a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_quat_float.h +++ b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_quat_float.h @@ -31,13 +31,6 @@ #include "firmwares/rotorcraft/stabilization/stabilization_attitude_common_float.h" #include "firmwares/rotorcraft/stabilization/stabilization_attitude_ref_quat_float.h" -#ifndef STABILIZATION_ATTITUDE_GAIN_NB -#define STABILIZATION_ATTITUDE_GAIN_NB 1 -#endif - -#ifndef STABILIZATION_ATTITUDE_GAIN_IDX_DEFAULT -#define STABILIZATION_ATTITUDE_GAIN_IDX_DEFAULT 0 -#endif extern struct FloatAttitudeGains stabilization_gains[]; diff --git a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_quat_int.c b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_quat_int.c index cc64b8567e..311325b724 100644 --- a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_quat_int.c +++ b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_quat_int.c @@ -25,6 +25,7 @@ #include "firmwares/rotorcraft/stabilization.h" #include "firmwares/rotorcraft/stabilization/stabilization_attitude_rc_setpoint.h" +#include "firmwares/rotorcraft/stabilization/stabilization_attitude_quat_transformations.h" #include #include "math/pprz_algebra_float.h" @@ -137,85 +138,27 @@ void stabilization_attitude_set_failsafe_setpoint(void) { PPRZ_ITRIG_SIN(stab_att_sp_quat.qz, heading2); } -void stabilization_attitude_set_cmd_i(struct Int32Eulers *sp_cmd) { - // copy euler setpoint for debugging - memcpy(&stab_att_sp_euler, sp_cmd, sizeof(struct Int32Eulers)); +void stabilization_attitude_set_rpy_setpoint_i(struct Int32Eulers *rpy) { + // stab_att_sp_euler.psi still used in ref.. + memcpy(&stab_att_sp_euler, rpy, sizeof(struct Int32Eulers)); - /// @todo calc sp_quat in fixed-point + quat_from_rpy_cmd_i(&stab_att_sp_quat, &stab_att_sp_euler); +} - /* orientation vector describing simultaneous rotation of roll/pitch */ - struct FloatVect3 ov; - ov.x = ANGLE_FLOAT_OF_BFP(sp_cmd->phi); - ov.y = ANGLE_FLOAT_OF_BFP(sp_cmd->theta); - ov.z = 0.0; - /* quaternion from that orientation vector */ - struct FloatQuat q_rp; - FLOAT_QUAT_OF_ORIENTATION_VECT(q_rp, ov); +void stabilization_attitude_set_earth_cmd_i(struct Int32Vect2 *cmd, int32_t heading) { + // stab_att_sp_euler.psi still used in ref.. + stab_att_sp_euler.psi = heading; - const float psi_sp = ANGLE_FLOAT_OF_BFP(sp_cmd->psi); + // compute sp_euler phi/theta for debugging/telemetry + /* Rotate horizontal commands to body frame by psi */ + int32_t psi = stateGetNedToBodyEulers_i()->psi; + int32_t s_psi, c_psi; + PPRZ_ITRIG_SIN(s_psi, psi); + PPRZ_ITRIG_COS(c_psi, psi); + stab_att_sp_euler.phi = (-s_psi * cmd->x + c_psi * cmd->y) >> INT32_TRIG_FRAC; + stab_att_sp_euler.theta = -(c_psi * cmd->x + s_psi * cmd->y) >> INT32_TRIG_FRAC; - /// @todo optimize yaw angle calculation - - /* - * Instead of using the psi setpoint angle to rotate around the body z-axis, - * calculate the real angle needed to align the projection of the body x-axis - * onto the horizontal plane with the psi setpoint. - * - * angle between two vectors a and b: - * angle = atan2(norm(cross(a,b)), dot(a,b)) * sign(dot(cross(a,b), n)) - * where n is the thrust vector (i.e. both a and b lie in that plane) - */ - const struct FloatVect3 xaxis = {1.0, 0.0, 0.0}; - const struct FloatVect3 zaxis = {0.0, 0.0, 1.0}; - struct FloatVect3 a; - FLOAT_QUAT_VMULT(a, q_rp, xaxis); - - // desired heading vect in earth x-y plane - struct FloatVect3 psi_vect; - psi_vect.x = cosf(psi_sp); - psi_vect.y = sinf(psi_sp); - psi_vect.z = 0.0; - // normal is the direction of the thrust vector - struct FloatVect3 normal; - FLOAT_QUAT_VMULT(normal, q_rp, zaxis); - - // projection of desired heading onto body x-y plane - // b = v - dot(v,n)*n - float dot = FLOAT_VECT3_DOT_PRODUCT(psi_vect, normal); - struct FloatVect3 dotn; - FLOAT_VECT3_SMUL(dotn, normal, dot); - - // b = v - dot(v,n)*n - struct FloatVect3 b; - FLOAT_VECT3_DIFF(b, psi_vect, dotn); - - dot = FLOAT_VECT3_DOT_PRODUCT(a, b); - struct FloatVect3 cross; - VECT3_CROSS_PRODUCT(cross, a, b); - // norm of the cross product - float nc = FLOAT_VECT3_NORM(cross); - // angle = atan2(norm(cross(a,b)), dot(a,b)) - float yaw2 = atan2(nc, dot) / 2.0; - - // negative angle if needed - // sign(dot(cross(a,b), n) - float dot_cross_ab = FLOAT_VECT3_DOT_PRODUCT(cross, normal); - if (dot_cross_ab < 0) { - yaw2 = -yaw2; - } - - /* quaternion with yaw command */ - struct FloatQuat q_yaw; - QUAT_ASSIGN(q_yaw, cosf(yaw2), 0.0, 0.0, sinf(yaw2)); - - /* final setpoint: apply roll/pitch, then yaw around resulting body z-axis */ - struct FloatQuat q_sp; - FLOAT_QUAT_COMP(q_sp, q_yaw, q_rp); - FLOAT_QUAT_NORMALIZE(q_sp); - FLOAT_QUAT_WRAP_SHORTEST(q_sp); - - /* convert to fixed point */ - QUAT_BFP_OF_REAL(stab_att_sp_quat, q_sp); + quat_from_earth_cmd_i(&stab_att_sp_quat, cmd, heading); } #define OFFSET_AND_ROUND(_a, _b) (((_a)+(1<<((_b)-1)))>>(_b)) diff --git a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_quat_transformations.c b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_quat_transformations.c new file mode 100644 index 0000000000..12ca369d62 --- /dev/null +++ b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_quat_transformations.c @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2013 Felix Ruess + * + * 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. + */ + +/** @file stabilization_attitude_quat_transformations.c + * Quaternion transformation functions. + */ + +#include "stabilization_attitude_quat_transformations.h" + +void quat_from_rpy_cmd_i(struct Int32Quat *quat, struct Int32Eulers *rpy) { + struct FloatEulers rpy_f; + EULERS_FLOAT_OF_BFP(rpy_f, *rpy); + struct FloatQuat quat_f; + quat_from_rpy_cmd_f(&quat_f, &rpy_f); + QUAT_BFP_OF_REAL(*quat, quat_f); +} + +void quat_from_rpy_cmd_f(struct FloatQuat *quat, struct FloatEulers *rpy) { + // only a plug for now... doesn't apply roll/pitch wrt. current yaw angle + + /* orientation vector describing simultaneous rotation of roll/pitch/yaw */ + const struct FloatVect3 ov = {rpy->phi, rpy->theta, rpy->psi}; + /* quaternion from that orientation vector */ + FLOAT_QUAT_OF_ORIENTATION_VECT(*quat, ov); + +} + +void quat_from_earth_cmd_i(struct Int32Quat *quat, struct Int32Vect2 *cmd, int32_t heading) { + // use float conversion for now... + struct FloatVect2 cmd_f; + cmd_f.x = ANGLE_FLOAT_OF_BFP(cmd->x); + cmd_f.y = ANGLE_FLOAT_OF_BFP(cmd->y); + float heading_f = ANGLE_FLOAT_OF_BFP(heading); + + struct FloatQuat quat_f; + quat_from_earth_cmd_f(&quat_f, &cmd_f, heading_f); + + // convert back to fixed point + QUAT_BFP_OF_REAL(*quat, quat_f); +} + +void quat_from_earth_cmd_f(struct FloatQuat *quat, struct FloatVect2 *cmd, float heading) { + + /* cmd_x is positive to north = negative pitch + * cmd_y is positive to east = positive roll + * + * orientation vector describing simultaneous rotation of roll/pitch + */ + const struct FloatVect3 ov = {cmd->y, -cmd->x, 0.0}; + /* quaternion from that orientation vector */ + struct FloatQuat q_rp; + FLOAT_QUAT_OF_ORIENTATION_VECT(q_rp, ov); + + /* as rotation matrix */ + struct FloatRMat R_rp; + FLOAT_RMAT_OF_QUAT(R_rp, q_rp); + /* body x-axis (before heading command) is first column */ + struct FloatVect3 b_x; + VECT3_ASSIGN(b_x, R_rp.m[0], R_rp.m[3], R_rp.m[6]); + /* body z-axis (thrust vect) is last column */ + struct FloatVect3 thrust_vect; + VECT3_ASSIGN(thrust_vect, R_rp.m[2], R_rp.m[5], R_rp.m[8]); + + /// @todo optimize yaw angle calculation + + /* + * Instead of using the psi setpoint angle to rotate around the body z-axis, + * calculate the real angle needed to align the projection of the body x-axis + * onto the horizontal plane with the psi setpoint. + * + * angle between two vectors a and b: + * angle = atan2(norm(cross(a,b)), dot(a,b)) * sign(dot(cross(a,b), n)) + * where the normal n is the thrust vector (i.e. both a and b lie in that plane) + */ + + // desired heading vect in earth x-y plane + const struct FloatVect3 psi_vect = {cosf(heading), sinf(heading), 0.0}; + + /* projection of desired heading onto body x-y plane + * b = v - dot(v,n)*n + */ + float dot = FLOAT_VECT3_DOT_PRODUCT(psi_vect, thrust_vect); + struct FloatVect3 dotn; + FLOAT_VECT3_SMUL(dotn, thrust_vect, dot); + + // b = v - dot(v,n)*n + struct FloatVect3 b; + FLOAT_VECT3_DIFF(b, psi_vect, dotn); + dot = FLOAT_VECT3_DOT_PRODUCT(b_x, b); + struct FloatVect3 cross; + VECT3_CROSS_PRODUCT(cross, b_x, b); + // norm of the cross product + float nc = FLOAT_VECT3_NORM(cross); + // angle = atan2(norm(cross(a,b)), dot(a,b)) + float yaw2 = atan2(nc, dot) / 2.0; + + // negative angle if needed + // sign(dot(cross(a,b), n) + float dot_cross_ab = FLOAT_VECT3_DOT_PRODUCT(cross, thrust_vect); + if (dot_cross_ab < 0) { + yaw2 = -yaw2; + } + + /* quaternion with yaw command */ + struct FloatQuat q_yaw; + QUAT_ASSIGN(q_yaw, cosf(yaw2), 0.0, 0.0, sinf(yaw2)); + + /* final setpoint: apply roll/pitch, then yaw around resulting body z-axis */ + FLOAT_QUAT_COMP(*quat, q_rp, q_yaw); + FLOAT_QUAT_NORMALIZE(*quat); + FLOAT_QUAT_WRAP_SHORTEST(*quat); + +} diff --git a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_quat_transformations.h b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_quat_transformations.h new file mode 100644 index 0000000000..1c57038b3f --- /dev/null +++ b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_quat_transformations.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2013 Felix Ruess + * + * 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. + */ + +/** @file stabilization_attitude_quat_transformations.h + * Quaternion transformation functions. + */ + +#ifndef STABILIZATION_ATTITUDE_QUAT_TRANSFORMATIONS_H +#define STABILIZATION_ATTITUDE_QUAT_TRANSFORMATIONS_H + +#include "math/pprz_algebra_float.h" +#include "math/pprz_algebra_int.h" + +extern void quat_from_rpy_cmd_i(struct Int32Quat *quat, struct Int32Eulers *rpy); +extern void quat_from_rpy_cmd_f(struct FloatQuat *quat, struct FloatEulers *rpy); + +extern void quat_from_earth_cmd_i(struct Int32Quat *quat, struct Int32Vect2 *cmd, int32_t heading); +extern void quat_from_earth_cmd_f(struct FloatQuat *quat, struct FloatVect2 *cmd, float heading); + +#endif diff --git a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_rc_setpoint.c b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_rc_setpoint.c index 7054d1824b..0affbcd21b 100644 --- a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_rc_setpoint.c +++ b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_rc_setpoint.c @@ -221,15 +221,14 @@ void stabilization_attitude_read_rc_setpoint_eulers_f(struct FloatEulers *sp, bo * @param[out] q quaternion representing the RC roll/pitch input */ void stabilization_attitude_read_rc_roll_pitch_quat_f(struct FloatQuat* q) { - q->qx = radio_control.values[RADIO_ROLL] * STABILIZATION_ATTITUDE_SP_MAX_PHI / MAX_PPRZ / 2; - q->qy = radio_control.values[RADIO_PITCH] * STABILIZATION_ATTITUDE_SP_MAX_THETA / MAX_PPRZ / 2; - q->qz = 0.0; + /* orientation vector describing simultaneous rotation of roll/pitch */ + struct FloatVect3 ov; + ov.x = radio_control.values[RADIO_ROLL] * STABILIZATION_ATTITUDE_SP_MAX_PHI / MAX_PPRZ / 2; + ov.y = radio_control.values[RADIO_PITCH] * STABILIZATION_ATTITUDE_SP_MAX_THETA / MAX_PPRZ / 2; + ov.z = 0.0; - /* normalize */ - float norm = sqrtf(1.0 + SQUARE(q->qx)+ SQUARE(q->qy)); - q->qi = 1.0 / norm; - q->qx /= norm; - q->qy /= norm; + /* quaternion from that orientation vector */ + FLOAT_QUAT_OF_ORIENTATION_VECT(*q, ov); } /** Read roll/pitch command from RC as quaternion. diff --git a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_euler_float.c b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_euler_float.c index a70e780560..04e3e60b10 100644 --- a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_euler_float.c +++ b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_euler_float.c @@ -1,4 +1,5 @@ -#include "firmwares/rotorcraft/stabilization/stabilization_attitude.h" +#include "firmwares/rotorcraft/stabilization/stabilization_attitude_ref_euler_float.h" +#include "firmwares/rotorcraft/stabilization/stabilization_attitude_ref_saturate.h" #include "generated/airframe.h" struct FloatEulers stab_att_sp_euler; diff --git a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_euler_float.h b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_euler_float.h index 762e66ed96..ba55615872 100644 --- a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_euler_float.h +++ b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_euler_float.h @@ -22,10 +22,7 @@ #ifndef STABILIZATION_ATTITUDE_FLOAT_REF_EULER_FLOAT_H #define STABILIZATION_ATTITUDE_FLOAT_REF_EULER_FLOAT_H -#include "math/pprz_algebra_float.h" - #include "stabilization_attitude_ref_float.h" -#include "stabilization_attitude_ref.h" void stabilization_attitude_ref_enter(void); diff --git a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_euler_int.c b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_euler_int.c index d7e8566a8b..14472fbb03 100644 --- a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_euler_int.c +++ b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_euler_int.c @@ -24,7 +24,8 @@ * */ -#include "firmwares/rotorcraft/stabilization/stabilization_attitude.h" +#include "firmwares/rotorcraft/stabilization/stabilization_attitude_ref_euler_int.h" +#include "firmwares/rotorcraft/stabilization/stabilization_attitude_ref_saturate.h" #include "generated/airframe.h" struct Int32Eulers stab_att_sp_euler; diff --git a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_euler_int.h b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_euler_int.h index bf3aacf19c..08579a412a 100644 --- a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_euler_int.h +++ b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_euler_int.h @@ -28,7 +28,5 @@ #define STABILIZATION_ATTITUDE_REF_EULER_INT_H #include "stabilization_attitude_ref_int.h" -#include "stabilization_attitude_ref.h" - #endif /* STABILIZATION_ATTITUDE_REF_EULER_INT_H */ diff --git a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_float.h b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_float.h index 2faf9e0bc9..fb62bcc457 100644 --- a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_float.h +++ b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_float.h @@ -27,9 +27,7 @@ #ifndef STABILIZATION_ATTITUDE_REF_FLOAT_H #define STABILIZATION_ATTITUDE_REF_FLOAT_H -#include "generated/airframe.h" - -#include "state.h" +#include "math/pprz_algebra_float.h" extern struct FloatEulers stab_att_sp_euler; extern struct FloatQuat stab_att_sp_quat; diff --git a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_int.h b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_int.h index c0ef65a2b8..24175b5fc2 100644 --- a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_int.h +++ b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_int.h @@ -29,8 +29,6 @@ #include "math/pprz_algebra_int.h" -#include "state.h" - extern struct Int32Eulers stab_att_ref_euler; ///< with #REF_ANGLE_FRAC extern struct Int32Quat stab_att_ref_quat; ///< with #INT32_QUAT_FRAC extern struct Int32Rates stab_att_ref_rate; ///< with #REF_RATE_FRAC diff --git a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_quat_float.c b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_quat_float.c index da50880f15..ff15cf95a8 100644 --- a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_quat_float.c +++ b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_quat_float.c @@ -28,10 +28,9 @@ */ #include "generated/airframe.h" -#include "firmwares/rotorcraft/stabilization.h" -#include "state.h" -#include "stabilization_attitude_ref_float.h" +#include "firmwares/rotorcraft/stabilization/stabilization_attitude_ref_quat_float.h" +#include "firmwares/rotorcraft/stabilization/stabilization_attitude_ref_saturate.h" #define REF_ACCEL_MAX_P STABILIZATION_ATTITUDE_REF_MAX_PDOT #define REF_ACCEL_MAX_Q STABILIZATION_ATTITUDE_REF_MAX_QDOT diff --git a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_quat_float.h b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_quat_float.h index 0424fbf820..b5543ed82b 100644 --- a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_quat_float.h +++ b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_quat_float.h @@ -30,14 +30,15 @@ #ifndef STABILIZATION_ATTITUDE_FLOAT_REF_QUAT_FLOAT_H #define STABILIZATION_ATTITUDE_FLOAT_REF_QUAT_FLOAT_H -#include "subsystems/radio_control.h" -#include "math/pprz_algebra_float.h" - #include "stabilization_attitude_ref_float.h" -#include "stabilization_attitude_ref.h" -#define DEADBAND_EXCEEDED(VARIABLE, VALUE) ((VARIABLE > VALUE) || (VARIABLE < -VALUE)) -#define APPLY_DEADBAND(VARIABLE, VALUE) (DEADBAND_EXCEEDED(VARIABLE, VALUE) ? VARIABLE : 0.0) +#ifndef STABILIZATION_ATTITUDE_GAIN_NB +#define STABILIZATION_ATTITUDE_GAIN_NB 1 +#endif + +#ifndef STABILIZATION_ATTITUDE_GAIN_IDX_DEFAULT +#define STABILIZATION_ATTITUDE_GAIN_IDX_DEFAULT 0 +#endif void stabilization_attitude_ref_enter(void); void stabilization_attitude_ref_schedule(uint8_t idx); diff --git a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_quat_int.c b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_quat_int.c index b0202847dd..aacd33d198 100644 --- a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_quat_int.c +++ b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_quat_int.c @@ -28,9 +28,8 @@ */ #include "generated/airframe.h" -#include "firmwares/rotorcraft/stabilization.h" - -#include "stabilization_attitude_ref_int.h" +#include "firmwares/rotorcraft/stabilization/stabilization_attitude_ref_quat_int.h" +#include "firmwares/rotorcraft/stabilization/stabilization_attitude_ref_saturate.h" #define REF_ACCEL_MAX_P BFP_OF_REAL(STABILIZATION_ATTITUDE_REF_MAX_PDOT, REF_ACCEL_FRAC) #define REF_ACCEL_MAX_Q BFP_OF_REAL(STABILIZATION_ATTITUDE_REF_MAX_QDOT, REF_ACCEL_FRAC) diff --git a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_quat_int.h b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_quat_int.h index 3b1cbaa3e8..4fe03f3218 100644 --- a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_quat_int.h +++ b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_quat_int.h @@ -31,7 +31,6 @@ #define STABILIZATION_ATTITUDE_INT_REF_QUAT_INT_H #include "stabilization_attitude_ref_int.h" -#include "stabilization_attitude_ref.h" void stabilization_attitude_ref_enter(void); diff --git a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref.h b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_saturate.h similarity index 92% rename from sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref.h rename to sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_saturate.h index 11d41dfb39..5bb4efb06d 100644 --- a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref.h +++ b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_attitude_ref_saturate.h @@ -19,12 +19,12 @@ * Boston, MA 02111-1307, USA. */ -/** @file firmwares/rotorcraft/stabilization/stabilization_attitude_ref.h - * Common rotorcraft attitude reference generation include. +/** @file firmwares/rotorcraft/stabilization/stabilization_attitude_ref_saturate.h + * Common rotorcraft attitude reference saturation include. */ -#ifndef STABILIZATION_ATTITUDE_REF_H -#define STABILIZATION_ATTITUDE_REF_H +#ifndef STABILIZATION_ATTITUDE_REF_SATURATE_H +#define STABILIZATION_ATTITUDE_REF_SATURATE_H #define SATURATE_SPEED_TRIM_ACCEL() { \ if (stab_att_ref_rate.p >= REF_RATE_MAX_P) { \ @@ -60,4 +60,4 @@ } -#endif /* STABILIZATION_ATTITUDE_REF_H */ +#endif /* STABILIZATION_ATTITUDE_REF_SATURATE_H */ diff --git a/sw/airborne/lisa/test_baro_i2c.c b/sw/airborne/lisa/test_baro_i2c.c index 250bf89c33..1bcff1dde1 100644 --- a/sw/airborne/lisa/test_baro_i2c.c +++ b/sw/airborne/lisa/test_baro_i2c.c @@ -36,8 +36,12 @@ #include "subsystems/datalink/downlink.h" #include "subsystems/sensors/baro.h" +#include "subsystems/air_data.h" //#include "my_debug_servo.h" +#define ABI_C +#include "subsystems/abi.h" + static inline void main_init( void ); static inline void main_periodic_task( void ); static inline void main_event_task( void ); @@ -107,7 +111,7 @@ static inline void main_periodic_task( void ) { static inline void main_event_task( void ) { - BaroEvent(main_on_baro_abs, main_on_baro_diff); + BaroEvent(); } @@ -117,5 +121,5 @@ static inline void main_on_baro_diff(void) { } static inline void main_on_baro_abs(void) { - RunOnceEvery(5,{DOWNLINK_SEND_BARO_RAW(DefaultChannel, DefaultDevice, &baro.absolute, &baro.differential);}); + RunOnceEvery(5,{DOWNLINK_SEND_BARO_RAW(DefaultChannel, DefaultDevice, &air_data.pressure, &air_data.differential);}); } diff --git a/sw/airborne/math/pprz_algebra_int.h b/sw/airborne/math/pprz_algebra_int.h index 50f7a1e88c..70d2ea22ae 100644 --- a/sw/airborne/math/pprz_algebra_int.h +++ b/sw/airborne/math/pprz_algebra_int.h @@ -218,6 +218,13 @@ struct Int64Vect3 { INT32_SQRT(n, n2); \ } +#define INT32_VECT2_NORMALIZE(_v,_frac) { \ + int32_t n; \ + INT32_VECT2_NORM(n, _v); \ + INT32_VECT2_SCALE_2(_v, _v, BFP_OF_REAL((1.),_frac) , n); \ + } + + #define INT32_VECT2_RSHIFT(_o, _i, _r) { \ (_o).x = ((_i).x >> (_r)); \ (_o).y = ((_i).y >> (_r)); \ diff --git a/sw/airborne/math/pprz_geodetic_int.c b/sw/airborne/math/pprz_geodetic_int.c index d66e3cfe2a..0562689d24 100644 --- a/sw/airborne/math/pprz_geodetic_int.c +++ b/sw/airborne/math/pprz_geodetic_int.c @@ -92,11 +92,40 @@ void enu_of_ecef_point_i(struct EnuCoor_i* enu, struct LtpDef_i* def, struct Ece void ned_of_ecef_point_i(struct NedCoor_i* ned, struct LtpDef_i* def, struct EcefCoor_i* ecef) { - struct EnuCoor_i enu; enu_of_ecef_point_i(&enu, def, ecef); ENU_OF_TO_NED(*ned, enu); +} + +/** Convert a ECEF position to local ENU. + * @param[out] enu ENU position in meter << #INT32_POS_FRAC + * @param[in] def local coordinate system definition + * @param[in] ecef ECEF position in cm + */ +void enu_of_ecef_pos_i(struct EnuCoor_i* enu, struct LtpDef_i* def, struct EcefCoor_i* ecef) { + struct EnuCoor_i enu_cm; + enu_of_ecef_point_i(&enu_cm, def, ecef); + + /* enu = (enu_cm / 100) << INT32_POS_FRAC + * to loose less range: + * enu_cm = enu << (INT32_POS_FRAC-2) / 25 + * which puts max enu output Q23.8 range to 8388km / 25 = 335km + */ + INT32_VECT3_LSHIFT(*enu, enu_cm, INT32_POS_FRAC-2); + VECT3_SDIV(*enu, *enu, 25); +} + + +/** Convert a ECEF position to local NED. + * @param[out] ned NED position in meter << #INT32_POS_FRAC + * @param[in] def local coordinate system definition + * @param[in] ecef ECEF position in cm + */ +void ned_of_ecef_pos_i(struct NedCoor_i* ned, struct LtpDef_i* def, struct EcefCoor_i* ecef) { + struct EnuCoor_i enu; + enu_of_ecef_pos_i(&enu, def, ecef); + ENU_OF_TO_NED(*ned, enu); } void enu_of_ecef_vect_i(struct EnuCoor_i* enu, struct LtpDef_i* def, struct EcefCoor_i* ecef) { @@ -149,11 +178,23 @@ void ecef_of_ned_vect_i(struct EcefCoor_i* ecef, struct LtpDef_i* def, struct Ne ecef_of_enu_vect_i(ecef, def, &enu); } + +/** Convert a point in local ENU to ECEF. + * @param[out] ecef ECEF point in cm + * @param[in] def local coordinate system definition + * @param[in] enu ENU point in cm + */ void ecef_of_enu_point_i(struct EcefCoor_i* ecef, struct LtpDef_i* def, struct EnuCoor_i* enu) { ecef_of_enu_vect_i(ecef, def, enu); INT32_VECT3_ADD(*ecef, def->ecef); } + +/** Convert a point in local NED to ECEF. + * @param[out] ecef ECEF point in cm + * @param[in] def local coordinate system definition + * @param[in] ned NED point in cm + */ void ecef_of_ned_point_i(struct EcefCoor_i* ecef, struct LtpDef_i* def, struct NedCoor_i* ned) { struct EnuCoor_i enu; ENU_OF_TO_NED(enu, *ned); @@ -161,6 +202,37 @@ void ecef_of_ned_point_i(struct EcefCoor_i* ecef, struct LtpDef_i* def, struct N } +/** Convert a local ENU position to ECEF. + * @param[out] ecef ECEF position in cm + * @param[in] def local coordinate system definition + * @param[in] enu ENU position in meter << #INT32_POS_FRAC + */ +void ecef_of_enu_pos_i(struct EcefCoor_i* ecef, struct LtpDef_i* def, struct EnuCoor_i* enu) { + /* enu_cm = (enu * 100) >> INT32_POS_FRAC + * to loose less range: + * enu_cm = (enu * 25) >> (INT32_POS_FRAC-2) + * which puts max enu input Q23.8 range to 8388km / 25 = 335km + */ + struct EnuCoor_i enu_cm; + VECT3_SMUL(enu_cm, *enu, 25); + INT32_VECT3_RSHIFT(enu_cm, enu_cm, INT32_POS_FRAC-2); + ecef_of_enu_vect_i(ecef, def, &enu_cm); + INT32_VECT3_ADD(*ecef, def->ecef); +} + + +/** Convert a local NED position to ECEF. + * @param[out] ecef ECEF position in cm + * @param[in] def local coordinate system definition + * @param[in] ned NED position in meter << #INT32_POS_FRAC + */ +void ecef_of_ned_pos_i(struct EcefCoor_i* ecef, struct LtpDef_i* def, struct NedCoor_i* ned) { + struct EnuCoor_i enu; + ENU_OF_TO_NED(enu, *ned); + ecef_of_enu_pos_i(ecef, def, &enu); +} + + void enu_of_lla_point_i(struct EnuCoor_i* enu, struct LtpDef_i* def, struct LlaCoor_i* lla) { struct EcefCoor_i ecef; ecef_of_lla_i(&ecef,lla); diff --git a/sw/airborne/math/pprz_geodetic_int.h b/sw/airborne/math/pprz_geodetic_int.h index f17ff2dc5a..cbeac4ac5f 100644 --- a/sw/airborne/math/pprz_geodetic_int.h +++ b/sw/airborne/math/pprz_geodetic_int.h @@ -104,6 +104,8 @@ extern void lla_of_ecef_i(struct LlaCoor_i* out, struct EcefCoor_i* in); extern void ecef_of_lla_i(struct EcefCoor_i* out, struct LlaCoor_i* in); extern void enu_of_ecef_point_i(struct EnuCoor_i* enu, struct LtpDef_i* def, struct EcefCoor_i* ecef); extern void ned_of_ecef_point_i(struct NedCoor_i* ned, struct LtpDef_i* def, struct EcefCoor_i* ecef); +extern void enu_of_ecef_pos_i(struct EnuCoor_i* enu, struct LtpDef_i* def, struct EcefCoor_i* ecef); +extern void ned_of_ecef_pos_i(struct NedCoor_i* ned, struct LtpDef_i* def, struct EcefCoor_i* ecef); extern void enu_of_ecef_vect_i(struct EnuCoor_i* enu, struct LtpDef_i* def, struct EcefCoor_i* ecef); extern void ned_of_ecef_vect_i(struct NedCoor_i* ned, struct LtpDef_i* def, struct EcefCoor_i* ecef); extern void enu_of_lla_point_i(struct EnuCoor_i* enu, struct LtpDef_i* def, struct LlaCoor_i* lla); @@ -112,6 +114,8 @@ extern void enu_of_lla_vect_i(struct EnuCoor_i* enu, struct LtpDef_i* def, struc extern void ned_of_lla_vect_i(struct NedCoor_i* ned, struct LtpDef_i* def, struct LlaCoor_i* lla); extern void ecef_of_enu_point_i(struct EcefCoor_i* ecef, struct LtpDef_i* def, struct EnuCoor_i* enu); extern void ecef_of_ned_point_i(struct EcefCoor_i* ecef, struct LtpDef_i* def, struct NedCoor_i* ned); +extern void ecef_of_enu_pos_i(struct EcefCoor_i* ecef, struct LtpDef_i* def, struct EnuCoor_i* enu); +extern void ecef_of_ned_pos_i(struct EcefCoor_i* ecef, struct LtpDef_i* def, struct NedCoor_i* ned); extern void ecef_of_enu_vect_i(struct EcefCoor_i* ecef, struct LtpDef_i* def, struct EnuCoor_i* enu); extern void ecef_of_ned_vect_i(struct EcefCoor_i* ecef, struct LtpDef_i* def, struct NedCoor_i* ned); diff --git a/sw/airborne/math/pprz_isa.h b/sw/airborne/math/pprz_isa.h new file mode 100644 index 0000000000..28c397975b --- /dev/null +++ b/sw/airborne/math/pprz_isa.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2013 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. + * + */ + +/** + * @file math/pprz_isa.h + * @brief Paparazzi atmospheric pressure convertion utilities + * + * Conversion functions are use to approximate altitude + * from atmospheric pressure based on the standard model + * and the International Standard Atmosphere (ISA) + * + * http://en.wikipedia.org/wiki/Atmospheric_pressure + * http://en.wikipedia.org/wiki/International_Standard_Atmosphere + * + */ + +#ifndef PPRZ_ISA_H +#define PPRZ_ISA_H + +#include "std.h" +#include + +// Standard Atmosphere constants +#define PPRZ_ISA_SEA_LEVEL_PRESSURE 101325.0 +#define PPRZ_ISA_SEA_LEVEL_TEMP 288.15 +#define PPRZ_ISA_TEMP_LAPS_RATE 0.0065 +#define PPRZ_ISA_GRAVITY 9.80665 +#define PPRZ_ISA_AIR_GAS_CONSTANT (8.31447/0.0289644) + +static const float PPRZ_ISA_M_OF_P_CONST = (PPRZ_ISA_AIR_GAS_CONSTANT*PPRZ_ISA_SEA_LEVEL_TEMP/PPRZ_ISA_GRAVITY); + +/** + * Get absolute altitude from pressure (using simplified equation). + * Referrence pressure is standard pressure at sea level + * + * @param pressure current pressure in Pascal (Pa) + * @return altitude in pressure in ISA conditions + */ +static inline float pprz_isa_altitude_of_pressure(float pressure) { + if (pressure > 0.) { + return (PPRZ_ISA_M_OF_P_CONST*logf(PPRZ_ISA_SEA_LEVEL_PRESSURE/pressure)); + } else { + return 0.; + } +} + +/** + * Get relative altitude from pressure (using simplified equation). + * + * @param pressure current pressure in Pascal (Pa) + * @param ref reference pressure (QFE) when height = 0 + * @return altitude in pressure in ISA conditions + */ +static inline float pprz_isa_height_of_pressure(float pressure, float ref) { + if (pressure > 0. && ref > 0.) { + return (PPRZ_ISA_M_OF_P_CONST*logf(ref/pressure)); + } else { + return 0.; + } +} + +/** + * Get pressure in Pa from absolute altitude (using simplified equation). + * + * @param altitude current absolute altitude in meters + * @return static pressure in Pa in ISA conditions + */ +static inline float pprz_isa_pressure_of_altitude(float altitude) { + return (PPRZ_ISA_SEA_LEVEL_PRESSURE*expf((-1./PPRZ_ISA_M_OF_P_CONST)*altitude)); +} + +/** + * Get pressure in Pa from height (using simplified equation). + * + * @param altitude current relative altitude in meters + * @param ref reference pressure (QFE) when height = 0 + * @return static pressure in Pa in ISA conditions + */ +static inline float pprz_isa_pressure_of_height(float altitude, float ref) { + return (ref*expf((-1./PPRZ_ISA_M_OF_P_CONST)*altitude)); +} + +#endif /* PPRZ_ISA_H */ diff --git a/sw/airborne/modules/cam_control/cam_track.c b/sw/airborne/modules/cam_control/cam_track.c index a73ca98e40..d570b58d33 100644 --- a/sw/airborne/modules/cam_control/cam_track.c +++ b/sw/airborne/modules/cam_control/cam_track.c @@ -64,7 +64,7 @@ static void send_cam_track(void) { } void track_init(void) { - ins_ltp_initialised = TRUE; // ltp is initialized and centered on the target + ins_impl.ltp_initialized = TRUE; // ltp is initialized and centered on the target ins_update_on_agl = TRUE; // use sonar to update agl (assume flat ground) cam_status = UNINIT; @@ -129,8 +129,8 @@ void track_periodic_task(void) { } void track_event(void) { - if (!ins_ltp_initialised) { - ins_ltp_initialised = TRUE; + if (!ins_impl.ltp_initialized) { + ins_impl.ltp_initialized = TRUE; ins.hf_realign = TRUE; } @@ -144,24 +144,24 @@ void track_event(void) { } const stuct FlotVect2 measuremet_noise = { 10.0, 10.0 }; b2_hff_update_pos(-target_pos_ned, measurement_noise); - ins_ltp_accel.x = ACCEL_BFP_OF_REAL(b2_hff_state.xdotdot); - ins_ltp_accel.y = ACCEL_BFP_OF_REAL(b2_hff_state.ydotdot); - ins_ltp_speed.x = SPEED_BFP_OF_REAL(b2_hff_state.xdot); - ins_ltp_speed.y = SPEED_BFP_OF_REAL(b2_hff_state.ydot); - ins_ltp_pos.x = POS_BFP_OF_REAL(b2_hff_state.x); - ins_ltp_pos.y = POS_BFP_OF_REAL(b2_hff_state.y); + ins_impl.ltp_accel.x = ACCEL_BFP_OF_REAL(b2_hff_state.xdotdot); + ins_impl.ltp_accel.y = ACCEL_BFP_OF_REAL(b2_hff_state.ydotdot); + ins_impl.ltp_speed.x = SPEED_BFP_OF_REAL(b2_hff_state.xdot); + ins_impl.ltp_speed.y = SPEED_BFP_OF_REAL(b2_hff_state.ydot); + ins_impl.ltp_pos.x = POS_BFP_OF_REAL(b2_hff_state.x); + ins_impl.ltp_pos.y = POS_BFP_OF_REAL(b2_hff_state.y); INS_NED_TO_STATE(); #else // store pos in ins - ins_ltp_pos.x = -(POS_BFP_OF_REAL(target_pos_ned.x)); - ins_ltp_pos.y = -(POS_BFP_OF_REAL(target_pos_ned.y)); + ins_impl.ltp_pos.x = -(POS_BFP_OF_REAL(target_pos_ned.x)); + ins_impl.ltp_pos.y = -(POS_BFP_OF_REAL(target_pos_ned.y)); // compute speed from last pos // TODO get delta T // store last pos VECT3_COPY(last_pos_ned, target_pos_ned); - stateSetPositionNed_i(&ins_ltp_pos); + stateSetPositionNed_i(&ins_impl.ltp_pos); #endif b2_hff_lost_counter = 0; diff --git a/sw/airborne/modules/mission/mission.c b/sw/airborne/modules/mission/mission.c new file mode 100644 index 0000000000..d3794bbca9 --- /dev/null +++ b/sw/airborne/modules/mission/mission.c @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2013 ENAC + * + * 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. + * + */ + +/** @file modules/mission/mission.c + * @brief messages parser for mission interface + */ + +#include "modules/mission/mission.h" + +#include +#include "generated/airframe.h" +#include "subsystems/datalink/datalink.h" +#include "subsystems/datalink/downlink.h" + + +struct _mission mission; + + +void mission_init(void) { + mission.insert_idx = 0; + mission.current_idx = 0; + mission.element_time = 0.; +} + +bool_t mission_insert(enum MissionInsertMode insert, struct _mission_element * element) { + uint8_t tmp; + + switch (insert) { + case Append: + tmp = (mission.insert_idx + 1) % MISSION_ELEMENT_NB; + if (tmp == mission.current_idx) return FALSE; // no room to insert element + memcpy(&mission.elements[mission.insert_idx], element, sizeof(struct _mission_element)); // add element + mission.insert_idx = tmp; // move insert index + break; + case Prepend: + if (mission.current_idx == 0) tmp = MISSION_ELEMENT_NB-1; + else tmp = mission.current_idx - 1; + if (tmp == mission.insert_idx) return FALSE; // no room to inser element + memcpy(&mission.elements[tmp], element, sizeof(struct _mission_element)); // add element + mission.current_idx = tmp; // move current index + break; + case ReplaceCurrent: + // current element can always be modified, index are not changed + memcpy(&mission.elements[mission.current_idx], element, sizeof(struct _mission_element)); + break; + case ReplaceAll: + // reset queue and index + memcpy(&mission.elements[0], element, sizeof(struct _mission_element)); + mission.insert_idx = 0; + mission.current_idx = 0; + break; + default: + // unknown insertion mode + return FALSE; + } + return TRUE; + +} + +struct _mission_element * mission_get(void) { + if (mission.current_idx == mission.insert_idx) { + return NULL; + } + return &(mission.elements[mission.current_idx]); +} + + + +/////////////////////// +// Parsing functions // +/////////////////////// + +int mission_parse_GOTO_WP(void) { + if (DL_MISSION_GOTO_WP_ac_id(dl_buffer) != AC_ID) return FALSE; // not for this aircraft + + struct _mission_element me; + me.type = MissionWP; + me.element.mission_wp.wp.x = DL_MISSION_GOTO_WP_wp_east(dl_buffer); + me.element.mission_wp.wp.y = DL_MISSION_GOTO_WP_wp_north(dl_buffer); + me.element.mission_wp.wp.z = DL_MISSION_GOTO_WP_wp_alt(dl_buffer); + me.duration = DL_MISSION_GOTO_WP_duration(dl_buffer); + + enum MissionInsertMode insert = (enum MissionInsertMode) (DL_MISSION_GOTO_WP_insert(dl_buffer)); + + return mission_insert(insert, &me); +} + +int mission_parse_GOTO_WP_LLA(void) { + if (DL_MISSION_GOTO_WP_LLA_ac_id(dl_buffer) != AC_ID) return FALSE; // not for this aircraft + + struct _mission_element me; + me.type = MissionWP; + + enum MissionInsertMode insert = (enum MissionInsertMode) (DL_MISSION_GOTO_WP_LLA_insert(dl_buffer)); + + return mission_insert(insert, &me); +} + +int mission_parse_CIRCLE(void) { + if (DL_MISSION_CIRCLE_ac_id(dl_buffer) != AC_ID) return FALSE; // not for this aircraft + + struct _mission_element me; + me.type = MissionCircle; + me.element.mission_circle.center.x = DL_MISSION_CIRCLE_center_east(dl_buffer); + me.element.mission_circle.center.y = DL_MISSION_CIRCLE_center_north(dl_buffer); + me.element.mission_circle.center.z = DL_MISSION_CIRCLE_center_alt(dl_buffer); + me.element.mission_circle.radius = DL_MISSION_CIRCLE_radius(dl_buffer); + me.duration = DL_MISSION_CIRCLE_duration(dl_buffer); + + enum MissionInsertMode insert = (enum MissionInsertMode) (DL_MISSION_CIRCLE_insert(dl_buffer)); + + return mission_insert(insert, &me); +} + +int mission_parse_CIRCLE_LLA(void) { + if (DL_MISSION_CIRCLE_LLA_ac_id(dl_buffer) != AC_ID) return FALSE; // not for this aircraft + + struct _mission_element me; + me.type = MissionCircle; + me.element.mission_circle.radius = DL_MISSION_CIRCLE_LLA_radius(dl_buffer); + me.duration = DL_MISSION_CIRCLE_LLA_duration(dl_buffer); + + enum MissionInsertMode insert = (enum MissionInsertMode) (DL_MISSION_CIRCLE_LLA_insert(dl_buffer)); + + return mission_insert(insert, &me); +} + +int mission_parse_SEGMENT(void) { + if (DL_MISSION_SEGMENT_ac_id(dl_buffer) != AC_ID) return FALSE; // not for this aircraft + + struct _mission_element me; + me.type = MissionSegment; + me.element.mission_segment.from.x = DL_MISSION_SEGMENT_segment_east_1(dl_buffer); + me.element.mission_segment.from.y = DL_MISSION_SEGMENT_segment_north_1(dl_buffer); + me.element.mission_segment.from.z = DL_MISSION_SEGMENT_segment_alt(dl_buffer); + me.element.mission_segment.to.x = DL_MISSION_SEGMENT_segment_east_2(dl_buffer); + me.element.mission_segment.to.y = DL_MISSION_SEGMENT_segment_north_2(dl_buffer); + me.element.mission_segment.to.z = DL_MISSION_SEGMENT_segment_alt(dl_buffer); + me.duration = DL_MISSION_SEGMENT_duration(dl_buffer); + + enum MissionInsertMode insert = (enum MissionInsertMode) (DL_MISSION_SEGMENT_insert(dl_buffer)); + + return mission_insert(insert, &me); +} + +int mission_parse_SEGMENT_LLA(void) { + if (DL_MISSION_SEGMENT_LLA_ac_id(dl_buffer) != AC_ID) return FALSE; // not for this aircraft + + struct _mission_element me; + me.type = MissionSegment; + me.duration = DL_MISSION_SEGMENT_LLA_duration(dl_buffer); + + enum MissionInsertMode insert = (enum MissionInsertMode) (DL_MISSION_SEGMENT_LLA_insert(dl_buffer)); + + return mission_insert(insert, &me); +} + +int mission_parse_PATH(void) { + if (DL_MISSION_PATH_ac_id(dl_buffer) != AC_ID) return FALSE; // not for this aircraft + + struct _mission_element me; + me.type = MissionPath; + me.element.mission_path.path[0].x = DL_MISSION_PATH_point_east_1(dl_buffer); + me.element.mission_path.path[0].y = DL_MISSION_PATH_point_north_1(dl_buffer); + me.element.mission_path.path[0].z = DL_MISSION_PATH_path_alt(dl_buffer); + me.element.mission_path.path[1].x = DL_MISSION_PATH_point_east_2(dl_buffer); + me.element.mission_path.path[1].y = DL_MISSION_PATH_point_north_2(dl_buffer); + me.element.mission_path.path[1].z = DL_MISSION_PATH_path_alt(dl_buffer); + me.element.mission_path.path[2].x = DL_MISSION_PATH_point_east_3(dl_buffer); + me.element.mission_path.path[2].y = DL_MISSION_PATH_point_north_3(dl_buffer); + me.element.mission_path.path[2].z = DL_MISSION_PATH_path_alt(dl_buffer); + me.element.mission_path.path[3].x = DL_MISSION_PATH_point_east_4(dl_buffer); + me.element.mission_path.path[3].y = DL_MISSION_PATH_point_north_4(dl_buffer); + me.element.mission_path.path[3].z = DL_MISSION_PATH_path_alt(dl_buffer); + me.element.mission_path.path[4].x = DL_MISSION_PATH_point_east_5(dl_buffer); + me.element.mission_path.path[4].y = DL_MISSION_PATH_point_north_5(dl_buffer); + me.element.mission_path.path[4].z = DL_MISSION_PATH_path_alt(dl_buffer); + me.element.mission_path.nb = DL_MISSION_PATH_nb(dl_buffer); + if (me.element.mission_path.nb > MISSION_PATH_NB) me.element.mission_path.nb = MISSION_PATH_NB; + me.element.mission_path.path_idx = 0; + me.duration = DL_MISSION_PATH_duration(dl_buffer); + + enum MissionInsertMode insert = (enum MissionInsertMode) (DL_MISSION_PATH_insert(dl_buffer)); + + return mission_insert(insert, &me); +} + +int mission_parse_PATH_LLA(void) { + if (DL_MISSION_PATH_LLA_ac_id(dl_buffer) != AC_ID) return FALSE; // not for this aircraft + + struct _mission_element me; + me.type = MissionPath; + me.element.mission_path.nb = DL_MISSION_PATH_LLA_nb(dl_buffer); + if (me.element.mission_path.nb > MISSION_PATH_NB) me.element.mission_path.nb = MISSION_PATH_NB; + me.element.mission_path.path_idx = 0; + me.duration = DL_MISSION_PATH_LLA_duration(dl_buffer); + + enum MissionInsertMode insert = (enum MissionInsertMode) (DL_MISSION_PATH_LLA_insert(dl_buffer)); + + return mission_insert(insert, &me); +} + +int mission_parse_GOTO_MISSION(void) { + if (DL_GOTO_MISSION_ac_id(dl_buffer) != AC_ID) return FALSE; // not for this aircraft + + uint8_t mission_id = DL_GOTO_MISSION_mission_id(dl_buffer); + if (mission_id < MISSION_ELEMENT_NB) { + mission.current_idx = mission_id; + } + else return FALSE; + + return TRUE; +} + +int mission_parse_NEXT_MISSION(void) { + if (DL_NEXT_MISSION_ac_id(dl_buffer) != AC_ID) return FALSE; // not for this aircraft + + if (mission.current_idx == mission.insert_idx) return FALSE; // already at the last position + + // increment current index + mission.current_idx = (mission.current_idx + 1) % MISSION_ELEMENT_NB; + return TRUE; +} + +int mission_parse_END_MISSION(void) { + if (DL_END_MISSION_ac_id(dl_buffer) != AC_ID) return FALSE; // not for this aircraft + + // set current index to insert index (last position) + mission.current_idx = mission.insert_idx; + return TRUE; +} + diff --git a/sw/airborne/modules/mission/mission.h b/sw/airborne/modules/mission/mission.h new file mode 100644 index 0000000000..d423c48c12 --- /dev/null +++ b/sw/airborne/modules/mission/mission.h @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2013 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. + * + */ + +/** @file modules/mission/mission.h + * @brief mission planner library + * + * Provide the generic interface for the mission control + * Handle the parsing of datalink messages + */ + +#ifndef MISSION_H +#define MISSION_H + +#include "std.h" +#include "math/pprz_geodetic_float.h" + +enum MissionType { + MissionWP, + MissionCircle, + MissionSegment, + MissionPath, + MissionSurvey, + MissionEight, + MissionOval +}; + +enum MissionInsertMode { + Append, ///< add at the last position + Prepend, ///< add before the current element + ReplaceCurrent, ///< replace current element + ReplaceAll ///< remove all elements and add the new one +}; + +struct _mission_wp { + struct EnuCoor_f wp; +}; + +struct _mission_circle { + struct EnuCoor_f center; + float radius; +}; + +struct _mission_segment { + struct EnuCoor_f from; + struct EnuCoor_f to; +}; + +#define MISSION_PATH_NB 5 +struct _mission_path { + struct EnuCoor_f path[MISSION_PATH_NB]; + uint8_t path_idx; + uint8_t nb; +}; + +struct _mission_element { + enum MissionType type; + union { + struct _mission_wp mission_wp; + struct _mission_circle mission_circle; + struct _mission_segment mission_segment; + struct _mission_path mission_path; + } element; + float duration; ///< time to spend in the element (<= 0 to disable) +}; + +#define MISSION_ELEMENT_NB 20 +struct _mission { + struct _mission_element elements[MISSION_ELEMENT_NB]; + float element_time; ///< time in second spend in the current element + uint8_t insert_idx; ///< inserstion index + uint8_t current_idx; ///< current mission element index +}; + +extern struct _mission mission; + +/** Init mission structure + */ +extern void mission_init(void); + +/** Insert a mission element according to the insertion mode + * @param insert insertion mode + * @param element mission element structure + * @return return TRUE if insertion is succesful, FALSE otherwise + */ +extern bool_t mission_insert(enum MissionInsertMode insert, struct _mission_element * element); + +/** Get current mission element + * @return return a pointer to the next mission element or NULL if no more elements + */ +extern struct _mission_element * mission_get(void); + +/** Run mission + * + * This function should be implemented into a dedicated file since + * navigation functions are different for different firmwares + * + * Currently, this function should be called from the flight plan + * + * @return return TRUE when the mission is running, FALSE when it is finished + */ +extern int mission_run(); + +/** Parsing functions called when a mission message is received + */ +extern int mission_parse_GOTO_WP(void); +extern int mission_parse_GOTO_WP_LLA(void); +extern int mission_parse_CIRCLE(void); +extern int mission_parse_CIRCLE_LLA(void); +extern int mission_parse_SEGMENT(void); +extern int mission_parse_SEGMENT_LLA(void); +extern int mission_parse_PATH(void); +extern int mission_parse_PATH_LLA(void); +extern int mission_parse_SURVEY(void); +extern int mission_parse_SURVEY_LLA(void); +extern int mission_parse_GOTO_MISSION(void); +extern int mission_parse_NEXT_MISSION(void); +extern int mission_parse_END_MISSION(void); + +/** Status report messages + * @todo + */ + +#endif // MISSION diff --git a/sw/airborne/modules/mission/mission_fw_nav.c b/sw/airborne/modules/mission/mission_fw_nav.c new file mode 100644 index 0000000000..f0b24e8094 --- /dev/null +++ b/sw/airborne/modules/mission/mission_fw_nav.c @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2013 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. + * + */ + +/** @file modules/mission/mission_fw_nav.c + * @brief mission navigation for fixedwing aircraft + * + * Implement specific navigation routines for the mission control + * of a fixedwing aircraft + */ + +#include +#include "modules/mission/mission.h" +#include "firmwares/fixedwing/autopilot.h" +#include "subsystems/nav.h" + +// navigation time step +const float dt_navigation = 1.0 / ((float)NAVIGATION_FREQUENCY); + +// dirty hack to comply with nav_approaching_xy function +struct EnuCoor_f last_wp = { 0., 0., 0. }; + +/** Navigation function to a single waypoint + */ +static inline bool_t mission_nav_wp(struct _mission_wp * wp) { + if (nav_approaching_xy(wp->wp.x, wp->wp.y, last_wp.x, last_wp.y, CARROT)) { + last_wp = wp->wp; // store last wp + return FALSE; // end of mission element + } + // set navigation command + fly_to_xy(wp->wp.x, wp->wp.y); + NavVerticalAutoThrottleMode(0.); + NavVerticalAltitudeMode(wp->wp.z, 0.); + return TRUE; +} + +/** Navigation function on a circle + */ +static inline bool_t mission_nav_circle(struct _mission_circle * circle) { + nav_circle_XY(circle->center.x, circle->center.y, circle->radius); + NavVerticalAutoThrottleMode(0.); + NavVerticalAltitudeMode(circle->center.z, 0.); + return TRUE; +} + +/** Navigation function along a segment + */ +static inline bool_t mission_nav_segment(struct _mission_segment * segment) { + if (nav_approaching_xy(segment->to.x, segment->to.y, segment->from.x, segment->from.y, CARROT)) { + last_wp = segment->to; + return FALSE; // end of mission element + } + nav_route_xy(segment->from.x, segment->from.y, segment->to.x, segment->to.y); + NavVerticalAutoThrottleMode(0.); + NavVerticalAltitudeMode(segment->to.z, 0.); // both altitude should be the same anyway + return TRUE; +} + +/** Navigation function along a path + */ +static inline bool_t mission_nav_path(struct _mission_path * path) { + if (path->nb == 0) { + return FALSE; // nothing to do + } + if (path->nb == 1) { + // handle as a single waypoint + struct _mission_wp wp = { path->path[0] }; + return mission_nav_wp(&wp); + } + if (path->path_idx == path->nb-1) { + last_wp = path->path[path->path_idx]; // store last wp + return FALSE; // end of path + } + // normal case + struct EnuCoor_f from = path->path[path->path_idx]; + struct EnuCoor_f to = path->path[path->path_idx+1]; + nav_route_xy(from.x, from.y, to.x, to.y); + NavVerticalAutoThrottleMode(0.); + NavVerticalAltitudeMode(to.z, 0.); // both altitude should be the same anyway + if (nav_approaching_xy(to.x, to.y, from.x, from.y, CARROT)) { + path->path_idx++; // go to next segment + } + return TRUE; +} + + +int mission_run() { + // current element + struct _mission_element * el = NULL; + if ((el = mission_get()) == NULL) { + // TODO do something special like a waiting circle before ending the mission ? + return FALSE; // end of mission + } + + bool_t el_running = FALSE; + switch (el->type){ + case MissionWP: + el_running = mission_nav_wp(&(el->element.mission_wp)); + break; + case MissionCircle: + el_running = mission_nav_circle(&(el->element.mission_circle)); + break; + case MissionSegment: + el_running = mission_nav_segment(&(el->element.mission_segment)); + break; + case MissionPath: + el_running = mission_nav_path(&(el->element.mission_path)); + break; + default: + // invalid type or pattern not yet handled + break; + } + + // increment element_time + mission.element_time += dt_navigation; + + // test if element is finished or element time is elapsed + if (!el_running || (el->duration > 0. && mission.element_time >= el->duration)) { + // reset timer + mission.element_time = 0.; + // go to next element + mission.current_idx++; + } + + return TRUE; +} + + diff --git a/sw/airborne/modules/sensors/baro_MS5534A.c b/sw/airborne/modules/sensors/baro_MS5534A.c index 3035013de0..9e5096b4cd 100644 --- a/sw/airborne/modules/sensors/baro_MS5534A.c +++ b/sw/airborne/modules/sensors/baro_MS5534A.c @@ -33,9 +33,11 @@ #ifndef BARO_NO_DOWNLINK #include "subsystems/datalink/downlink.h" #endif +#include "subsystems/abi.h" #include "subsystems/nav.h" #include "state.h" + bool_t baro_MS5534A_do_reset; uint32_t baro_MS5534A_pressure; uint16_t baro_MS5534A_temp; @@ -257,14 +259,13 @@ void baro_MS5534A_event( void ) { spi_message_received = FALSE; baro_MS5534A_event_task(); if (baro_MS5534A_available) { - // baro_MS5534A_available = FALSE; // Checked by INS + baro_MS5534A_available = FALSE; baro_MS5534A_z = ground_alt +((float)baro_MS5534A_ground_pressure - baro_MS5534A_pressure)*0.084; #if SENSO_SYNC_SEND DOWNLINK_SEND_BARO_MS5534A(DefaultChannel, DefaultDevice, &baro_MS5534A_pressure, &baro_MS5534A_temp, &baro_MS5534A_z); #endif - // if (alt_baro_enabled) { - // EstimatorSetAlt(baro_MS5534A_z); // Updated by INS - // } + float pressure = (float)baro_MS5534A_pressure; + AbiSendMsgBARO_ABS(BARO_MS5534A_SENDER_ID, &pressure); } } } diff --git a/sw/airborne/modules/sensors/baro_MS5534A.h b/sw/airborne/modules/sensors/baro_MS5534A.h index 7e98fa1c34..0b7b0f6373 100644 --- a/sw/airborne/modules/sensors/baro_MS5534A.h +++ b/sw/airborne/modules/sensors/baro_MS5534A.h @@ -54,8 +54,6 @@ void baro_MS5534A_event_task( void ); void baro_MS5534A_event( void ); -#define BaroMS5534AUpdate(_b, _h) { if (baro_MS5534A_available) { _b = baro_MS5534A_pressure; _h(); baro_MS5534A_available = FALSE; } } - #endif // USE_BARO_MS5534A #endif // BARO_MS5534A_H diff --git a/sw/airborne/modules/sensors/baro_amsys.c b/sw/airborne/modules/sensors/baro_amsys.c index 60ed9919da..e45e89b246 100644 --- a/sw/airborne/modules/sensors/baro_amsys.c +++ b/sw/airborne/modules/sensors/baro_amsys.c @@ -25,25 +25,17 @@ #include "sensors/baro_amsys.h" #include "mcu_periph/i2c.h" +#include "subsystems/abi.h" #include "state.h" #include #include "generated/flight_plan.h" // for ground alt -#ifdef SITL -#include "subsystems/gps.h" -#include "subsystems/navigation/common_nav.h" -#endif - //Messages #include "mcu_periph/uart.h" #include "messages.h" #include "subsystems/datalink/downlink.h" //#include "gps.h" -#ifdef SITL -#include "subsystems/gps.h" -#endif - #define BARO_AMSYS_ADDR 0xE4 #define BARO_AMSYS_REG 0x07 #ifndef BARO_AMSYS_SCALE @@ -74,6 +66,7 @@ #define BARO_AMSYS_I2C_DEV i2c0 #endif + // Global variables uint16_t pBaroRaw; uint16_t tBaroRaw; @@ -123,7 +116,6 @@ void baro_amsys_init( void ) { void baro_amsys_read_periodic( void ) { // Initiate next read -#ifndef SITL if (baro_amsys_i2c_trans.status == I2CTransDone){ #ifndef MEASURE_AMSYS_TEMPERATURE i2c_receive(&BARO_AMSYS_I2C_DEV, &baro_amsys_i2c_trans, BARO_AMSYS_ADDR, 2); @@ -131,17 +123,6 @@ void baro_amsys_read_periodic( void ) { i2c_receive(&BARO_AMSYS_I2C_DEV, &baro_amsys_i2c_trans, BARO_AMSYS_ADDR, 4); #endif } -#else // SITL - /* fake an offset so sim works for under hmsl as well */ - if (!baro_amsys_offset_init) { - baro_amsys_offset = BARO_AMSYS_OFFSET_MAX; - baro_amsys_offset_init = TRUE; - } - pBaroRaw = 0; - baro_amsys_altitude = gps.hmsl / 1000.0; - baro_amsys_adc = baro_amsys_offset - ((baro_amsys_altitude - ground_alt) / INS_BARO_SENS); - baro_amsys_valid = TRUE; -#endif #ifdef BARO_AMSYS_SYNC_SEND DOWNLINK_SEND_AMSYS_BARO(DefaultChannel, DefaultDevice, &pBaroRaw, &baro_amsys_p, &baro_amsys_offset, &ref_alt_init, &baro_amsys_abs_altitude, &baro_amsys_altitude, &baro_amsys_temp); @@ -177,6 +158,9 @@ void baro_amsys_read_event( void ) { //Convert to pressure baro_amsys_p = (float)(pBaroRaw-BARO_AMSYS_OFFSET_MIN)*BARO_AMSYS_MAX_PRESSURE/(float)(BARO_AMSYS_OFFSET_MAX-BARO_AMSYS_OFFSET_MIN); + // Send pressure over ABI + AbiSendMsgBARO_ABS(BARO_AMSYS_SENDER_ID, &baro_amsys_p); + // compute altitude localy if (!baro_amsys_offset_init) { --baro_amsys_cnt; // Check if averaging completed diff --git a/sw/airborne/modules/sensors/baro_amsys.h b/sw/airborne/modules/sensors/baro_amsys.h index a6852dab58..5fda78c154 100644 --- a/sw/airborne/modules/sensors/baro_amsys.h +++ b/sw/airborne/modules/sensors/baro_amsys.h @@ -48,6 +48,4 @@ extern void baro_amsys_read_event( void ); #define BaroAmsysEvent() { if (baro_amsys_i2c_trans.status == I2CTransSuccess) baro_amsys_read_event(); } -#define BaroAmsysUpdate(_b, _h) { if (baro_amsys_valid) { _b = baro_amsys_adc; _h(); baro_amsys_valid = FALSE; } } - #endif // BARO_AMSYS_H diff --git a/sw/airborne/modules/sensors/baro_bmp.c b/sw/airborne/modules/sensors/baro_bmp.c index 622e8aede9..fb11910505 100644 --- a/sw/airborne/modules/sensors/baro_bmp.c +++ b/sw/airborne/modules/sensors/baro_bmp.c @@ -36,6 +36,7 @@ #include "mcu_periph/i2c.h" #include "led.h" #include "mcu_periph/uart.h" +#include "subsystems/abi.h" #include "messages.h" #include "subsystems/datalink/downlink.h" @@ -48,7 +49,6 @@ #define BMP_I2C_DEV i2c0 #endif - #define BARO_BMP_R 0.5 #define BARO_BMP_SIGMA2 0.1 @@ -89,6 +89,9 @@ void baro_bmp_event(void) { tmp = pow(tmp, 0.190295); baro_bmp_alt = 44330 * (1.0 - tmp); + float pressure = (float)baro_bmp.pressure; + AbiSendMsgBARO_ABS(BARO_BMP_SENDER_ID, &pressure); + #ifdef SENSOR_SYNC_SEND DOWNLINK_SEND_BMP_STATUS(DefaultChannel, DefaultDevice, &baro_bmp.up, &baro_bmp.ut, &baro_bmp.pressure, diff --git a/sw/airborne/modules/sensors/baro_bmp.h b/sw/airborne/modules/sensors/baro_bmp.h index db1039e817..aa56e10266 100644 --- a/sw/airborne/modules/sensors/baro_bmp.h +++ b/sw/airborne/modules/sensors/baro_bmp.h @@ -36,11 +36,7 @@ extern struct Bmp085 baro_bmp; /// new measurement every 3rd baro_bmp_periodic -#ifndef SITL #define BARO_BMP_DT (BARO_BMP_PERIODIC_PERIOD / 3) -#else -#define BARO_BMP_DT BARO_BMP_PERIODIC_PERIOID -#endif extern bool_t baro_bmp_enabled; extern float baro_bmp_r; @@ -51,6 +47,4 @@ void baro_bmp_init(void); void baro_bmp_periodic(void); void baro_bmp_event(void); -#define BaroBmpUpdate(_b, _h) { if (baro_bmp.data_available) { _b = baro_bmp.pressure; _h(); baro_bmp.data_available = FALSE; } } - #endif diff --git a/sw/airborne/modules/sensors/baro_board_module.c b/sw/airborne/modules/sensors/baro_board_module.c deleted file mode 100644 index f5271f0df9..0000000000 --- a/sw/airborne/modules/sensors/baro_board_module.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2012 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. - * - */ - -/* - * Wrapper for the board specific barometer - * Allows to use external baro sensor to feed the general baro interface - */ - -#include "modules/sensors/baro_board_module.h" - -/* Common Baro struct */ -struct Baro baro; - -/* Counter to init custom baro at startup */ -#define BARO_STARTUP_COUNTER 200 -uint16_t startup_cnt; - -/** Implementation of the generic baro interface initialization. - * No need to call this functions from the modules, already done by main. - */ -void baro_init( void ) { - baro.status = BS_UNINITIALIZED; - baro.absolute = 0; - baro.differential = 0; - startup_cnt = BARO_STARTUP_COUNTER; -} - -/** Implementation of the generic baro interface periodic task. - * No need to call this functions from the modules, already done by main. - */ -void baro_periodic( void ) { - if (baro.status == BS_UNINITIALIZED) { - // Run some loops to get correct readings from the adc - --startup_cnt; - if (startup_cnt == 0) { - baro.status = BS_RUNNING; - } - } -} - diff --git a/sw/airborne/modules/sensors/baro_board_module.h b/sw/airborne/modules/sensors/baro_board_module.h deleted file mode 100644 index bc5f48d23b..0000000000 --- a/sw/airborne/modules/sensors/baro_board_module.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -/** - * @file modules/sensors/baro_board_module.h - * - * Wrapper for the board specific barometer. - */ - -#ifndef BARO_BOARD_MODULE_H -#define BARO_BOARD_MODULE_H - -#include "subsystems/sensors/baro.h" - -/** Absolute baro macro mapping. - * Select the baro module you want to use to feed the common baro interface - * in your airframe file when configuring baro_board module - * ex: - * for module baro_ets - * @verbatim - * - * @endverbatim - */ -#ifndef BARO_ABS_EVENT -#define BARO_ABS_EVENT NoBaro -#endif - -/** Differential baro macro mapping. - * TODO - */ -#ifndef BARO_DIFF_EVENT -#define BARO_DIFF_EVENT NoBaro -#endif - -#define NoBaro(_b, _h) {} - -/** BaroEvent macro. - * Need to be maped to one the external baro running has a module - * - * Undef if necessary (already defined in a baro_board.h file) - */ -#ifdef BaroEvent -#undef BaroEvent -#endif - -#define BaroEvent(_b_abs_handler, _b_diff_handler) { \ - BARO_ABS_EVENT(baro.absolute, _b_abs_handler); \ - BARO_DIFF_EVENT(baro.differential, _b_diff_handler); \ -} - - -#endif diff --git a/sw/airborne/modules/sensors/baro_ets.c b/sw/airborne/modules/sensors/baro_ets.c index c4301495e5..46e3d787b4 100644 --- a/sw/airborne/modules/sensors/baro_ets.c +++ b/sw/airborne/modules/sensors/baro_ets.c @@ -42,15 +42,12 @@ #include "sensors/baro_ets.h" #include "mcu_periph/i2c.h" #include "state.h" +#include "subsystems/abi.h" #include #include "mcu_periph/sys_time.h" #include "subsystems/nav.h" -#ifdef SITL -#include "subsystems/gps.h" -#endif - #ifdef BARO_ETS_SYNC_SEND #include "mcu_periph/uart.h" @@ -60,9 +57,6 @@ #define BARO_ETS_ADDR 0xE8 #define BARO_ETS_REG 0x07 -#ifndef BARO_ETS_SCALE -#define BARO_ETS_SCALE 0.32 -#endif #define BARO_ETS_OFFSET_MAX 30000 #define BARO_ETS_OFFSET_MIN 10 #define BARO_ETS_OFFSET_NBSAMPLES_INIT 20 @@ -70,11 +64,35 @@ #define BARO_ETS_R 0.5 #define BARO_ETS_SIGMA2 0.1 +/** scale factor to convert raw ADC measurement to pressure in Pascal. + * @todo check value + * At low altitudes pressure change is ~1.2 kPa for every 100 meters. + * So with a scale ADC->meters of 0.32 we get: + * 12 Pascal = 0.32 * ADC + * -> SCALE = ~ 12 / 0.32 = 37.5 + */ +#ifndef BARO_ETS_SCALE +#define BARO_ETS_SCALE 37.5 +#endif + +/** scale factor to convert raw ADC measurement to altitude change in meters */ +#ifndef BARO_ETS_ALT_SCALE +#define BARO_ETS_ALT_SCALE 0.32 +#endif + +/** Pressure offset in Pascal when converting raw adc to real pressure (@todo find real value) */ +#ifndef BARO_ETS_PRESSURE_OFFSET +#define BARO_ETS_PRESSURE_OFFSET 101325.0 +#endif + #ifndef BARO_ETS_I2C_DEV #define BARO_ETS_I2C_DEV i2c0 #endif PRINT_CONFIG_VAR(BARO_ETS_I2C_DEV) + +PRINT_CONFIG_VAR(BARO_ETS_SENDER_ID) + /** delay in seconds until sensor is read after startup */ #ifndef BARO_ETS_START_DELAY #define BARO_ETS_START_DELAY 0.2 @@ -119,27 +137,13 @@ void baro_ets_init( void ) { void baro_ets_read_periodic( void ) { // Initiate next read -#ifndef SITL if (!baro_ets_delay_done) { if (SysTimeTimer(baro_ets_delay_time) < USEC_OF_SEC(BARO_ETS_START_DELAY)) return; else baro_ets_delay_done = TRUE; } - if (baro_ets_i2c_trans.status == I2CTransDone) + if (baro_ets_i2c_trans.status == I2CTransDone) { i2c_receive(&BARO_ETS_I2C_DEV, &baro_ets_i2c_trans, BARO_ETS_ADDR, 2); -#else // SITL - /* fake an offset so sim works as well */ - if (!baro_ets_offset_init) { - baro_ets_offset = 12400; - baro_ets_offset_init = TRUE; } - baro_ets_altitude = gps.hmsl / 1000.0; - baro_ets_adc = baro_ets_offset - ((baro_ets_altitude - ground_alt) / BARO_ETS_SCALE); - baro_ets_valid = TRUE; -#endif - -#ifdef BARO_ETS_SYNC_SEND - DOWNLINK_SEND_BARO_ETS(DefaultChannel, DefaultDevice, &baro_ets_adc, &baro_ets_offset, &baro_ets_altitude); -#endif } void baro_ets_read_event( void ) { @@ -173,8 +177,10 @@ void baro_ets_read_event( void ) { } // Convert raw to m/s if (baro_ets_offset_init) { - baro_ets_altitude = ground_alt + BARO_ETS_SCALE * (float)(baro_ets_offset-baro_ets_adc); + baro_ets_altitude = ground_alt + BARO_ETS_ALT_SCALE * (float)(baro_ets_offset-baro_ets_adc); // New value available + float pressure = BARO_ETS_SCALE * (float) baro_ets_adc + BARO_ETS_PRESSURE_OFFSET; + AbiSendMsgBARO_ABS(BARO_ETS_SENDER_ID, &pressure); #ifdef BARO_ETS_SYNC_SEND DOWNLINK_SEND_BARO_ETS(DefaultChannel, DefaultDevice, &baro_ets_adc, &baro_ets_offset, &baro_ets_altitude); #endif diff --git a/sw/airborne/modules/sensors/baro_ets.h b/sw/airborne/modules/sensors/baro_ets.h index 33f7bbd592..90d02ab4c6 100644 --- a/sw/airborne/modules/sensors/baro_ets.h +++ b/sw/airborne/modules/sensors/baro_ets.h @@ -64,6 +64,4 @@ extern void baro_ets_read_event( void ); #define BaroEtsEvent() { if (baro_ets_i2c_trans.status == I2CTransSuccess) baro_ets_read_event(); } -#define BaroEtsUpdate(_b, _h) { if (baro_ets_valid) { _b = baro_ets_adc; _h(); baro_ets_valid = FALSE; } } - #endif // BARO_ETS_H diff --git a/sw/airborne/modules/sensors/baro_hca.c b/sw/airborne/modules/sensors/baro_hca.c index 944213673c..899b29dbc8 100644 --- a/sw/airborne/modules/sensors/baro_hca.c +++ b/sw/airborne/modules/sensors/baro_hca.c @@ -22,6 +22,7 @@ #include "sensors/baro_hca.h" #include "mcu_periph/i2c.h" +#include "subsystems/abi.h" #include //Messages @@ -36,6 +37,16 @@ #define BARO_HCA_MAX_OUT 27852 //dec #define BARO_HCA_MIN_OUT 1638 //dec +// FIXME +#ifndef BARO_HCA_SCALE +#define BARO_HCA_SCALE 1.0 +#endif + +// FIXME +#ifndef BARO_HCA_PRESSURE_OFFSET +#define BARO_HCA_PRESSURE_OFFSET 101325.0 +#endif + #ifndef BARO_HCA_I2C_DEV #define BARO_HCA_I2C_DEV i2c0 #endif @@ -80,6 +91,8 @@ void baro_hca_read_event( void ) { if (pBaroRaw > BARO_HCA_MAX_OUT) pBaroRaw = BARO_HCA_MAX_OUT; + float pressure = BARO_HCA_SCALE*(float)pBaroRaw + BARO_HCA_PRESSURE_OFFSET; + AbiSendMsgBARO_ABS(BARO_HCA_SENDER_ID, &pressure); } baro_hca_i2c_trans.status = I2CTransDone; diff --git a/sw/airborne/modules/sensors/baro_mpl3115.c b/sw/airborne/modules/sensors/baro_mpl3115.c index 018ac5af8b..b4c96b9857 100644 --- a/sw/airborne/modules/sensors/baro_mpl3115.c +++ b/sw/airborne/modules/sensors/baro_mpl3115.c @@ -17,10 +17,18 @@ * 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. + */ + +/** + * @file modules/sensors/baro_mpl3155.c + * + * Module for the baro MPL3115A2 from Freescale (i2c) * */ #include "modules/sensors/baro_mpl3115.h" +#include "peripherals/mpl3115.h" +#include "subsystems/abi.h" //Messages #include "mcu_periph/uart.h" @@ -28,23 +36,37 @@ #include "subsystems/datalink/downlink.h" +#ifndef BARO_MPL3115_I2C_DEV +#define BARO_MPL3115_I2C_DEV i2c0 +#endif + +#ifndef BARO_MPL3115_I2C_SLAVE_ADDR +#define BARO_MPL3115_I2C_SLAVE_ADDR MPL3115_I2C_ADDR +#endif + + +struct Mpl3115 baro_mpl; + void baro_mpl3115_init( void ) { - mpl3115_init(); + mpl3115_init(&baro_mpl, &BARO_MPL3115_I2C_DEV, BARO_MPL3115_I2C_SLAVE_ADDR); } void baro_mpl3115_read_periodic( void ) { -#ifdef SENSOR_SYNC_SEND - if (mpl3115_data_available) { - DOWNLINK_SEND_MPL3115_BARO(DefaultChannel, DefaultDevice, &mpl3115_pressure, &mpl3115_temperature, &mpl3115_alt); - } -#endif - Mpl3115Periodic(); + mpl3115_periodic(&baro_mpl); } void baro_mpl3115_read_event( void ) { - mpl3115_event(); + mpl3115_event(&baro_mpl); + if (baro_mpl.data_available) { + float pressure = (float)baro_mpl.pressure/(1<<2); + AbiSendMsgBARO_ABS(BARO_MPL3115_SENDER_ID, &pressure); +#ifdef SENSOR_SYNC_SEND + DOWNLINK_SEND_MPL3115_BARO(DefaultChannel, DefaultDevice, &baro_mpl.pressure, &baro_mpl.temperature, &baro_mpl.alt); +#endif + baro_mpl.data_available = FALSE; + } } diff --git a/sw/airborne/modules/sensors/baro_mpl3115.h b/sw/airborne/modules/sensors/baro_mpl3115.h index ef9f8b1124..de6568a356 100644 --- a/sw/airborne/modules/sensors/baro_mpl3115.h +++ b/sw/airborne/modules/sensors/baro_mpl3115.h @@ -17,16 +17,22 @@ * 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. + */ + +/** + * @file modules/sensors/baro_mpl3155.h + * + * Module for the baro MPL3115A2 from Freescale (i2c) * */ #ifndef BARO_MPL3115_H #define BARO_MPL3115_H -#include "peripherals/mpl3115.h" - extern void baro_mpl3115_init( void ); extern void baro_mpl3115_read_periodic( void ); extern void baro_mpl3115_read_event( void ); +#define BaroMpl3115Update(_b, _h) { if (mpl3115_data_available) { _b = mpl3115_pressure; _h(); mpl3115_data_available = FALSE; } } + #endif diff --git a/sw/airborne/modules/sensors/baro_ms5611_i2c.c b/sw/airborne/modules/sensors/baro_ms5611_i2c.c index 63be57aaa3..90096b26e5 100644 --- a/sw/airborne/modules/sensors/baro_ms5611_i2c.c +++ b/sw/airborne/modules/sensors/baro_ms5611_i2c.c @@ -29,7 +29,9 @@ #include "modules/sensors/baro_ms5611_i2c.h" +#include "math/pprz_isa.h" #include "mcu_periph/sys_time.h" +#include "subsystems/abi.h" #include "mcu_periph/uart.h" #include "messages.h" #include "subsystems/datalink/downlink.h" @@ -69,9 +71,9 @@ void baro_ms5611_periodic_check( void ) { ms5611_i2c_periodic_check(&baro_ms5611); -#if BARO_MS5611_SEND_COEFF - // send coeff every 5s - RunOnceEvery((5*BARO_MS5611_PERIODIC_CHECK_FREQUENCY), baro_ms5611_send_coeff()); +#if SENSOR_SYNC_SEND + // send coeff every 30s + RunOnceEvery((30*BARO_MS5611_PERIODIC_CHECK_FREQ), baro_ms5611_send_coeff()); #endif } @@ -87,16 +89,19 @@ void baro_ms5611_event( void ) { ms5611_i2c_event(&baro_ms5611); if (baro_ms5611.data_available) { - float tmp_float = baro_ms5611.data.pressure / 101325.0; //pressure at sea level - tmp_float = pow(tmp_float, 0.190295); - baro_ms5611_alt = 44330 * (1.0 - tmp_float); //altitude above MSL + float pressure = (float)baro_ms5611.data.pressure; + AbiSendMsgBARO_ABS(BARO_MS5611_SENDER_ID, &pressure); + baro_ms5611.data_available = FALSE; + + baro_ms5611_alt = pprz_isa_altitude_of_pressure(pressure); baro_ms5611_alt_valid = TRUE; #ifdef SENSOR_SYNC_SEND ftempms = baro_ms5611.data.temperature / 100.; fbaroms = baro_ms5611.data.pressure / 100.; DOWNLINK_SEND_BARO_MS5611(DefaultChannel, DefaultDevice, - &baro_ms5611.data.d1, &baro_ms5611.data.d2, &fbaroms, &ftempms); + &baro_ms5611.data.d1, &baro_ms5611.data.d2, + &fbaroms, &ftempms); #endif } } diff --git a/sw/airborne/modules/sensors/baro_ms5611_i2c.h b/sw/airborne/modules/sensors/baro_ms5611_i2c.h index 549b6bf731..ac57cf2d8d 100644 --- a/sw/airborne/modules/sensors/baro_ms5611_i2c.h +++ b/sw/airborne/modules/sensors/baro_ms5611_i2c.h @@ -23,8 +23,4 @@ extern void baro_ms5611_periodic_check(void); extern void baro_ms5611_event(void); extern void baro_ms5611_send_coeff(void); -#define BaroMs5611UpdatePressure(_b, _h) { if (baro_ms5611.data_available) { _b = baro_ms5611.data.pressure; _h(); baro_ms5611.data_available = FALSE; } } - -#define BaroMs5611UpdateAlt(_b, _h) { if (baro_ms5611.data_available) { _b = baro_ms5611_alt; _h(); baro_ms5611.data_available = FALSE; } } - #endif diff --git a/sw/airborne/modules/sensors/baro_ms5611_spi.c b/sw/airborne/modules/sensors/baro_ms5611_spi.c index 7da2575f41..9a457b78e5 100644 --- a/sw/airborne/modules/sensors/baro_ms5611_spi.c +++ b/sw/airborne/modules/sensors/baro_ms5611_spi.c @@ -29,7 +29,9 @@ #include "modules/sensors/baro_ms5611_spi.h" +#include "math/pprz_isa.h" #include "mcu_periph/sys_time.h" +#include "subsystems/abi.h" #include "mcu_periph/uart.h" #include "messages.h" #include "subsystems/datalink/downlink.h" @@ -42,8 +44,8 @@ #define MS5611_SPI_DEV spi1 #endif -#ifndef MS5611_SLAVE_DEV -#define MS5611_SLAVE_DEV SPI_SLAVE0 +#ifndef MS5611_SLAVE_IDX +#define MS5611_SLAVE_IDX SPI_SLAVE0 #endif @@ -59,7 +61,7 @@ float baro_ms5611_sigma2; void baro_ms5611_init(void) { - ms5611_spi_init(&baro_ms5611, &MS5611_SPI_DEV, MS5611_SLAVE_DEV); + ms5611_spi_init(&baro_ms5611, &MS5611_SPI_DEV, MS5611_SLAVE_IDX); baro_ms5611_enabled = TRUE; baro_ms5611_alt_valid = FALSE; @@ -72,9 +74,9 @@ void baro_ms5611_periodic_check( void ) { ms5611_spi_periodic_check(&baro_ms5611); -#if BARO_MS5611_SEND_COEFF - // send coeff every 5s - RunOnceEvery((5*BARO_MS5611_PERIODIC_CHECK_FREQUENCY), baro_ms5611_send_coeff()); +#if SENSOR_SYNC_SEND + // send coeff every 30s + RunOnceEvery((5*BARO_MS5611_PERIODIC_CHECK_FREQ), baro_ms5611_send_coeff()); #endif } @@ -91,16 +93,19 @@ void baro_ms5611_event( void ) { ms5611_spi_event(&baro_ms5611); if (baro_ms5611.data_available) { - float tmp_float = baro_ms5611.data.pressure / 101325.0; //pressure at sea level - tmp_float = pow(tmp_float, 0.190295); - baro_ms5611_alt = 44330 * (1.0 - tmp_float); //altitude above MSL + float pressure = (float)baro_ms5611.data.pressure; + AbiSendMsgBARO_ABS(BARO_MS5611_SENDER_ID, &pressure); + baro_ms5611.data_available = FALSE; + + baro_ms5611_alt = pprz_isa_altitude_of_pressure(pressure); baro_ms5611_alt_valid = TRUE; #ifdef SENSOR_SYNC_SEND ftempms = baro_ms5611.data.temperature / 100.; fbaroms = baro_ms5611.data.pressure / 100.; DOWNLINK_SEND_BARO_MS5611(DefaultChannel, DefaultDevice, - &baro_ms5611.data.d1, &baro_ms5611.data.d2, &fbaroms, &ftempms); + &baro_ms5611.data.d1, &baro_ms5611.data.d2, + &fbaroms, &ftempms); #endif } } diff --git a/sw/airborne/modules/sensors/baro_ms5611_spi.h b/sw/airborne/modules/sensors/baro_ms5611_spi.h index 7be9f9c2e5..43eb997e02 100644 --- a/sw/airborne/modules/sensors/baro_ms5611_spi.h +++ b/sw/airborne/modules/sensors/baro_ms5611_spi.h @@ -51,8 +51,4 @@ extern void baro_ms5611_periodic_check(void); extern void baro_ms5611_event(void); extern void baro_ms5611_send_coeff(void); -#define BaroMs5611UpdatePressure(_b, _h) { if (baro_ms5611.data_available) { _b = baro_ms5611.data.pressure; _h(); baro_ms5611.data_available = FALSE; } } - -#define BaroMs5611UpdateAlt(_b, _h) { if (baro_ms5611.data_available) { _b = baro_ms5611_alt; _h(); baro_ms5611.data_available = FALSE; } } - #endif diff --git a/sw/airborne/modules/sensors/baro_scp.c b/sw/airborne/modules/sensors/baro_scp.c index 60de6a0842..aa6d9a785e 100644 --- a/sw/airborne/modules/sensors/baro_scp.c +++ b/sw/airborne/modules/sensors/baro_scp.c @@ -2,6 +2,7 @@ #include "mcu_periph/sys_time.h" #include "led.h" #include "mcu.h" +#include "subsystems/abi.h" #include "mcu_periph/uart.h" #include "messages.h" @@ -181,6 +182,8 @@ static void baro_scp_read(void) { void baro_scp_event( void ) { if (baro_scp_available == TRUE) { + float pressure = (float)baro_scp_pressure; + AbiSendMsgBARO_ABS(BARO_SCP_SENDER_ID, &pressure); #ifdef SENSOR_SYNC_SEND DOWNLINK_SEND_SCP_STATUS(DefaultChannel, DefaultDevice, &baro_scp_pressure, &baro_scp_temperature); #endif diff --git a/sw/airborne/modules/sensors/baro_scp.h b/sw/airborne/modules/sensors/baro_scp.h index 77aeb504d1..c69534ec0f 100644 --- a/sw/airborne/modules/sensors/baro_scp.h +++ b/sw/airborne/modules/sensors/baro_scp.h @@ -20,6 +20,4 @@ void baro_scp_init(void); void baro_scp_periodic(void); void baro_scp_event(void); -#define BaroScpUpdate(_b, _h) { if (baro_scp_available) { _b = baro_scp_pressure; _h(); baro_scp_available = FALSE; } } - #endif diff --git a/sw/airborne/modules/sensors/baro_scp_i2c.c b/sw/airborne/modules/sensors/baro_scp_i2c.c index 3711301752..0b78ce7516 100644 --- a/sw/airborne/modules/sensors/baro_scp_i2c.c +++ b/sw/airborne/modules/sensors/baro_scp_i2c.c @@ -9,6 +9,7 @@ #include "mcu_periph/sys_time.h" #include "mcu_periph/i2c.h" +#include "subsystems/abi.h" #include "led.h" #include "mcu_periph/uart.h" @@ -96,6 +97,8 @@ void baro_scp_event( void ) { baro_scp_pressure |= scp_trans.buf[1]; baro_scp_pressure *= 25; + float pressure = (float) baro_scp_pressure; + AbiSendMsgBARO_ABS(BARO_SCP_SENDER_ID, &pressure); #ifdef SENSOR_SYNC_SEND DOWNLINK_SEND_SCP_STATUS(DefaultChannel, DefaultDevice, &baro_scp_pressure, &baro_scp_temperature); #endif diff --git a/sw/airborne/modules/sensors/baro_sim.c b/sw/airborne/modules/sensors/baro_sim.c new file mode 100644 index 0000000000..b78e6995c4 --- /dev/null +++ b/sw/airborne/modules/sensors/baro_sim.c @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2013 Felix Ruess + * + * 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. + */ + +/** + * @file baro_sim.c + * + * Simulate barometer pressure measurement using gps.hmsl + */ + +#include "math/pprz_isa.h" +#include "subsystems/gps.h" +#include "subsystems/abi.h" + +PRINT_CONFIG_VAR(BARO_SIM_SENDER_ID) + +void baro_sim_init(void) { + +} + +void baro_sim_periodic(void) { + float pressure = pprz_isa_pressure_of_altitude(gps.hmsl / 1000.0); + AbiSendMsgBARO_ABS(BARO_SIM_SENDER_ID, &pressure); +} diff --git a/sw/airborne/modules/sensors/baro_sim.h b/sw/airborne/modules/sensors/baro_sim.h new file mode 100644 index 0000000000..a78d3218fa --- /dev/null +++ b/sw/airborne/modules/sensors/baro_sim.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2013 Felix Ruess + * + * 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. + */ + +/** + * @file baro_sim.h + * + * Simulate barometer pressure measurement using gps.hmsl + */ + +#ifndef BARO_SIM_H +#define BARO_SIM_H + +/// new measurement every baro_sim_periodic +#define BARO_SIM_DT BARO_SIM_PERIODIC_PERIOD + +extern void baro_sim_init(void); +extern void baro_sim_periodic(void); + +#endif diff --git a/sw/airborne/modules/sensors/pressure_board_navarro.c b/sw/airborne/modules/sensors/pressure_board_navarro.c index ebe33e997a..d832fad9a0 100644 --- a/sw/airborne/modules/sensors/pressure_board_navarro.c +++ b/sw/airborne/modules/sensors/pressure_board_navarro.c @@ -27,6 +27,7 @@ #include "pressure_board_navarro.h" #include "state.h" +#include "subsystems/abi.h" /* Default I2C device on tiny is i2c0 */ @@ -56,6 +57,11 @@ #define PBN_ALTITUDE_SCALE 0.32 #endif +#ifndef PBN_PRESSURE_OFFSET +#define PBN_PRESSURE_OFFSET 101325.0 +#endif + + // Global variables uint16_t altitude_adc; uint16_t airspeed_adc; @@ -132,6 +138,9 @@ void pbn_read_event( void ) { --offset_cnt; } else { + // Compute pressure + float pressure = PBN_ALTITUDE_SCALE * (float) altitude_adc + PBN_PRESSURE_OFFSET; + AbiSendMsgBARO_ABS(BARO_PBN_SENDER_ID, &pressure); // Compute airspeed and altitude //pbn_airspeed = (-4.45 + sqrtf(19.84-0.57*(float)(airspeed_offset-airspeed_adc)))/0.28; uint16_t diff = Max(airspeed_adc-airspeed_offset, 0); diff --git a/sw/airborne/modules/sensors/pressure_board_navarro.h b/sw/airborne/modules/sensors/pressure_board_navarro.h index 3ba8b2d208..f5e78f2a2f 100644 --- a/sw/airborne/modules/sensors/pressure_board_navarro.h +++ b/sw/airborne/modules/sensors/pressure_board_navarro.h @@ -54,8 +54,6 @@ extern void pbn_read_event( void ); #define PbnEvent() { if (pbn_trans.status == I2CTransSuccess) pbn_read_event(); } -#define BaroPbnUpdate(_b) { if (data_valid) { _b = altitude_adc; data_valid = FALSE; } } - #define PERIODIC_SEND_PBN(_chan) DOWNLINK_SEND_PBN(DefaultChannel, DefaultDevice,&airspeed_adc,&altitude_adc,&pbn_airspeed,&pbn_altitude,&airspeed_offset,&altitude_offset); #endif // PRESSURE_BOARD_NAVARRO_H diff --git a/sw/airborne/modules/vehicle_interface/vi_test_signal.c b/sw/airborne/modules/vehicle_interface/vi_test_signal.c index 35edb58220..de29c7d25e 100644 --- a/sw/airborne/modules/vehicle_interface/vi_test_signal.c +++ b/sw/airborne/modules/vehicle_interface/vi_test_signal.c @@ -67,7 +67,7 @@ void booz_fms_impl_periodic(void) { #if 0 case BOOZ_FMS_TEST_SIGNAL_MODE_VERTICAL: { if (guidance_v_mode < GUIDANCE_V_MODE_HOVER) - booz_fms_test_signal_start_z = ins_ltp_pos.z; + booz_fms_test_signal_start_z = ins_impl.ltp_pos.z; else { booz_fms_input.v_sp.height = (booz_fms_test_signal_counter < booz_fms_test_signal_period) ? booz_fms_test_signal_start_z : diff --git a/sw/airborne/peripherals/mpl3115.c b/sw/airborne/peripherals/mpl3115.c index 24a3bab2a1..bfac2abad1 100644 --- a/sw/airborne/peripherals/mpl3115.c +++ b/sw/airborne/peripherals/mpl3115.c @@ -27,57 +27,50 @@ #include "peripherals/mpl3115.h" #include "std.h" -#define MPL_CONF_UNINIT 0 -#define MPL_CONF_PT_DATA 1 -#define MPL_CONF_CTRL1 2 -#define MPL_CONF_DONE 3 - -// Data ready flag -volatile bool_t mpl3115_data_available; -// Data -uint32_t mpl3115_pressure; -int16_t mpl3115_temperature; -float mpl3115_alt; -// I2C transaction for reading and configuring -struct i2c_transaction mpl3115_trans; -// I2C transaction for conversion request -struct i2c_transaction mpl3115_req_trans; -// Init flag -bool_t mpl3115_initialized; -uint8_t mpl3115_init_status; - -void mpl3115_init(void) +void mpl3115_init(struct Mpl3115 *mpl, struct i2c_periph *i2c_p, uint8_t addr) { - mpl3115_trans.status = I2CTransDone; - mpl3115_req_trans.status = I2CTransDone; - mpl3115_initialized = FALSE; - mpl3115_init_status = MPL_CONF_UNINIT; - mpl3115_pressure = 0; - mpl3115_temperature = 0; - mpl3115_alt = 0.; + /* set i2c_peripheral */ + mpl->i2c_p = i2c_p; + + /* slave address */ + mpl->trans.slave_addr = addr; + + mpl->trans.status = I2CTransDone; + mpl->req_trans.status = I2CTransDone; + mpl->initialized = FALSE; + mpl->init_status = MPL_CONF_UNINIT; + + /* by default disable raw mode and set pressure mode */ + mpl->raw_mode = FALSE; + mpl->alt_mode = FALSE; + + mpl->pressure = 0; + mpl->temperature = 0; + mpl->altitude = 0.; } // Configuration function called once before normal use -static void mpl3115_send_config(void) +static void mpl3115_send_config(struct Mpl3115 *mpl) { - switch (mpl3115_init_status) { + switch (mpl->init_status) { case MPL_CONF_PT_DATA: - mpl3115_trans.buf[0] = MPL3115_REG_PT_DATA_CFG; - mpl3115_trans.buf[1] = MPL3115_PT_DATA_CFG; - i2c_transmit(&MPL3115_I2C_DEV, &mpl3115_trans, MPL3115_I2C_ADDR, 2); - mpl3115_init_status++; + mpl->trans.buf[0] = MPL3115_REG_PT_DATA_CFG; + mpl->trans.buf[1] = MPL3115_PT_DATA_CFG; + i2c_transmit(mpl->i2c_p, &mpl->trans, mpl->trans.slave_addr, 2); + mpl->init_status++; break; case MPL_CONF_CTRL1: - mpl3115_trans.buf[0] = MPL3115_REG_CTRL_REG1; - mpl3115_trans.buf[1] = MPL3115_CTRL_REG1; - i2c_transmit(&MPL3115_I2C_DEV, &mpl3115_trans, MPL3115_I2C_ADDR, 2); - mpl3115_init_status++; + mpl->trans.buf[0] = MPL3115_REG_CTRL_REG1; + mpl->trans.buf[1] = ((MPL3115_OVERSAMPLING<<3) | (mpl->raw_mode<<6) | + (mpl->alt_mode<<7)); + i2c_transmit(mpl->i2c_p, &mpl->trans, mpl->trans.slave_addr, 2); + mpl->init_status++; break; case MPL_CONF_DONE: - mpl3115_initialized = TRUE; - mpl3115_trans.status = I2CTransDone; + mpl->initialized = TRUE; + mpl->trans.status = I2CTransDone; break; default: break; @@ -85,77 +78,85 @@ static void mpl3115_send_config(void) } // Configure -void mpl3115_configure(void) +void mpl3115_configure(struct Mpl3115 *mpl) { - if (mpl3115_init_status == MPL_CONF_UNINIT) { - mpl3115_init_status++; - if (mpl3115_trans.status == I2CTransSuccess || mpl3115_trans.status == I2CTransDone) { - mpl3115_send_config(); + if (mpl->init_status == MPL_CONF_UNINIT) { + mpl->init_status++; + if (mpl->trans.status == I2CTransSuccess || mpl->trans.status == I2CTransDone) { + mpl3115_send_config(mpl); } } } // Normal reading -void mpl3115_read(void) +void mpl3115_read(struct Mpl3115 *mpl) { // ask for a reading and then prepare next conversion - if (mpl3115_initialized && mpl3115_trans.status == I2CTransDone) { - mpl3115_trans.buf[0] = MPL3115_REG_STATUS; - i2c_transceive(&MPL3115_I2C_DEV, &mpl3115_trans, MPL3115_I2C_ADDR, 1, 6); - if (mpl3115_req_trans.status == I2CTransDone) { - mpl3115_req_trans.buf[0] = MPL3115_REG_CTRL_REG1; - mpl3115_req_trans.buf[1] = MPL3115_CTRL_REG1 | MPL3115_OST_BIT; - i2c_transmit(&MPL3115_I2C_DEV, &mpl3115_req_trans, MPL3115_I2C_ADDR, 2); + if (mpl->initialized && mpl->trans.status == I2CTransDone) { + mpl->trans.buf[0] = MPL3115_REG_STATUS; + i2c_transceive(mpl->i2c_p, &mpl->trans, mpl->trans.slave_addr, 1, 6); + if (mpl->req_trans.status == I2CTransDone) { + mpl->req_trans.buf[0] = MPL3115_REG_CTRL_REG1; + mpl->req_trans.buf[1] = ((MPL3115_OVERSAMPLING<<3) | (mpl->raw_mode<<6) | + (mpl->alt_mode<<7) | MPL3115_OST_BIT); + i2c_transmit(mpl->i2c_p, &mpl->trans, mpl->trans.slave_addr, 2); } } } -void mpl3115_event(void) +void mpl3115_event(struct Mpl3115 *mpl) { - if (mpl3115_initialized) { - if (mpl3115_trans.status == I2CTransFailed) { - mpl3115_trans.status = I2CTransDone; + if (mpl->initialized) { + if (mpl->trans.status == I2CTransFailed) { + mpl->trans.status = I2CTransDone; } - else if (mpl3115_trans.status == I2CTransSuccess) { + else if (mpl->trans.status == I2CTransSuccess) { // Successfull reading and new pressure data available - if (mpl3115_trans.buf[0] & (1<<2)) { -#if MPL3115_RAW_OUTPUT - // New data available - mpl3115_pressure = ((uint32_t)mpl3115_trans.buf[1]<<16)|((uint16_t)mpl3115_trans.buf[2]<<8)|mpl3115_trans.buf[3]; - mpl3115_temperature = ((int16_t)mpl3115_trans.buf[4]<<8)|mpl3115_trans.buf[5]; - mpl3115_data_available = TRUE; -#else // Not in raw mode -#if MPL3115_ALT_MODE - uint32_t tmp = ((uint32_t)mpl3115_trans.buf[1]<<16)|((uint16_t)mpl3115_trans.buf[2]<<8)|mpl3115_trans.buf[3]; - mpl3115_alt = (float)(tmp>>4)/(1<<4); - tmp = ((int16_t)mpl3115_trans.buf[4]<<8)|mpl3115_trans.buf[5]; - mpl3115_temperature = (tmp>>4); - mpl3115_data_available = TRUE; -#else // Pressure mode - uint32_t tmp = ((uint32_t)mpl3115_trans.buf[1]<<16)|((uint16_t)mpl3115_trans.buf[2]<<8)|mpl3115_trans.buf[3]; - mpl3115_pressure = (tmp>>4); - tmp = ((int16_t)mpl3115_trans.buf[4]<<8)|mpl3115_trans.buf[5]; - mpl3115_temperature = (tmp>>4); - mpl3115_data_available = TRUE; -#endif // end alt mode -#endif // end raw mode + if (mpl->trans.buf[0] & (1<<2)) { + if (mpl->raw_mode) { + // New data available + mpl->pressure = (((uint32_t)mpl->trans.buf[1]<<16) | + ((uint16_t)mpl->trans.buf[2]<<8) | + mpl->trans.buf[3]); + mpl->temperature = ((int16_t)mpl->trans.buf[4]<<8) | mpl->trans.buf[5]; + } + else { // not in raw mode + uint32_t tmp = (((uint32_t)mpl->trans.buf[1]<<16) | + ((uint16_t)mpl->trans.buf[2]<<8) | + mpl->trans.buf[3]); + if (mpl->alt_mode) { + mpl->altitude = (float)(tmp>>4) / (1<<4); + } + else { // Pressure mode + mpl->pressure = (tmp>>4); + } + tmp = ((int16_t)mpl->trans.buf[4]<<8) | mpl->trans.buf[5]; + mpl->temperature = (tmp>>4); + } + mpl->data_available = TRUE; } - mpl3115_trans.status = I2CTransDone; + mpl->trans.status = I2CTransDone; } } - else if (!mpl3115_initialized && mpl3115_init_status != MPL_CONF_UNINIT) { // Configuring - if (mpl3115_trans.status == I2CTransSuccess || mpl3115_trans.status == I2CTransDone) { - mpl3115_trans.status = I2CTransDone; - mpl3115_send_config(); + else if (!mpl->initialized && mpl->init_status != MPL_CONF_UNINIT) { // Configuring + if (mpl->trans.status == I2CTransSuccess || mpl->trans.status == I2CTransDone) { + mpl->trans.status = I2CTransDone; + mpl3115_send_config(mpl); } - if (mpl3115_trans.status == I2CTransFailed) { - mpl3115_init_status--; - mpl3115_trans.status = I2CTransDone; - mpl3115_send_config(); // Retry config (TODO max retry) + if (mpl->trans.status == I2CTransFailed) { + mpl->init_status--; + mpl->trans.status = I2CTransDone; + mpl3115_send_config(mpl); // Retry config (TODO max retry) } } - if (mpl3115_req_trans.status == I2CTransSuccess || mpl3115_req_trans.status == I2CTransFailed) { - mpl3115_req_trans.status = I2CTransDone; + if (mpl->req_trans.status == I2CTransSuccess || mpl->req_trans.status == I2CTransFailed) { + mpl->req_trans.status = I2CTransDone; } } +void mpl3115_periodic(struct Mpl3115 *mpl) { + if (mpl->initialized) + mpl3115_read(mpl); + else + mpl3115_configure(mpl); +} diff --git a/sw/airborne/peripherals/mpl3115.h b/sw/airborne/peripherals/mpl3115.h index 5c723ed379..096f91c4ce 100644 --- a/sw/airborne/peripherals/mpl3115.h +++ b/sw/airborne/peripherals/mpl3115.h @@ -34,11 +34,6 @@ /* Device address (8 bits) */ #define MPL3115_I2C_ADDR 0xC0 -/* Default I2C device */ -#ifndef MPL3115_I2C_DEV -#define MPL3115_I2C_DEV i2c0 -#endif - /* Registers */ #define MPL3115_REG_STATUS 0x00 #define MPL3115_REG_OUT_P_MSB 0x01 @@ -63,36 +58,34 @@ #ifndef MPL3115_OVERSAMPLING #define MPL3115_OVERSAMPLING 0x5 // Oversample ratio (0x5: 130ms between data sample) #endif -#ifndef MPL3115_RAW_OUTPUT -#define MPL3115_RAW_OUTPUT 0x0 // Raw output (disable alt mode if true) -#endif -#ifndef MPL3115_ALT_MODE -#define MPL3115_ALT_MODE 0x1 // 0: baro, 1: alti (disable by raw mode) -#endif -#define MPL3115_CTRL_REG1 ((MPL3115_OVERSAMPLING<<3)|(MPL3115_RAW_OUTPUT<<6)|(MPL3115_ALT_MODE<<7)) -// Config done flag -extern bool_t mpl3115_initialized; -// Data ready flag -extern volatile bool_t mpl3115_data_available; -// Data -extern uint32_t mpl3115_pressure; -extern int16_t mpl3115_temperature; -extern float mpl3115_alt; -// I2C transaction structure -//extern struct i2c_transaction mpl3115_trans; +enum Mpl3115Status { + MPL_CONF_UNINIT, + MPL_CONF_PT_DATA, + MPL_CONF_CTRL1, + MPL_CONF_DONE +}; + +struct Mpl3115 { + struct i2c_periph *i2c_p; + struct i2c_transaction trans; ///< I2C transaction for reading and configuring + struct i2c_transaction req_trans; ///< I2C transaction for conversion request + enum Mpl3115Status init_status; + bool_t initialized; ///< config done flag + volatile bool_t data_available; ///< data ready flag + bool_t raw_mode; ///< set to TRUE to enable raw output + bool_t alt_mode; ///< set to TRUE to enable altitude output (otherwise pressure) + int16_t temperature; ///< temperature in 1/16 degrees Celcius + uint32_t pressure; ///< pressure in 1/4 Pascal + float altitude; ///< altitude in meters +}; // Functions -extern void mpl3115_init(void); -extern void mpl3115_configure(void); -extern void mpl3115_read(void); -extern void mpl3115_event(void); - -// Macro for using MPL3115 in periodic function -#define Mpl3115Periodic() { \ - if (mpl3115_initialized) mpl3115_read(); \ - else mpl3115_configure(); \ -} +extern void mpl3115_init(struct Mpl3115 *mpl, struct i2c_periph *i2c_p, uint8_t addr); +extern void mpl3115_configure(struct Mpl3115 *mpl); +extern void mpl3115_read(struct Mpl3115 *mpl); +extern void mpl3115_event(struct Mpl3115 *mpl); +extern void mpl3115_periodic(struct Mpl3115 *mpl); #endif // MPL3115_H diff --git a/sw/airborne/state.c b/sw/airborne/state.c index 0b92f2fe3a..f72bc48438 100644 --- a/sw/airborne/state.c +++ b/sw/airborne/state.c @@ -69,8 +69,7 @@ void stateCalcPositionEcef_i(void) { ECEF_BFP_OF_REAL(state.ecef_pos_i, state.ecef_pos_f); } else if (bit_is_set(state.pos_status, POS_NED_I)) { - /// @todo check if resolution is good enough - ecef_of_ned_point_i(&state.ecef_pos_i, &state.ned_origin_i, &state.ned_pos_i); + ecef_of_ned_pos_i(&state.ecef_pos_i, &state.ned_origin_i, &state.ned_pos_i); } else if (bit_is_set(state.pos_status, POS_NED_F)) { /* transform ned_f to ecef_f, set status bit, then convert to int */ @@ -114,7 +113,7 @@ void stateCalcPositionNed_i(void) { INT32_VECT3_NED_OF_ENU(state.ned_pos_i, state.enu_pos_i); } else if (bit_is_set(state.pos_status, POS_ECEF_I)) { - ned_of_ecef_point_i(&state.ned_pos_i, &state.ned_origin_i, &state.ecef_pos_i); + ned_of_ecef_pos_i(&state.ned_pos_i, &state.ned_origin_i, &state.ecef_pos_i); } else if (bit_is_set(state.pos_status, POS_ECEF_F)) { /* transform ecef_f -> ned_f, set status bit, then convert to int */ @@ -206,7 +205,7 @@ void stateCalcPositionEnu_i(void) { INT32_VECT3_ENU_OF_NED(state.enu_pos_i, state.ned_pos_i); } else if (bit_is_set(state.pos_status, POS_ECEF_I)) { - enu_of_ecef_point_i(&state.enu_pos_i, &state.ned_origin_i, &state.ecef_pos_i); + enu_of_ecef_pos_i(&state.enu_pos_i, &state.ned_origin_i, &state.ecef_pos_i); } else if (bit_is_set(state.pos_status, POS_ECEF_F)) { /* transform ecef_f -> enu_f, set status bit, then convert to int */ @@ -306,8 +305,7 @@ void stateCalcPositionLla_i(void) { } else if (bit_is_set(state.pos_status, POS_NED_I)) { /* transform ned_i -> ecef_i -> lla_i, set status bits */ - /// @todo check if resolution is enough - ecef_of_ned_point_i(&state.ecef_pos_i, &state.ned_origin_i, &state.ned_pos_i); + ecef_of_ned_pos_i(&state.ecef_pos_i, &state.ned_origin_i, &state.ned_pos_i); SetBit(state.pos_status, POS_ECEF_I); lla_of_ecef_i(&state.lla_pos_i, &state.ecef_pos_i); /* uses double version internally */ } @@ -360,8 +358,7 @@ void stateCalcPositionEcef_f(void) { } else if (bit_is_set(state.pos_status, POS_NED_I)) { /* transform ned_i -> ecef_i -> ecef_f, set status bits */ - /// @todo check if resolution is good enough - ecef_of_ned_point_i(&state.ecef_pos_i, &state.ned_origin_i, &state.ned_pos_i); + ecef_of_ned_pos_i(&state.ecef_pos_i, &state.ned_origin_i, &state.ned_pos_i); SetBit(state.pos_status, POS_ECEF_F); ECEF_FLOAT_OF_BFP(state.ecef_pos_f, state.ecef_pos_i); } @@ -396,7 +393,7 @@ void stateCalcPositionNed_f(void) { } else if (bit_is_set(state.pos_status, POS_ECEF_I)) { /* transform ecef_i -> ned_i -> ned_f, set status bits */ - ned_of_ecef_point_i(&state.ned_pos_i, &state.ned_origin_i, &state.ecef_pos_i); + ned_of_ecef_pos_i(&state.ned_pos_i, &state.ned_origin_i, &state.ecef_pos_i); SetBit(state.pos_status, POS_NED_I); NED_FLOAT_OF_BFP(state.ned_pos_f, state.ned_pos_i); } @@ -407,7 +404,7 @@ void stateCalcPositionNed_f(void) { /* transform lla_i -> ecef_i -> ned_i -> ned_f, set status bits */ ecef_of_lla_i(&state.ecef_pos_i, &state.lla_pos_i); /* converts to doubles internally */ SetBit(state.pos_status, POS_ECEF_I); - ned_of_ecef_point_i(&state.ned_pos_i, &state.ned_origin_i, &state.ecef_pos_i); + ned_of_ecef_pos_i(&state.ned_pos_i, &state.ned_origin_i, &state.ecef_pos_i); SetBit(state.pos_status, POS_NED_I); NED_FLOAT_OF_BFP(state.ned_pos_f, state.ned_pos_i); } @@ -481,7 +478,7 @@ void stateCalcPositionEnu_f(void) { } else if (bit_is_set(state.pos_status, POS_ECEF_I)) { /* transform ecef_i -> enu_i -> enu_f, set status bits */ - enu_of_ecef_point_i(&state.enu_pos_i, &state.ned_origin_i, &state.ecef_pos_i); + enu_of_ecef_pos_i(&state.enu_pos_i, &state.ned_origin_i, &state.ecef_pos_i); SetBit(state.pos_status, POS_ENU_I); ENU_FLOAT_OF_BFP(state.enu_pos_f, state.enu_pos_i); } @@ -492,7 +489,7 @@ void stateCalcPositionEnu_f(void) { /* transform lla_i -> ecef_i -> enu_i -> enu_f, set status bits */ ecef_of_lla_i(&state.ecef_pos_i, &state.lla_pos_i); /* converts to doubles internally */ SetBit(state.pos_status, POS_ECEF_I); - enu_of_ecef_point_i(&state.enu_pos_i, &state.ned_origin_i, &state.ecef_pos_i); + enu_of_ecef_pos_i(&state.enu_pos_i, &state.ned_origin_i, &state.ecef_pos_i); SetBit(state.pos_status, POS_ENU_I); ENU_FLOAT_OF_BFP(state.enu_pos_f, state.enu_pos_i); } diff --git a/sw/airborne/subsystems/abi.h b/sw/airborne/subsystems/abi.h index 1e950e4e9f..d0289b13b4 100644 --- a/sw/airborne/subsystems/abi.h +++ b/sw/airborne/subsystems/abi.h @@ -19,11 +19,16 @@ * Boston, MA 02111-1307, USA. */ +/** + * @file subsystems/abi.h + * + * Main include for ABI (AirBorneInterface). + * @todo explain how to use ABI + */ + #ifndef ABI_H #define ABI_H -/* TODO Explain how to use ABI */ - #include "abi_messages.h" #endif /* ABI_H */ diff --git a/sw/airborne/subsystems/abi_common.h b/sw/airborne/subsystems/abi_common.h index 1e668b2e9c..f4eac21514 100644 --- a/sw/airborne/subsystems/abi_common.h +++ b/sw/airborne/subsystems/abi_common.h @@ -19,7 +19,11 @@ * Boston, MA 02111-1307, USA. */ -/* Common tools for ABI middelware */ +/** + * @file subsystems/abi_common.h + * + * Common tools for ABI middelware. + */ #ifndef ABI_COMMON_H #define ABI_COMMON_H @@ -32,20 +36,21 @@ * Ex: '#include "subsystems/gps.h"' in order to use the GpsState structure */ +#include "subsystems/abi_sender_ids.h" /* Some magic to avoid to compile C code, only headers */ #ifdef ABI_C -#define EXTERN +#define ABI_EXTERN #else -#define EXTERN extern +#define ABI_EXTERN extern #endif /** Generic callback definition */ typedef void (*abi_callback)(void); /** Broadcast address. - * When passing broadcast address has a sender id, - * messages from all sender are received + * When passing broadcast address as a sender id, + * messages from all senders are received */ #define ABI_BROADCAST 0 diff --git a/sw/airborne/subsystems/abi_sender_ids.h b/sw/airborne/subsystems/abi_sender_ids.h new file mode 100644 index 0000000000..f87b5298b8 --- /dev/null +++ b/sw/airborne/subsystems/abi_sender_ids.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2013 Felix Ruess + * + * 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. + */ + +/** + * @file subsystems/abi_sender_ids.h + * + * Convenience defines for ABI sender IDs. + */ + +#ifndef ABI_SENDER_IDS_H +#define ABI_SENDER_IDS_H + +/** default onboard baro */ +#ifndef BARO_BOARD_SENDER_ID +#define BARO_BOARD_SENDER_ID 1 +#endif + +/* + * IDs of baro modules that can be loaded + */ +#ifndef BARO_MS5611_SENDER_ID +#define BARO_MS5611_SENDER_ID 10 +#endif + +#ifndef BARO_AMSYS_SENDER_ID +#define BARO_AMSYS_SENDER_ID 11 +#endif + +#ifndef BARO_BMP_SENDER_ID +#define BARO_BMP_SENDER_ID 12 +#endif + +#ifndef BARO_ETS_SENDER_ID +#define BARO_ETS_SENDER_ID 13 +#endif + +#ifndef BARO_MS5534A_SENDER_ID +#define BARO_MS5534A_SENDER_ID 14 +#endif + +#ifndef BARO_HCA_SENDER_ID +#define BARO_HCA_SENDER_ID 15 +#endif + +#ifndef BARO_MPL3115_SENDER_ID +#define BARO_MPL3115_SENDER_ID 16 +#endif + +#ifndef BARO_SCP_SENDER_ID +#define BARO_SCP_SENDER_ID 17 +#endif + +#ifndef BARO_PBN_SENDER_ID +#define BARO_PBN_SENDER_ID 18 +#endif + +#ifndef BARO_SIM_SENDER_ID +#define BARO_SIM_SENDER_ID 19 +#endif + +#endif /* ABI_SENDER_IDS_H */ diff --git a/sw/airborne/subsystems/ahrs/ahrs_float_cmpl.c b/sw/airborne/subsystems/ahrs/ahrs_float_cmpl.c index 8965e1202c..1d85f64d22 100644 --- a/sw/airborne/subsystems/ahrs/ahrs_float_cmpl.c +++ b/sw/airborne/subsystems/ahrs/ahrs_float_cmpl.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 The Paparazzi Team + * Copyright (C) 2010-2013 The Paparazzi Team * * This file is part of paparazzi. * @@ -60,6 +60,39 @@ #ifndef AHRS_PROPAGATE_FREQUENCY #define AHRS_PROPAGATE_FREQUENCY PERIODIC_FREQUENCY #endif +PRINT_CONFIG_VAR(AHRS_PROPAGATE_FREQUENCY) + +#ifndef AHRS_CORRECT_FREQUENCY +#define AHRS_CORRECT_FREQUENCY AHRS_PROPAGATE_FREQUENCY +#endif +PRINT_CONFIG_VAR(AHRS_CORRECT_FREQUENCY) + +#ifndef AHRS_MAG_CORRECT_FREQUENCY +#define AHRS_MAG_CORRECT_FREQUENCY 50 +#endif +PRINT_CONFIG_VAR(AHRS_MAG_CORRECT_FREQUENCY) + +/* + * default gains for correcting attitude and bias from accel/mag + */ +#ifndef AHRS_ACCEL_OMEGA +#define AHRS_ACCEL_OMEGA 0.063 +#endif +#ifndef AHRS_ACCEL_ZETA +#define AHRS_ACCEL_ZETA 0.9 +#endif + +#ifndef AHRS_MAG_OMEGA +#define AHRS_MAG_OMEGA 0.04 +#endif +#ifndef AHRS_MAG_ZETA +#define AHRS_MAG_ZETA 0.9 +#endif + +/** by default use the gravity heuristic to reduce gain */ +#ifndef AHRS_GRAVITY_HEURISTIC_FACTOR +#define AHRS_GRAVITY_HEURISTIC_FACTOR 30 +#endif #ifdef AHRS_UPDATE_FW_ESTIMATOR // remotely settable @@ -145,12 +178,20 @@ void ahrs_init(void) { FLOAT_RATES_ZERO(ahrs_impl.imu_rate); + /* set default filter cut-off frequency and damping */ + ahrs_impl.accel_omega = AHRS_ACCEL_OMEGA; + ahrs_impl.accel_zeta = AHRS_ACCEL_ZETA; + ahrs_impl.mag_omega = AHRS_MAG_OMEGA; + ahrs_impl.mag_zeta = AHRS_MAG_ZETA; + #if AHRS_GRAVITY_UPDATE_COORDINATED_TURN ahrs_impl.correct_gravity = TRUE; #else ahrs_impl.correct_gravity = FALSE; #endif + ahrs_impl.gravity_heuristic_factor = AHRS_GRAVITY_HEURISTIC_FACTOR; + VECT3_ASSIGN(ahrs_impl.mag_h, AHRS_H_X, AHRS_H_Y, AHRS_H_Z); #if DOWNLINK @@ -180,7 +221,6 @@ void ahrs_align(void) { struct Int32Rates bias0; RATES_COPY(bias0, ahrs_aligner.lp_gyro); RATES_FLOAT_OF_BFP(ahrs_impl.gyro_bias, bias0); - ahrs.status = AHRS_RUNNING; } @@ -233,6 +273,8 @@ void ahrs_update_accel(void) { struct FloatVect3 residual; + struct FloatVect3 pseudo_gravity_measurement; + if (ahrs_impl.correct_gravity && ahrs_impl.ltp_vel_norm_valid) { /* * centrifugal acceleration in body frame @@ -249,30 +291,51 @@ void ahrs_update_accel(void) { struct FloatVect3 acc_c_imu; FLOAT_RMAT_VECT3_MUL(acc_c_imu, ahrs_impl.body_to_imu_rmat, acc_c_body); - /* and subtract it from imu measurement to get a corrected measurement of the gravitiy vector */ - struct FloatVect3 corrected_gravity; - VECT3_DIFF(corrected_gravity, imu_accel_float, acc_c_imu); + /* and subtract it from imu measurement to get a corrected measurement of the gravity vector */ + VECT3_DIFF(pseudo_gravity_measurement, imu_accel_float, acc_c_imu); - /* compute the residual of gravity vector in imu frame */ - FLOAT_VECT3_CROSS_PRODUCT(residual, corrected_gravity, c2); } else { - FLOAT_VECT3_CROSS_PRODUCT(residual, imu_accel_float, c2); + VECT3_COPY(pseudo_gravity_measurement, imu_accel_float); } -#ifdef AHRS_GRAVITY_UPDATE_NORM_HEURISTIC - /* heuristic on acceleration norm */ - const float acc_norm = FLOAT_VECT3_NORM(imu_accel_float); - const float weight = Chop(1.-6*fabs((9.81-acc_norm)/9.81), 0., 1.); -#else - const float weight = 1.; -#endif + FLOAT_VECT3_CROSS_PRODUCT(residual, pseudo_gravity_measurement, c2); - /* compute correction */ - const float gravity_rate_update_gain = -5e-2; // -5e-2 - FLOAT_RATES_ADD_SCALED_VECT(ahrs_impl.rate_correction, residual, weight*gravity_rate_update_gain); + /* FIR filtered pseudo_gravity_measurement */ + #define FIR_FILTER_SIZE 8 + static struct FloatVect3 filtered_gravity_measurement = {0., 0., 0.}; + VECT3_SMUL(filtered_gravity_measurement, filtered_gravity_measurement, FIR_FILTER_SIZE-1); + VECT3_ADD(filtered_gravity_measurement, pseudo_gravity_measurement); + VECT3_SDIV(filtered_gravity_measurement, filtered_gravity_measurement, FIR_FILTER_SIZE); - const float gravity_bias_update_gain = 1e-5; // -5e-6 - FLOAT_RATES_ADD_SCALED_VECT(ahrs_impl.gyro_bias, residual, weight*gravity_bias_update_gain); + if (ahrs_impl.gravity_heuristic_factor) { + /* heuristic on acceleration (gravity estimate) norm */ + /* Factor how strongly to change the weight. + * e.g. for gravity_heuristic_factor 30: + * <0.66G = 0, 1G = 1.0, >1.33G = 0 + */ + + const float g_meas_norm = FLOAT_VECT3_NORM(filtered_gravity_measurement) / 9.81; + ahrs_impl.weight = 1.0 - ahrs_impl.gravity_heuristic_factor * fabs(1.0 - g_meas_norm) / 10.0; + Bound(ahrs_impl.weight, 0.15, 1.0); + } + else { + ahrs_impl.weight = 1.0; + } + + /* Complementary filter proportional gain. + * Kp = 2 * zeta * omega * weight * AHRS_PROPAGATE_FREQUENCY / AHRS_CORRECT_FREQUENCY + */ + const float gravity_rate_update_gain = -2 * ahrs_impl.accel_zeta * ahrs_impl.accel_omega * + ahrs_impl.weight * AHRS_PROPAGATE_FREQUENCY / (AHRS_CORRECT_FREQUENCY * 9.81); + FLOAT_RATES_ADD_SCALED_VECT(ahrs_impl.rate_correction, residual, gravity_rate_update_gain); + + /* Complementary filter integral gain + * Correct the gyro bias. + * Ki = (omega*weight)^2/AHRS_CORRECT_FREQUENCY + */ + const float gravity_bias_update_gain = ahrs_impl.accel_omega * ahrs_impl.accel_omega * + ahrs_impl.weight * ahrs_impl.weight / (AHRS_CORRECT_FREQUENCY * 9.81); + FLOAT_RATES_ADD_SCALED_VECT(ahrs_impl.gyro_bias, residual, gravity_bias_update_gain); /* FIXME: saturate bias */ @@ -301,37 +364,66 @@ void ahrs_update_mag_full(void) { // DISPLAY_FLOAT_VECT3("# measured", measured_imu); // DISPLAY_FLOAT_VECT3("# residual", residual); - const float mag_rate_update_gain = 2.5; + /* Complementary filter proportional gain. + * Kp = 2 * zeta * omega * weight * AHRS_PROPAGATE_FREQUENCY / AHRS_MAG_CORRECT_FREQUENCY + */ + + const float mag_rate_update_gain = 2 * ahrs_impl.mag_zeta * ahrs_impl.mag_omega * + AHRS_PROPAGATE_FREQUENCY / AHRS_MAG_CORRECT_FREQUENCY; FLOAT_RATES_ADD_SCALED_VECT(ahrs_impl.rate_correction, residual_imu, mag_rate_update_gain); - const float mag_bias_update_gain = -2.5e-3; + /* Complementary filter integral gain + * Correct the gyro bias. + * Ki = (omega*weight)^2/AHRS_CORRECT_FREQUENCY + */ + const float mag_bias_update_gain = -(ahrs_impl.mag_omega * ahrs_impl.mag_omega) / + AHRS_MAG_CORRECT_FREQUENCY; FLOAT_RATES_ADD_SCALED_VECT(ahrs_impl.gyro_bias, residual_imu, mag_bias_update_gain); } void ahrs_update_mag_2d(void) { + struct FloatVect2 expected_ltp; + VECT2_COPY(expected_ltp, ahrs_impl.mag_h); + // normalize expected ltp in 2D (x,y) + FLOAT_VECT2_NORMALIZE(expected_ltp); + struct FloatVect3 measured_imu; MAGS_FLOAT_OF_BFP(measured_imu, imu.mag); struct FloatVect3 measured_ltp; FLOAT_RMAT_VECT3_TRANSP_MUL(measured_ltp, ahrs_impl.ltp_to_imu_rmat, measured_imu); + struct FloatVect2 measured_ltp_2d={measured_ltp.x, measured_ltp.y}; + + // normalize measured ltp in 2D (x,y) + FLOAT_VECT2_NORMALIZE(measured_ltp_2d); + const struct FloatVect3 residual_ltp = { 0, 0, - measured_ltp.x * ahrs_impl.mag_h.y - measured_ltp.y * ahrs_impl.mag_h.x }; + measured_ltp_2d.x * expected_ltp.y - measured_ltp_2d.y * expected_ltp.x }; // printf("res : %f\n", residual_ltp.z); struct FloatVect3 residual_imu; FLOAT_RMAT_VECT3_MUL(residual_imu, ahrs_impl.ltp_to_imu_rmat, residual_ltp); - const float mag_rate_update_gain = 2.5; + + /* Complementary filter proportional gain. + * Kp = 2 * zeta * omega * weight * AHRS_PROPAGATE_FREQUENCY / AHRS_MAG_CORRECT_FREQUENCY + */ + const float mag_rate_update_gain = 2 * ahrs_impl.mag_zeta * ahrs_impl.mag_omega * + AHRS_PROPAGATE_FREQUENCY / AHRS_MAG_CORRECT_FREQUENCY; FLOAT_RATES_ADD_SCALED_VECT(ahrs_impl.rate_correction, residual_imu, mag_rate_update_gain); - const float mag_bias_update_gain = -2.5e-3; + /* Complementary filter integral gain + * Correct the gyro bias. + * Ki = (omega*weight)^2/AHRS_CORRECT_FREQUENCY + */ + const float mag_bias_update_gain = -(ahrs_impl.mag_omega * ahrs_impl.mag_omega) / + AHRS_MAG_CORRECT_FREQUENCY; FLOAT_RATES_ADD_SCALED_VECT(ahrs_impl.gyro_bias, residual_imu, mag_bias_update_gain); - } @@ -349,7 +441,8 @@ void ahrs_update_mag_2d_dumb(void) { const float mn = ctheta * magf.x + sphi*stheta*magf.y + cphi*stheta*magf.z; const float me = 0. * magf.x + cphi *magf.y - sphi *magf.z; - const float res_norm = -RMAT_ELMT(ahrs_impl.ltp_to_imu_rmat, 0,0)*me + RMAT_ELMT(ahrs_impl.ltp_to_imu_rmat, 1,0)*mn; + const float res_norm = -RMAT_ELMT(ahrs_impl.ltp_to_imu_rmat, 0,0) * me + + RMAT_ELMT(ahrs_impl.ltp_to_imu_rmat, 1,0) * mn; const struct FloatVect3 r2 = {RMAT_ELMT(ahrs_impl.ltp_to_imu_rmat, 2,0), RMAT_ELMT(ahrs_impl.ltp_to_imu_rmat, 2,1), RMAT_ELMT(ahrs_impl.ltp_to_imu_rmat, 2,2)}; @@ -491,5 +584,3 @@ static inline void compute_body_orientation_and_rates(void) { FLOAT_RMAT_TRANSP_RATEMULT(body_rate, ahrs_impl.body_to_imu_rmat, ahrs_impl.imu_rate); stateSetBodyRates_f(&body_rate); } - - diff --git a/sw/airborne/subsystems/ahrs/ahrs_float_cmpl.h b/sw/airborne/subsystems/ahrs/ahrs_float_cmpl.h index b14831fa3e..a3b83ba6b7 100644 --- a/sw/airborne/subsystems/ahrs/ahrs_float_cmpl.h +++ b/sw/airborne/subsystems/ahrs/ahrs_float_cmpl.h @@ -38,10 +38,21 @@ struct AhrsFloatCmpl { struct FloatRates imu_rate; struct FloatQuat ltp_to_imu_quat; struct FloatRMat ltp_to_imu_rmat; - /* for gravity correction during coordinated turns */ - float ltp_vel_norm; + + bool_t correct_gravity; ///< enable gravity correction during coordinated turns + float ltp_vel_norm; ///< velocity norm for gravity correction during coordinated turns bool_t ltp_vel_norm_valid; - bool_t correct_gravity; + + float accel_omega; ///< filter cut-off frequency for correcting the attitude from accels (pseudo-gravity measurement) + float accel_zeta; ///< filter damping for correcting the gyro-bias from accels (pseudo-gravity measurement) + float mag_omega; ///< filter cut-off frequency for correcting the attitude (heading) from magnetometer + float mag_zeta; ///< filter damping for correcting the gyro bias from magnetometer + + /** sets how strongly the gravity heuristic reduces accel correction. + * Set to zero in order to disable gravity heuristic. + */ + uint8_t gravity_heuristic_factor; + float weight; bool_t heading_aligned; struct FloatVect3 mag_h; diff --git a/sw/airborne/subsystems/ahrs/ahrs_int_cmpl_quat.c b/sw/airborne/subsystems/ahrs/ahrs_int_cmpl_quat.c index 7eafe7ebc8..5105c12b33 100644 --- a/sw/airborne/subsystems/ahrs/ahrs_int_cmpl_quat.c +++ b/sw/airborne/subsystems/ahrs/ahrs_int_cmpl_quat.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2012 The Paparazzi Team + * Copyright (C) 2008-2013 The Paparazzi Team * * This file is part of paparazzi. * @@ -28,6 +28,8 @@ * */ +#include "generated/airframe.h" + #include "subsystems/ahrs/ahrs_int_cmpl_quat.h" #include "subsystems/ahrs/ahrs_aligner.h" #include "subsystems/ahrs/ahrs_int_utils.h" @@ -41,26 +43,61 @@ #include "math/pprz_trig_int.h" #include "math/pprz_algebra_int.h" -#include "generated/airframe.h" - -//#include "../../test/pprz_algebra_print.h" - -static inline void ahrs_update_mag_full(void); -static inline void ahrs_update_mag_2d(void); +#ifdef AHRS_PROPAGATE_LOW_PASS_RATES +PRINT_CONFIG_MSG("LOW PASS FILTER ON GYRO RATES") +#endif #ifdef AHRS_MAG_UPDATE_YAW_ONLY -#warning "AHRS_MAG_UPDATE_YAW_ONLY is deprecated, please remove it. This is the default behaviour. Define AHRS_MAG_UPDATE_ALL_AXES to use mag for all axes and not only yaw." +#error "The define AHRS_MAG_UPDATE_YAW_ONLY doesn't exist anymore, please remove it. This is the default behaviour. Define AHRS_MAG_UPDATE_ALL_AXES to use mag for all axes and not only yaw." #endif #if USE_MAGNETOMETER && AHRS_USE_GPS_HEADING -#warning "Using magnetometer and GPS course to update heading. Probably better to set USE_MAGNETOMETER=0 if you want to use GPS course." +#warning "Using both magnetometer and GPS course to update heading. Probably better to set USE_MAGNETOMETER=0 if you want to use GPS course." #endif + #ifndef AHRS_PROPAGATE_FREQUENCY #define AHRS_PROPAGATE_FREQUENCY PERIODIC_FREQUENCY #endif +PRINT_CONFIG_VAR(AHRS_PROPAGATE_FREQUENCY) + +#ifndef AHRS_CORRECT_FREQUENCY +#define AHRS_CORRECT_FREQUENCY AHRS_PROPAGATE_FREQUENCY +#endif +PRINT_CONFIG_VAR(AHRS_CORRECT_FREQUENCY) + +#ifndef AHRS_MAG_CORRECT_FREQUENCY +#define AHRS_MAG_CORRECT_FREQUENCY 50 +#endif +PRINT_CONFIG_VAR(AHRS_MAG_CORRECT_FREQUENCY) + +/* + * default gains for correcting attitude and bias from accel/mag + */ +#ifndef AHRS_ACCEL_OMEGA +#define AHRS_ACCEL_OMEGA 0.063 +#endif +#ifndef AHRS_ACCEL_ZETA +#define AHRS_ACCEL_ZETA 0.9 +#endif +PRINT_CONFIG_VAR(AHRS_ACCEL_OMEGA) +PRINT_CONFIG_VAR(AHRS_ACCEL_ZETA) + + +#ifndef AHRS_MAG_OMEGA +#define AHRS_MAG_OMEGA 0.04 +#endif +#ifndef AHRS_MAG_ZETA +#define AHRS_MAG_ZETA 0.9 +#endif +PRINT_CONFIG_VAR(AHRS_MAG_OMEGA) +PRINT_CONFIG_VAR(AHRS_MAG_ZETA) + +/** by default use the gravity heuristic to reduce gain */ +#ifndef AHRS_GRAVITY_HEURISTIC_FACTOR +#define AHRS_GRAVITY_HEURISTIC_FACTOR 30 +#endif -struct AhrsIntCmpl ahrs_impl; #ifdef AHRS_UPDATE_FW_ESTIMATOR // remotely settable @@ -74,7 +111,11 @@ float ins_roll_neutral = INS_ROLL_NEUTRAL_DEFAULT; float ins_pitch_neutral = INS_PITCH_NEUTRAL_DEFAULT; #endif +struct AhrsIntCmplQuat ahrs_impl; + static inline void set_body_state_from_quat(void); +static inline void ahrs_update_mag_full(void); +static inline void ahrs_update_mag_2d(void); #if DOWNLINK #include "subsystems/datalink/telemetry.h" @@ -125,19 +166,25 @@ void ahrs_init(void) { INT_RATES_ZERO(ahrs_impl.rate_correction); INT_RATES_ZERO(ahrs_impl.high_rez_bias); + /* set default filter cut-off frequency and damping */ + ahrs_impl.accel_omega = AHRS_ACCEL_OMEGA; + ahrs_impl.accel_zeta = AHRS_ACCEL_ZETA; + ahrs_set_accel_gains(); + ahrs_impl.mag_omega = AHRS_MAG_OMEGA; + ahrs_impl.mag_zeta = AHRS_MAG_ZETA; + ahrs_set_mag_gains(); + + /* set default gravity heuristic */ + ahrs_impl.gravity_heuristic_factor = AHRS_GRAVITY_HEURISTIC_FACTOR; + #if AHRS_GRAVITY_UPDATE_COORDINATED_TURN ahrs_impl.correct_gravity = TRUE; #else ahrs_impl.correct_gravity = FALSE; #endif -#if AHRS_GRAVITY_UPDATE_NORM_HEURISTIC - ahrs_impl.use_gravity_heuristic = TRUE; -#else - ahrs_impl.use_gravity_heuristic = FALSE; -#endif - - VECT3_ASSIGN(ahrs_impl.mag_h, MAG_BFP_OF_REAL(AHRS_H_X), MAG_BFP_OF_REAL(AHRS_H_Y), MAG_BFP_OF_REAL(AHRS_H_Z)); + VECT3_ASSIGN(ahrs_impl.mag_h, MAG_BFP_OF_REAL(AHRS_H_X), + MAG_BFP_OF_REAL(AHRS_H_Y), MAG_BFP_OF_REAL(AHRS_H_Z)); #if DOWNLINK register_periodic_telemetry(DefaultPeriodic, "AHRS_QUAT_INT", send_quat); @@ -147,11 +194,13 @@ void ahrs_init(void) { } + void ahrs_align(void) { #if USE_MAGNETOMETER /* Compute an initial orientation from accel and mag directly as quaternion */ - ahrs_int_get_quat_from_accel_mag(&ahrs_impl.ltp_to_imu_quat, &ahrs_aligner.lp_accel, &ahrs_aligner.lp_mag); + ahrs_int_get_quat_from_accel_mag(&ahrs_impl.ltp_to_imu_quat, + &ahrs_aligner.lp_accel, &ahrs_aligner.lp_mag); ahrs_impl.heading_aligned = TRUE; #else /* Compute an initial orientation from accel and just set heading to zero */ @@ -162,20 +211,14 @@ void ahrs_align(void) { set_body_state_from_quat(); /* Use low passed gyro value as initial bias */ - RATES_COPY( ahrs_impl.gyro_bias, ahrs_aligner.lp_gyro); - RATES_COPY( ahrs_impl.high_rez_bias, ahrs_aligner.lp_gyro); + RATES_COPY(ahrs_impl.gyro_bias, ahrs_aligner.lp_gyro); + RATES_COPY(ahrs_impl.high_rez_bias, ahrs_aligner.lp_gyro); INT_RATES_LSHIFT(ahrs_impl.high_rez_bias, ahrs_impl.high_rez_bias, 28); ahrs.status = AHRS_RUNNING; } - -/* - * - * - * - */ void ahrs_propagate(void) { /* unbias gyro */ @@ -191,13 +234,14 @@ void ahrs_propagate(void) { RATES_COPY(ahrs_impl.imu_rate, omega); #endif - /* add correction */ + /* add correction */ RATES_ADD(omega, ahrs_impl.rate_correction); /* and zeros it */ INT_RATES_ZERO(ahrs_impl.rate_correction); /* integrate quaternion */ - INT32_QUAT_INTEGRATE_FI(ahrs_impl.ltp_to_imu_quat, ahrs_impl.high_rez_quat, omega, AHRS_PROPAGATE_FREQUENCY); + INT32_QUAT_INTEGRATE_FI(ahrs_impl.ltp_to_imu_quat, ahrs_impl.high_rez_quat, + omega, AHRS_PROPAGATE_FREQUENCY); INT32_QUAT_NORMALIZE(ahrs_impl.ltp_to_imu_quat); set_body_state_from_quat(); @@ -205,7 +249,27 @@ void ahrs_propagate(void) { } +void ahrs_set_accel_gains(void) { + /* Complementary filter proportionnal gain + * Kp = 2 * omega * zeta * AHRS_PROPAGATE_FREQUENCY / AHRS_CORRECT_FREQUENCY + * + * accel_inv_kp = 1 / (Kp * FRAC_conversion / cross_product_gain) + * accel_inv_kp = 4096 * 9.81 / Kp + */ + ahrs_impl.accel_inv_kp = 4096 * 9.81 / + (2 * ahrs_impl.accel_omega * ahrs_impl.accel_zeta * + AHRS_PROPAGATE_FREQUENCY / AHRS_PROPAGATE_FREQUENCY); + /* Complementary filter integral gain + * Ki = omega^2 / AHRS_CORRECT_FREQUENCY + * + * accel_inv_ki = 2^5 / (Ki * FRAC_conversion / cross_product_gain) + * accel_inv_ki = 2^5 / 2^16 * 9.81 / Ki + * accel_inv_ki = 9.81 / 2048 / Ki + */ + ahrs_impl.accel_inv_ki = AHRS_CORRECT_FREQUENCY * 9.81 / 2048 / + (ahrs_impl.accel_omega * ahrs_impl.accel_omega); +} void ahrs_update_accel(void) { @@ -230,17 +294,20 @@ void ahrs_update_accel(void) { // FIXME: check overflows ! #define COMPUTATION_FRAC 16 +#define ACC_FROM_CROSS_FRAC INT32_RATE_FRAC + INT32_SPEED_FRAC - INT32_ACCEL_FRAC - COMPUTATION_FRAC - const struct Int32Vect3 vel_tangential_body = {ahrs_impl.ltp_vel_norm >> COMPUTATION_FRAC, 0, 0}; + const struct Int32Vect3 vel_tangential_body = + {ahrs_impl.ltp_vel_norm >> COMPUTATION_FRAC, 0, 0}; struct Int32Vect3 acc_c_body; VECT3_RATES_CROSS_VECT3(acc_c_body, (*stateGetBodyRates_i()), vel_tangential_body); - INT32_VECT3_RSHIFT(acc_c_body, acc_c_body, INT32_SPEED_FRAC+INT32_RATE_FRAC-INT32_ACCEL_FRAC-COMPUTATION_FRAC); + INT32_VECT3_RSHIFT(acc_c_body, acc_c_body, ACC_FROM_CROSS_FRAC); /* convert centrifucal acceleration from body to imu frame */ struct Int32Vect3 acc_c_imu; INT32_RMAT_VMULT(acc_c_imu, imu.body_to_imu_rmat, acc_c_body); - /* and subtract it from imu measurement to get a corrected measurement of the gravitiy vector */ + /* and subtract it from imu measurement to get a corrected measurement + * of the gravity vector */ INT32_VECT3_DIFF(pseudo_gravity_measurement, imu.accel, acc_c_imu); } else { VECT3_COPY(pseudo_gravity_measurement, imu.accel); @@ -250,50 +317,81 @@ void ahrs_update_accel(void) { INT32_VECT3_CROSS_PRODUCT(residual, pseudo_gravity_measurement, c2); - int32_t inv_weight; - if (ahrs_impl.use_gravity_heuristic) { - /* heuristic on acceleration norm */ + /* FIR filtered pseudo_gravity_measurement */ + #define FIR_FILTER_SIZE 8 + static struct Int32Vect3 filtered_gravity_measurement = {0, 0, 0}; + VECT3_SMUL(filtered_gravity_measurement, filtered_gravity_measurement, FIR_FILTER_SIZE-1); + VECT3_ADD(filtered_gravity_measurement, pseudo_gravity_measurement); + VECT3_SDIV(filtered_gravity_measurement, filtered_gravity_measurement, FIR_FILTER_SIZE); - /* FIR filtered pseudo_gravity_measurement */ - static struct Int32Vect3 filtered_gravity_measurement = {0, 0, 0}; - VECT3_SMUL(filtered_gravity_measurement, filtered_gravity_measurement, 7); - VECT3_ADD(filtered_gravity_measurement, pseudo_gravity_measurement); - VECT3_SDIV(filtered_gravity_measurement, filtered_gravity_measurement, 8); - int32_t acc_norm; - INT32_VECT3_NORM(acc_norm, filtered_gravity_measurement); - const int32_t acc_norm_d = ABS(ACCEL_BFP_OF_REAL(9.81)-acc_norm); - inv_weight = Chop(50*acc_norm_d/ACCEL_BFP_OF_REAL(9.81), 1, 50); + if (ahrs_impl.gravity_heuristic_factor) { + /* heuristic on acceleration (gravity estimate) norm */ + /* Factor how strongly to change the weight. + * e.g. for gravity_heuristic_factor 30: + * <0.66G = 0, 1G = 1.0, >1.33G = 0 + */ + + struct FloatVect3 g_meas_f; + ACCELS_FLOAT_OF_BFP(g_meas_f, filtered_gravity_measurement); + const float g_meas_norm = FLOAT_VECT3_NORM(g_meas_f)/9.81; + ahrs_impl.weight = 1.0 - ahrs_impl.gravity_heuristic_factor * fabs(1.0 - g_meas_norm) / 10; + Bound(ahrs_impl.weight, 0.15, 1.0); } else { - inv_weight = 1; + ahrs_impl.weight = 1.0; } - // residual FRAC : ACCEL_FRAC + TRIG_FRAC = 10 + 14 = 24 - // rate_correction FRAC = RATE_FRAC = 12 - // 2^12 / 2^24 * 5e-2 = 1/81920 - ahrs_impl.rate_correction.p += -residual.x/82000/inv_weight; - ahrs_impl.rate_correction.q += -residual.y/82000/inv_weight; - ahrs_impl.rate_correction.r += -residual.z/82000/inv_weight; + /* Complementary filter proportional gain. + * Kp = 2 * zeta * omega * AHRS_PROPAGATE_FREQUENCY / AHRS_CORRECT_FREQUENCY + * + * residual FRAC : ACCEL_FRAC + TRIG_FRAC = 10 + 14 = 24 + * rate_correction FRAC: RATE_FRAC = 12 + * FRAC_conversion: 2^12 / 2^24 = 1 / 4096 + * cross_product_gain : 9.81 m/s2 + * + * accel_inv_kp = 1 / (Kp * FRAC_conversion / cross_product_gain) + * accel_inv_kp = 4096 * 9.81 / Kp + * + * inv_rate_scale = 1 / (weight * Kp * FRAC_conversion / cross_product_gain) + * inv_rate_scale = inv_kp / weight + */ + int32_t inv_rate_scale = (int32_t)(ahrs_impl.accel_inv_kp / ahrs_impl.weight); + Bound(inv_rate_scale, 8192, 4194304); - // residual FRAC = ACCEL_FRAC + TRIG_FRAC = 10 + 14 = 24 - // high_rez_bias = RATE_FRAC+28 = 40 - // 2^40 / 2^24 * 5e-6 = 1/3.05 - - // ahrs_impl.high_rez_bias.p += residual.x*3; - // ahrs_impl.high_rez_bias.q += residual.y*3; - // ahrs_impl.high_rez_bias.r += residual.z*3; - - ahrs_impl.high_rez_bias.p += residual.x/(2*inv_weight); - ahrs_impl.high_rez_bias.q += residual.y/(2*inv_weight); - ahrs_impl.high_rez_bias.r += residual.z/(2*inv_weight); + ahrs_impl.rate_correction.p -= residual.x / inv_rate_scale; + ahrs_impl.rate_correction.q -= residual.y / inv_rate_scale; + ahrs_impl.rate_correction.r -= residual.z / inv_rate_scale; - /* */ + /* Complementary filter integral gain + * Correct the gyro bias. + * Ki = omega^2 / AHRS_CORRECT_FREQUENCY + * + * residual FRAC = ACCEL_FRAC + TRIG_FRAC = 10 + 14 = 24 + * high_rez_bias = RATE_FRAC+28 = 40 + * FRAC_conversion: 2^40 / 2^24 = 2^16 + * cross_product_gain : 9.81 m/s2 + * + * accel_inv_ki = 2^5 / (Ki * FRAC_conversion / cross_product_gain) + * accel_inv_ki = 2^5 / 2^16 * 9.81 * Ki = 9.81 / 2^11 * Ki + * + * inv_bias_gain = 2^5 / (weight^2 * Ki * FRAC_conversion / cross_product_gain) + * inv_bias_gain = accel_inv_ki / weight^2 + */ + + int32_t inv_bias_gain = (int32_t)(ahrs_impl.accel_inv_ki / + (ahrs_impl.weight * ahrs_impl.weight)); + Bound(inv_bias_gain, 8, 65536) + ahrs_impl.high_rez_bias.p += (residual.x / inv_bias_gain) << 5; + ahrs_impl.high_rez_bias.q += (residual.y / inv_bias_gain) << 5; + ahrs_impl.high_rez_bias.r += (residual.z / inv_bias_gain) << 5; + INT_RATES_RSHIFT(ahrs_impl.gyro_bias, ahrs_impl.high_rez_bias, 28); } + void ahrs_update_mag(void) { #if AHRS_MAG_UPDATE_ALL_AXES ahrs_update_mag_full(); @@ -302,6 +400,15 @@ void ahrs_update_mag(void) { #endif } +void ahrs_set_mag_gains(void) { + /* Complementary filter proportionnal gain = 2*omega*zeta */ + ahrs_impl.mag_kp = 2 * ahrs_impl.mag_zeta * ahrs_impl.mag_omega * + AHRS_PROPAGATE_FREQUENCY / AHRS_MAG_CORRECT_FREQUENCY; + /* Complementary filter integral gain = omega^2 */ + ahrs_impl.mag_ki = ahrs_impl.mag_omega * ahrs_impl.mag_omega / + AHRS_MAG_CORRECT_FREQUENCY; +} + static inline void ahrs_update_mag_full(void) { @@ -314,14 +421,38 @@ static inline void ahrs_update_mag_full(void) { struct Int32Vect3 residual; INT32_VECT3_CROSS_PRODUCT(residual, imu.mag, expected_imu); - ahrs_impl.rate_correction.p += residual.x/32/16; - ahrs_impl.rate_correction.q += residual.y/32/16; - ahrs_impl.rate_correction.r += residual.z/32/16; + /* Complementary filter proportionnal gain. + * Kp = 2 * mag_zeta * mag_omega * AHRS_PROPAGATE_FREQUENCY / AHRS_MAG_CORRECT_FREQUENCY + * + * residual FRAC: 2 * MAG_FRAC = 22 + * rate_correction FRAC: RATE_FRAC = 12 + * FRAC conversion: 2^12 / 2^22 = 1/1024 + * + * inv_rate_gain = 1 / Kp / FRAC_conversion + * inv_rate_gain = 1024 / Kp + */ + const int32_t inv_rate_gain = (int32_t)(1024.0 / ahrs_impl.mag_kp); - ahrs_impl.high_rez_bias.p -= residual.x/32*1024; - ahrs_impl.high_rez_bias.q -= residual.y/32*1024; - ahrs_impl.high_rez_bias.r -= residual.z/32*1024; + ahrs_impl.rate_correction.p += residual.x / inv_rate_gain; + ahrs_impl.rate_correction.q += residual.y / inv_rate_gain; + ahrs_impl.rate_correction.r += residual.z / inv_rate_gain; + + /* Complementary filter integral gain + * Correct the gyro bias. + * Ki = omega^2 / AHRS_MAG_CORRECT_FREQUENCY + * + * residual FRAC: 2* MAG_FRAC = 22 + * high_rez_bias FRAC: RATE_FRAC+28 = 40 + * FRAC conversion: 2^40 / 2^22 = 2^18 + * + * bias_gain = Ki * FRAC_conversion = Ki * 2^18 + */ + const int32_t bias_gain = (int32_t)(ahrs_impl.mag_ki * (1<<18)); + + ahrs_impl.high_rez_bias.p -= residual.x * bias_gain; + ahrs_impl.high_rez_bias.q -= residual.y * bias_gain; + ahrs_impl.high_rez_bias.r -= residual.z * bias_gain; INT_RATES_RSHIFT(ahrs_impl.gyro_bias, ahrs_impl.high_rez_bias, 28); @@ -331,45 +462,61 @@ static inline void ahrs_update_mag_full(void) { static inline void ahrs_update_mag_2d(void) { + struct Int32Vect2 expected_ltp = {ahrs_impl.mag_h.x, ahrs_impl.mag_h.y}; + /* normalize expected ltp in 2D (x,y) */ + INT32_VECT2_NORMALIZE(expected_ltp, INT32_MAG_FRAC); + struct Int32RMat ltp_to_imu_rmat; INT32_RMAT_OF_QUAT(ltp_to_imu_rmat, ahrs_impl.ltp_to_imu_quat); struct Int32Vect3 measured_ltp; INT32_RMAT_TRANSP_VMULT(measured_ltp, ltp_to_imu_rmat, imu.mag); + /* normalize measured ltp in 2D (x,y) */ + struct Int32Vect2 measured_ltp_2d = {measured_ltp.x, measured_ltp.y}; + INT32_VECT2_NORMALIZE(measured_ltp_2d, INT32_MAG_FRAC); + + /* residual_ltp FRAC: 2 * MAG_FRAC - 5 = 17 */ struct Int32Vect3 residual_ltp = { 0, 0, - (measured_ltp.x * ahrs_impl.mag_h.y - measured_ltp.y * ahrs_impl.mag_h.x)/(1<<5)}; + (measured_ltp_2d.x * expected_ltp.y - measured_ltp_2d.y * expected_ltp.x)/(1<<5)}; + struct Int32Vect3 residual_imu; INT32_RMAT_VMULT(residual_imu, ltp_to_imu_rmat, residual_ltp); - // residual_ltp FRAC = 2 * MAG_FRAC = 22 - // rate_correction FRAC = RATE_FRAC = 12 - // 2^12 / 2^22 * 2.5 = 1/410 + /* Complementary filter proportionnal gain. + * Kp = 2 * mag_zeta * mag_omega * AHRS_PROPAGATE_FREQUENCY / AHRS_MAG_CORRECT_FREQUENCY + * + * residual_imu FRAC = residual_ltp FRAC = 17 + * rate_correction FRAC: RATE_FRAC = 12 + * FRAC conversion: 2^12 / 2^17 = 1/32 + * + * inv_rate_gain = 1 / Kp / FRAC_conversion + * inv_rate_gain = 32 / Kp + */ + int32_t inv_rate_gain = (int32_t)(32.0 / ahrs_impl.mag_kp); - // ahrs_impl.rate_correction.p += residual_imu.x*(1<<5)/410; - // ahrs_impl.rate_correction.q += residual_imu.y*(1<<5)/410; - // ahrs_impl.rate_correction.r += residual_imu.z*(1<<5)/410; + ahrs_impl.rate_correction.p += (residual_imu.x / inv_rate_gain); + ahrs_impl.rate_correction.q += (residual_imu.y / inv_rate_gain); + ahrs_impl.rate_correction.r += (residual_imu.z / inv_rate_gain); - ahrs_impl.rate_correction.p += residual_imu.x/16; - ahrs_impl.rate_correction.q += residual_imu.y/16; - ahrs_impl.rate_correction.r += residual_imu.z/16; - - - // residual_ltp FRAC = 2 * MAG_FRAC = 22 - // high_rez_bias = RATE_FRAC+28 = 40 - // 2^40 / 2^22 * 2.5e-3 = 655 - - // ahrs_impl.high_rez_bias.p -= residual_imu.x*(1<<5)*655; - // ahrs_impl.high_rez_bias.q -= residual_imu.y*(1<<5)*655; - // ahrs_impl.high_rez_bias.r -= residual_imu.z*(1<<5)*655; - - ahrs_impl.high_rez_bias.p -= residual_imu.x*1024; - ahrs_impl.high_rez_bias.q -= residual_imu.y*1024; - ahrs_impl.high_rez_bias.r -= residual_imu.z*1024; + /* Complementary filter integral gain + * Correct the gyro bias. + * Ki = omega^2 / AHRS_MAG_CORRECT_FREQUENCY + * + * residual_imu FRAC = residual_ltp FRAC = 17 + * high_rez_bias FRAC: RATE_FRAC+28 = 40 + * FRAC conversion: 2^40 / 2^17 = 2^23 + * + * bias_gain = Ki * FRAC_conversion = Ki * 2^23 + */ + int32_t bias_gain = (int32_t)(ahrs_impl.mag_ki * (1 << 23)); + ahrs_impl.high_rez_bias.p -= (residual_imu.x * bias_gain); + ahrs_impl.high_rez_bias.q -= (residual_imu.y * bias_gain); + ahrs_impl.high_rez_bias.r -= (residual_imu.z * bias_gain); INT_RATES_RSHIFT(ahrs_impl.gyro_bias, ahrs_impl.high_rez_bias, 28); @@ -502,7 +649,7 @@ void ahrs_realign_heading(int32_t heading) { /* Rotate angles and rates from imu to body frame and set state */ -__attribute__ ((always_inline)) static inline void set_body_state_from_quat(void) { +static inline void set_body_state_from_quat(void) { /* Compute LTP to BODY quaternion */ struct Int32Quat ltp_to_body_quat; INT32_QUAT_COMP_INV(ltp_to_body_quat, ahrs_impl.ltp_to_imu_quat, imu.body_to_imu_quat); @@ -527,5 +674,3 @@ __attribute__ ((always_inline)) static inline void set_body_state_from_quat(void /* Set state */ stateSetBodyRates_i(&body_rate); } - - diff --git a/sw/airborne/subsystems/ahrs/ahrs_int_cmpl_quat.h b/sw/airborne/subsystems/ahrs/ahrs_int_cmpl_quat.h index b5e2ac3df3..e7c5fbce6d 100644 --- a/sw/airborne/subsystems/ahrs/ahrs_int_cmpl_quat.h +++ b/sw/airborne/subsystems/ahrs/ahrs_int_cmpl_quat.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 The Paparazzi Team + * Copyright (C) 2008-2013 The Paparazzi Team * * This file is part of paparazzi. * @@ -28,29 +28,67 @@ * */ -#ifndef AHRS_INT_CMPL_H -#define AHRS_INT_CMPL_H +#ifndef AHRS_INT_CMPL_QUAT_H +#define AHRS_INT_CMPL_QUAT_H #include "subsystems/ahrs.h" #include "std.h" #include "math/pprz_algebra_int.h" -struct AhrsIntCmpl { +/** + * Ahrs implementation specifc values + */ +struct AhrsIntCmplQuat { struct Int32Rates gyro_bias; struct Int32Rates imu_rate; struct Int32Rates rate_correction; struct Int64Quat high_rez_quat; struct Int64Rates high_rez_bias; struct Int32Quat ltp_to_imu_quat; - struct Int32Vect3 mag_h; + struct Int32Vect3 mag_h; + int32_t ltp_vel_norm; bool_t ltp_vel_norm_valid; - bool_t correct_gravity; - bool_t use_gravity_heuristic; bool_t heading_aligned; + float weight; + float accel_inv_kp; + float accel_inv_ki; + float mag_kp; + float mag_ki; + + /* parameters/options that can be changed */ + /** enable gravity vector correction by removing centrifugal acceleration */ + bool_t correct_gravity; + + /** sets how strongly the gravity heuristic reduces accel correction. + * Set to zero in order to disable gravity heuristic. + */ + uint8_t gravity_heuristic_factor; + + /** filter cut-off frequency for correcting the attitude from accels. + * (pseudo-gravity measurement) + * only update through #ahrs_int_cmpl_quat_SetAccelOmega(omega) + */ + float accel_omega; + + /** filter damping for correcting the gyro-bias from accels. + * (pseudo-gravity measurement) + * only update through #ahrs_int_cmpl_quat_SetAccelZeta(zeta) + */ + float accel_zeta; + + /** filter cut-off frequency for correcting the attitude (heading) from magnetometer. + * only update through #ahrs_int_cmpl_quat_SetMagOmega(omega) + */ + float mag_omega; + + /** filter damping for correcting the gyro bias from magnetometer. + * only update through #ahrs_int_cmpl_quat_SetMagZeta(zeta) + */ + float mag_zeta; }; -extern struct AhrsIntCmpl ahrs_impl; +extern struct AhrsIntCmplQuat ahrs_impl; /** Update yaw based on a heading measurement. @@ -66,10 +104,37 @@ void ahrs_update_heading(int32_t heading); */ void ahrs_realign_heading(int32_t heading); + +/// update pre-computed inv_kp and inv_ki gains from acc_omega and acc_zeta +extern void ahrs_set_accel_gains(void); + +static inline void ahrs_int_cmpl_quat_SetAccelOmega(float omega) { + ahrs_impl.accel_omega = omega; + ahrs_set_accel_gains(); +} + +static inline void ahrs_int_cmpl_quat_SetAccelZeta(float zeta) { + ahrs_impl.accel_zeta = zeta; + ahrs_set_accel_gains(); +} + +/// update pre-computed kp and ki gains from mag_omega and mag_zeta +extern void ahrs_set_mag_gains(void); + +static inline void ahrs_int_cmpl_quat_SetMagOmega(float omega) { + ahrs_impl.mag_omega = omega; + ahrs_set_mag_gains(); +} + +static inline void ahrs_int_cmpl_quat_SetMagZeta(float zeta) { + ahrs_impl.mag_zeta = zeta; + ahrs_set_mag_gains(); +} + + #ifdef AHRS_UPDATE_FW_ESTIMATOR extern float ins_roll_neutral; extern float ins_pitch_neutral; #endif - -#endif /* AHRS_INT_CMPL_H */ +#endif /* AHRS_INT_CMPL_QUAT_H */ diff --git a/sw/airborne/subsystems/air_data.c b/sw/airborne/subsystems/air_data.c new file mode 100644 index 0000000000..e7cd6b068f --- /dev/null +++ b/sw/airborne/subsystems/air_data.c @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2013 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. + */ + +/** + * @file subsystems/air_data.c + * Air Data interface + * - pressures + * - airspeed + * - angle of attack and sideslip + * - wind + */ + +#include "subsystems/air_data.h" +#include "subsystems/abi.h" + +/** global AirData state + */ +struct AirData air_data; + +/** ABI bindings + */ +#ifndef AIR_DATA_BARO_ABS_ID +#define AIR_DATA_BARO_ABS_ID ABI_BROADCAST +#endif +static abi_event pressure_abs_ev; + +static void pressure_abs_cb(uint8_t __attribute__((unused)) sender_id, const float * pressure) { + air_data.pressure = *pressure; +} + +/** AirData initialization. Called at startup. + * Bind ABI messages + */ +void air_data_init( void ) { + AbiBindMsgBARO_ABS(AIR_DATA_BARO_ABS_ID, &pressure_abs_ev, pressure_abs_cb); +} + diff --git a/sw/airborne/subsystems/air_data.h b/sw/airborne/subsystems/air_data.h new file mode 100644 index 0000000000..b4963c4832 --- /dev/null +++ b/sw/airborne/subsystems/air_data.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2013 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. + */ + +/** + * @file subsystems/air_data.h + * Air Data interface + * - pressures + * - airspeed + * - angle of attack and sideslip + * - wind + */ + +#ifndef AIR_DATA_H +#define AIR_DATA_H + +#include "std.h" + +/** Air Data strucute */ +struct AirData { + float pressure; ///< Static atmospheric pressure (Pa) + float differential; ///< Differential pressure (dynamic - static pressure) (Pa) + float airspeed; ///< Conventional Air Speed (m/s) + float aoa; ///< angle of attack (rad) + float sideslip; ///< sideslip angle (rad) + float wind_speed; ///< wind speed (m/s) + float wind_dir; ///< wind direction (rad, 0 north, >0 clockwise) +}; + +/** global AirData state + */ +extern struct AirData air_data; + +/** AirData initialization. Called at startup. + */ +extern void air_data_init( void ); + +#endif /* AIR_DATA_H */ + diff --git a/sw/airborne/subsystems/ins/hf_float.c b/sw/airborne/subsystems/ins/hf_float.c index 1fa57f3d44..7beb16e0d8 100644 --- a/sw/airborne/subsystems/ins/hf_float.c +++ b/sw/airborne/subsystems/ins/hf_float.c @@ -28,7 +28,6 @@ */ #include "subsystems/ins/hf_float.h" -#include "subsystems/ins.h" #include "subsystems/imu.h" #include "state.h" #include "subsystems/gps.h" @@ -501,14 +500,6 @@ void b2_hff_propagate(void) { b2_hff_propagate_x(&b2_hff_state); b2_hff_propagate_y(&b2_hff_state); - /* update ins state from horizontal filter */ - ins_ltp_accel.x = ACCEL_BFP_OF_REAL(b2_hff_state.xdotdot); - ins_ltp_accel.y = ACCEL_BFP_OF_REAL(b2_hff_state.ydotdot); - ins_ltp_speed.x = SPEED_BFP_OF_REAL(b2_hff_state.xdot); - ins_ltp_speed.y = SPEED_BFP_OF_REAL(b2_hff_state.ydot); - ins_ltp_pos.x = POS_BFP_OF_REAL(b2_hff_state.x); - ins_ltp_pos.y = POS_BFP_OF_REAL(b2_hff_state.y); - #ifdef GPS_LAG /* increase lag counter on last saved state */ if (b2_hff_rb_n > 0) @@ -532,7 +523,7 @@ void b2_hff_propagate(void) { -void b2_hff_update_gps(void) { +void b2_hff_update_gps(struct FloatVect2* pos_ned, struct FloatVect2* speed_ned) { b2_hff_lost_counter = 0; #if USE_GPS_ACC4R @@ -550,20 +541,13 @@ void b2_hff_update_gps(void) { #endif /* update filter state with measurement */ - b2_hff_update_x(&b2_hff_state, ins_gps_pos_m_ned.x, Rgps_pos); - b2_hff_update_y(&b2_hff_state, ins_gps_pos_m_ned.y, Rgps_pos); + b2_hff_update_x(&b2_hff_state, pos_ned->x, Rgps_pos); + b2_hff_update_y(&b2_hff_state, pos_ned->y, Rgps_pos); #ifdef HFF_UPDATE_SPEED - b2_hff_update_xdot(&b2_hff_state, ins_gps_speed_m_s_ned.x, Rgps_vel); - b2_hff_update_ydot(&b2_hff_state, ins_gps_speed_m_s_ned.y, Rgps_vel); + b2_hff_update_xdot(&b2_hff_state, speed_ned->x, Rgps_vel); + b2_hff_update_ydot(&b2_hff_state, speed_ned->y, Rgps_vel); #endif - /* update ins state */ - ins_ltp_accel.x = ACCEL_BFP_OF_REAL(b2_hff_state.xdotdot); - ins_ltp_accel.y = ACCEL_BFP_OF_REAL(b2_hff_state.ydotdot); - ins_ltp_speed.x = SPEED_BFP_OF_REAL(b2_hff_state.xdot); - ins_ltp_speed.y = SPEED_BFP_OF_REAL(b2_hff_state.ydot); - ins_ltp_pos.x = POS_BFP_OF_REAL(b2_hff_state.x); - ins_ltp_pos.y = POS_BFP_OF_REAL(b2_hff_state.y); #ifdef GPS_LAG } else if (b2_hff_rb_n > 0) { @@ -572,11 +556,11 @@ void b2_hff_update_gps(void) { PRINT_DBG(2, ("update. rb_n: %d lag_counter: %d lag_cnt_err: %d\n", b2_hff_rb_n, b2_hff_rb_last->lag_counter, lag_counter_err)); if (abs(lag_counter_err) <= GPS_LAG_TOL_N) { b2_hff_rb_last->rollback = TRUE; - b2_hff_update_x(b2_hff_rb_last, ins_gps_pos_m_ned.x, Rgps_pos); - b2_hff_update_y(b2_hff_rb_last, ins_gps_pos_m_ned.y, Rgps_pos); + b2_hff_update_x(b2_hff_rb_last, pos_ned->x, Rgps_pos); + b2_hff_update_y(b2_hff_rb_last, pos_ned->y, Rgps_pos); #ifdef HFF_UPDATE_SPEED - b2_hff_update_xdot(b2_hff_rb_last, ins_gps_speed_m_s_ned.x, Rgps_vel); - b2_hff_update_ydot(b2_hff_rb_last, ins_gps_speed_m_s_ned.y, Rgps_vel); + b2_hff_update_xdot(b2_hff_rb_last, speed_ned->x, Rgps_vel); + b2_hff_update_ydot(b2_hff_rb_last, speed_ned->y, Rgps_vel); #endif past_save_counter = GPS_DT_N-1;// + lag_counter_err; PRINT_DBG(2, ("gps updated. past_save_counter: %d\n", past_save_counter)); diff --git a/sw/airborne/subsystems/ins/hf_float.h b/sw/airborne/subsystems/ins/hf_float.h index 2d1c08dbc9..c53ddb6b8b 100644 --- a/sw/airborne/subsystems/ins/hf_float.h +++ b/sw/airborne/subsystems/ins/hf_float.h @@ -81,7 +81,7 @@ extern float b2_hff_ydd_meas; 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_gps(struct FloatVect2* pos_ned, struct FloatVect2* speed_ned); extern void b2_hff_update_pos(struct FloatVect2 pos, struct FloatVect2 Rpos); extern void b2_hff_update_vel(struct FloatVect2 vel, struct FloatVect2 Rvel); extern void b2_hff_realign(struct FloatVect2 pos, struct FloatVect2 vel); diff --git a/sw/airborne/subsystems/ins/ins_alt_float.c b/sw/airborne/subsystems/ins/ins_alt_float.c index e8727750c7..cf451b7e43 100644 --- a/sw/airborne/subsystems/ins/ins_alt_float.c +++ b/sw/airborne/subsystems/ins/ins_alt_float.c @@ -24,7 +24,9 @@ * Filters altitude and climb rate for fixedwings. */ -#include "subsystems/ins.h" +#include "subsystems/ins/ins_alt_float.h" + +#include "subsystems/abi.h" #include #include @@ -46,9 +48,18 @@ float ins_alt_dot; #if USE_BAROMETER #include "subsystems/sensors/baro.h" -int32_t ins_qfe; -bool_t ins_baro_initialised; +#include "math/pprz_isa.h" +float ins_qfe; +bool_t ins_baro_initialized; float ins_baro_alt; + +// Baro event on ABI +#ifndef INS_BARO_ID +#define INS_BARO_ID BARO_BOARD_SENDER_ID +#endif +abi_event baro_ev; +static void baro_cb(uint8_t sender_id, const float *pressure); + #endif void ins_init() { @@ -62,13 +73,16 @@ void ins_init() { #if USE_BAROMETER ins_qfe = 0;; - ins_baro_initialised = FALSE; + ins_baro_initialized = FALSE; ins_baro_alt = 0.; + // Bind to BARO_ABS message + AbiBindMsgBARO_ABS(INS_BARO_ID, &baro_ev, baro_cb); #endif ins.vf_realign = FALSE; EstimatorSetAlt(0.); + ins.status = INS_RUNNING; } void ins_periodic( void ) { @@ -83,36 +97,37 @@ void ins_realign_v(float z __attribute__ ((unused))) { void ins_propagate() { } -void ins_update_baro() { +void ins_update_baro() {} + #if USE_BAROMETER - // TODO update kalman filter with baro struct - if (baro.status == BS_RUNNING) { - if (!ins_baro_initialised) { - ins_qfe = baro.absolute; - ins_baro_initialised = TRUE; - } - if (ins.vf_realign) { - ins.vf_realign = FALSE; - ins_qfe = baro.absolute; - } - else { /* not realigning, so normal update with baro measurement */ - /* altitude decreases with increasing baro.absolute pressure */ - ins_baro_alt = ground_alt - (baro.absolute - ins_qfe) * INS_BARO_SENS; - /* run the filter */ - EstimatorSetAlt(ins_baro_alt); - /* set new altitude, just copy old horizontal position */ - struct UtmCoor_f utm; - UTM_COPY(utm, *stateGetPositionUtm_f()); - utm.alt = ins_alt; - stateSetPositionUtm_f(&utm); - struct NedCoor_f ned_vel; - memcpy(&ned_vel, stateGetSpeedNed_f(), sizeof(struct NedCoor_f)); - ned_vel.z = -ins_alt_dot; - stateSetSpeedNed_f(&ned_vel); - } +static void baro_cb(uint8_t __attribute__((unused)) sender_id, const float *pressure) { + if (!ins_baro_initialized) { + ins_qfe = *pressure; + ins_baro_initialized = TRUE; + } + if (ins.vf_realign) { + ins.vf_realign = FALSE; + ins_alt = ground_alt; + ins_alt_dot = 0.; + ins_qfe = *pressure; + alt_kalman_reset(); + } + else { /* not realigning, so normal update with baro measurement */ + ins_baro_alt = ground_alt + pprz_isa_height_of_pressure(*pressure, ins_qfe); + /* run the filter */ + EstimatorSetAlt(ins_baro_alt); + /* set new altitude, just copy old horizontal position */ + struct UtmCoor_f utm; + UTM_COPY(utm, *stateGetPositionUtm_f()); + utm.alt = ins_alt; + stateSetPositionUtm_f(&utm); + struct NedCoor_f ned_vel; + memcpy(&ned_vel, stateGetSpeedNed_f(), sizeof(struct NedCoor_f)); + ned_vel.z = -ins_alt_dot; + stateSetSpeedNed_f(&ned_vel); } -#endif } +#endif void ins_update_gps(void) { @@ -178,7 +193,11 @@ void alt_kalman(float z_meas) { float SIGMA2; #if USE_BAROMETER -#if USE_BARO_MS5534A +#ifdef SITL + DT = BARO_SIM_DT; + R = 0.5; + SIGMA2 = 0.1; +#elif USE_BARO_MS5534A if (alt_baro_enabled) { DT = BARO_DT; R = baro_MS5534A_r; diff --git a/sw/airborne/subsystems/ins/ins_alt_float.h b/sw/airborne/subsystems/ins/ins_alt_float.h index 613ebc5281..837ca01c35 100644 --- a/sw/airborne/subsystems/ins/ins_alt_float.h +++ b/sw/airborne/subsystems/ins/ins_alt_float.h @@ -56,9 +56,9 @@ #include "modules/sensors/baro_amsys.h" #endif -extern int32_t ins_qfe; -extern float ins_baro_alt; -extern bool_t ins_baro_initialised; +extern float ins_qfe; +extern float ins_baro_alt; +extern bool_t ins_baro_initialized; #endif //USE_BAROMETER extern float ins_alt; ///< estimated altitude above MSL in meters diff --git a/sw/airborne/subsystems/ins/ins_ardrone2.c b/sw/airborne/subsystems/ins/ins_ardrone2.c index a50f0ed908..cdce78e65d 100644 --- a/sw/airborne/subsystems/ins/ins_ardrone2.c +++ b/sw/airborne/subsystems/ins/ins_ardrone2.c @@ -41,53 +41,39 @@ PRINT_CONFIG_MSG("USE_INS_NAV_INIT defaulting to TRUE") #endif - -/* TODO: implement in state */ -int32_t ins_qfe; -int32_t ins_baro_alt; - -//Keep track of gps pos and the init pos -struct NedCoor_i ins_ltp_pos; -struct LtpDef_i ins_ltp_def; - -// Keep track of INS LTP accel and speed -struct NedCoor_f ins_ltp_accel; -struct NedCoor_f ins_ltp_speed; - -bool_t ins_ltp_initialised; +struct InsArdrone2 ins_impl; void ins_init() { #if USE_INS_NAV_INIT - struct LlaCoor_i llh_nav; + struct LlaCoor_i llh_nav0; /* Height above the ellipsoid */ + llh_nav0.lat = INT32_RAD_OF_DEG(NAV_LAT0); + llh_nav0.lon = INT32_RAD_OF_DEG(NAV_LON0); + /* NAV_ALT0 = ground alt above msl, NAV_MSL0 = geoid-height (msl) over ellipsoid */ + llh_nav0.alt = NAV_ALT0 + NAV_MSL0; - /** FIXME: should use the same code than MOVE_WP in firmwares/rotorcraft/datalink.c */ - llh_nav.lat = INT32_RAD_OF_DEG(NAV_LAT0); - llh_nav.lon = INT32_RAD_OF_DEG(NAV_LON0); - llh_nav.alt = NAV_ALT0 + NAV_MSL0; + struct EcefCoor_i ecef_nav0; + ecef_of_lla_i(&ecef_nav0, &llh_nav0); - //Convert ltp - ltp_def_from_lla_i(&ins_ltp_def, &llh_nav); - ins_ltp_def.hmsl = NAV_ALT0; + ltp_def_from_ecef_i(&ins_impl.ltp_def, &ecef_nav0); + ins_impl.ltp_def.hmsl = NAV_ALT0; + stateSetLocalOrigin_i(&ins_impl.ltp_def); - //Set the ltp - stateSetLocalOrigin_i(&ins_ltp_def); - - ins_ltp_initialised = TRUE; + ins_impl.ltp_initialized = TRUE; #else - ins_ltp_initialised = FALSE; + ins_impl.ltp_initialized = FALSE; #endif ins.vf_realign = FALSE; ins.hf_realign = FALSE; - INT32_VECT3_ZERO(ins_ltp_pos); - - // TODO correct init - ins.status = INS_RUNNING; + INT32_VECT3_ZERO(ins_impl.ltp_pos); + INT32_VECT3_ZERO(ins_impl.ltp_speed); + INT32_VECT3_ZERO(ins_impl.ltp_accel); } void ins_periodic( void ) { - + if (ins_impl.ltp_initialized) + ins.status = INS_RUNNING; } void ins_realign_h(struct FloatVect2 pos __attribute__ ((unused)), struct FloatVect2 speed __attribute__ ((unused))) { @@ -100,21 +86,21 @@ void ins_realign_v(float z __attribute__ ((unused))) { void ins_propagate() { /* untilt accels and speeds */ - FLOAT_RMAT_VECT3_TRANSP_MUL(ins_ltp_accel, (*stateGetNedToBodyRMat_f()), ahrs_impl.accel); - FLOAT_RMAT_VECT3_TRANSP_MUL(ins_ltp_speed, (*stateGetNedToBodyRMat_f()), ahrs_impl.speed); + FLOAT_RMAT_VECT3_TRANSP_MUL(ins_impl.ltp_accel, (*stateGetNedToBodyRMat_f()), ahrs_impl.accel); + FLOAT_RMAT_VECT3_TRANSP_MUL(ins_impl.ltp_speed, (*stateGetNedToBodyRMat_f()), ahrs_impl.speed); //Add g to the accelerations - ins_ltp_accel.z += 9.81; + ins_impl.ltp_accel.z += 9.81; //Save the accelerations and speeds - stateSetAccelNed_f(&ins_ltp_accel); - stateSetSpeedNed_f(&ins_ltp_speed); + stateSetAccelNed_f(&ins_impl.ltp_accel); + stateSetSpeedNed_f(&ins_impl.ltp_speed); //Don't set the height if we use the one from the gps #if !USE_GPS_HEIGHT //Set the height and save the position - ins_ltp_pos.z = -(ahrs_impl.altitude * INT32_POS_OF_CM_NUM) / INT32_POS_OF_CM_DEN; - stateSetPositionNed_i(&ins_ltp_pos); + ins_impl.ltp_pos.z = -(ahrs_impl.altitude * INT32_POS_OF_CM_NUM) / INT32_POS_OF_CM_DEN; + stateSetPositionNed_i(&ins_impl.ltp_pos); #endif } @@ -128,27 +114,27 @@ void ins_update_gps(void) { //Check for GPS fix if (gps.fix == GPS_FIX_3D) { //Set the initial coordinates - if(!ins_ltp_initialised) { - ltp_def_from_ecef_i(&ins_ltp_def, &gps.ecef_pos); - ins_ltp_def.lla.alt = gps.lla_pos.alt; - ins_ltp_def.hmsl = gps.hmsl; - ins_ltp_initialised = TRUE; - stateSetLocalOrigin_i(&ins_ltp_def); + if(!ins_impl.ltp_initialized) { + ltp_def_from_ecef_i(&ins_impl.ltp_def, &gps.ecef_pos); + ins_impl.ltp_def.lla.alt = gps.lla_pos.alt; + ins_impl.ltp_def.hmsl = gps.hmsl; + ins_impl.ltp_initialized = TRUE; + stateSetLocalOrigin_i(&ins_impl.ltp_def); } //Set the x and y and maybe z position in ltp and save struct NedCoor_i ins_gps_pos_cm_ned; - ned_of_ecef_point_i(&ins_gps_pos_cm_ned, &ins_ltp_def, &gps.ecef_pos); + ned_of_ecef_point_i(&ins_gps_pos_cm_ned, &ins_impl.ltp_def, &gps.ecef_pos); //When we don't want to use the height of the navdata we can use the gps height #if USE_GPS_HEIGHT - INT32_VECT3_SCALE_2(ins_ltp_pos, ins_gps_pos_cm_ned, INT32_POS_OF_CM_NUM, INT32_POS_OF_CM_DEN); + INT32_VECT3_SCALE_2(ins_impl.ltp_pos, ins_gps_pos_cm_ned, INT32_POS_OF_CM_NUM, INT32_POS_OF_CM_DEN); #else - INT32_VECT2_SCALE_2(ins_ltp_pos, ins_gps_pos_cm_ned, INT32_POS_OF_CM_NUM, INT32_POS_OF_CM_DEN); + INT32_VECT2_SCALE_2(ins_impl.ltp_pos, ins_gps_pos_cm_ned, INT32_POS_OF_CM_NUM, INT32_POS_OF_CM_DEN); #endif //Set the local origin - stateSetPositionNed_i(&ins_ltp_pos); + stateSetPositionNed_i(&ins_impl.ltp_pos); } #endif /* USE_GPS */ } diff --git a/sw/airborne/subsystems/ins/ins_ardrone2.h b/sw/airborne/subsystems/ins/ins_ardrone2.h index c14e362eea..617c2845f3 100644 --- a/sw/airborne/subsystems/ins/ins_ardrone2.h +++ b/sw/airborne/subsystems/ins/ins_ardrone2.h @@ -24,22 +24,26 @@ * INS implementation for ardrone2-sdk. */ -#ifndef INS_INT_H -#define INS_INT_H +#ifndef INS_ARDRONE2_SDK_H +#define INS_ARDRONE2_SDK_H #include "subsystems/ins.h" #include "std.h" #include "math/pprz_geodetic_int.h" #include "math/pprz_algebra_float.h" -//TODO: implement in state -extern int32_t ins_qfe; -extern int32_t ins_baro_alt; +struct InsArdrone2 { + struct LtpDef_i ltp_def; + bool_t ltp_initialized; -extern struct NedCoor_i ins_ltp_pos; -extern struct LtpDef_i ins_ltp_def; -extern struct NedCoor_f ins_ltp_speed; -extern struct NedCoor_f ins_ltp_accel; -extern bool_t ins_ltp_initialised; + float qfe; ///< not used, only dummy for INS_REF message -#endif /* INS_INT_H */ + /* output LTP NED */ + struct NedCoor_i ltp_pos; + struct NedCoor_i ltp_speed; + struct NedCoor_i ltp_accel; +}; + +extern struct InsArdrone2 ins_impl; + +#endif /* INS_ARDRONE2_SDK_H */ diff --git a/sw/airborne/subsystems/ins/ins_gps_passthrough.c b/sw/airborne/subsystems/ins/ins_gps_passthrough.c index c274b32024..ab1d5356f1 100644 --- a/sw/airborne/subsystems/ins/ins_gps_passthrough.c +++ b/sw/airborne/subsystems/ins/ins_gps_passthrough.c @@ -38,6 +38,8 @@ void ins_init() { struct UtmCoor_f utm0 = { nav_utm_north0, nav_utm_east0, 0., nav_utm_zone0 }; stateSetLocalUtmOrigin_f(&utm0); stateSetPositionUtm_f(&utm0); + + ins.status = INS_RUNNING; } void ins_periodic( void ) { diff --git a/sw/airborne/subsystems/ins/ins_int.c b/sw/airborne/subsystems/ins/ins_int.c index 567b21b9f5..1044c02cd6 100644 --- a/sw/airborne/subsystems/ins/ins_int.c +++ b/sw/airborne/subsystems/ins/ins_int.c @@ -28,13 +28,16 @@ #include "subsystems/ins/ins_int.h" +#include "subsystems/abi.h" + #include "subsystems/imu.h" -#include "subsystems/sensors/baro.h" #include "subsystems/gps.h" #include "generated/airframe.h" -#if USE_VFF +#if USE_VFF_EXTENDED +#include "subsystems/ins/vf_extended_float.h" +#else #include "subsystems/ins/vf_float.h" #endif @@ -42,42 +45,50 @@ #include "subsystems/ins/hf_float.h" #endif -#ifdef SITL -#include "nps_fdm.h" +#if defined SITL && USE_NPS +//#include "nps_fdm.h" +#include "nps_autopilot.h" #include #endif #include "math/pprz_geodetic_int.h" +#include "math/pprz_isa.h" #include "generated/flight_plan.h" + +#if USE_SONAR + +#if !USE_VFF_EXTENDED +#error USE_SONAR needs USE_VFF_EXTENDED +#endif + +#ifdef INS_SONAR_THROTTLE_THRESHOLD +#include "firmwares/rotorcraft/stabilization.h" +#endif + +#ifndef INS_SONAR_OFFSET +#define INS_SONAR_OFFSET 0 +#endif +#define VFF_R_SONAR_0 0.1 +#define VFF_R_SONAR_OF_M 0.2 + +#endif // USE_SONAR + #ifndef USE_INS_NAV_INIT #define USE_INS_NAV_INIT TRUE PRINT_CONFIG_MSG("USE_INS_NAV_INIT defaulting to TRUE") #endif -/* gps transformed to LTP-NED */ -struct LtpDef_i ins_ltp_def; - bool_t ins_ltp_initialised; -struct NedCoor_i ins_gps_pos_cm_ned; -struct NedCoor_i ins_gps_speed_cm_s_ned; -#if USE_HFF -/* horizontal gps transformed to NED in meters as float */ -struct FloatVect2 ins_gps_pos_m_ned; -struct FloatVect2 ins_gps_speed_m_s_ned; -#endif -/* barometer */ -#if USE_VFF -int32_t ins_qfe; -bool_t ins_baro_initialised; -int32_t ins_baro_alt; +/** default barometer to use in INS */ +#ifndef INS_BARO_ID +#define INS_BARO_ID BARO_BOARD_SENDER_ID #endif +abi_event baro_ev; +static void baro_cb(uint8_t sender_id, const float *pressure); -/* output */ -struct NedCoor_i ins_ltp_pos; -struct NedCoor_i ins_ltp_speed; -struct NedCoor_i ins_ltp_accel; +struct InsInt ins_impl; #if DOWNLINK #include "subsystems/datalink/telemetry.h" @@ -104,41 +115,48 @@ static void send_ins_ref(void) { } #endif -void ins_init() { +static void ins_init_origin_from_flightplan(void); +static void ins_ned_to_state(void); +#if USE_HFF +static void ins_update_from_hff(void); +#endif + + +void ins_init(void) { + #if USE_INS_NAV_INIT - ins_ltp_initialised = TRUE; - - /** FIXME: should use the same code than MOVE_WP in firmwares/rotorcraft/datalink.c */ - struct LlaCoor_i llh_nav0; /* Height above the ellipsoid */ - llh_nav0.lat = INT32_RAD_OF_DEG(NAV_LAT0); - llh_nav0.lon = INT32_RAD_OF_DEG(NAV_LON0); - /* NAV_ALT0 = ground alt above msl, NAV_MSL0 = geoid-height (msl) over ellipsoid */ - llh_nav0.alt = NAV_ALT0 + NAV_MSL0; - - struct EcefCoor_i ecef_nav0; - ecef_of_lla_i(&ecef_nav0, &llh_nav0); - - ltp_def_from_ecef_i(&ins_ltp_def, &ecef_nav0); - ins_ltp_def.hmsl = NAV_ALT0; - stateSetLocalOrigin_i(&ins_ltp_def); + ins_init_origin_from_flightplan(); + ins_impl.ltp_initialized = TRUE; #else - ins_ltp_initialised = FALSE; + ins_impl.ltp_initialized = FALSE; #endif -#if USE_VFF - ins_baro_initialised = FALSE; - vff_init(0., 0., 0.); + + // Bind to BARO_ABS message + AbiBindMsgBARO_ABS(INS_BARO_ID, &baro_ev, baro_cb); + ins_impl.baro_initialized = FALSE; + +#if USE_SONAR + ins_impl.update_on_agl = FALSE; + init_median_filter(&ins_impl.sonar_median); + ins_impl.sonar_offset = INS_SONAR_OFFSET; #endif + ins.vf_realign = FALSE; ins.hf_realign = FALSE; + + /* init vertical and horizontal filters */ +#if USE_VFF_EXTENDED + vff_init(0., 0., 0., 0.); +#else + vff_init(0., 0., 0.); +#endif #if USE_HFF b2_hff_init(0., 0., 0., 0.); #endif - INT32_VECT3_ZERO(ins_ltp_pos); - INT32_VECT3_ZERO(ins_ltp_speed); - INT32_VECT3_ZERO(ins_ltp_accel); - // TODO correct init - ins.status = INS_RUNNING; + INT32_VECT3_ZERO(ins_impl.ltp_pos); + INT32_VECT3_ZERO(ins_impl.ltp_speed); + INT32_VECT3_ZERO(ins_impl.ltp_accel); #if DOWNLINK register_periodic_telemetry(DefaultPeriodic, "INS", send_ins); @@ -147,19 +165,23 @@ void ins_init() { #endif } -void ins_periodic( void ) { +void ins_periodic(void) { + if (ins_impl.ltp_initialized) + ins.status = INS_RUNNING; } -void ins_realign_h(struct FloatVect2 pos __attribute__ ((unused)), struct FloatVect2 speed __attribute__ ((unused))) { #if USE_HFF +void ins_realign_h(struct FloatVect2 pos, struct FloatVect2 speed) { b2_hff_realign(pos, speed); -#endif /* USE_HFF */ } +#else +void ins_realign_h(struct FloatVect2 pos __attribute__ ((unused)), + struct FloatVect2 speed __attribute__ ((unused))) {} +#endif /* USE_HFF */ -void ins_realign_v(float z __attribute__ ((unused))) { -#if USE_VFF + +void ins_realign_v(float z) { vff_realign(z); -#endif } void ins_propagate() { @@ -169,116 +191,218 @@ void ins_propagate() { struct Int32Vect3 accel_meas_ltp; INT32_RMAT_TRANSP_VMULT(accel_meas_ltp, (*stateGetNedToBodyRMat_i()), accel_meas_body); -#if USE_VFF float z_accel_meas_float = ACCEL_FLOAT_OF_BFP(accel_meas_ltp.z); - if (baro.status == BS_RUNNING && ins_baro_initialised) { + if (ins_impl.baro_initialized) { vff_propagate(z_accel_meas_float); - ins_ltp_accel.z = ACCEL_BFP_OF_REAL(vff_zdotdot); - ins_ltp_speed.z = SPEED_BFP_OF_REAL(vff_zdot); - ins_ltp_pos.z = POS_BFP_OF_REAL(vff_z); + ins_impl.ltp_accel.z = ACCEL_BFP_OF_REAL(vff_zdotdot); + ins_impl.ltp_speed.z = SPEED_BFP_OF_REAL(vff_zdot); + ins_impl.ltp_pos.z = POS_BFP_OF_REAL(vff_z); } else { // feed accel from the sensors - // subtract -9.81m/s2 (acceleration measured due to gravity, but vehivle not accelerating in ltp) - ins_ltp_accel.z = accel_meas_ltp.z + ACCEL_BFP_OF_REAL(9.81); + // subtract -9.81m/s2 (acceleration measured due to gravity, + // but vehicle not accelerating in ltp) + ins_impl.ltp_accel.z = accel_meas_ltp.z + ACCEL_BFP_OF_REAL(9.81); } -#else - ins_ltp_accel.z = accel_meas_ltp.z + ACCEL_BFP_OF_REAL(9.81); -#endif /* USE_VFF */ #if USE_HFF /* propagate horizontal filter */ b2_hff_propagate(); + /* convert and copy result to ins_impl */ + ins_update_from_hff(); #else - ins_ltp_accel.x = accel_meas_ltp.x; - ins_ltp_accel.y = accel_meas_ltp.y; + ins_impl.ltp_accel.x = accel_meas_ltp.x; + ins_impl.ltp_accel.y = accel_meas_ltp.y; #endif /* USE_HFF */ - INS_NED_TO_STATE(); + ins_ned_to_state(); } -void ins_update_baro() { -#if USE_VFF - if (baro.status == BS_RUNNING) { - if (!ins_baro_initialised) { - ins_qfe = baro.absolute; - ins_baro_initialised = TRUE; - } - if (ins.vf_realign) { - ins.vf_realign = FALSE; - ins_qfe = baro.absolute; - vff_realign(0.); - ins_ltp_accel.z = ACCEL_BFP_OF_REAL(vff_zdotdot); - ins_ltp_speed.z = SPEED_BFP_OF_REAL(vff_zdot); - ins_ltp_pos.z = POS_BFP_OF_REAL(vff_z); - } - else { /* not realigning, so normal update with baro measurement */ - ins_baro_alt = ((baro.absolute - ins_qfe) * INS_BARO_SENS_NUM)/INS_BARO_SENS_DEN; - float alt_float = POS_FLOAT_OF_BFP(ins_baro_alt); - vff_update(alt_float); - } +static void baro_cb(uint8_t __attribute__((unused)) sender_id, const float *pressure) { + if (!ins_impl.baro_initialized) { + ins_impl.qfe = *pressure; + ins_impl.baro_initialized = TRUE; } - INS_NED_TO_STATE(); + if (ins.vf_realign) { + ins.vf_realign = FALSE; + ins_impl.qfe = *pressure; + vff_realign(0.); + ins_impl.ltp_accel.z = ACCEL_BFP_OF_REAL(vff_zdotdot); + ins_impl.ltp_speed.z = SPEED_BFP_OF_REAL(vff_zdot); + ins_impl.ltp_pos.z = POS_BFP_OF_REAL(vff_z); + } + else { + ins_impl.baro_z = -pprz_isa_height_of_pressure(*pressure, ins_impl.qfe); +#if USE_VFF_EXTENDED + vff_update_baro(ins_impl.baro_z); +#else + vff_update(ins_impl.baro_z); #endif + } + ins_ned_to_state(); +} + + +void ins_update_baro() { } void ins_update_gps(void) { #if USE_GPS if (gps.fix == GPS_FIX_3D) { - if (!ins_ltp_initialised) { - ltp_def_from_ecef_i(&ins_ltp_def, &gps.ecef_pos); - ins_ltp_def.lla.alt = gps.lla_pos.alt; - ins_ltp_def.hmsl = gps.hmsl; - ins_ltp_initialised = TRUE; - stateSetLocalOrigin_i(&ins_ltp_def); + if (!ins_impl.ltp_initialized) { + ltp_def_from_ecef_i(&ins_impl.ltp_def, &gps.ecef_pos); + ins_impl.ltp_def.lla.alt = gps.lla_pos.alt; + ins_impl.ltp_def.hmsl = gps.hmsl; + ins_impl.ltp_initialized = TRUE; + stateSetLocalOrigin_i(&ins_impl.ltp_def); } - ned_of_ecef_point_i(&ins_gps_pos_cm_ned, &ins_ltp_def, &gps.ecef_pos); - ned_of_ecef_vect_i(&ins_gps_speed_cm_s_ned, &ins_ltp_def, &gps.ecef_vel); + + struct NedCoor_i gps_pos_cm_ned; + ned_of_ecef_point_i(&gps_pos_cm_ned, &ins_impl.ltp_def, &gps.ecef_pos); + /// @todo maybe use gps.ned_vel directly?? + struct NedCoor_i gps_speed_cm_s_ned; + ned_of_ecef_vect_i(&gps_speed_cm_s_ned, &ins_impl.ltp_def, &gps.ecef_vel); + #if USE_HFF - VECT2_ASSIGN(ins_gps_pos_m_ned, ins_gps_pos_cm_ned.x, ins_gps_pos_cm_ned.y); - VECT2_SDIV(ins_gps_pos_m_ned, ins_gps_pos_m_ned, 100.); - VECT2_ASSIGN(ins_gps_speed_m_s_ned, ins_gps_speed_cm_s_ned.x, ins_gps_speed_cm_s_ned.y); - VECT2_SDIV(ins_gps_speed_m_s_ned, ins_gps_speed_m_s_ned, 100.); + /* horizontal gps transformed to NED in meters as float */ + struct FloatVect2 gps_pos_m_ned; + VECT2_ASSIGN(gps_pos_m_ned, gps_pos_cm_ned.x, gps_pos_cm_ned.y); + VECT2_SDIV(gps_pos_m_ned, gps_pos_m_ned, 100.); + + struct FloatVect2 gps_speed_m_s_ned; + VECT2_ASSIGN(gps_speed_m_s_ned, gps_speed_cm_s_ned.x, gps_speed_cm_s_ned.y); + VECT2_SDIV(gps_speed_m_s_ned, gps_speed_m_s_ned, 100.); + if (ins.hf_realign) { ins.hf_realign = FALSE; -#ifdef SITL - struct FloatVect2 true_pos, true_speed; - VECT2_COPY(true_pos, fdm.ltpprz_pos); - VECT2_COPY(true_speed, fdm.ltpprz_ecef_vel); - b2_hff_realign(true_pos, true_speed); -#else const struct FloatVect2 zero = {0.0, 0.0}; - b2_hff_realign(ins_gps_pos_m_ned, zero); -#endif + b2_hff_realign(gps_pos_m_ned, zero); } - b2_hff_update_gps(); -#if !USE_VFF /* vff not used */ - ins_ltp_pos.z = (ins_gps_pos_cm_ned.z * INT32_POS_OF_CM_NUM) / INT32_POS_OF_CM_DEN; - ins_ltp_speed.z = (ins_gps_speed_cm_s_ned.z * INT32_SPEED_OF_CM_S_NUM) INT32_SPEED_OF_CM_S_DEN; -#endif /* vff not used */ -#endif /* hff used */ + // run horizontal filter + b2_hff_update_gps(&gps_pos_m_ned, &gps_speed_m_s_ned); + // convert and copy result to ins_impl + ins_update_from_hff(); +#else /* hff not used */ + /* simply copy horizontal pos/speed from gps */ + INT32_VECT2_SCALE_2(ins_impl.ltp_pos, gps_pos_cm_ned, + INT32_POS_OF_CM_NUM, INT32_POS_OF_CM_DEN); + INT32_VECT2_SCALE_2(ins_impl.ltp_speed, gps_speed_cm_s_ned, + INT32_SPEED_OF_CM_S_NUM, INT32_SPEED_OF_CM_S_DEN); +#endif /* USE_HFF */ -#if !USE_HFF /* hff not used */ -#if !USE_VFF /* neither hf nor vf used */ - INT32_VECT3_SCALE_3(ins_ltp_pos, ins_gps_pos_cm_ned, INT32_POS_OF_CM_NUM, INT32_POS_OF_CM_DEN); - INT32_VECT3_SCALE_3(ins_ltp_speed, ins_gps_speed_cm_s_ned, INT32_SPEED_OF_CM_S_NUM, INT32_SPEED_OF_CM_S_DEN); -#else /* only vff used */ - INT32_VECT2_SCALE_2(ins_ltp_pos, ins_gps_pos_cm_ned, INT32_POS_OF_CM_NUM, INT32_POS_OF_CM_DEN); - INT32_VECT2_SCALE_2(ins_ltp_speed, ins_gps_speed_cm_s_ned, INT32_SPEED_OF_CM_S_NUM, INT32_SPEED_OF_CM_S_DEN); -#endif - -#if USE_GPS_LAG_HACK - VECT2_COPY(d_pos, ins_ltp_speed); - INT32_VECT2_RSHIFT(d_pos, d_pos, 11); - VECT2_ADD(ins_ltp_pos, d_pos); -#endif -#endif /* hff not used */ - - INS_NED_TO_STATE(); + ins_ned_to_state(); } #endif /* USE_GPS */ } + +//#define INS_SONAR_VARIANCE_THRESHOLD 0.01 + +#ifdef INS_SONAR_VARIANCE_THRESHOLD + +#include "messages.h" +#include "mcu_periph/uart.h" +#include "subsystems/datalink/downlink.h" + +#include "math/pprz_stat.h" +#define VAR_ERR_MAX 10 +float var_err[VAR_ERR_MAX]; +uint8_t var_idx = 0; +#endif + + void ins_update_sonar() { +#if USE_SONAR + static float last_offset = 0.; + // new value filtered with median_filter + ins_impl.sonar_alt = update_median_filter(&ins_impl.sonar_median, sonar_meas); + float sonar = (ins_impl.sonar_alt - ins_impl.sonar_offset) * INS_SONAR_SENS; + +#ifdef INS_SONAR_VARIANCE_THRESHOLD + /* compute variance of error between sonar and baro alt */ + float err = sonar + ins_impl.baro_z; // sonar positive up, baro positive down !!!! + var_err[var_idx] = err; + var_idx = (var_idx + 1) % VAR_ERR_MAX; + float var = variance_float(var_err, VAR_ERR_MAX); + DOWNLINK_SEND_INS_SONAR(DefaultChannel,DefaultDevice,&err, &sonar, &var); + //DOWNLINK_SEND_INS_SONAR(DefaultChannel,DefaultDevice,&ins_impl.sonar_alt, &sonar, &var); +#endif + + /* update filter assuming a flat ground */ + if (sonar < INS_SONAR_MAX_RANGE +#ifdef INS_SONAR_MIN_RANGE + && sonar > INS_SONAR_MIN_RANGE +#endif +#ifdef INS_SONAR_THROTTLE_THRESHOLD + && stabilization_cmd[COMMAND_THRUST] < INS_SONAR_THROTTLE_THRESHOLD +#endif +#ifdef INS_SONAR_STAB_THRESHOLD + && stabilization_cmd[COMMAND_ROLL] < INS_SONAR_STAB_THRESHOLD + && stabilization_cmd[COMMAND_ROLL] > -INS_SONAR_STAB_THRESHOLD + && stabilization_cmd[COMMAND_PITCH] < INS_SONAR_STAB_THRESHOLD + && stabilization_cmd[COMMAND_PITCH] > -INS_SONAR_STAB_THRESHOLD + && stabilization_cmd[COMMAND_YAW] < INS_SONAR_STAB_THRESHOLD + && stabilization_cmd[COMMAND_YAW] > -INS_SONAR_STAB_THRESHOLD +#endif +#ifdef INS_SONAR_BARO_THRESHOLD + && ins_impl.baro_z > -INS_SONAR_BARO_THRESHOLD /* z down */ +#endif +#ifdef INS_SONAR_VARIANCE_THRESHOLD + && var < INS_SONAR_VARIANCE_THRESHOLD +#endif + && ins_impl.update_on_agl + && ins_impl.baro_initialized) { + vff_update_alt_conf(-sonar, VFF_R_SONAR_0 + VFF_R_SONAR_OF_M * fabs(sonar)); + last_offset = vff_offset; + } + else { + /* update offset with last value to avoid divergence */ + vff_update_offset(last_offset); + } +#endif // USE_SONAR } + + +/** initialize the local origin (ltp_def) from flight plan position */ +static void ins_init_origin_from_flightplan(void) { + + struct LlaCoor_i llh_nav0; /* Height above the ellipsoid */ + llh_nav0.lat = INT32_RAD_OF_DEG(NAV_LAT0); + llh_nav0.lon = INT32_RAD_OF_DEG(NAV_LON0); + /* NAV_ALT0 = ground alt above msl, NAV_MSL0 = geoid-height (msl) over ellipsoid */ + llh_nav0.alt = NAV_ALT0 + NAV_MSL0; + + struct EcefCoor_i ecef_nav0; + ecef_of_lla_i(&ecef_nav0, &llh_nav0); + + ltp_def_from_ecef_i(&ins_impl.ltp_def, &ecef_nav0); + ins_impl.ltp_def.hmsl = NAV_ALT0; + stateSetLocalOrigin_i(&ins_impl.ltp_def); + +} + +/** copy position and speed to state interface */ +static void ins_ned_to_state(void) { + stateSetPositionNed_i(&ins_impl.ltp_pos); + stateSetSpeedNed_i(&ins_impl.ltp_speed); + stateSetAccelNed_i(&ins_impl.ltp_accel); + +#if defined SITL && USE_NPS + if (nps_bypass_ins) + sim_overwrite_ins(); +#endif +} + + +#if USE_HFF +/** update ins state from horizontal filter */ +static void ins_update_from_hff(void) { + ins_impl.ltp_accel.x = ACCEL_BFP_OF_REAL(b2_hff_state.xdotdot); + ins_impl.ltp_accel.y = ACCEL_BFP_OF_REAL(b2_hff_state.ydotdot); + ins_impl.ltp_speed.x = SPEED_BFP_OF_REAL(b2_hff_state.xdot); + ins_impl.ltp_speed.y = SPEED_BFP_OF_REAL(b2_hff_state.ydot); + ins_impl.ltp_pos.x = POS_BFP_OF_REAL(b2_hff_state.x); + ins_impl.ltp_pos.y = POS_BFP_OF_REAL(b2_hff_state.y); +} +#endif diff --git a/sw/airborne/subsystems/ins/ins_int.h b/sw/airborne/subsystems/ins/ins_int.h index c72c805c52..71171c5fbf 100644 --- a/sw/airborne/subsystems/ins/ins_int.h +++ b/sw/airborne/subsystems/ins/ins_int.h @@ -34,42 +34,34 @@ #include "math/pprz_geodetic_int.h" #include "math/pprz_algebra_float.h" -// TODO integrate all internal state to the structure -///** Ins implementation state (fixed point) */ -//struct InsInt { -//}; -// -///** global INS state */ -//extern struct InsInt ins_impl; - -/* gps transformed to LTP-NED */ -extern struct LtpDef_i ins_ltp_def; -extern bool_t ins_ltp_initialised; -extern struct NedCoor_i ins_gps_pos_cm_ned; -extern struct NedCoor_i ins_gps_speed_cm_s_ned; - -/* barometer */ -#if USE_VFF -extern int32_t ins_baro_alt; ///< altitude calculated from baro in meters with #INT32_POS_FRAC -extern int32_t ins_qfe; -extern bool_t ins_baro_initialised; +#if USE_SONAR +#include "filters/median_filter.h" #endif -/* output LTP NED */ -extern struct NedCoor_i ins_ltp_pos; -extern struct NedCoor_i ins_ltp_speed; -extern struct NedCoor_i ins_ltp_accel; -#if USE_HFF -/* horizontal gps transformed to NED in meters as float */ -extern struct FloatVect2 ins_gps_pos_m_ned; -extern struct FloatVect2 ins_gps_speed_m_s_ned; -#endif +/** Ins implementation state (fixed point) */ +struct InsInt { + struct LtpDef_i ltp_def; + bool_t ltp_initialized; -/* copy position and speed to state interface */ -#define INS_NED_TO_STATE() { \ - stateSetPositionNed_i(&ins_ltp_pos); \ - stateSetSpeedNed_i(&ins_ltp_speed); \ - stateSetAccelNed_i(&ins_ltp_accel); \ -} + /* output LTP NED */ + struct NedCoor_i ltp_pos; + struct NedCoor_i ltp_speed; + struct NedCoor_i ltp_accel; + + /* baro */ + float baro_z; ///< z-position calculated from baro in meters (z-down) + float qfe; + bool_t baro_initialized; + +#if USE_SONAR + bool_t update_on_agl; /* use sonar to update agl if available */ + int32_t sonar_alt; + int32_t sonar_offset; + struct MedianFilterInt sonar_median; +#endif +}; + +/** global INS state */ +extern struct InsInt ins_impl; #endif /* INS_INT_H */ diff --git a/sw/airborne/subsystems/ins/ins_int_extended.c b/sw/airborne/subsystems/ins/ins_int_extended.c deleted file mode 100644 index aefa07f10f..0000000000 --- a/sw/airborne/subsystems/ins/ins_int_extended.c +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Copyright (C) 2008-2010 The Paparazzi Team - * Copyright (C) 2012 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. - */ - -/** - * @file subsystems/ins/ins_int_extended.c - * - * INS for rotorcrafts combining vertical and horizontal filters. - * - */ - -#include "subsystems/ins/ins_int_extended.h" - -#include "subsystems/imu.h" -#include "subsystems/sensors/baro.h" -#include "subsystems/gps.h" - -#include "generated/airframe.h" -#include "math/pprz_algebra_int.h" -#include "math/pprz_algebra_float.h" - -#include "state.h" - -#include "subsystems/ins/vf_extended_float.h" - -#if USE_HFF -#include "subsystems/ins/hf_float.h" -#endif - -#ifdef SITL -#include "nps_fdm.h" -#include -#endif - -#ifdef INS_SONAR_THROTTLE_THRESHOLD -#include "firmwares/rotorcraft/stabilization.h" -#endif - -#include "math/pprz_geodetic_int.h" - -#include "generated/flight_plan.h" - -#ifndef USE_INS_NAV_INIT -#define USE_INS_NAV_INIT TRUE -PRINT_CONFIG_MSG("USE_INS_NAV_INIT defaulting to TRUE") -#endif - - -/* gps transformed to LTP-NED */ -struct LtpDef_i ins_ltp_def; - bool_t ins_ltp_initialised; -struct NedCoor_i ins_gps_pos_cm_ned; -struct NedCoor_i ins_gps_speed_cm_s_ned; -#if USE_HFF -/* horizontal gps transformed to NED in meters as float */ -struct FloatVect2 ins_gps_pos_m_ned; -struct FloatVect2 ins_gps_speed_m_s_ned; -#endif - -/* barometer */ -int32_t ins_qfe; -bool_t ins_baro_initialised; -int32_t ins_baro_alt; -#include "filters/median_filter.h" -struct MedianFilterInt baro_median; - -#if USE_SONAR -/* sonar */ -bool_t ins_update_on_agl; -int32_t ins_sonar_alt; -int32_t ins_sonar_offset; -struct MedianFilterInt sonar_median; -#ifndef INS_SONAR_OFFSET -#define INS_SONAR_OFFSET 0 -#endif -#define VFF_R_SONAR_0 0.1 -#define VFF_R_SONAR_OF_M 0.2 -#endif // USE_SONAR - -/* output */ -struct NedCoor_i ins_ltp_pos; -struct NedCoor_i ins_ltp_speed; -struct NedCoor_i ins_ltp_accel; - - -void ins_init() { -#if USE_INS_NAV_INIT - ins_ltp_initialised = TRUE; - - /** FIXME: should use the same code than MOVE_WP in firmwares/rotorcraft/datalink.c */ - struct LlaCoor_i llh_nav0; /* Height above the ellipsoid */ - llh_nav0.lat = INT32_RAD_OF_DEG(NAV_LAT0); - llh_nav0.lon = INT32_RAD_OF_DEG(NAV_LON0); - /* NAV_ALT0 = ground alt above msl, NAV_MSL0 = geoid-height (msl) over ellipsoid */ - llh_nav0.alt = NAV_ALT0 + NAV_MSL0; - - struct EcefCoor_i ecef_nav0; - ecef_of_lla_i(&ecef_nav0, &llh_nav0); - - ltp_def_from_ecef_i(&ins_ltp_def, &ecef_nav0); - ins_ltp_def.hmsl = NAV_ALT0; - stateSetLocalOrigin_i(&ins_ltp_def); -#else - ins_ltp_initialised = FALSE; -#endif - - ins_baro_initialised = FALSE; - init_median_filter(&baro_median); - -#if USE_SONAR - ins_update_on_agl = FALSE; - init_median_filter(&sonar_median); - ins_sonar_offset = INS_SONAR_OFFSET; -#endif - - vff_init(0., 0., 0., 0.); - ins.vf_realign = FALSE; - ins.hf_realign = FALSE; -#if USE_HFF - b2_hff_init(0., 0., 0., 0.); -#endif - INT32_VECT3_ZERO(ins_ltp_pos); - INT32_VECT3_ZERO(ins_ltp_speed); - INT32_VECT3_ZERO(ins_ltp_accel); -} - -void ins_periodic( void ) { -} - -#if USE_HFF -void ins_realign_h(struct FloatVect2 pos, struct FloatVect2 speed) { - b2_hff_realign(pos, speed); -} -#else -void ins_realign_h(struct FloatVect2 pos __attribute__ ((unused)), struct FloatVect2 speed __attribute__ ((unused))) {} -#endif /* USE_HFF */ - - -void ins_realign_v(float z) { - vff_realign(z); -} - -void ins_propagate() { - /* untilt accels */ - struct Int32Vect3 accel_meas_body; - INT32_RMAT_TRANSP_VMULT(accel_meas_body, imu.body_to_imu_rmat, imu.accel); - struct Int32Vect3 accel_meas_ltp; - INT32_RMAT_TRANSP_VMULT(accel_meas_ltp, *stateGetNedToBodyRMat_i(), accel_meas_body); - - float z_accel_meas_float = ACCEL_FLOAT_OF_BFP(accel_meas_ltp.z); - if (baro.status == BS_RUNNING && ins_baro_initialised) { - vff_propagate(z_accel_meas_float); - ins_ltp_accel.z = ACCEL_BFP_OF_REAL(vff_zdotdot); - ins_ltp_speed.z = SPEED_BFP_OF_REAL(vff_zdot); - ins_ltp_pos.z = POS_BFP_OF_REAL(vff_z); - } - else { // feed accel from the sensors - // subtract -9.81m/s2 (acceleration measured due to gravity, but vehivle not accelerating in ltp) - ins_ltp_accel.z = accel_meas_ltp.z + ACCEL_BFP_OF_REAL(9.81); - } - -#if USE_HFF - /* propagate horizontal filter */ - b2_hff_propagate(); -#else - ins_ltp_accel.x = accel_meas_ltp.x; - ins_ltp_accel.y = accel_meas_ltp.y; -#endif /* USE_HFF */ - - INS_NED_TO_STATE(); -} - -void ins_update_baro() { - int32_t baro_pressure = update_median_filter(&baro_median, baro.absolute); - if (baro.status == BS_RUNNING) { - if (!ins_baro_initialised) { - ins_qfe = baro_pressure; - ins_baro_initialised = TRUE; - } - if (ins.vf_realign) { - ins.vf_realign = FALSE; - ins_qfe = baro_pressure; - vff_realign(0.); - ins_ltp_accel.z = ACCEL_BFP_OF_REAL(vff_zdotdot); - ins_ltp_speed.z = SPEED_BFP_OF_REAL(vff_zdot); - ins_ltp_pos.z = POS_BFP_OF_REAL(vff_z); - } - else { /* not realigning, so normal update with baro measurement */ - ins_baro_alt = ((baro_pressure - ins_qfe) * INS_BARO_SENS_NUM)/INS_BARO_SENS_DEN; - float alt_float = POS_FLOAT_OF_BFP(ins_baro_alt); - vff_update_baro(alt_float); - } - } - INS_NED_TO_STATE(); -} - - -void ins_update_gps(void) { -#if USE_GPS - if (gps.fix == GPS_FIX_3D) { - if (!ins_ltp_initialised) { - ltp_def_from_ecef_i(&ins_ltp_def, &gps.ecef_pos); - ins_ltp_def.lla.alt = gps.lla_pos.alt; - ins_ltp_def.hmsl = gps.hmsl; - ins_ltp_initialised = TRUE; - stateSetLocalOrigin_i(&ins_ltp_def); - } - ned_of_ecef_point_i(&ins_gps_pos_cm_ned, &ins_ltp_def, &gps.ecef_pos); - ned_of_ecef_vect_i(&ins_gps_speed_cm_s_ned, &ins_ltp_def, &gps.ecef_vel); -#if USE_HFF - VECT2_ASSIGN(ins_gps_pos_m_ned, ins_gps_pos_cm_ned.x, ins_gps_pos_cm_ned.y); - VECT2_SDIV(ins_gps_pos_m_ned, ins_gps_pos_m_ned, 100.); - VECT2_ASSIGN(ins_gps_speed_m_s_ned, ins_gps_speed_cm_s_ned.x, ins_gps_speed_cm_s_ned.y); - VECT2_SDIV(ins_gps_speed_m_s_ned, ins_gps_speed_m_s_ned, 100.); - if (ins.hf_realign) { - ins.hf_realign = FALSE; -#ifdef SITL - struct FloatVect2 true_pos, true_speed; - VECT2_COPY(true_pos, fdm.ltpprz_pos); - VECT2_COPY(true_speed, fdm.ltpprz_ecef_vel); - b2_hff_realign(true_pos, true_speed); -#else - const struct FloatVect2 zero = {0.0, 0.0}; - b2_hff_realign(ins_gps_pos_m_ned, zero); -#endif - } - b2_hff_update_gps(); -#endif /* hff used */ - -#if !USE_HFF /* hff not used */ - INT32_VECT2_SCALE_2(ins_ltp_pos, ins_gps_pos_cm_ned, INT32_POS_OF_CM_NUM, INT32_POS_OF_CM_DEN); - INT32_VECT2_SCALE_2(ins_ltp_speed, ins_gps_speed_cm_s_ned, INT32_SPEED_OF_CM_S_NUM, INT32_SPEED_OF_CM_S_DEN); -#endif /* hff not used */ - - } - INS_NED_TO_STATE(); -#endif /* USE_GPS */ -} - -//#define INS_SONAR_VARIANCE_THRESHOLD 0.01 - -#ifdef INS_SONAR_VARIANCE_THRESHOLD - -#include "messages.h" -#include "mcu_periph/uart.h" -#include "subsystems/datalink/downlink.h" - -#include "math/pprz_stat.h" -#define VAR_ERR_MAX 10 -float var_err[VAR_ERR_MAX]; -uint8_t var_idx = 0; -#endif - - -void ins_update_sonar() { -#if USE_SONAR - static float last_offset = 0.; - // new value filtered with median_filter - ins_sonar_alt = update_median_filter(&sonar_median, sonar_meas); - float sonar = (ins_sonar_alt - ins_sonar_offset) * INS_SONAR_SENS; - -#ifdef INS_SONAR_VARIANCE_THRESHOLD - /* compute variance of error between sonar and baro alt */ - int32_t err = POS_BFP_OF_REAL(sonar) + ins_baro_alt; // sonar positive up, baro positive down !!!! - var_err[var_idx] = POS_FLOAT_OF_BFP(err); - var_idx = (var_idx + 1) % VAR_ERR_MAX; - float var = variance_float(var_err, VAR_ERR_MAX); - DOWNLINK_SEND_INS_SONAR(DefaultChannel,DefaultDevice,&err, &sonar, &var); - //DOWNLINK_SEND_INS_SONAR(DefaultChannel,DefaultDevice,&ins_sonar_alt, &sonar, &var); -#endif - - /* update filter assuming a flat ground */ - if (sonar < INS_SONAR_MAX_RANGE -#ifdef INS_SONAR_MIN_RANGE - && sonar > INS_SONAR_MIN_RANGE -#endif -#ifdef INS_SONAR_THROTTLE_THRESHOLD - && stabilization_cmd[COMMAND_THRUST] < INS_SONAR_THROTTLE_THRESHOLD -#endif -#ifdef INS_SONAR_STAB_THRESHOLD - && stabilization_cmd[COMMAND_ROLL] < INS_SONAR_STAB_THRESHOLD - && stabilization_cmd[COMMAND_ROLL] > -INS_SONAR_STAB_THRESHOLD - && stabilization_cmd[COMMAND_PITCH] < INS_SONAR_STAB_THRESHOLD - && stabilization_cmd[COMMAND_PITCH] > -INS_SONAR_STAB_THRESHOLD - && stabilization_cmd[COMMAND_YAW] < INS_SONAR_STAB_THRESHOLD - && stabilization_cmd[COMMAND_YAW] > -INS_SONAR_STAB_THRESHOLD -#endif -#ifdef INS_SONAR_BARO_THRESHOLD - && ins_baro_alt > -POS_BFP_OF_REAL(INS_SONAR_BARO_THRESHOLD) /* z down */ -#endif -#ifdef INS_SONAR_VARIANCE_THRESHOLD - && var < INS_SONAR_VARIANCE_THRESHOLD -#endif - && ins_update_on_agl - && baro.status == BS_RUNNING) { - vff_update_alt_conf(-sonar, VFF_R_SONAR_0 + VFF_R_SONAR_OF_M * fabs(sonar)); - last_offset = vff_offset; - } - else { - /* update offset with last value to avoid divergence */ - vff_update_offset(last_offset); - } -#endif // USE_SONAR -} - diff --git a/sw/airborne/subsystems/ins/ins_int_extended.h b/sw/airborne/subsystems/ins/ins_int_extended.h deleted file mode 100644 index 6d0ae9b2ec..0000000000 --- a/sw/airborne/subsystems/ins/ins_int_extended.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2008-2012 The Paparazzi Team - * - * 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. - */ - -/** - * @file subsystems/ins/ins_int_extended.h - * - * INS for rotorcrafts combining vertical and horizontal filters. - * This filter includes estimation of the baro drift based on sonar. - * - * Vertical filter is always enabled - * - * TODO: use GPS alt if good enough, especially when sonar readings are not available - * - */ - -#ifndef INS_INT_EXTENDED_H -#define INS_INT_EXTENDED_H - -#include "subsystems/ins.h" -#include "std.h" -#include "math/pprz_geodetic_int.h" -#include "math/pprz_algebra_float.h" - -// TODO integrate all internal state to the structure -///** Ins extended implementation state (fixed point) */ -//struct InsIntExtended { -//}; -// -///** global INS state */ -//extern struct InsInt ins_impl; - -/* gps transformed to LTP-NED */ -extern struct LtpDef_i ins_ltp_def; -extern bool_t ins_ltp_initialised; -extern struct NedCoor_i ins_gps_pos_cm_ned; -extern struct NedCoor_i ins_gps_speed_cm_s_ned; - -/* barometer */ -extern int32_t ins_baro_alt; ///< altitude calculated from baro in meters with #INT32_POS_FRAC -extern int32_t ins_qfe; -extern bool_t ins_baro_initialised; -#if USE_SONAR -extern bool_t ins_update_on_agl; /* use sonar to update agl if available */ -extern int32_t ins_sonar_offset; -#endif - -/* output LTP NED */ -extern struct NedCoor_i ins_ltp_pos; -extern struct NedCoor_i ins_ltp_speed; -extern struct NedCoor_i ins_ltp_accel; -#if USE_HFF -/* horizontal gps transformed to NED in meters as float */ -extern struct FloatVect2 ins_gps_pos_m_ned; -extern struct FloatVect2 ins_gps_speed_m_s_ned; -#endif - -/* copy position and speed to state interface */ -#define INS_NED_TO_STATE() { \ - stateSetPositionNed_i(&ins_ltp_pos); \ - stateSetSpeedNed_i(&ins_ltp_speed); \ - stateSetAccelNed_i(&ins_ltp_accel); \ -} - -#endif /* INS_INT_EXTENDED_H */ diff --git a/sw/airborne/subsystems/navigation/common_nav.c b/sw/airborne/subsystems/navigation/common_nav.c index 7e641c05d6..9e2623e3fe 100644 --- a/sw/airborne/subsystems/navigation/common_nav.c +++ b/sw/airborne/subsystems/navigation/common_nav.c @@ -26,6 +26,7 @@ #include "subsystems/navigation/common_nav.h" #include "generated/flight_plan.h" +#include "subsystems/ins.h" #include "subsystems/gps.h" #include "math/pprz_geodetic_float.h" @@ -116,6 +117,10 @@ unit_t nav_reset_reference( void ) { struct UtmCoor_f utm0 = { nav_utm_north0, nav_utm_east0, 0., nav_utm_zone0 }; stateSetLocalUtmOrigin_f(&utm0); + // realign INS if needed + ins.hf_realign = TRUE; + ins.vf_realign = TRUE; + previous_ground_alt = ground_alt; ground_alt = gps.hmsl/1000.; return 0; diff --git a/sw/airborne/subsystems/sensors/baro.h b/sw/airborne/subsystems/sensors/baro.h index 76dd521dbc..643da7bbef 100644 --- a/sw/airborne/subsystems/sensors/baro.h +++ b/sw/airborne/subsystems/sensors/baro.h @@ -23,31 +23,16 @@ * @file subsystems/sensors/baro.h * * Common barometric sensor implementation. + * Used with baro integrated to the autopilot board. + * Implementation is in boards//baro_board.[ch] * */ #ifndef SUBSYSTEMS_SENSORS_BARO_H #define SUBSYSTEMS_SENSORS_BARO_H -#include - -enum BaroStatus { - BS_UNINITIALIZED, - BS_RUNNING -}; - -/* pressure in which units ? */ -struct Baro { - int32_t absolute; - int32_t differential; - enum BaroStatus status; -}; - -extern struct Baro baro; - - #include BOARD_CONFIG -#if defined BOARD_HAS_BARO +#if USE_BARO_BOARD #include "baro_board.h" #endif diff --git a/sw/airborne/subsystems/sensors/baro_ms5611_i2c.c b/sw/airborne/subsystems/sensors/baro_ms5611_i2c.c deleted file mode 100644 index a3c446e4bd..0000000000 --- a/sw/airborne/subsystems/sensors/baro_ms5611_i2c.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2011-2013 The Paparazzi Team - * - * 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. - * - */ - -/** - * @file subsystems/sensors/baro_ms5611_i2c.c - * - * Driver for MS5611 baro via I2C. - * - */ - -#include "subsystems/sensors/baro.h" -#include "peripherals/ms5611_i2c.h" - -#include "mcu_periph/sys_time.h" -#include "led.h" -#include "std.h" - -#ifndef MS5611_I2C_DEV -#define MS5611_I2C_DEV i2c2 -#endif - -/* default i2c address - * when CSB is set to GND addr is 0xEE - * when CSB is set to VCC addr is 0xEC - * - * Note: Aspirin 2.1 has CSB bound to GND. - */ -#ifndef MS5611_SLAVE_ADDR -#define MS5611_SLAVE_ADDR 0xEE -#endif - -#ifdef DEBUG - -#ifndef DOWNLINK_DEVICE -#define DOWNLINK_DEVICE DOWNLINK_AP_DEVICE -#endif -#include "mcu_periph/uart.h" -#include "messages.h" -#include "subsystems/datalink/downlink.h" - -float fbaroms, ftempms; -#endif - -struct Baro baro; -struct Ms5611_I2c baro_ms5611; - - -void baro_init(void) { - baro.status = BS_UNINITIALIZED; - baro.absolute = 0; - baro.differential = 0; - - ms5611_i2c_init(&baro_ms5611, &MS5611_I2C_DEV, MS5611_SLAVE_ADDR); -} - -void baro_periodic(void) { - if (sys_time.nb_sec > 1) { - - /* call the convenience periodic that initializes the sensor and starts reading*/ - ms5611_i2c_periodic(&baro_ms5611); - - if (baro_ms5611.initialized) { - baro.status = BS_RUNNING; -#if DEBUG - RunOnceEvery((4*30), DOWNLINK_SEND_MS5611_COEFF(DefaultChannel, DefaultDevice, - &baro_ms5611.data.c[0], - &baro_ms5611.data.c[1], - &baro_ms5611.data.c[2], - &baro_ms5611.data.c[3], - &baro_ms5611.data.c[4], - &baro_ms5611.data.c[5], - &baro_ms5611.data.c[6], - &baro_ms5611.data.c[7])); -#endif - } - } -} - -void baro_event(void (*b_abs_handler)(void)){ - if (sys_time.nb_sec > 1) { - ms5611_i2c_event(&baro_ms5611); - - if (baro_ms5611.data_available) { - baro.absolute = baro_ms5611.data.pressure; - b_abs_handler(); - baro_ms5611.data_available = FALSE; - -#ifdef ROTORCRAFT_BARO_LED - RunOnceEvery(10,LED_TOGGLE(ROTORCRAFT_BARO_LED)); -#endif - -#if DEBUG - ftempms = baro_ms5611.data.temperature / 100.; - fbaroms = baro_ms5611.data.pressure / 100.; - DOWNLINK_SEND_BARO_MS5611(DefaultChannel, DefaultDevice, - &baro_ms5611.data.d1, &baro_ms5611.data.d2, - &fbaroms, &ftempms); -#endif - } - } -} diff --git a/sw/airborne/subsystems/sensors/baro_ms5611_spi.c b/sw/airborne/subsystems/sensors/baro_ms5611_spi.c deleted file mode 100644 index bd8603ea43..0000000000 --- a/sw/airborne/subsystems/sensors/baro_ms5611_spi.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2011-2013 The Paparazzi Team - * - * 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. - * - */ - -/** - * @file subsystems/sensors/baro_ms5611_spi.c - * - * Driver for MS5611 baro on LisaM/Aspirin2.2 via SPI. - * - */ - -#include "subsystems/sensors/baro.h" -#include "peripherals/ms5611_spi.h" - -#include "mcu_periph/sys_time.h" -#include "led.h" -#include "std.h" - -#ifndef MS5611_SPI_DEV -#define MS5611_SPI_DEV spi2 -#endif - -/* SPI SLAVE3 is on pin PC13 - * Aspirin 2.2 has ms5611 on SPI bus - */ -#ifndef MS5611_SLAVE_DEV -#define MS5611_SLAVE_DEV SPI_SLAVE3 -#endif - - -#ifdef DEBUG - -#ifndef DOWNLINK_DEVICE -#define DOWNLINK_DEVICE DOWNLINK_AP_DEVICE -#endif -#include "mcu_periph/uart.h" -#include "messages.h" -#include "subsystems/datalink/downlink.h" - -float fbaroms, ftempms; -#endif - -struct Baro baro; -struct Ms5611_Spi baro_ms5611; - - -void baro_init(void) { - baro.status = BS_UNINITIALIZED; - baro.absolute = 0; - baro.differential = 0; - - ms5611_spi_init(&baro_ms5611, &MS5611_SPI_DEV, MS5611_SLAVE_DEV); -} - -void baro_periodic(void) { - if (sys_time.nb_sec > 1) { - - /* call the convenience periodic that initializes the sensor and starts reading*/ - ms5611_spi_periodic(&baro_ms5611); - - if (baro_ms5611.initialized) { - baro.status = BS_RUNNING; -#if DEBUG - RunOnceEvery((4*30), DOWNLINK_SEND_MS5611_COEFF(DefaultChannel, DefaultDevice, - &baro_ms5611.data.c[0], - &baro_ms5611.data.c[1], - &baro_ms5611.data.c[2], - &baro_ms5611.data.c[3], - &baro_ms5611.data.c[4], - &baro_ms5611.data.c[5], - &baro_ms5611.data.c[6], - &baro_ms5611.data.c[7])); -#endif - } - } -} - -void baro_event(void (*b_abs_handler)(void)){ - if (sys_time.nb_sec > 1) { - ms5611_spi_event(&baro_ms5611); - - if (baro_ms5611.data_available) { - baro.absolute = baro_ms5611.data.pressure; - b_abs_handler(); - baro_ms5611.data_available = FALSE; - -#ifdef ROTORCRAFT_BARO_LED - RunOnceEvery(10,LED_TOGGLE(ROTORCRAFT_BARO_LED)); -#endif - -#if DEBUG - ftempms = baro_ms5611.data.temperature / 100.; - fbaroms = baro_ms5611.data.pressure / 100.; - DOWNLINK_SEND_BARO_MS5611(DefaultChannel, DefaultDevice, - &baro_ms5611.data.d1, &baro_ms5611.data.d2, - &fbaroms, &ftempms); -#endif - } - } -} diff --git a/sw/airborne/test/Makefile b/sw/airborne/test/Makefile index f8e05d1151..5938ed851a 100644 --- a/sw/airborne/test/Makefile +++ b/sw/airborne/test/Makefile @@ -4,7 +4,8 @@ Q=@ CC = gcc -CFLAGS = -std=c99 -I.. -I../../include -I../booz -I../../booz -Wall +CFLAGS = -std=c99 -I.. -I../../include -Wall +#CFLAGS += -DDEBUG LDFLAGS = -lm diff --git a/sw/airborne/test/test_geodetic.c b/sw/airborne/test/test_geodetic.c index e4c24a983e..51197828f5 100644 --- a/sw/airborne/test/test_geodetic.c +++ b/sw/airborne/test/test_geodetic.c @@ -20,6 +20,7 @@ static void test_lla_of_utm(void); static void test_floats(void); static void test_doubles(void); static void test_enu_of_ecef_int(void); +static void test_ecef_of_ned_int(void); static void test_ned_to_ecef_to_ned(void); static void test_enu_to_ecef_to_enu( void ); @@ -32,12 +33,16 @@ int main(int argc, char** argv) { //test_floats(); //test_doubles(); - test_lla_of_utm(); + //test_lla_of_utm(); + + //test_ned_to_ecef_to_ned(); + + //test_enu_to_ecef_to_enu(); + + test_ecef_of_ned_int(); //test_enu_of_ecef_int(); - // test_ned_to_ecef_to_ned(); - // test_enu_to_ecef_to_enu(); return 0; } @@ -48,7 +53,7 @@ static void test_lla_of_utm(void) { struct UtmCoor_d utm_d = { .east=348805.71, .north=4759354.89, .zone=31 }; struct LlaCoor_d lla_d; struct LlaCoor_d l_ref_d = {.lat=0.749999999392454875, - .lon=0.019999999054505127}; + .lon=0.019999999054505127}; lla_of_utm_d(&lla_d, &utm_d); printf(" lat=%.16f lon=%.16f\nref_lat=%.16f ref_lon=%.16f\n", lla_d.lat, lla_d.lon, l_ref_d.lat, l_ref_d.lon); @@ -58,7 +63,7 @@ static void test_lla_of_utm(void) { struct UtmCoor_f utm_f = { .east=348805.71, .north=4759354.89, .zone=31 }; struct LlaCoor_f lla_f; struct LlaCoor_f l_ref_f = {.lat=0.749999999392454875, - .lon=0.019999999054505127}; + .lon=0.019999999054505127}; lla_of_utm_f(&lla_f, &utm_f); printf(" lat=%.16f lon=%.16f\nref_lat=%.16f ref_lon=%.16f\n", lla_f.lat, lla_f.lon, l_ref_f.lat, l_ref_f.lon); @@ -78,15 +83,16 @@ static void test_floats(void) { struct LtpDef_f ltp_def; ltp_def_from_ecef_f(<p_def, &ref_coor); - printf("lla0 : (%f,%f,%f)\n", DegOfRad(ltp_def.lla.lat), DegOfRad(ltp_def.lla.lon), ltp_def.lla.alt); + printf("lla0 : (%f,%f,%f)\n", DegOfRad(ltp_def.lla.lat), DegOfRad(ltp_def.lla.lon), + ltp_def.lla.alt); struct EcefCoor_f my_ecef_point = ref_coor; struct EnuCoor_f my_enu_point; enu_of_ecef_point_f(&my_enu_point, <p_def, &my_ecef_point); printf("ecef to enu : (%f,%f,%f) -> (%f,%f,%f)\n", - my_ecef_point.x, my_ecef_point.y, my_ecef_point.z, - my_enu_point.x, my_enu_point.y, my_enu_point.z ); + my_ecef_point.x, my_ecef_point.y, my_ecef_point.z, + my_enu_point.x, my_enu_point.y, my_enu_point.z ); printf("\n"); } @@ -105,18 +111,91 @@ static void test_doubles(void) { struct LtpDef_d ltp_def; ltp_def_from_ecef_d(<p_def, &ref_coor); - printf("lla0 : (%f,%f,%f)\n", DegOfRad(ltp_def.lla.lat), DegOfRad(ltp_def.lla.lon), ltp_def.lla.alt); + printf("lla0 : (%f,%f,%f)\n", DegOfRad(ltp_def.lla.lat), DegOfRad(ltp_def.lla.lon), + ltp_def.lla.alt); struct EcefCoor_d my_ecef_point = ref_coor; struct EnuCoor_d my_enu_point; enu_of_ecef_point_d(&my_enu_point, <p_def, &my_ecef_point); printf("ecef to enu : (%f,%f,%f) -> (%f,%f,%f)\n", - my_ecef_point.x, my_ecef_point.y, my_ecef_point.z, - my_enu_point.x, my_enu_point.y, my_enu_point.z ); + my_ecef_point.x, my_ecef_point.y, my_ecef_point.z, + my_enu_point.x, my_enu_point.y, my_enu_point.z ); printf("\n"); } +static void test_ecef_of_ned_int(void) { + + printf("\n--- ecef_of_ned int ---\n"); + struct EcefCoor_d ref_coor_d = { 4624497.0 , 116475.0, 4376563.0}; + struct LtpDef_d ltp_def_d; + ltp_def_from_ecef_d(<p_def_d, &ref_coor_d); + + struct EcefCoor_i ref_coor_i = { rint(CM_OF_M(ref_coor_d.x)), + rint(CM_OF_M(ref_coor_d.y)), + rint(CM_OF_M(ref_coor_d.z))}; + printf("ecef0 : (%d,%d,%d)\n", ref_coor_i.x, ref_coor_i.y, ref_coor_i.z); + struct LtpDef_i ltp_def_i; + ltp_def_from_ecef_i(<p_def_i, &ref_coor_i); + + +#define STEP_NED 100.0 +#define RANGE_NED 10000. + double sum_err = 0; + struct FloatVect3 max_err; + FLOAT_VECT3_ZERO(max_err); + struct FloatVect3 offset; + for (offset.x=-RANGE_NED; offset.x<=RANGE_NED; offset.x+=STEP_NED) { + for (offset.y=-RANGE_NED; offset.y<=RANGE_NED; offset.y+=STEP_NED) { + for (offset.z=-RANGE_NED; offset.z<=RANGE_NED; offset.z+=STEP_NED) { + struct NedCoor_d my_ned_point_d; + VECT3_COPY(my_ned_point_d, offset); + struct EcefCoor_d my_ecef_point_d; + ecef_of_ned_point_d(&my_ecef_point_d, <p_def_d, &my_ned_point_d); +#if DEBUG + printf("ned to ecef double : (%.02f,%.02f,%.02f) -> (%.02f,%.02f,%.02f)\n", + my_enu_point_f.x, my_enu_point_f.y, my_enu_point_f.z, + my_ecef_point_f.x, my_ecef_point_f.y, my_ecef_point_f.z); +#endif + + struct NedCoor_i my_ned_point_i; + POSITIONS_BFP_OF_REAL(my_ned_point_i, my_ned_point_d); + struct EcefCoor_i my_ecef_point_i; + ecef_of_ned_pos_i(&my_ecef_point_i, <p_def_i, &my_ned_point_i); + +#if DEBUG + //printf("def->ecef (%d,%d,%d)\n", ltp_def_i.ecef.x, ltp_def_i.ecef.y, ltp_def_i.ecef.z); + printf("ned to ecef int : (%.2f,%.02f,%.02f) -> (%.02f,%.02f,%.02f)\n\n", + POS_BFP_OF_REAL(my_ned_point_i.x), + POS_BFP_OF_REAL(my_ned_point_i.y), + POS_BFP_OF_REAL(my_ned_point_i.z), + M_OF_CM((double)my_ecef_point_i.x), + M_OF_CM((double)my_ecef_point_i.y), + M_OF_CM((double)my_ecef_point_i.z)); +#endif + + float ex = my_ecef_point_d.x - M_OF_CM((double)my_ecef_point_i.x); + if (fabs(ex) > max_err.x) max_err.x = fabs(ex); + float ey = my_ecef_point_d.y - M_OF_CM((double)my_ecef_point_i.y); + if (fabs(ey) > max_err.y) max_err.y = fabs(ey); + float ez = my_ecef_point_d.z - M_OF_CM((double)my_ecef_point_i.z); + if (fabs(ez) > max_err.z) max_err.z = fabs(ez); + sum_err += ex*ex + ey*ey + ez*ez; + } + } + } + + double nb_samples = (2*RANGE_NED / STEP_NED + 1) * (2*RANGE_NED / STEP_NED + 1) * + (2*RANGE_NED / STEP_NED + 1); + + + printf("ecef_of_ned_pos int/float comparison:\n"); + printf("error max (%f,%f,%f) m\n", max_err.x, max_err.y, max_err.z ); + printf("error avg (%f ) m \n", sqrt(sum_err) / nb_samples ); + printf("\n"); + +} + static void test_enu_of_ecef_int(void) { @@ -126,15 +205,16 @@ static void test_enu_of_ecef_int(void) { ltp_def_from_ecef_f(<p_def_f, &ref_coor_f); struct EcefCoor_i ref_coor_i = { rint(CM_OF_M(ref_coor_f.x)), - rint(CM_OF_M(ref_coor_f.y)), - rint(CM_OF_M(ref_coor_f.z))}; + rint(CM_OF_M(ref_coor_f.y)), + rint(CM_OF_M(ref_coor_f.z))}; printf("ecef0 : (%d,%d,%d)\n", ref_coor_i.x, ref_coor_i.y, ref_coor_i.z); struct LtpDef_i ltp_def_i; ltp_def_from_ecef_i(<p_def_i, &ref_coor_i); - printf("lla0 : (%f deg, %f deg, %f m) (%f,%f,%f)\n", DegOfRad(ltp_def_f.lla.lat), DegOfRad(ltp_def_f.lla.lon), ltp_def_f.lla.alt, - DegOfRad(RAD_OF_EM7RAD((double)ltp_def_i.lla.lat)), - DegOfRad(RAD_OF_EM7RAD((double)ltp_def_i.lla.lon)), - M_OF_MM((double)ltp_def_i.lla.alt)); + printf("lla0 : float (%f deg, %f deg, %f m) , int (%f, %f, %f)\n", + DegOfRad(ltp_def_f.lla.lat), DegOfRad(ltp_def_f.lla.lon), ltp_def_f.lla.alt, + DegOfRad(RAD_OF_EM7RAD((double)ltp_def_i.lla.lat)), + DegOfRad(RAD_OF_EM7RAD((double)ltp_def_i.lla.lon)), + M_OF_MM((double)ltp_def_i.lla.alt)); #define STEP 1000. #define RANGE 100000. @@ -145,40 +225,40 @@ static void test_enu_of_ecef_int(void) { for (offset.x=-RANGE; offset.x<=RANGE; offset.x+=STEP) { for (offset.y=-RANGE; offset.y<=RANGE; offset.y+=STEP) { for (offset.z=-RANGE; offset.z<=RANGE; offset.z+=STEP) { - struct EcefCoor_f my_ecef_point_f = ref_coor_f; - VECT3_ADD(my_ecef_point_f, offset); - struct EnuCoor_f my_enu_point_f; - enu_of_ecef_point_f(&my_enu_point_f, <p_def_f, &my_ecef_point_f); + struct EcefCoor_f my_ecef_point_f = ref_coor_f; + VECT3_ADD(my_ecef_point_f, offset); + struct EnuCoor_f my_enu_point_f; + enu_of_ecef_point_f(&my_enu_point_f, <p_def_f, &my_ecef_point_f); #if DEBUG - printf("ecef to enu float : (%.02f,%.02f,%.02f) -> (%.02f,%.02f,%.02f)\n", - my_ecef_point_f.x, my_ecef_point_f.y, my_ecef_point_f.z, - my_enu_point_f.x, my_enu_point_f.y, my_enu_point_f.z ); + printf("ecef to enu float : (%.02f,%.02f,%.02f) -> (%.02f,%.02f,%.02f)\n", + my_ecef_point_f.x, my_ecef_point_f.y, my_ecef_point_f.z, + my_enu_point_f.x, my_enu_point_f.y, my_enu_point_f.z ); #endif - struct EcefCoor_i my_ecef_point_i = { rint(CM_OF_M(my_ecef_point_f.x)), - rint(CM_OF_M(my_ecef_point_f.y)), - rint(CM_OF_M(my_ecef_point_f.z))};; - struct EnuCoor_i my_enu_point_i; - enu_of_ecef_point_i(&my_enu_point_i, <p_def_i, &my_ecef_point_i); + struct EcefCoor_i my_ecef_point_i = { rint(CM_OF_M(my_ecef_point_f.x)), + rint(CM_OF_M(my_ecef_point_f.y)), + rint(CM_OF_M(my_ecef_point_f.z))};; + struct EnuCoor_i my_enu_point_i; + enu_of_ecef_point_i(&my_enu_point_i, <p_def_i, &my_ecef_point_i); #if DEBUG - // printf("def->ecef (%d,%d,%d)\n", ltp_def_i.ecef.x, ltp_def_i.ecef.y, ltp_def_i.ecef.z); - printf("ecef to enu int : (%.2f,%.02f,%.02f) -> (%.02f,%.02f,%.02f)\n\n", - M_OF_CM((double)my_ecef_point_i.x), - M_OF_CM((double)my_ecef_point_i.y), - M_OF_CM((double)my_ecef_point_i.z), - M_OF_CM((double)my_enu_point_i.x), - M_OF_CM((double)my_enu_point_i.y), - M_OF_CM((double)my_enu_point_i.z)); + //printf("def->ecef (%d,%d,%d)\n", ltp_def_i.ecef.x, ltp_def_i.ecef.y, ltp_def_i.ecef.z); + printf("ecef to enu int : (%.2f,%.02f,%.02f) -> (%.02f,%.02f,%.02f)\n\n", + M_OF_CM((double)my_ecef_point_i.x), + M_OF_CM((double)my_ecef_point_i.y), + M_OF_CM((double)my_ecef_point_i.z), + M_OF_CM((double)my_enu_point_i.x), + M_OF_CM((double)my_enu_point_i.y), + M_OF_CM((double)my_enu_point_i.z)); #endif - float ex = my_enu_point_f.x - M_OF_CM((double)my_enu_point_i.x); - if (fabs(ex) > max_err.x) max_err.x = fabs(ex); - float ey = my_enu_point_f.y - M_OF_CM((double)my_enu_point_i.y); - if (fabs(ey) > max_err.y) max_err.y = fabs(ey); - float ez = my_enu_point_f.z - M_OF_CM((double)my_enu_point_i.z); - if (fabs(ez) > max_err.z) max_err.z = fabs(ez); - sum_err += ex*ex + ey*ey + ez*ez; + float ex = my_enu_point_f.x - M_OF_CM((double)my_enu_point_i.x); + if (fabs(ex) > max_err.x) max_err.x = fabs(ex); + float ey = my_enu_point_f.y - M_OF_CM((double)my_enu_point_i.y); + if (fabs(ey) > max_err.y) max_err.y = fabs(ey); + float ez = my_enu_point_f.z - M_OF_CM((double)my_enu_point_i.z); + if (fabs(ez) > max_err.z) max_err.z = fabs(ez); + sum_err += ex*ex + ey*ey + ez*ez; } } } @@ -191,7 +271,6 @@ static void test_enu_of_ecef_int(void) { printf("error avg (%f ) m \n", sqrt(sum_err) / nb_samples ); printf("\n"); - } @@ -200,7 +279,8 @@ static void test_enu_of_ecef_int(void) { void test_ned_to_ecef_to_ned( void ) { -#if 0 + printf("\n--- NED -> ECEF -> NED in double ---\n"); + struct EcefCoor_d ref_coor = { 4624497.0 , 116475.0, 4376563.0}; printf("ecef0 : (%.02f,%.02f,%.02f)\n", ref_coor.x, ref_coor.y, ref_coor.z); @@ -211,18 +291,16 @@ void test_ned_to_ecef_to_ned( void ) { struct NedCoor_d ned_p1; ned_of_ecef_point_d(&ned_p1, <p_def, &ecef_p1); printf("ecef to ned : (%f,%f,%f) -> (%f,%f,%f)\n", - ecef_p1.x, ecef_p1.y, ecef_p1.z, - ned_p1.x, ned_p1.y, ned_p1.z ); + ecef_p1.x, ecef_p1.y, ecef_p1.z, + ned_p1.x, ned_p1.y, ned_p1.z ); struct EcefCoor_d ecef_p2; ecef_of_ned_point_d(&ecef_p2, <p_def, &ned_p1); printf("ned to ecef : (%f,%f,%f) -> (%f,%f,%f)\n", - ned_p1.x, ned_p1.y, ned_p1.z, - ecef_p2.x, ecef_p2.y, ecef_p2.z); + ned_p1.x, ned_p1.y, ned_p1.z, + ecef_p2.x, ecef_p2.y, ecef_p2.z); printf("\n"); -#endif - } @@ -233,6 +311,8 @@ void test_ned_to_ecef_to_ned( void ) { void test_enu_to_ecef_to_enu( void ) { + printf("\n--- ENU -> ECEF -> ENU in float ---\n"); + struct EcefCoor_f ref_coor = { 4624497.0 , 116475.0, 4376563.0}; printf("ecef0 : (%.02f,%.02f,%.02f)\n", ref_coor.x, ref_coor.y, ref_coor.z); @@ -243,19 +323,16 @@ void test_enu_to_ecef_to_enu( void ) { struct EnuCoor_f enu_p1; enu_of_ecef_point_f(&enu_p1, <p_def, &ecef_p1); printf("ecef to enu : (%f,%f,%f) -> (%f,%f,%f)\n", - ecef_p1.x, ecef_p1.y, ecef_p1.z, - enu_p1.x, enu_p1.y, enu_p1.z ); + ecef_p1.x, ecef_p1.y, ecef_p1.z, + enu_p1.x, enu_p1.y, enu_p1.z ); -#if 0 struct EcefCoor_f ecef_p2; ecef_of_enu_point_f(&ecef_p2, <p_def, &enu_p1); printf("enu to ecef : (%f,%f,%f) -> (%f,%f,%f)\n", - enu_p1.x, enu_p1.y, enu_p1.z, - ecef_p2.x, ecef_p2.y, ecef_p2.z); + enu_p1.x, enu_p1.y, enu_p1.z, + ecef_p2.x, ecef_p2.y, ecef_p2.z); printf("\n"); -#endif - } diff --git a/sw/in_progress/python/attitude_viz.py b/sw/in_progress/python/attitude_viz.py index ebc5074440..325c5d3b7f 100755 --- a/sw/in_progress/python/attitude_viz.py +++ b/sw/in_progress/python/attitude_viz.py @@ -18,353 +18,362 @@ import os _NAME = 'attitude_viz' + class TelemetryQuat: - def __init__(self, message_name, index, name, integer): - self.message_name = message_name - self.index = index - self.name = name - self.qi = 1 - self.qx = 0 - self.qy = 0 - self.qz = 0 - # optional scaling for fixed point telemetry - if integer: - self.scale = 0.00003051757812 - else: - self.scale = 1.0 + def __init__(self, message_name, index, name, integer): + self.message_name = message_name + self.index = index + self.name = name + self.qi = 1 + self.qx = 0 + self.qy = 0 + self.qz = 0 + # optional scaling for fixed point telemetry + if integer: + self.scale = 0.00003051757812 + else: + self.scale = 1.0 + class TelemetryValue: - def __init__(self, message_name, index, name, offset, scale, max): - self.message_name = message_name - self.index = index - self.name = name - self.offset = offset - self.scale = scale - self.max = max - self.value = 0 + def __init__(self, message_name, index, name, offset, scale, max): + self.message_name = message_name + self.index = index + self.name = name + self.offset = offset + self.scale = scale + self.max = max + self.value = 0 + class Visualization: - def __init__(self, parent): - self.quats = [] - self.graph_values = [] - self.throttle = 0.0 - self.mode = 0.0 - self.airspeed = 0.0 - self.display_list = None - self.display_dirty = True - self.rotate_theta = parent.rotate_theta - - for message_name, index, name, bfp in VEHICLE_QUATS: - self.quats.append(TelemetryQuat(message_name, index, name, bfp)) - for message_name, index, name, offset, scale, max in BAR_VALUES: - self.graph_values.append(TelemetryValue(message_name, index, name, offset, scale, max)) - - def onmsgproc(self, agent, *larg): - data = str(larg[0]).split(' ') - for telemetry_quat in self.quats: - if (telemetry_quat.message_name == data[1]): + def __init__(self, parent): + self.quats = [] + self.graph_values = [] + self.throttle = 0.0 + self.mode = 0.0 + self.airspeed = 0.0 + self.display_list = None self.display_dirty = True - telemetry_quat.qi = float(data[telemetry_quat.index + 0]) - telemetry_quat.qx = float(data[telemetry_quat.index + 1]) - telemetry_quat.qy = float(data[telemetry_quat.index + 2]) - telemetry_quat.qz = float(data[telemetry_quat.index + 3]) + self.rotate_theta = parent.rotate_theta - for graph_value in self.graph_values: - if (graph_value.message_name == data[1]): - self.display_dirty = True - graph_value.value = (float(data[graph_value.index + 0]) + graph_value.offset) / graph_value.scale + for message_name, index, name, bfp in VEHICLE_QUATS: + self.quats.append(TelemetryQuat(message_name, index, name, bfp)) + for message_name, index, name, offset, scale, max in BAR_VALUES: + self.graph_values.append(TelemetryValue(message_name, index, name, offset, scale, max)) - def DrawCircle(self, radius): - glBegin(GL_TRIANGLE_FAN) - glVertex3f(0, 0, 0) - for angle in range (0, 361, 12): - glVertex3f( math.sin(math.radians(angle)) * radius, math.cos(math.radians(angle)) * radius, 0) - glEnd() + def onmsgproc(self, agent, *larg): + data = str(larg[0]).split(' ') + for telemetry_quat in self.quats: + if telemetry_quat.message_name == data[1]: + self.display_dirty = True + telemetry_quat.qi = float(data[telemetry_quat.index + 0]) + telemetry_quat.qx = float(data[telemetry_quat.index + 1]) + telemetry_quat.qy = float(data[telemetry_quat.index + 2]) + telemetry_quat.qz = float(data[telemetry_quat.index + 3]) - # draw quad centered at origin, z = 0 - def DrawQuad(self, width, height): - glBegin (GL_QUADS) - glVertex3f( width, height, 0) - glVertex3f( -width, height, 0) - glVertex3f( -width, -height, 0) - glVertex3f( width, -height, 0) - glEnd() + for graph_value in self.graph_values: + if graph_value.message_name == data[1]: + self.display_dirty = True + graph_value.value = (float(data[graph_value.index + 0]) + graph_value.offset) / graph_value.scale - def DrawBox(self, width, height, depth): - glPushMatrix() - glTranslate(0, 0, depth) - self.DrawQuad(width, height) - glTranslate(0, 0, -2 * depth) - self.DrawQuad(width, height) - glPopMatrix() + def DrawCircle(self, radius): + glBegin(GL_TRIANGLE_FAN) + glVertex3f(0, 0, 0) + for angle in range(0, 361, 12): + glVertex3f(math.sin(math.radians(angle)) * radius, math.cos(math.radians(angle)) * radius, 0) + glEnd() - glPushMatrix() - glRotate(90, 1, 0, 0) - glTranslate(0, 0, height) - self.DrawQuad(width, depth) - glTranslate(0, 0, -2 * height) - self.DrawQuad(width, depth) - glPopMatrix() + # draw quad centered at origin, z = 0 + def DrawQuad(self, width, height): + glBegin(GL_QUADS) + glVertex3f(width, height, 0) + glVertex3f(-width, height, 0) + glVertex3f(-width, -height, 0) + glVertex3f(width, -height, 0) + glEnd() - glPushMatrix() - glRotate(90, 0, 1, 0) - glTranslate(0, 0, width) - self.DrawQuad(depth, height) - glTranslate(0, 0, -2 * width) - self.DrawQuad(depth, height) - glPopMatrix() - - def DrawVehicle(self, name): - wingspan = 2.7 - separation = 0.7 - chord = 0.35 - thickness = 0.08 - strutcount = 3 - discradius = 0.45 - discseparation = 0.01 - - #wings - glColor3f(0.1, 0.1, 0.9) - glPushMatrix() - glTranslate(0, 0, 0.05) - self.DrawBox(wingspan, chord, thickness) - glColor3f(0.0, 0.0, 0.0) - glTranslate(-wingspan, -0.2, thickness + 0.01) - glScale(0.004, 0.004, 0.004) - for c in name: - glutStrokeCharacter(GLUT_STROKE_ROMAN, ord(c)) - glPopMatrix() - - glPushMatrix() - glTranslate(0, 0, -0.05) - glColor3f(0.6, 0.6, 0.2) - self.DrawBox(wingspan, chord, thickness) - glColor3f(0.0, 0.0, 0.0) - glTranslate(wingspan, -0.2, -0.01 - thickness) - glScale(0.004, 0.004, 0.004) - glRotate(180, 0, 1, 0) - for c in name: - glutStrokeCharacter(GLUT_STROKE_ROMAN, ord(c)) - glPopMatrix() - - if self.display_list is None: - self.display_list = glGenLists(1) - glNewList(self.display_list, GL_COMPILE) - # struts - glColor3f(0.4, 0.4, 0.4) - glPushMatrix() - glTranslate(-wingspan/2, 0, separation/2) - glRotate(90, 0, 1, 0) - for x in range (0, strutcount-1): - self.DrawBox(separation/2, chord - .01, thickness) - glTranslate(0, 0, wingspan) - glTranslate(separation, 0, -5*wingspan/2) - for x in range (0, strutcount-1): - self.DrawBox(separation/2, chord - .01, thickness) - glTranslate(0, 0, 2*wingspan) - glPopMatrix() - - #rotors - glColor3f(0.9, 0.1, 0.1) - glPushMatrix() - glRotate(90, 1, 0, 0) - glTranslate(-wingspan/2, separation, -(chord + .01)) - for x in range (0, strutcount): - if (x != strutcount/2): - self.DrawCircle(discradius) - glTranslate(2 * wingspan/(strutcount + 1), 0, 0) - glPopMatrix() - - glPushMatrix() - glRotate(90, 1, 0, 0) - glTranslate(-wingspan, -separation, -(chord + .01)) - for x in range (0, strutcount): - if (x != strutcount/2): - self.DrawCircle(discradius) - glTranslate(2 * wingspan/(strutcount - 1), 0, 0) - glPopMatrix() - glEndList() - - glCallList(self.display_list) - - def DrawBar(self, name, value): - bar_height = 0.12 - bar_length = 3 - glPushMatrix() - glColor3f(0, 0, 0) - glTranslate(-bar_length, -0.09, 0.02) - glScale(0.0015, 0.0015, 0.0015) - for c in name: - glutStrokeCharacter(GLUT_STROKE_ROMAN, ord(c)) - glPopMatrix() - glColor3f(0.92, 0.92, 0.92) - glPushMatrix() - glTranslate(0, 0, 0) - self.DrawQuad(bar_length, bar_height) - glPopMatrix() - glPushMatrix() - glTranslate(bar_length * value - bar_length, 0, 0.01) - glColor3f(0.6, 0.6, 0.6) - self.DrawQuad(bar_length * value, bar_height) - glPopMatrix() - - def Draw(self): - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) - - glPushMatrix() - - height = 5 - - glDisable(GL_LIGHTING) - glPushMatrix() - for graph_value in self.graph_values: - self.DrawBar(graph_value.name % (graph_value.value), graph_value.value / graph_value.max) - glTranslate(0, 0.35, 0) - glPopMatrix() - glEnable(GL_LIGHTING) - - glTranslate(0, -height + (height / len(self.quats) + 1), 0) - for telemetry_quat in self.quats: - glPushMatrix() - try: - scaled_quat = [telemetry_quat.qi * telemetry_quat.scale, telemetry_quat.qx * telemetry_quat.scale, telemetry_quat.qy * telemetry_quat.scale, telemetry_quat.qz * telemetry_quat.scale] - glRotate(360 * math.acos(scaled_quat[0] ) / math.pi, scaled_quat[2], -scaled_quat[3], -scaled_quat[1]) - glRotate(self.rotate_theta, 1, 0, 0) - - self.DrawVehicle(telemetry_quat.name) - except Exception: - raise Exception - finally: + def DrawBox(self, width, height, depth): + glPushMatrix() + glTranslate(0, 0, depth) + self.DrawQuad(width, height) + glTranslate(0, 0, -2 * depth) + self.DrawQuad(width, height) glPopMatrix() - glTranslate(0, 2 * height / (len(self.quats)), 0) - glPopMatrix() + + glPushMatrix() + glRotate(90, 1, 0, 0) + glTranslate(0, 0, height) + self.DrawQuad(width, depth) + glTranslate(0, 0, -2 * height) + self.DrawQuad(width, depth) + glPopMatrix() + + glPushMatrix() + glRotate(90, 0, 1, 0) + glTranslate(0, 0, width) + self.DrawQuad(depth, height) + glTranslate(0, 0, -2 * width) + self.DrawQuad(depth, height) + glPopMatrix() + + def DrawVehicle(self, name): + wingspan = 2.7 + separation = 0.7 + chord = 0.35 + thickness = 0.08 + strutcount = 3 + discradius = 0.45 + discseparation = 0.01 + + #wings + glColor3f(0.1, 0.1, 0.9) + glPushMatrix() + glTranslate(0, 0, 0.05) + self.DrawBox(wingspan, chord, thickness) + glColor3f(0.0, 0.0, 0.0) + glTranslate(-wingspan, -0.2, thickness + 0.01) + glScale(0.004, 0.004, 0.004) + for c in name: + glutStrokeCharacter(GLUT_STROKE_ROMAN, ord(c)) + glPopMatrix() + + glPushMatrix() + glTranslate(0, 0, -0.05) + glColor3f(0.6, 0.6, 0.2) + self.DrawBox(wingspan, chord, thickness) + glColor3f(0.0, 0.0, 0.0) + glTranslate(wingspan, -0.2, -0.01 - thickness) + glScale(0.004, 0.004, 0.004) + glRotate(180, 0, 1, 0) + for c in name: + glutStrokeCharacter(GLUT_STROKE_ROMAN, ord(c)) + glPopMatrix() + + if self.display_list is None: + self.display_list = glGenLists(1) + glNewList(self.display_list, GL_COMPILE) + # struts + glColor3f(0.4, 0.4, 0.4) + glPushMatrix() + glTranslate(-wingspan / 2, 0, separation / 2) + glRotate(90, 0, 1, 0) + for x in range(0, strutcount - 1): + self.DrawBox(separation / 2, chord - .01, thickness) + glTranslate(0, 0, wingspan) + glTranslate(separation, 0, -5 * wingspan / 2) + for x in range(0, strutcount - 1): + self.DrawBox(separation / 2, chord - .01, thickness) + glTranslate(0, 0, 2 * wingspan) + glPopMatrix() + + #rotors + glColor3f(0.9, 0.1, 0.1) + glPushMatrix() + glRotate(90, 1, 0, 0) + glTranslate(-wingspan / 2, separation, -(chord + .01)) + for x in range(0, strutcount): + if (x != strutcount / 2): + self.DrawCircle(discradius) + glTranslate(2 * wingspan / (strutcount + 1), 0, 0) + glPopMatrix() + + glPushMatrix() + glRotate(90, 1, 0, 0) + glTranslate(-wingspan, -separation, -(chord + .01)) + for x in range(0, strutcount): + if (x != strutcount / 2): + self.DrawCircle(discradius) + glTranslate(2 * wingspan / (strutcount - 1), 0, 0) + glPopMatrix() + glEndList() + + glCallList(self.display_list) + + def DrawBar(self, name, value): + bar_height = 0.12 + bar_length = 3 + glPushMatrix() + glColor3f(0, 0, 0) + glTranslate(-bar_length, -0.09, 0.02) + glScale(0.0015, 0.0015, 0.0015) + for c in name: + glutStrokeCharacter(GLUT_STROKE_ROMAN, ord(c)) + glPopMatrix() + glColor3f(0.92, 0.92, 0.92) + glPushMatrix() + glTranslate(0, 0, 0) + self.DrawQuad(bar_length, bar_height) + glPopMatrix() + glPushMatrix() + glTranslate(bar_length * value - bar_length, 0, 0.01) + glColor3f(0.6, 0.6, 0.6) + self.DrawQuad(bar_length * value, bar_height) + glPopMatrix() + + def Draw(self): + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) + + glPushMatrix() + + height = 5 + + glDisable(GL_LIGHTING) + glPushMatrix() + for graph_value in self.graph_values: + self.DrawBar(graph_value.name % (graph_value.value), graph_value.value / graph_value.max) + glTranslate(0, 0.35, 0) + glPopMatrix() + glEnable(GL_LIGHTING) + + glTranslate(0, -height + (height / len(self.quats) + 1), 0) + for telemetry_quat in self.quats: + glPushMatrix() + try: + scaled_quat = [telemetry_quat.qi * telemetry_quat.scale, telemetry_quat.qx * telemetry_quat.scale, + telemetry_quat.qy * telemetry_quat.scale, telemetry_quat.qz * telemetry_quat.scale] + glRotate(360 * math.acos(scaled_quat[0]) / math.pi, scaled_quat[2], -scaled_quat[3], -scaled_quat[1]) + glRotate(self.rotate_theta, 1, 0, 0) + + self.DrawVehicle(telemetry_quat.name) + except Exception: + raise Exception + finally: + glPopMatrix() + glTranslate(0, 2 * height / (len(self.quats)), 0) + glPopMatrix() + class Visualizer: - def __init__(self, rotate_theta): - self.rotate_theta = rotate_theta - self.visualization = Visualization(self) + def __init__(self, rotate_theta): + self.rotate_theta = rotate_theta + self.visualization = Visualization(self) - # listen to Ivy - logging.getLogger('Ivy').setLevel(logging.WARN) - IvyInit(_NAME, - "", - 0, - lambda x, y: y, - lambda x, z: z - ) + # listen to Ivy + logging.getLogger('Ivy').setLevel(logging.WARN) + IvyInit(_NAME, + "", + 0, + lambda x, y: y, + lambda x, z: z) - if os.getenv('IVY_BUS') != None: - IvyStart(os.getenv('IVY_BUS')) - else: - if platform.system() == 'Darwin': - IvyStart("224.255.255.255:2010") - else: - IvyStart() + if os.getenv('IVY_BUS') is not None: + IvyStart(os.getenv('IVY_BUS')) + else: + if platform.system() == 'Darwin': + IvyStart("224.255.255.255:2010") + else: + IvyStart() - # list of all message names - messages = [] + # list of all message names + messages = [] - # append all message names - for vehicle_quat in VEHICLE_QUATS: - messages.append(vehicle_quat[0]) - for bar_value in BAR_VALUES: - messages.append(bar_value[0]) + # append all message names + for vehicle_quat in VEHICLE_QUATS: + messages.append(vehicle_quat[0]) + for bar_value in BAR_VALUES: + messages.append(bar_value[0]) - # bind to set of messages (ie, only bind each message once) - for message_name in set(messages): - bind_string = "(^.*" + message_name + ".*$)" - IvyBindMsg(self.visualization.onmsgproc, bind_string) + # bind to set of messages (ie, only bind each message once) + for message_name in set(messages): + bind_string = "(^.*" + message_name + ".*$)" + IvyBindMsg(self.visualization.onmsgproc, bind_string) - def Draw(self): - if self.visualization.display_dirty: - self.visualization.Draw() - self.visualization.display_dirty = False + def Draw(self): + if self.visualization.display_dirty: + self.visualization.Draw() + self.visualization.display_dirty = False + + def OnClose(self): + IvyStop() - def OnClose(self): - IvyStop() SCREEN_SIZE = (800, 800) + def resize(width, height): - glViewport(0, 0, width, height) - glMatrixMode(GL_PROJECTION) - glLoadIdentity() - gluPerspective(60.0, float(width/height), .1, 100.) - glMatrixMode(GL_MODELVIEW) - glLoadIdentity() + glViewport(0, 0, width, height) + glMatrixMode(GL_PROJECTION) + glLoadIdentity() + gluPerspective(60.0, float(width / height), .1, 100.) + glMatrixMode(GL_MODELVIEW) + glLoadIdentity() + def init(): - glutInit() - glEnable(GL_LINE_SMOOTH) - glEnable(GL_DEPTH_TEST) - glEnable(GL_LIGHTING) - glEnable(GL_LIGHT0) - glEnable(GL_BLEND) - glShadeModel (GL_SMOOTH) - glClearColor(1.0, 1.0, 1.0, 1.0) - glClearDepth(1.0) + glutInit() + glEnable(GL_LINE_SMOOTH) + glEnable(GL_DEPTH_TEST) + glEnable(GL_LIGHTING) + glEnable(GL_LIGHT0) + glEnable(GL_BLEND) + glShadeModel(GL_SMOOTH) + glClearColor(1.0, 1.0, 1.0, 1.0) + glClearDepth(1.0) - glPointSize(3.0) + glPointSize(3.0) - glMatrixMode(GL_PROJECTION) - glLoadIdentity() - gluPerspective(7.0, 1.0, 95.0, 105.0) + glMatrixMode(GL_PROJECTION) + glLoadIdentity() + gluPerspective(7.0, 1.0, 95.0, 105.0) - glMatrixMode(GL_MODELVIEW) + glMatrixMode(GL_MODELVIEW) - glLight(GL_LIGHT0, GL_POSITION, [5, 30, -20]) - glLight(GL_LIGHT0, GL_AMBIENT, [0.5, 0.5, 0.5]) - glLight(GL_LIGHT0, GL_SPECULAR, [0.0, 0.0, 0.0]) - glLight(GL_LIGHT0, GL_DIFFUSE, [0.8, 0.8, 0.8]) - glEnable(GL_COLOR_MATERIAL) - glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE) + glLight(GL_LIGHT0, GL_POSITION, [5, 30, -20]) + glLight(GL_LIGHT0, GL_AMBIENT, [0.5, 0.5, 0.5]) + glLight(GL_LIGHT0, GL_SPECULAR, [0.0, 0.0, 0.0]) + glLight(GL_LIGHT0, GL_DIFFUSE, [0.8, 0.8, 0.8]) + glEnable(GL_COLOR_MATERIAL) + glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE) + + glMatrixMode(GL_MODELVIEW) + glLoadIdentity() + gluLookAt(0.0, 0.0, 100.0, + 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0) - glMatrixMode(GL_MODELVIEW) - glLoadIdentity() - gluLookAt(0.0, 0.0, 100.0, - 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0) def run(): - global VEHICLE_QUATS, BAR_VALUES - VEHICLE_QUATS = [ ["AHRS_REF_QUAT", 6, "Estimate", True], ["AHRS_REF_QUAT", 2, "Reference", True]] - BAR_VALUES = [ ["ROTORCRAFT_RADIO_CONTROL", 5, "Throttle (%%) %i", 0, 100, 100] ] - window_title = "Attitude_Viz" - rotate_theta = -90 - try: - opts, args = getopt.getopt(sys.argv[1:], "t:r:", ["title", "rotate_theta"]) - for o, a in opts: - if o in ("-t", "--title"): - window_title = a - if o in ("-r", "--rotate_theta"): - rotate_theta = int(a) - except getopt.error as msg: - print(msg) - print("""usage: + global VEHICLE_QUATS, BAR_VALUES + VEHICLE_QUATS = [["AHRS_REF_QUAT", 6, "Estimate", True], ["AHRS_REF_QUAT", 2, "Reference", True]] + BAR_VALUES = [["ROTORCRAFT_RADIO_CONTROL", 5, "Throttle (%%) %i", 0, 100, 100]] + window_title = "Attitude_Viz" + rotate_theta = -90 + try: + opts, args = getopt.getopt(sys.argv[1:], "t:r:", ["title", "rotate_theta"]) + for o, a in opts: + if o in ("-t", "--title"): + window_title = a + if o in ("-r", "--rotate_theta"): + rotate_theta = int(a) + except getopt.error as msg: + print(msg) + print("""usage: -t, --title set window title -r, --rotate_theta rotate the quaternion by n degrees over the pitch axis (default: -90) """) - pygame.init() - screen = pygame.display.set_mode(SCREEN_SIZE, pygame.OPENGL|pygame.DOUBLEBUF) - #resize(*SCREEN_SIZE) - init() - visualizer = Visualizer(rotate_theta) + pygame.init() + screen = pygame.display.set_mode(SCREEN_SIZE, pygame.OPENGL | pygame.DOUBLEBUF) + #resize(*SCREEN_SIZE) + init() + visualizer = Visualizer(rotate_theta) + + try: + while True: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + visualizer.OnClose() + return + if event.type == pygame.KEYUP and event.key == pygame.K_ESCAPE: + visualizer.OnClose() + return + visualizer.Draw() + pygame.display.flip() + time.sleep(.02) + except KeyboardInterrupt: + visualizer.OnClose() + return - try: - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: - visualizer.OnClose() - return - if event.type == pygame.KEYUP and event.key == pygame.K_ESCAPE: - visualizer.OnClose() - return - visualizer.Draw() - pygame.display.flip() - time.sleep(.02) - except KeyboardInterrupt: - visualizer.OnClose() - return if __name__ == "__main__": - run() + run() diff --git a/sw/lib/ocaml/expr_syntax.ml b/sw/lib/ocaml/expr_syntax.ml index d94a1cfe71..269f959b85 100644 --- a/sw/lib/ocaml/expr_syntax.ml +++ b/sw/lib/ocaml/expr_syntax.ml @@ -39,22 +39,32 @@ type expression = let c_var_of_ident = fun x -> "_var_" ^ x -let rec sprint = function -Ident i when i.[0] = '$' -> sprintf "%s" (c_var_of_ident (String.sub i 1 (String.length i - 1))) - | Ident i -> sprintf "%s" i - | Int i -> sprintf "%d" i - | Float i -> sprintf "%f" i - | CallOperator (op, [e1;e2]) -> - sprintf "(%s%s%s)" (sprint e1) op (sprint e2) - | CallOperator (op, [e1]) -> - sprintf "%s(%s)" op (sprint e1) - | CallOperator (_,_) -> failwith "Operator should be binary or unary" - | Call (i, es) -> - let ses = List.map sprint es in - sprintf "%s(%s)" i (String.concat "," ses) - | Index (i,e) -> sprintf "%s[%s]" i (sprint e) - | Field (i,f) -> sprintf "%s.%s" i f - | Deref (e,f) -> sprintf "(%s)->%s" (sprint e) f +let sprint = fun ?call_assoc expr -> + let n, l = match call_assoc with + | None -> None, [] + | Some (n, l) -> Some n, l + in + let rec eval = function + | Ident i when i.[0] = '$' -> sprintf "%s" (c_var_of_ident (String.sub i 1 (String.length i - 1))) + | Ident i -> sprintf "%s" i + | Int i -> sprintf "%d" i + | Float i -> sprintf "%f" i + | CallOperator (op, [e1;e2]) -> + sprintf "(%s%s%s)" (eval e1) op (eval e2) + | CallOperator (op, [e1]) -> + sprintf "%s(%s)" op (eval e1) + | CallOperator (_,_) -> failwith "Operator should be binary or unary" + | Call (i, [Ident s]) when Some i = n -> + let index = try List.assoc s l with Not_found -> failwith (sprintf "Unknown block: '%s'" s) in + sprintf "%d" index + | Call (i, es) -> + let ses = List.map eval es in + sprintf "%s(%s)" i (String.concat "," ses) + | Index (i,e) -> sprintf "%s[%s]" i (eval e) + | Field (i,f) -> sprintf "%s.%s" i f + | Deref (e,f) -> sprintf "(%s)->%s" (eval e) f + in + eval expr (* Valid functions : FIXME *) let functions = [ diff --git a/sw/lib/ocaml/expr_syntax.mli b/sw/lib/ocaml/expr_syntax.mli index ee57fbe537..46c6f30c23 100644 --- a/sw/lib/ocaml/expr_syntax.mli +++ b/sw/lib/ocaml/expr_syntax.mli @@ -37,7 +37,8 @@ type expression = val c_var_of_ident : ident -> string (** Encapsulate a user ident into a C variable *) -val sprint : expression -> string +val sprint : ?call_assoc:(ident * (ident * int) list) -> expression -> string +(** call_assoc: call an optional association list function *) exception Unknown_ident of string exception Unknown_operator of string diff --git a/sw/lib/ocaml/latlong.ml b/sw/lib/ocaml/latlong.ml index 1e7e3d689a..5862626830 100644 --- a/sw/lib/ocaml/latlong.ml +++ b/sw/lib/ocaml/latlong.ml @@ -469,9 +469,16 @@ let bearing = fun geo1 geo2 -> ((Rad>>Deg)(atan2 dx dy), sqrt(dx*.dx+.dy*.dy)) -let leap_seconds = 15 (* http://www.leapsecond.com/java/gpsclock.htm *) +(** Offset between GPS and UTC times in seconds. + * Update when a new leap second is inserted and be careful about times in the + * past when this offset was different. + * Last leap second was inserted on June 30, 2012 at 23:59:60 UTC + * http://www.leapsecond.com/java/gpsclock.htm + *) +let leap_seconds = 16 -let gps_epoch = 315964800. (* In seconds, in the unix reference *) +(** Unix timestamp of the GPS epoch 1980-01-06 00:00:00 UTC *) +let gps_epoch = 315964800. let gps_tow_of_utc = fun ?wday hour min sec -> let wday = diff --git a/sw/simulator/fg.c b/sw/simulator/fg.c index 63493b2a30..19bd9c7a91 100644 --- a/sw/simulator/fg.c +++ b/sw/simulator/fg.c @@ -41,7 +41,7 @@ value fg_msg_native(value s, value lat, value lon, value z, value phi, value the msg.num_tanks = 1; msg.fuel_quantity[0] = 10.; - msg.cur_time = 3213092700ul;//time(NULL); + msg.cur_time = 3213092700ul+((uint32_t)((msg.longitude)*13578)); //time(NULL); msg.warp = 0; msg.ground_elev = 0.; diff --git a/sw/simulator/nps/nps_autopilot.h b/sw/simulator/nps/nps_autopilot.h index 730c46cce0..04d8304d0b 100644 --- a/sw/simulator/nps/nps_autopilot.h +++ b/sw/simulator/nps/nps_autopilot.h @@ -11,10 +11,15 @@ struct NpsAutopilot { extern struct NpsAutopilot autopilot; +extern bool_t nps_bypass_ahrs; +extern bool_t nps_bypass_ins; +extern void sim_overwrite_ahrs(void); +extern void sim_overwrite_ins(void); + extern void nps_autopilot_init(enum NpsRadioControlType type, int num_script, char* js_dev); extern void nps_autopilot_run_step(double time); extern void nps_autopilot_run_systime_step(void); + #endif /* NPS_AUTOPILOT_H */ - diff --git a/sw/simulator/nps/nps_autopilot_fixedwing.c b/sw/simulator/nps/nps_autopilot_fixedwing.c index 27826df4e3..409a0c3a43 100644 --- a/sw/simulator/nps/nps_autopilot_fixedwing.c +++ b/sw/simulator/nps/nps_autopilot_fixedwing.c @@ -20,7 +20,7 @@ * Boston, MA 02111-1307, USA. */ -#include "nps_autopilot_fixedwing.h" +#include "nps_autopilot.h" #ifdef FBW #include "firmwares/fixedwing/main_fbw.h" @@ -50,14 +50,19 @@ #include "subsystems/commands.h" - struct NpsAutopilot autopilot; bool_t nps_bypass_ahrs; +bool_t nps_bypass_ins; #ifndef NPS_BYPASS_AHRS #define NPS_BYPASS_AHRS FALSE #endif +#ifndef NPS_BYPASS_INS +#define NPS_BYPASS_INS FALSE +#endif + + #if !defined (FBW) || !defined (AP) #error NPS does not currently support dual processor simulation for FBW and AP on fixedwing! #endif @@ -68,6 +73,7 @@ void nps_autopilot_init(enum NpsRadioControlType type_rc, int num_rc_script, cha nps_electrical_init(); nps_bypass_ahrs = NPS_BYPASS_AHRS; + nps_bypass_ins = NPS_BYPASS_INS; Fbw(init); Ap(init); @@ -105,8 +111,7 @@ void nps_autopilot_run_step(double time) { } if (nps_sensors_baro_available()) { - /** @todo feed baro values */ - //baro_feed_value(sensors.baro.value); + baro_feed_value(sensors.baro.value); Fbw(event_task); Ap(event_task); } @@ -121,6 +126,10 @@ void nps_autopilot_run_step(double time) { sim_overwrite_ahrs(); } + if (nps_bypass_ins) { + sim_overwrite_ins(); + } + Fbw(handle_periodic_tasks); Ap(handle_periodic_tasks); @@ -141,3 +150,19 @@ void sim_overwrite_ahrs(void) { stateSetBodyRates_f(&rates_f); } + +void sim_overwrite_ins(void) { + + struct NedCoor_f ltp_pos; + VECT3_COPY(ltp_pos, fdm.ltpprz_pos); + stateSetPositionNed_f(<p_pos); + + struct NedCoor_f ltp_speed; + VECT3_COPY(ltp_speed, fdm.ltpprz_ecef_vel); + stateSetSpeedNed_f(<p_speed); + + struct NedCoor_f ltp_accel; + VECT3_COPY(ltp_accel, fdm.ltpprz_ecef_accel); + stateSetAccelNed_f(<p_accel); + +} diff --git a/sw/simulator/nps/nps_autopilot_fixedwing.h b/sw/simulator/nps/nps_autopilot_fixedwing.h deleted file mode 100644 index a4d05a199b..0000000000 --- a/sw/simulator/nps/nps_autopilot_fixedwing.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef NPS_AUTOPILOT_FIXEDWING_H -#define NPS_AUTOPILOT_FIXEDWING_H - -#include "nps_autopilot.h" - - -extern bool_t nps_bypass_ahrs; -extern void sim_overwrite_ahrs(void); - -#endif /* NPS_AUTOPILOT_FIXEDWING_H */ diff --git a/sw/simulator/nps/nps_autopilot_rotorcraft.c b/sw/simulator/nps/nps_autopilot_rotorcraft.c index 6641cc5dc8..681d5bf5d8 100644 --- a/sw/simulator/nps/nps_autopilot_rotorcraft.c +++ b/sw/simulator/nps/nps_autopilot_rotorcraft.c @@ -19,7 +19,7 @@ * Boston, MA 02111-1307, USA. */ -#include "nps_autopilot_rotorcraft.h" +#include "nps_autopilot.h" #include "firmwares/rotorcraft/main.h" #include "nps_sensors.h" diff --git a/sw/simulator/nps/nps_autopilot_rotorcraft.h b/sw/simulator/nps/nps_autopilot_rotorcraft.h deleted file mode 100644 index b71ffd7eb8..0000000000 --- a/sw/simulator/nps/nps_autopilot_rotorcraft.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef NPS_AUTOPILOT_ROTORCRAFT_H -#define NPS_AUTOPILOT_ROTORCRAFT_H - -#include "nps_autopilot.h" - - -extern bool_t nps_bypass_ahrs; -extern bool_t nps_bypass_ins; -extern void sim_overwrite_ahrs(void); -extern void sim_overwrite_ins(void); - -#endif /* NPS_AUTOPILOT_ROTORCRAFT_H */ diff --git a/sw/simulator/nps/nps_ivy_rotorcraft.c b/sw/simulator/nps/nps_ivy_rotorcraft.c index bf0ef5562b..afb4764d7d 100644 --- a/sw/simulator/nps/nps_ivy_rotorcraft.c +++ b/sw/simulator/nps/nps_ivy_rotorcraft.c @@ -8,8 +8,8 @@ #include "nps_autopilot.h" #include "nps_fdm.h" #include "nps_sensors.h" -#include "subsystems/ins.h" #include "firmwares/rotorcraft/navigation.h" +#include "state.h" #ifdef RADIO_CONTROL_TYPE_DATALINK #include "subsystems/radio_control.h" @@ -31,7 +31,6 @@ void nps_ivy_init(char* ivy_bus) { } -//TODO use datalink parsing from rotorcraft instead of doing it here explicitly #include "generated/settings.h" #include "dl_protocol.h" @@ -43,16 +42,13 @@ static void on_DL_MOVE_WP(IvyClientPtr app __attribute__ ((unused)), uint8_t wp_id = atoi(argv[1]); struct LlaCoor_i lla; - struct EnuCoor_i enu; lla.lat = INT32_RAD_OF_DEG(atoi(argv[3])); lla.lon = INT32_RAD_OF_DEG(atoi(argv[4])); - lla.alt = atoi(argv[5])*10 - ins_ltp_def.hmsl + ins_ltp_def.lla.alt; - enu_of_lla_point_i(&enu,&ins_ltp_def,&lla); - enu.x = POS_BFP_OF_REAL(enu.x)/100; - enu.y = POS_BFP_OF_REAL(enu.y)/100; - enu.z = POS_BFP_OF_REAL(enu.z)/100; - VECT3_ASSIGN(waypoints[wp_id], enu.x, enu.y, enu.z); - DOWNLINK_SEND_WP_MOVED_ENU(DefaultChannel, DefaultDevice, &wp_id, &enu.x, &enu.y, &enu.z); - printf("move wp id=%d x=%d y=%d z=%d\n", wp_id, enu.x, enu.y, enu.z); + /* WP_alt from message is alt above MSL in cm + * lla.alt is above ellipsoid in mm + */ + lla.alt = atoi(argv[5]) *10 - state.ned_origin_i.hmsl + state.ned_origin_i.lla.alt; + nav_move_waypoint_lla(wp_id, &lla); + printf("move wp id=%d x=%d y=%d z=%d\n", wp_id, waypoints[wp_id].x, waypoints[wp_id].y, waypoints[wp_id].z); } } diff --git a/sw/simulator/nps/nps_sensor_baro.c b/sw/simulator/nps/nps_sensor_baro.c index f0fdce2686..22ca9f9a4c 100644 --- a/sw/simulator/nps/nps_sensor_baro.c +++ b/sw/simulator/nps/nps_sensor_baro.c @@ -1,6 +1,7 @@ #include "nps_sensor_baro.h" #include "generated/airframe.h" +#include "math/pprz_isa.h" #include "std.h" #include "nps_fdm.h" @@ -21,15 +22,10 @@ void nps_sensor_baro_run_step(struct NpsSensorBaro* baro, double time) { if (time < baro->next_update) return; - /*if (time < 10.) - baro->value = rint(time*90); - else {*/ - double z = fdm.ltpprz_pos.z + get_gaussian_noise()*NPS_BARO_NOISE_STD_DEV; - double baro_reading = NPS_BARO_QNH + z * NPS_BARO_SENSITIVITY; - baro_reading = rint(baro_reading); - baro->value = baro_reading; - Bound(baro->value, 0, 1024); - //} + /* pressure in Pascal */ + baro->value = pprz_isa_pressure_of_altitude(fdm.hmsl); + /* add noise with std dev Pascal */ + baro->value += get_gaussian_noise() * NPS_BARO_NOISE_STD_DEV; baro->next_update += NPS_BARO_DT; baro->data_available = TRUE; diff --git a/sw/simulator/nps/nps_sensor_baro.h b/sw/simulator/nps/nps_sensor_baro.h index 06630b066d..0a07c4a04c 100644 --- a/sw/simulator/nps/nps_sensor_baro.h +++ b/sw/simulator/nps/nps_sensor_baro.h @@ -7,7 +7,7 @@ #include "std.h" struct NpsSensorBaro { - double value; + double value; ///< pressure in Pascal double next_update; bool_t data_available; }; diff --git a/sw/tools/calibration/calibrate.py b/sw/tools/calibration/calibrate.py index c67aa7df0b..082545f995 100755 --- a/sw/tools/calibration/calibrate.py +++ b/sw/tools/calibration/calibrate.py @@ -30,6 +30,7 @@ from scipy import optimize import calibration_utils + def main(): usage = "usage: %prog [options] log_filename.data" + "\n" + "Run %prog --help to list the options." parser = OptionParser(usage) @@ -58,7 +59,7 @@ def main(): print(args[0] + " not found") sys.exit(1) ac_ids = calibration_utils.get_ids_in_log(filename) - if options.ac_id == None: + if options.ac_id is None: if len(ac_ids) == 1: options.ac_id = ac_ids[0] else: @@ -69,13 +70,13 @@ def main(): if options.sensor == "ACCEL": sensor_ref = 9.81 sensor_res = 10 - noise_window = 20; - noise_threshold = 40; + noise_window = 20 + noise_threshold = 40 elif options.sensor == "MAG": sensor_ref = 1. sensor_res = 11 - noise_window = 10; - noise_threshold = 1000; + noise_window = 10 + noise_threshold = 1000 if not filename.endswith(".data"): parser.error("Please specify a *.data log file") @@ -88,7 +89,7 @@ def main(): print("Error: found zero IMU_"+options.sensor+"_RAW measurements for aircraft with id "+options.ac_id+" in log file!") sys.exit(1) if options.verbose: - print("found "+str(len(measurements))+" records") + print("found "+str(len(measurements))+" records") # estimate the noise threshold # find the median of measurement vector lenght diff --git a/sw/tools/calibration/calibrate_gyro.py b/sw/tools/calibration/calibrate_gyro.py index 7f2970e0fd..77aac9f076 100755 --- a/sw/tools/calibration/calibrate_gyro.py +++ b/sw/tools/calibration/calibrate_gyro.py @@ -87,7 +87,7 @@ def main(): if options.verbose: print("reading file "+filename+" for aircraft "+str(options.ac_id)+" and turntable "+str(options.tt_id)) - samples = calibration_utils.read_turntable_log(options.ac_id, options.tt_id, filename, 1, 7) + samples = calibration_utils.read_turntable_log(options.ac_id, options.tt_id, filename, 1, 7) if len(samples) == 0: print("Error: found zero matching messages in log file!") @@ -106,13 +106,13 @@ def main(): parser.error("Specify a valid axis!") #Linear regression using stats.linregress - t = samples[:, 0] + t = samples[:, 0] xn = samples[:, axis_idx] - (a_s, b_s, r, tt, stderr)=stats.linregress(t, xn) + (a_s, b_s, r, tt, stderr) = stats.linregress(t, xn) print('Linear regression using stats.linregress') print(('regression: a=%.2f b=%.2f, std error= %.3f' % (a_s, b_s, stderr))) - print(('' % (b_s))); - print(('' % (pow(2, 12)/a_s))); + print(('' % (b_s))) + print(('' % (pow(2, 12)/a_s))) # # overlay fited value @@ -125,7 +125,7 @@ def main(): plot(samples[:, 1]) plot(samples[:, 2]) plot(samples[:, 3]) - legend(['p', 'q', 'r']); + legend(['p', 'q', 'r']) subplot(3, 1, 2) plot(samples[:, 0]) @@ -134,7 +134,7 @@ def main(): plot(samples[:, 0], samples[:, axis_idx], 'b.') plot(ovl_omega, ovl_adc, 'r') - show(); + show() if __name__ == "__main__": diff --git a/sw/tools/calibration/calibrate_mag_current.py b/sw/tools/calibration/calibrate_mag_current.py index d93f6cfc64..6779f0f9a1 100755 --- a/sw/tools/calibration/calibrate_mag_current.py +++ b/sw/tools/calibration/calibrate_mag_current.py @@ -49,7 +49,7 @@ def main(): print(args[0] + " not found") sys.exit(1) ac_ids = calibration_utils.get_ids_in_log(filename) - if options.ac_id == None: + if options.ac_id is None: if len(ac_ids) == 1: options.ac_id = ac_ids[0] else: @@ -57,10 +57,6 @@ def main(): if options.verbose: print("Using aircraft id "+options.ac_id) - sensor_ref = 1. - sensor_res = 11 - noise_window = 10; - noise_threshold = 1000; if not filename.endswith(".data"): parser.error("Please specify a *.data log file") @@ -73,7 +69,7 @@ def main(): print("Error: found zero IMU_MAG_CURRENT_CALIBRATION measurements for aircraft with id "+options.ac_id+" in log file!") sys.exit(1) if options.verbose: - print("found "+str(len(measurements))+" records") + print("found "+str(len(measurements))+" records") coefficient = calibration_utils.estimate_mag_current_relation(measurements) diff --git a/sw/tools/calibration/calibration_utils.py b/sw/tools/calibration/calibration_utils.py index 0cc8f54b75..4fc13aab6c 100644 --- a/sw/tools/calibration/calibration_utils.py +++ b/sw/tools/calibration/calibration_utils.py @@ -38,7 +38,7 @@ def get_ids_in_log(filename): line = f.readline().strip() if line == '': break - m=re.match(pattern, line) + m = re.match(pattern, line) if m: id = m.group(1) if not id in ids: @@ -56,7 +56,7 @@ def read_log(ac_id, filename, sensor): line = f.readline().strip() if line == '': break - m=re.match(pattern, line) + m = re.match(pattern, line) if m: list_meas.append([float(m.group(2)), float(m.group(3)), float(m.group(4))]) return scipy.array(list_meas) @@ -72,7 +72,7 @@ def read_log_mag_current(ac_id, filename): line = f.readline().strip() if line == '': break - m=re.match(pattern, line) + m = re.match(pattern, line) if m: list_meas.append([float(m.group(2)), float(m.group(3)), float(m.group(4)), float(m.group(5))]) return scipy.array(list_meas) @@ -106,8 +106,8 @@ def get_min_max_guess(meas, scale): # scale the set of measurements # def scale_measurements(meas, p): - l_comp = []; - l_norm = []; + l_comp = [] + l_norm = [] for m in meas[:,]: sm = (m - p[0:3])*p[3:6] l_comp.append(sm) @@ -120,7 +120,7 @@ def scale_measurements(meas, p): def estimate_mag_current_relation(meas): coefficient = [] for i in range(0,3): - gradient, intercept, r_value, p_value, std_err = stats.linregress(meas[:,3],meas[:,i]) + gradient, intercept, r_value, p_value, std_err = stats.linregress(meas[:,3], meas[:,i]) coefficient.append(gradient) return coefficient @@ -154,26 +154,26 @@ def plot_results(block, measurements, flt_idx, flt_meas, cp0, np0, cp1, np1, sen title('Raw sensors') subplot(3, 2, 3) - plot(cp0[:, 0]); - plot(cp0[:, 1]); - plot(cp0[:, 2]); - plot(-sensor_ref*scipy.ones(len(flt_meas))); - plot(sensor_ref*scipy.ones(len(flt_meas))); + plot(cp0[:, 0]) + plot(cp0[:, 1]) + plot(cp0[:, 2]) + plot(-sensor_ref*scipy.ones(len(flt_meas))) + plot(sensor_ref*scipy.ones(len(flt_meas))) subplot(3, 2, 4) - plot(np0); - plot(sensor_ref*scipy.ones(len(flt_meas))); + plot(np0) + plot(sensor_ref*scipy.ones(len(flt_meas))) subplot(3, 2, 5) - plot(cp1[:, 0]); - plot(cp1[:, 1]); - plot(cp1[:, 2]); - plot(-sensor_ref*scipy.ones(len(flt_meas))); - plot(sensor_ref*scipy.ones(len(flt_meas))); + plot(cp1[:, 0]) + plot(cp1[:, 1]) + plot(cp1[:, 2]) + plot(-sensor_ref*scipy.ones(len(flt_meas))) + plot(sensor_ref*scipy.ones(len(flt_meas))) subplot(3, 2, 6) - plot(np1); - plot(sensor_ref*scipy.ones(len(flt_meas))); + plot(np1) + plot(sensor_ref*scipy.ones(len(flt_meas))) # if we want to have another plot we only draw the figure (non-blocking) # also in matplotlib before 1.0.0 there is only one call to show possible @@ -187,14 +187,14 @@ def plot_results(block, measurements, flt_idx, flt_meas, cp0, np0, cp1, np1, sen # def plot_mag_3d(measured, calibrated, p): # set up points for sphere and ellipsoid wireframes - u=r_[0:2*pi:20j] - v=r_[0:pi:20j] - wx=outer(cos(u),sin(v)) - wy=outer(sin(u),sin(v)) - wz=outer(ones(size(u)),cos(v)) - ex=p[0]*ones(size(u)) + outer(cos(u),sin(v))/p[3] - ey=p[1]*ones(size(u)) + outer(sin(u),sin(v))/p[4] - ez=p[2]*ones(size(u)) + outer(ones(size(u)),cos(v))/p[5] + u = r_[0:2 * pi:20j] + v = r_[0:pi:20j] + wx = outer(cos(u), sin(v)) + wy = outer(sin(u), sin(v)) + wz = outer(ones(size(u)), cos(v)) + ex = p[0] * ones(size(u)) + outer(cos(u), sin(v)) / p[3] + ey = p[1] * ones(size(u)) + outer(sin(u), sin(v)) / p[4] + ez = p[2] * ones(size(u)) + outer(ones(size(u)), cos(v)) / p[5] # measurements mx = measured[:, 0] @@ -228,10 +228,10 @@ def plot_mag_3d(measured, calibrated, p): ax.plot_wireframe(ex, ey, ez, color='grey', alpha=0.5) # Create cubic bounding box to simulate equal aspect ratio - max_range = np.array([mx.max()-mx.min(), my.max()-my.min(), mz.max()-mz.min()]).max() - Xb = 0.5*max_range*np.mgrid[-1:2:2,-1:2:2,-1:2:2][0].flatten() + 0.5*(mx.max()+mx.min()) - Yb = 0.5*max_range*np.mgrid[-1:2:2,-1:2:2,-1:2:2][1].flatten() + 0.5*(my.max()+my.min()) - Zb = 0.5*max_range*np.mgrid[-1:2:2,-1:2:2,-1:2:2][2].flatten() + 0.5*(mz.max()+mz.min()) + max_range = np.array([mx.max() - mx.min(), my.max() - my.min(), mz.max() - mz.min()]).max() + Xb = 0.5 * max_range * np.mgrid[-1:2:2, -1:2:2, -1:2:2][0].flatten() + 0.5 * (mx.max() + mx.min()) + Yb = 0.5 * max_range * np.mgrid[-1:2:2, -1:2:2, -1:2:2][1].flatten() + 0.5 * (my.max() + my.min()) + Zb = 0.5 * max_range * np.mgrid[-1:2:2, -1:2:2, -1:2:2][2].flatten() + 0.5 * (mz.max() + mz.min()) # uncomment following both lines to test the fake bounding box: #for xb, yb, zb in zip(Xb, Yb, Zb): # ax.plot([xb], [yb], [zb], 'r*') @@ -241,7 +241,6 @@ def plot_mag_3d(measured, calibrated, p): ax.set_ylabel('y') ax.set_zlabel('z') - if matplotlib.__version__.startswith('0'): ax = Axes3D(fig, rect=rect_r) else: @@ -273,10 +272,10 @@ def read_turntable_log(ac_id, tt_id, filename, _min, _max): line = f.readline().strip() if line == '': break - m=re.match(pattern_t, line) + m = re.match(pattern_t, line) if m: last_tt = float(m.group(2)) - m=re.match(pattern_g, line) + m = re.match(pattern_g, line) if m and last_tt and last_tt > _min and last_tt < _max: list_tt.append([last_tt, float(m.group(2)), float(m.group(3)), float(m.group(4))]) return scipy.array(list_tt) diff --git a/sw/tools/gen_abi.ml b/sw/tools/gen_abi.ml index 2b2eb95a10..d8b5010a58 100644 --- a/sw/tools/gen_abi.ml +++ b/sw/tools/gen_abi.ml @@ -92,17 +92,17 @@ module Gen_onboard = struct let print_struct = fun h size -> Printf.fprintf h "\n/* Array and linked list structure */\n"; Printf.fprintf h "#define ABI_MESSAGE_NB %d\n\n" (size+1); - Printf.fprintf h "EXTERN abi_event* abi_queues[ABI_MESSAGE_NB];\n" + Printf.fprintf h "ABI_EXTERN abi_event* abi_queues[ABI_MESSAGE_NB];\n" (* Print arguments' function from fields *) - let print_args = fun h fields starter -> + let print_args = fun h fields -> let rec args = fun h l -> match l with [] -> Printf.fprintf h ")" - | [(n,t)] -> Printf.fprintf h "const %s %s)" t n - | (n,t)::l' -> Printf.fprintf h "const %s %s, " t n; args h l' + | [(n,t)] -> Printf.fprintf h ", const %s * %s)" t n + | (n,t)::l' -> Printf.fprintf h ", const %s * %s" t n; args h l' in - Printf.fprintf h "(%s" starter; + Printf.fprintf h "(uint8_t sender_id"; args h fields (* Print callbacks prototypes for all messages *) @@ -110,7 +110,7 @@ module Gen_onboard = struct Printf.fprintf h "\n/* Callbacks */\n"; List.iter (fun msg -> Printf.fprintf h "typedef void (*abi_callback%s)" (String.capitalize msg.name); - print_args h msg.fields ""; + print_args h msg.fields; Printf.fprintf h ";\n"; ) messages @@ -129,18 +129,18 @@ module Gen_onboard = struct let rec args = fun h l -> match l with [] -> Printf.fprintf h ");\n" - | [(n,_)] -> Printf.fprintf h "%s);\n" n - | (n,_)::l' -> Printf.fprintf h "%s, " n; args h l' + | [(n,_)] -> Printf.fprintf h ", %s);\n" n + | (n,_)::l' -> Printf.fprintf h ", %s" n; args h l' in let name = String.capitalize msg.name in Printf.fprintf h "\nstatic inline void AbiSendMsg%s" name; - print_args h msg.fields "uint8_t sender_id, "; + print_args h msg.fields; Printf.fprintf h " {\n"; Printf.fprintf h " abi_event* e;\n"; Printf.fprintf h " ABI_FOREACH(abi_queues[ABI_%s_ID],e) {\n" name; Printf.fprintf h " if (e->id == ABI_BROADCAST || e->id == sender_id) {\n"; Printf.fprintf h " abi_callback%s cb = (abi_callback%s)(e->cb);\n" name name; - Printf.fprintf h " cb("; + Printf.fprintf h " cb(sender_id"; args h msg.fields; Printf.fprintf h " };\n"; Printf.fprintf h " };\n"; diff --git a/sw/tools/gen_flight_plan.ml b/sw/tools/gen_flight_plan.ml index 972704966b..d0f466edf2 100644 --- a/sw/tools/gen_flight_plan.ml +++ b/sw/tools/gen_flight_plan.ml @@ -36,6 +36,8 @@ let georef_of_xml = fun xml -> let sof = string_of_float let soi = string_of_int +let index_of_blocks = ref [] + let check_expressions = ref false let cm = fun x -> 100. *. x @@ -55,7 +57,7 @@ let parse = fun s -> | Expr_syntax.Unknown_function x -> unexpected "function" x end end; - Expr_syntax.sprint e + Expr_syntax.sprint ~call_assoc:("IndexOfBlock", !index_of_blocks) e let parsed_attrib = fun xml a -> parse (ExtXml.attrib xml a) @@ -126,8 +128,6 @@ let print_waypoint_lla = fun utm0 default_alt waypoint -> printf " {%d, %d, %.0f}, /* 1e7deg, 1e7deg, cm (hmsl=%.2fm) */ \\\n" (convert_angle wgs84.posn_lat) (convert_angle wgs84.posn_long) (100. *. float_of_string alt) (Egm96.of_wgs84 wgs84) -let index_of_blocks = ref [] - let get_index_block = fun x -> try List.assoc x !index_of_blocks @@ -481,6 +481,13 @@ let rec print_stage = fun index_of_waypoints x -> let statement = ExtXml.attrib x "fun" in lprintf "if (! (%s))\n" statement; lprintf " NextStageAndBreak();\n"; + begin + try + let c = parsed_attrib x "until" in + lprintf "if (%s) NextStageAndBreak();\n" c + with + ExtXml.Error _ -> () + end; lprintf "break;\n" | "survey_rectangle" -> let grid = parsed_attrib x "grid" @@ -495,6 +502,13 @@ let rec print_stage = fun index_of_waypoints x -> left (); stage (); lprintf "NavSurveyRectangle(%s, %s);\n" wp1 wp2; + begin + try + let c = parsed_attrib x "until" in + lprintf "if (%s) NextStageAndBreak();\n" c + with + ExtXml.Error _ -> () + end; lprintf "break;\n" | _s -> failwith "Unreachable" end; @@ -785,6 +799,9 @@ let () = lprintf "};\n"; Xml2h.define "NB_WAYPOINT" (string_of_int (List.length waypoints)); + Xml2h.define "FP_BLOCKS" "{ \\"; + List.iter (fun b -> printf " { \"%s\" }, \\\n" (ExtXml.attrib b "name")) blocks; + lprintf "};\n"; Xml2h.define "NB_BLOCK" (string_of_int (List.length blocks)); Xml2h.define "GROUND_ALT" (sof !ground_alt); @@ -794,15 +811,6 @@ let () = Xml2h.define "HOME_MODE_HEIGHT" (sof home_mode_height); Xml2h.define "MAX_DIST_FROM_HOME" (sof mdfh); - (** Print defines for blocks **) - lprintf "\n"; - let idx = ref 0 in - List.iter - (fun s -> - let v = ExtXml.attrib s "name" in - lprintf "#define BLOCK_%s %d\n" (Str.global_replace (Str.regexp "[\\. ]") "_" v) !idx; incr idx) blocks; - lprintf "\n"; - let index_of_waypoints = let i = ref (-1) in List.map (fun w -> incr i; (name_of w, !i)) waypoints in diff --git a/sw/tools/gen_settings.ml b/sw/tools/gen_settings.ml index 087d477f22..e959b8e400 100644 --- a/sw/tools/gen_settings.ml +++ b/sw/tools/gen_settings.ml @@ -69,14 +69,10 @@ let print_dl_settings = fun settings -> lprintf "\n"; (** Datalink knowing what settings mean **) - let idx = ref 0 in - lprintf "\n"; - List.iter - (fun s -> - let v = ExtXml.attrib s "var" in - lprintf "#define SETTINGS_%s %d\n" (Str.global_replace (Str.regexp "\\.") "_" v) !idx; incr idx) - settings; - lprintf "\n"; + Xml2h.define "SETTINGS" "{ \\"; + List.iter (fun b -> printf " { \"%s\" }, \\\n" (ExtXml.attrib b "var")) settings; + lprintf "};\n"; + Xml2h.define "NB_SETTING" (string_of_int (List.length settings)); (** Macro to call to set one variable *) lprintf "#define DlSetting(_idx, _value) { \\\n";