diff --git a/.gitignore b/.gitignore
index 4cc7b9421a..de78b4a36c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -94,6 +94,7 @@
/sw/ground_segment/tmtc/diadec
/sw/ground_segment/tmtc/ivy_serial_bridge
/sw/ground_segment/tmtc/GSM/SMS_GS
+/sw/ground_segment/tmtc/app_server
/sw/ground_segment/tmtc/gpsd2ivy
# /sw/ground_segment/joystick
@@ -140,13 +141,13 @@
/sw/supervision/gtk_pc.ml
# /sw/tools/
-/sw/tools/fp_parser.ml
/sw/tools/wiki_gen/wiki_gen
/sw/tools/mergelogs
# /sw/ground_segment/misc
/sw/ground_segment/misc/davis2ivy
/sw/ground_segment/misc/kestrel2ivy
+/sw/ground_segment/misc/natnet2ivy
# /sw/airborne/arch/lpc21/test/bootloader
diff --git a/Makefile b/Makefile
index 294068a846..6a00332709 100644
--- a/Makefile
+++ b/Makefile
@@ -64,7 +64,7 @@ SIMULATOR=sw/simulator
MULTIMON=sw/ground_segment/multimon
COCKPIT=sw/ground_segment/cockpit
TMTC=sw/ground_segment/tmtc
-TOOLS=$(PAPARAZZI_SRC)/sw/tools
+GENERATORS=$(PAPARAZZI_SRC)/sw/tools/generators
JOYSTICK=sw/ground_segment/joystick
EXT=sw/ext
@@ -121,7 +121,7 @@ conf/%.xml :conf/%_example.xml
ground_segment: print_build_version update_google_version conf libpprz subdirs commands static
ground_segment.opt: ground_segment cockpit.opt tmtc.opt
-static: cockpit tmtc tools sim_static joystick static_h
+static: cockpit tmtc generators sim_static joystick static_h
libpprz:
$(MAKE) -C $(LIB)/ocaml
@@ -141,8 +141,8 @@ tmtc: libpprz cockpit multimon
tmtc.opt: libpprz cockpit.opt multimon
$(MAKE) -C $(TMTC) opt
-tools: libpprz
- $(MAKE) -C $(TOOLS)
+generators: libpprz
+ $(MAKE) -C $(GENERATORS)
joystick: libpprz
$(MAKE) -C $(JOYSTICK)
@@ -168,68 +168,68 @@ $(LOGALIZER): libpprz
static_h: $(GEN_HEADERS)
-$(MESSAGES_H) : $(MESSAGES_XML) tools
+$(MESSAGES_H) : $(MESSAGES_XML) generators
$(Q)test -d $(STATICINCLUDE) || mkdir -p $(STATICINCLUDE)
@echo GENERATE $@
$(eval $@_TMP := $(shell $(MKTEMP)))
- $(Q)PAPARAZZI_SRC=$(PAPARAZZI_SRC) PAPARAZZI_HOME=$(PAPARAZZI_HOME) $(TOOLS)/gen_messages.out $< telemetry > $($@_TMP)
+ $(Q)PAPARAZZI_SRC=$(PAPARAZZI_SRC) PAPARAZZI_HOME=$(PAPARAZZI_HOME) $(GENERATORS)/gen_messages.out $< telemetry > $($@_TMP)
$(Q)mv $($@_TMP) $@
$(Q)chmod a+r $@
-$(MESSAGES2_H) : $(MESSAGES_XML) tools
+$(MESSAGES2_H) : $(MESSAGES_XML) generators
$(Q)test -d $(STATICINCLUDE) || mkdir -p $(STATICINCLUDE)
@echo GENERATE $@
$(eval $@_TMP := $(shell $(MKTEMP)))
- $(Q)PAPARAZZI_SRC=$(PAPARAZZI_SRC) PAPARAZZI_HOME=$(PAPARAZZI_HOME) $(TOOLS)/gen_messages2.out $< telemetry > $($@_TMP)
+ $(Q)PAPARAZZI_SRC=$(PAPARAZZI_SRC) PAPARAZZI_HOME=$(PAPARAZZI_HOME) $(GENERATORS)/gen_messages2.out $< telemetry > $($@_TMP)
$(Q)mv $($@_TMP) $@
$(Q)chmod a+r $@
-$(UBX_PROTOCOL_H) : $(UBX_XML) tools
+$(UBX_PROTOCOL_H) : $(UBX_XML) generators
@echo GENERATE $@
$(eval $@_TMP := $(shell $(MKTEMP)))
- $(Q)PAPARAZZI_SRC=$(PAPARAZZI_SRC) PAPARAZZI_HOME=$(PAPARAZZI_HOME) $(TOOLS)/gen_ubx.out $< > $($@_TMP)
+ $(Q)PAPARAZZI_SRC=$(PAPARAZZI_SRC) PAPARAZZI_HOME=$(PAPARAZZI_HOME) $(GENERATORS)/gen_ubx.out $< > $($@_TMP)
$(Q)mv $($@_TMP) $@
$(Q)chmod a+r $@
-$(MTK_PROTOCOL_H) : $(MTK_XML) tools
+$(MTK_PROTOCOL_H) : $(MTK_XML) generators
@echo GENERATE $@
$(eval $@_TMP := $(shell $(MKTEMP)))
- $(Q)PAPARAZZI_SRC=$(PAPARAZZI_SRC) PAPARAZZI_HOME=$(PAPARAZZI_HOME) $(TOOLS)/gen_mtk.out $< > $($@_TMP)
+ $(Q)PAPARAZZI_SRC=$(PAPARAZZI_SRC) PAPARAZZI_HOME=$(PAPARAZZI_HOME) $(GENERATORS)/gen_mtk.out $< > $($@_TMP)
$(Q)mv $($@_TMP) $@
$(Q)chmod a+r $@
-$(XSENS_PROTOCOL_H) : $(XSENS_XML) tools
+$(XSENS_PROTOCOL_H) : $(XSENS_XML) generators
@echo GENERATE $@
$(eval $@_TMP := $(shell $(MKTEMP)))
- $(Q)PAPARAZZI_SRC=$(PAPARAZZI_SRC) PAPARAZZI_HOME=$(PAPARAZZI_HOME) $(TOOLS)/gen_xsens.out $< > $($@_TMP)
+ $(Q)PAPARAZZI_SRC=$(PAPARAZZI_SRC) PAPARAZZI_HOME=$(PAPARAZZI_HOME) $(GENERATORS)/gen_xsens.out $< > $($@_TMP)
$(Q)mv $($@_TMP) $@
$(Q)chmod a+r $@
-$(DL_PROTOCOL_H) : $(MESSAGES_XML) tools
+$(DL_PROTOCOL_H) : $(MESSAGES_XML) generators
@echo GENERATE $@
$(eval $@_TMP := $(shell $(MKTEMP)))
- $(Q)PAPARAZZI_SRC=$(PAPARAZZI_SRC) PAPARAZZI_HOME=$(PAPARAZZI_HOME) $(TOOLS)/gen_messages.out $< datalink > $($@_TMP)
+ $(Q)PAPARAZZI_SRC=$(PAPARAZZI_SRC) PAPARAZZI_HOME=$(PAPARAZZI_HOME) $(GENERATORS)/gen_messages.out $< datalink > $($@_TMP)
$(Q)mv $($@_TMP) $@
$(Q)chmod a+r $@
-$(DL_PROTOCOL2_H) : $(MESSAGES_XML) tools
+$(DL_PROTOCOL2_H) : $(MESSAGES_XML) generators
@echo GENERATE $@
$(eval $@_TMP := $(shell $(MKTEMP)))
- $(Q)PAPARAZZI_SRC=$(PAPARAZZI_SRC) PAPARAZZI_HOME=$(PAPARAZZI_HOME) $(TOOLS)/gen_messages2.out $< datalink > $($@_TMP)
+ $(Q)PAPARAZZI_SRC=$(PAPARAZZI_SRC) PAPARAZZI_HOME=$(PAPARAZZI_HOME) $(GENERATORS)/gen_messages2.out $< datalink > $($@_TMP)
$(Q)mv $($@_TMP) $@
$(Q)chmod a+r $@
-$(ABI_MESSAGES_H) : $(ABI_XML) tools
+$(ABI_MESSAGES_H) : $(ABI_XML) generators
@echo GENERATE $@
$(eval $@_TMP := $(shell $(MKTEMP)))
- $(Q)PAPARAZZI_SRC=$(PAPARAZZI_SRC) PAPARAZZI_HOME=$(PAPARAZZI_HOME) $(TOOLS)/gen_abi.out $< airborne > $($@_TMP)
+ $(Q)PAPARAZZI_SRC=$(PAPARAZZI_SRC) PAPARAZZI_HOME=$(PAPARAZZI_HOME) $(GENERATORS)/gen_abi.out $< airborne > $($@_TMP)
$(Q)mv $($@_TMP) $@
$(Q)chmod a+r $@
include Makefile.ac
-ac_h ac fbw ap: static conf tools ext
+ac_h ac fbw ap: static conf generators ext
sim: sim_static
@@ -307,7 +307,7 @@ test: all replace_current_conf_xml run_tests restore_conf_xml
.PHONY: all print_build_version update_google_version dox ground_segment ground_segment.opt \
-subdirs $(SUBDIRS) conf ext libpprz multimon cockpit cockpit.opt tmtc tmtc.opt tools\
+subdirs $(SUBDIRS) conf ext libpprz multimon cockpit cockpit.opt tmtc tmtc.opt generators\
static sim_static lpctools commands \
clean cleanspaces ab_clean dist_clean distclean dist_clean_irreversible \
test replace_current_conf_xml run_tests restore_conf_xml
diff --git a/Makefile.ac b/Makefile.ac
index 9939768bcd..b2f40075c6 100644
--- a/Makefile.ac
+++ b/Makefile.ac
@@ -31,7 +31,7 @@ AIRBORNE=sw/airborne
MESSAGES_XML = $(CONF)/messages.xml
ACINCLUDE = $(PAPARAZZI_HOME)/var/$(AIRCRAFT)
AIRCRAFT_CONF_DIR = $(ACINCLUDE)/conf
-AC_GENERATED = $(ACINCLUDE)/generated
+AC_GENERATED = $(ACINCLUDE)/$(TARGET)/generated
AIRFRAME_H=$(AC_GENERATED)/airframe.h
PERIODIC_H=$(AC_GENERATED)/periodic_telemetry.h
@@ -104,16 +104,16 @@ $(AIRFRAME_H) : $(CONF)/$(AIRFRAME_XML) $(CONF_XML) $(AIRCRAFT_MD5)
$(Q)test -d $(AC_GENERATED) || mkdir -p $(AC_GENERATED)
@echo GENERATE $@
$(eval $@_TMP := $(shell $(MKTEMP)))
- $(Q)$(TOOLS)/gen_airframe.out $(AC_ID) $(AIRCRAFT) $(MD5SUM) $< > $($@_TMP)
+ $(Q)$(GENERATORS)/gen_airframe.out $(AC_ID) $(AIRCRAFT) $(MD5SUM) $< > $($@_TMP)
$(Q)mv $($@_TMP) $@
$(Q)chmod a+r $@
$(Q)cp $(CONF)/airframes/airframe.dtd $(AIRCRAFT_CONF_DIR)/airframes
-$(RADIO_H) : $(CONF)/$(RADIO) $(CONF_XML) $(TOOLS)/gen_radio.out
+$(RADIO_H) : $(CONF)/$(RADIO) $(CONF_XML) $(GENERATORS)/gen_radio.out
$(Q)test -d $(AC_GENERATED) || mkdir -p $(AC_GENERATED)
@echo GENERATE $@
$(eval $@_TMP := $(shell $(MKTEMP)))
- $(Q)$(TOOLS)/gen_radio.out $< > $($@_TMP)
+ $(Q)$(GENERATORS)/gen_radio.out $< > $($@_TMP)
$(Q)mv $($@_TMP) $@
$(Q)chmod a+r $@
$(Q)cp $< $(AIRCRAFT_CONF_DIR)/radios
@@ -122,59 +122,59 @@ $(PERIODIC_H) : $(CONF)/$(AIRFRAME_XML) $(MESSAGES_XML) $(CONF_XML) $(CONF)/$(TE
$(Q)test -d $(AC_GENERATED) || mkdir -p $(AC_GENERATED)
@echo GENERATE $@
$(eval $@_TMP := $(shell $(MKTEMP)))
- $(Q)$(TOOLS)/gen_periodic.out $(CONF)/$(AIRFRAME_XML) $(MESSAGES_XML) $(CONF)/$(TELEMETRY) $(TELEMETRY_FREQUENCY) $(SETTINGS_TELEMETRY) > $($@_TMP)
+ $(Q)$(GENERATORS)/gen_periodic.out $(CONF)/$(AIRFRAME_XML) $(MESSAGES_XML) $(CONF)/$(TELEMETRY) $(TELEMETRY_FREQUENCY) $(SETTINGS_TELEMETRY) > $($@_TMP)
$(Q)mv $($@_TMP) $@
$(Q)chmod a+r $@
$(Q)cp $(CONF)/$(TELEMETRY) $(AIRCRAFT_CONF_DIR)/telemetry
-$(FLIGHT_PLAN_H) : $(CONF)/$(FLIGHT_PLAN) $(CONF_XML) $(TOOLS)/gen_flight_plan.out
+$(FLIGHT_PLAN_H) : $(CONF)/$(FLIGHT_PLAN) $(CONF_XML) $(GENERATORS)/gen_flight_plan.out
$(Q)test -d $(AC_GENERATED) || mkdir -p $(AC_GENERATED)
@echo GENERATE $@
$(eval $@_TMP := $(shell $(MKTEMP)))
- $(Q)$(TOOLS)/gen_flight_plan.out $< > $($@_TMP)
+ $(Q)$(GENERATORS)/gen_flight_plan.out $< > $($@_TMP)
$(Q)mv $($@_TMP) $@
$(Q)chmod a+r $@
$(Q)cp $< $(AIRCRAFT_CONF_DIR)/flight_plans
-$(FLIGHT_PLAN_XML) : $(CONF)/$(FLIGHT_PLAN) $(CONF_XML) $(TOOLS)/gen_flight_plan.out
+$(FLIGHT_PLAN_XML) : $(CONF)/$(FLIGHT_PLAN) $(CONF_XML) $(GENERATORS)/gen_flight_plan.out
@echo GENERATE $@
$(eval $@_TMP := $(shell $(MKTEMP)))
- $(Q)$(TOOLS)/gen_flight_plan.out -dump $< > $($@_TMP)
+ $(Q)$(GENERATORS)/gen_flight_plan.out -dump $< > $($@_TMP)
$(Q)mv $($@_TMP) $@
$(Q)chmod a+r $@
-$(SETTINGS_H) : $(SETTINGS_XMLS) $(CONF_XML) $(SETTINGS_MODULES) $(SETTINGS_TELEMETRY) $(TOOLS)/gen_settings.out
+$(SETTINGS_H) : $(SETTINGS_XMLS) $(CONF_XML) $(SETTINGS_MODULES) $(SETTINGS_TELEMETRY) $(GENERATORS)/gen_settings.out
$(Q)test -d $(AC_GENERATED) || mkdir -p $(AC_GENERATED)
@echo GENERATE $@
$(eval $@_TMP := $(shell $(MKTEMP)))
- $(Q)$(TOOLS)/gen_settings.out $(SETTINGS_XML) $(SETTINGS_TELEMETRY) $(SETTINGS_XMLS) $(SETTINGS_MODULES) > $($@_TMP)
+ $(Q)$(GENERATORS)/gen_settings.out $(SETTINGS_XML) $(SETTINGS_TELEMETRY) $(SETTINGS_XMLS) $(SETTINGS_MODULES) > $($@_TMP)
$(Q)mv $($@_TMP) $@
$(Q)chmod a+r $@
$(Q)cp $(SETTINGS_XMLS) $(AIRCRAFT_CONF_DIR)/settings
-$(MODULES_H) : $(CONF)/$(AIRFRAME_XML) $(TOOLS)/gen_modules.out $(CONF)/modules/*.xml
+$(MODULES_H) : $(CONF)/$(AIRFRAME_XML) $(GENERATORS)/gen_modules.out $(CONF)/modules/*.xml
$(Q)test -d $(AC_GENERATED) || mkdir -p $(AC_GENERATED)
@echo GENERATE $@
$(eval $@_TMP := $(shell $(MKTEMP)))
- $(Q)$(TOOLS)/gen_modules.out $(SETTINGS_MODULES) $(DEFAULT_MODULES_FREQUENCY) $< > $($@_TMP)
+ $(Q)$(GENERATORS)/gen_modules.out $(SETTINGS_MODULES) $(DEFAULT_MODULES_FREQUENCY) $< > $($@_TMP)
$(Q)mv $($@_TMP) $@
$(Q)chmod a+r $@
-$(AUTOPILOT_H) : $(CONF)/$(AIRFRAME_XML) $(TOOLS)/gen_autopilot.out $(CONF)/autopilot/*.xml
+$(AUTOPILOT_H) : $(CONF)/$(AIRFRAME_XML) $(GENERATORS)/gen_autopilot.out $(CONF)/autopilot/*.xml
$(Q)test -d $(AC_GENERATED) || mkdir -p $(AC_GENERATED)
@echo GENERATE $@
$(eval $@_TMP := $(shell $(MKTEMP)))
- $(Q)$(TOOLS)/gen_autopilot.out $(CONF)/$(AIRFRAME_XML) $($@_TMP)
+ $(Q)$(GENERATORS)/gen_autopilot.out $(CONF)/$(AIRFRAME_XML) $($@_TMP)
$(Q)mv $($@_TMP) $@
$(Q)chmod a+r $@
$(SETTINGS_MODULES) : $(MODULES_H)
$(SETTINGS_TELEMETRY) : $(PERIODIC_H)
-%.ac_h : $(TOOLS)/gen_aircraft.out
+%.ac_h : $(GENERATORS)/gen_aircraft.out
$(Q)if (expr "$(AIRCRAFT)"); then : ; else echo "AIRCRAFT undefined: type 'make AIRCRAFT=AircraftName ...'"; exit 1; fi
@echo BUILD $(AIRCRAFT), TARGET $*
- +$(Q)PAPARAZZI_SRC=$(PAPARAZZI_SRC) PAPARAZZI_HOME=$(PAPARAZZI_HOME) TARGET=$* Q=$(Q) $(TOOLS)/gen_aircraft.out $(AIRCRAFT)
+ $(Q)PAPARAZZI_SRC=$(PAPARAZZI_SRC) PAPARAZZI_HOME=$(PAPARAZZI_HOME) TARGET=$* Q=$(Q) $(GENERATORS)/gen_aircraft.out $(AIRCRAFT)
%.compile: %.ac_h print_version
cd $(AIRBORNE); $(MAKE) TARGET=$* all
diff --git a/README.md b/README.md
index 4cd013f77b..24aaa7027c 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@ Paparazzi UAS
Paparazzi is an attempt to develop a free software Unmanned (Air) Vehicle System.
As of today the system is being used successfuly by a number of hobyists, universities and companies all over the world, on vehicle of various size ( 100g to 25Kg ) and of various nature ( fixed wing, rotorcrafts, boats and surface vehicles).
-Up to date information is available in the wiki http://paparazzi.enac.fr
+Up to date information is available in the wiki http://wiki.paparazziuav.org
and from the mailing list [paparazzi-devel@nongnu.org] (http://savannah.nongnu.org/mail/?group=paparazzi)
and the IRC channel (freenode, #paparazzi).
@@ -13,10 +13,10 @@ and the IRC channel (freenode, #paparazzi).
Required Software
-----------------
-Installation is described in the wiki (http://paparazzi.enac.fr/wiki/Installation).
+Installation is described in the wiki (http://wiki.paparazziuav.org/wiki/Installation).
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 users can use the [OpenSUSE Build Service repository] (http://download.opensuse.org/repositories/home:/flixr:/paparazzi-uav/Debian_7.0/)
Debian/Ubuntu packages:
- **paparazzi-dev** is the meta-package that depends on everything needed to compile and run the ground segment and the simulator.
diff --git a/conf/Makefile.chibios-libopencm3 b/conf/Makefile.chibios-libopencm3
index 91280de61b..06a1eff254 100644
--- a/conf/Makefile.chibios-libopencm3
+++ b/conf/Makefile.chibios-libopencm3
@@ -41,7 +41,7 @@ CHIBIOS_BOARD_DIR = $(PAPARAZZI_SRC)/sw/airborne/boards/$(BOARD)/chibios-libopen
CHIBIOS_LIB_DIR = $(PAPARAZZI_SRC)/sw/airborne/subsystems/chibios-libopencm3
CHIBIOS_EXT = $(PAPARAZZI_SRC)/sw/ext/chibios
OPENCM3_EXT = $(PAPARAZZI_SRC)/sw/ext/libopencm3
-PPRZ_GENERATED = $(PAPARAZZI_SRC)/var/$(AIRCRAFT)/generated
+PPRZ_GENERATED = $(PAPARAZZI_SRC)/var/$(AIRCRAFT)/$(TARGET)/generated
PPRZ_CHIBIOS_OCM3 = $(SRC_FIRMWARE)/chibios-libopencm3
# Launch with "make Q=''" to get full command display
diff --git a/conf/Makefile.local b/conf/Makefile.local
index 0958fa2da5..d02b081e07 100644
--- a/conf/Makefile.local
+++ b/conf/Makefile.local
@@ -7,8 +7,8 @@ PAPARAZZI_HOME=$(HOME)/paparazzi
endif
ifeq ($(PAPARAZZI_SRC),)
-TOOLS=$(DESTDIR)/usr/share/paparazzi/bin
+GENERATORS=$(DESTDIR)/usr/share/paparazzi/bin
else
-TOOLS=$(PAPARAZZI_SRC)/sw/tools
+GENERATORS=$(PAPARAZZI_SRC)/sw/tools/generators
endif
diff --git a/conf/Makefile.stm32-upload b/conf/Makefile.stm32-upload
index 1bff711bf6..4066ab7a79 100644
--- a/conf/Makefile.stm32-upload
+++ b/conf/Makefile.stm32-upload
@@ -59,9 +59,14 @@ else ifeq ($(FLASH_MODE),DFU-UTIL)
#
# DFU flash mode using dfu-util
DFU_ADDR ?= 0x08000000
+DFU_SIZE ?= $(shell stat --printf=%s $^)
upload: $(OBJDIR)/$(TARGET).bin
@echo "Using dfu-util at $(DFU_ADDR)"
$(Q)dfu-util -d 0483:df11 -c 1 -i 0 -a 0 -s $(DFU_ADDR) -D $^
+ $(Q)rm -f $(OBJDIR)/verify.bla
+ $(Q)dfu-util -d 0483:df11 -c 1 -i 0 -a 0 -s $(DFU_ADDR):$(DFU_SIZE) -U $(OBJDIR)/verify.bla
+ $(Q)diff $^ $(OBJDIR)/verify.bla
+ $(Q)rm -f $(OBJDIR)/verify.bla
#
# serial flash mode
diff --git a/conf/abi.xml b/conf/abi.xml
index 1b4d345a29..ff6cd327c0 100644
--- a/conf/abi.xml
+++ b/conf/abi.xml
@@ -11,6 +11,11 @@
+
+
+
+
+
diff --git a/conf/airframes/CDW/DualBoardApFbw.xml b/conf/airframes/CDW/DualBoardApFbw.xml
index f46838d67c..99d5a5103d 100644
--- a/conf/airframes/CDW/DualBoardApFbw.xml
+++ b/conf/airframes/CDW/DualBoardApFbw.xml
@@ -218,7 +218,7 @@
-
+
diff --git a/conf/airframes/CDW/classix.xml b/conf/airframes/CDW/classix.xml
index 6f3f3a87d3..968e9f3e06 100644
--- a/conf/airframes/CDW/classix.xml
+++ b/conf/airframes/CDW/classix.xml
@@ -180,10 +180,6 @@
-
-
-
-
@@ -230,7 +226,7 @@
-
+
diff --git a/conf/airframes/CDW/test/yapa3_aspirin2.xml b/conf/airframes/CDW/test/yapa3_aspirin2.xml
index 231cb1a8be..9cb255fd5c 100644
--- a/conf/airframes/CDW/test/yapa3_aspirin2.xml
+++ b/conf/airframes/CDW/test/yapa3_aspirin2.xml
@@ -214,7 +214,7 @@
diff --git a/conf/airframes/CDW/yapa_xsens.xml b/conf/airframes/CDW/yapa_xsens.xml
index 8f2d011d30..919721742a 100644
--- a/conf/airframes/CDW/yapa_xsens.xml
+++ b/conf/airframes/CDW/yapa_xsens.xml
@@ -199,7 +199,7 @@
-
+
diff --git a/conf/airframes/ENAC/quadrotor/blender.xml b/conf/airframes/ENAC/quadrotor/blender.xml
index e1946c7a97..d85b06817b 100644
--- a/conf/airframes/ENAC/quadrotor/blender.xml
+++ b/conf/airframes/ENAC/quadrotor/blender.xml
@@ -5,7 +5,7 @@
-
+
@@ -254,8 +254,6 @@
diff --git a/conf/airframes/ENAC/quadrotor/booz2_g1.xml b/conf/airframes/ENAC/quadrotor/booz2_g1.xml
index 632b993672..0e6a25ce3c 100644
--- a/conf/airframes/ENAC/quadrotor/booz2_g1.xml
+++ b/conf/airframes/ENAC/quadrotor/booz2_g1.xml
@@ -3,8 +3,9 @@
-
+
+
@@ -177,13 +179,16 @@
+
+
-
-
+
diff --git a/conf/airframes/PPZUAV/fixed-wing/ppzimu_tiny.xml b/conf/airframes/PPZUAV/fixed-wing/ppzimu_tiny.xml
index 00ade274dc..b9ab81647b 100644
--- a/conf/airframes/PPZUAV/fixed-wing/ppzimu_tiny.xml
+++ b/conf/airframes/PPZUAV/fixed-wing/ppzimu_tiny.xml
@@ -185,29 +185,6 @@
-
-
-
-
-
-
-
-
-
diff --git a/conf/airframes/TUDelft/delfly.xml b/conf/airframes/TUDelft/delfly.xml
new file mode 100644
index 0000000000..c07812c4b7
--- /dev/null
+++ b/conf/airframes/TUDelft/delfly.xml
@@ -0,0 +1,199 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/conf/airframes/ardrone2_raw_optitrack.xml b/conf/airframes/ardrone2_raw_optitrack.xml
index 6d919681fd..262d253bb2 100644
--- a/conf/airframes/ardrone2_raw_optitrack.xml
+++ b/conf/airframes/ardrone2_raw_optitrack.xml
@@ -18,7 +18,7 @@
-
+
@@ -26,6 +26,11 @@
+
+
+
+
+
@@ -102,6 +107,9 @@
@@ -133,7 +141,7 @@
-
+
@@ -155,17 +163,17 @@
-
+
-
+
-
+
-
+
-
+
@@ -191,8 +199,16 @@
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/conf/airframes/examples/MentorEnergy.xml b/conf/airframes/examples/MentorEnergy.xml
index e320508b39..188d9a0f54 100644
--- a/conf/airframes/examples/MentorEnergy.xml
+++ b/conf/airframes/examples/MentorEnergy.xml
@@ -79,7 +79,7 @@
-
+
diff --git a/conf/airframes/examples/Twinstar_energyadaptive.xml b/conf/airframes/examples/Twinstar_energyadaptive.xml
index 5863d2b287..9eea22514c 100644
--- a/conf/airframes/examples/Twinstar_energyadaptive.xml
+++ b/conf/airframes/examples/Twinstar_energyadaptive.xml
@@ -58,7 +58,7 @@ twog_1.0 + aspirin + ETS baro + ETS speed
-
+
diff --git a/conf/airframes/examples/funjet_cam.xml b/conf/airframes/examples/funjet_cam.xml
index 5f98dddb82..f2674a8d81 100644
--- a/conf/airframes/examples/funjet_cam.xml
+++ b/conf/airframes/examples/funjet_cam.xml
@@ -43,7 +43,7 @@
-
+
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 ee7a9f1bf8..b875a461ef 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
@@ -218,8 +218,6 @@
-
-
diff --git a/conf/airframes/examples/quadrotor_lisa_mx.xml b/conf/airframes/examples/quadrotor_lisa_mx.xml
index 1cf5bc6ee3..95e406d9c3 100644
--- a/conf/airframes/examples/quadrotor_lisa_mx.xml
+++ b/conf/airframes/examples/quadrotor_lisa_mx.xml
@@ -37,7 +37,7 @@
-
+
@@ -52,6 +52,8 @@
+
+
diff --git a/conf/airframes/examples/quadrotor_navgo.xml b/conf/airframes/examples/quadrotor_navgo.xml
index 194bba93bb..0a7da95fae 100644
--- a/conf/airframes/examples/quadrotor_navgo.xml
+++ b/conf/airframes/examples/quadrotor_navgo.xml
@@ -239,8 +239,6 @@
diff --git a/conf/airframes/examples/separate_fbw_ap.xml b/conf/airframes/examples/separate_fbw_ap.xml
index a2747c1603..abb0185263 100644
--- a/conf/airframes/examples/separate_fbw_ap.xml
+++ b/conf/airframes/examples/separate_fbw_ap.xml
@@ -219,7 +219,7 @@
-
+
diff --git a/conf/airframes/obsolete/vor.xml b/conf/airframes/obsolete/vor.xml
deleted file mode 100644
index 6793fa5f24..0000000000
--- a/conf/airframes/obsolete/vor.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-ARCH=lpc21
-
-
-FLASH_MODE = IAP
-main.ARCHDIR = $(ARCH)
-
-main.CFLAGS += -DBOARD_CONFIG=\"boards/olimex_lpc_h2148.h\"
-main.srcs = firmwares/vor/lpc_vor_main.c
-
-main.CFLAGS += -DPERIODIC_FREQUENCY='29880.'
-main.srcs += sys_time.c $(SRC_ARCH)/sys_time_hw.c
-
-main.CFLAGS += -DUSE_LED
-
-main.srcs += $(SRC_ARCH)/armVIC.c
-
-main.srcs += firmwares/vor/lpc_vor_convertions.c
-
-main.CFLAGS += -DUSE_UART0 -DUART0_BAUD=B9600
-main.srcs += $(SRC_ARCH)/mcu_periph/uart_arch.c
-
-main.CFLAGS += -DDOWNLINK -DDOWNLINK_TRANSPORT=PprzTransport -DDOWNLINK_DEVICE=UART0
-main.srcs += subsystems/datalink/downlink.c subsystems/datalink/pprz_transport.c
-
-main.srcs += firmwares/vor/vor_int_demod_decim.c
-
-
-
-
-
diff --git a/conf/boa.conf b/conf/boa.conf
deleted file mode 100644
index 0ac987eaf5..0000000000
--- a/conf/boa.conf
+++ /dev/null
@@ -1,241 +0,0 @@
-# Boa v0.94 configuration file
-# File format has not changed from 0.93
-# File format has changed little from 0.92
-# version changes are noted in the comments
-#
-# The Boa configuration file is parsed with a custom parser. If it
-# reports an error, the line number will be provided; it should be easy
-# to spot. The syntax of each of these rules is very simple, and they
-# can occur in any order. Where possible these directives mimic those
-# of NCSA httpd 1.3; I saw no reason to introduce gratuitous
-# differences.
-
-# $Id$
-
-# The "ServerRoot" is not in this configuration file. It can be
-# compiled into the server (see defines.h) or specified on the command
-# line with the -c option, for example:
-#
-# boa -c /usr/local/boa
-
-
-# Port: The port Boa runs on. The default port for http servers is 80.
-# If it is less than 1024, the server must be started as root.
-
-Port 8889
-
-# Listen: the Internet address to bind(2) to. If you leave it out,
-# it takes the behavior before 0.93.17.2, which is to bind to all
-# addresses (INADDR_ANY). You only get one "Listen" directive,
-# if you want service on multiple IP addresses, you have three choices:
-# 1. Run boa without a "Listen" directive
-# a. All addresses are treated the same; makes sense if the addresses
-# are localhost, ppp, and eth0.
-# b. Use the VirtualHost directive below to point requests to different
-# files. Should be good for a very large number of addresses (web
-# hosting clients).
-# 2. Run one copy of boa per IP address, each has its own configuration
-# with a "Listen" directive. No big deal up to a few tens of addresses.
-# Nice separation between clients.
-# The name you provide gets run through inet_aton(3), so you have to use dotted
-# quad notation. This configuration is too important to trust some DNS.
-
-#Listen 192.68.0.5
-
-# User: The name or UID the server should run as.
-# Group: The group name or GID the server should run as.
-
-User www-data
-Group www-data
-
-# ServerAdmin: The email address where server problems should be sent.
-# Note: this is not currently used, except as an environment variable
-# for CGIs.
-
-#ServerAdmin root@localhost
-
-# PidFile: where to put the pid of the process.
-# Comment out to write no pid file.
-# Note: Because Boa drops privileges at startup, and the
-# pid file is written by the UID/GID before doing so, Boa
-# does not attempt removal of the pid file.
-# PidFile /var/run/boa.pid
-
-# ErrorLog: The location of the error log file. If this does not start
-# with /, it is considered relative to the server root.
-# Set to /dev/null if you don't want errors logged.
-# If unset, defaults to /dev/stderr
-# Please NOTE: Sending the logs to a pipe ('|'), as shown below,
-# is somewhat experimental and might fail under heavy load.
-# "Usual libc implementations of printf will stall the whole
-# process if the receiving end of a pipe stops reading."
-#ErrorLog "|/usr/sbin/cronolog --symlink=/var/log/boa/error_log /var/log/boa/error-%Y%m%d.log"
-
-ErrorLog PAPARAZZI_HOME/var/logs/boa.log
-
-# AccessLog: The location of the access log file. If this does not
-# start with /, it is considered relative to the server root.
-# Comment out or set to /dev/null (less effective) to disable.
-# Useful to set to /dev/stdout for use with daemontools.
-# Access logging.
-# Please NOTE: Sending the logs to a pipe ('|'), as shown below,
-# is somewhat experimental and might fail under heavy load.
-# "Usual libc implementations of printf will stall the whole
-# process if the receiving end of a pipe stops reading."
-#AccessLog "|/usr/sbin/cronolog --symlink=/var/log/boa/access_log /var/log/boa/access-%Y%m%d.log"
-
-AccessLog PAPARAZZI_HOME/var/logs/boa_access.log
-
-# CGILog /var/log/boa/cgi_log
-# CGILog: The location of the CGI stderr log file. If this does not
-# start with /, it is considered relative to the server root.
-# The log file would contain any contents send to /dev/stderr
-# by the CGI. If this is commented out, it defaults to whatever
-# ErrorLog points. Set to /dev/null to disable CGI stderr logging.
-# Please NOTE: Sending the logs to a pipe ('|'), as shown below,
-# is somewhat experimental and might fail under heavy load.
-# "Usual libc implementations of printf will stall the whole
-# process if the receiving end of a pipe stops reading."
-#CGILog "|/usr/sbin/cronolog --symlink=/var/log/boa/cgi_log /var/log/boa/cgi-%Y%m%d.log"
-
-# CGIumask 027 (no mask for user, read-only for group, and nothing for user)
-# CGIumask 027
-# The CGIumask is set immediately before execution of the CGI.
-
-# UseLocaltime: Logical switch. Uncomment to use localtime
-# instead of UTC time
-#UseLocaltime
-
-# VerboseCGILogs: this is just a logical switch.
-# It simply notes the start and stop times of cgis in the error log
-# Comment out to disable.
-
-#VerboseCGILogs
-
-# ServerName: the name of this server that should be sent back to
-# clients if different than that returned by gethostname + gethostbyname
-
-#ServerName www.your.org.here
-
-# VirtualHost: a logical switch.
-# Comment out to disable.
-# Given DocumentRoot /var/www, requests on interface 'A' or IP 'IP-A'
-# become /var/www/IP-A.
-# Example: http://localhost/ becomes /var/www/127.0.0.1
-#
-# Not used until version 0.93.17.2. This "feature" also breaks commonlog
-# output rules, it prepends the interface number to each access_log line.
-# You are expected to fix that problem with a postprocessing script.
-
-#VirtualHost
-
-
-# VHostRoot: the root location for all virtually hosted data
-# Comment out to disable.
-# Incompatible with 'Virtualhost' and 'DocumentRoot'!!
-# Given VHostRoot /var/www, requests to host foo.bar.com,
-# where foo.bar.com is ip a.b.c.d,
-# become /var/www/a.b.c.d/foo.bar.com
-# Hostnames are "cleaned", and must conform to the rules
-# specified in rfc1034, which are be summarized here:
-#
-# Hostnames must start with a letter, end with a letter or digit,
-# and have as interior characters only letters, digits, and hyphen.
-# Hostnames must not exceed 63 characters in length.
-
-#VHostRoot /var/www
-
-# DefaultVHost
-# Define this in order to have a default hostname when the client does not
-# specify one, if using VirtualHostName. If not specified, the word
-# "default" will be used for compatibility with older clients.
-
-#DefaultVHost foo.bar.com
-
-# DocumentRoot: The root directory of the HTML documents.
-# Comment out to disable server non user files.
-
-DocumentRoot PAPARAZZI_HOME
-
-# UserDir: The name of the directory which is appended onto a user's home
-# directory if a ~user request is received.
-
-UserDir public_html
-
-# DirectoryIndex: Name of the file to use as a pre-written HTML
-# directory index. Please MAKE AND USE THESE FILES. On the
-# fly creation of directory indexes can be _slow_.
-# Comment out to always use DirectoryMaker
-
-DirectoryIndex index.html
-
-# DirectoryMaker: Name of program used to create a directory listing.
-# Comment out to disable directory listings. If both this and
-# DirectoryIndex are commented out, accessing a directory will give
-# an error (though accessing files in the directory are still ok).
-
-DirectoryMaker /usr/lib/boa/boa_indexer
-
-# DirectoryCache: If DirectoryIndex doesn't exist, and DirectoryMaker
-# has been commented out, the the on-the-fly indexing of Boa can be used
-# to generate indexes of directories. Be warned that the output is
-# extremely minimal and can cause delays when slow disks are used.
-# Note: The DirectoryCache must be writable by the same user/group that
-# Boa runs as.
-
-# DirectoryCache /var/spool/boa/dircache
-
-# KeepAliveMax: Number of KeepAlive requests to allow per connection
-# Comment out, or set to 0 to disable keepalive processing
-
-KeepAliveMax 1000
-
-# KeepAliveTimeout: seconds to wait before keepalive connection times out
-
-KeepAliveTimeout 10
-
-# MimeTypes: This is the file that is used to generate mime type pairs
-# and Content-Type fields for boa.
-# Set to /dev/null if you do not want to load a mime types file.
-# Do *not* comment out (better use AddType!)
-
-MimeTypes /etc/mime.types
-
-# DefaultType: MIME type used if the file extension is unknown, or there
-# is no file extension.
-
-DefaultType text/plain
-
-# CGIPath: The value of the $PATH environment variable given to CGI progs.
-
-CGIPath /bin:/usr/bin:/usr/local/bin
-
-# SinglePostLimit: The maximum allowable number of bytes in
-# a single POST. Default is normally 1MB.
-
-# AddType: adds types without editing mime.types
-# Example: AddType type extension [extension ...]
-
-# Uncomment the next line if you want .cgi files to execute from anywhere
-AddType application/x-httpd-cgi cgi
-
-# Redirect, Alias, and ScriptAlias all have the same semantics -- they
-# match the beginning of a request and take appropriate action. Use
-# Redirect for other servers, Alias for the same server, and ScriptAlias
-# to enable directories for script execution.
-
-# Redirect allows you to tell clients about documents which used to exist in
-# your server's namespace, but do not anymore. This allows you to tell the
-# clients where to look for the relocated document.
-# Example: Redirect /bar http://elsewhere/feh/bar
-
-# Aliases: Aliases one path to another.
-# Example: Alias /path1/bar /path2/foo
-
-Alias /doc /usr/share/doc
-
-# ScriptAlias: Maps a virtual path to a directory for serving scripts
-# Example: ScriptAlias /htbin/ /www/htbin/
-
-ScriptAlias /cgi-bin/ PAPARAZZI_HOME/sw/cgi/
-
diff --git a/conf/chibios/chibios_rules.mk b/conf/chibios/chibios_rules.mk
index 60bdc3e03c..8d74f87b0c 100644
--- a/conf/chibios/chibios_rules.mk
+++ b/conf/chibios/chibios_rules.mk
@@ -116,10 +116,10 @@ all: $(OBJS) $(OUTFILES) MAKE_ALL_RULE_HOOK
MAKE_ALL_RULE_HOOK:
-$(OBJS): | $(BUILDDIR)
+$(OBJS): | $(OBJDIR)
$(BUILDDIR) $(OBJDIR) $(LSTDIR):
-ifneq ($(USE_VERBOSE_COMPILE),yes)
+ifeq ($(USE_VERBOSE_COMPILE),yes)
@echo Compiler Options
@echo $(CC) -c $(CFLAGS) -I. $(IINCDIR) main.c -o main.o
@echo
diff --git a/conf/control_panel_example.xml b/conf/control_panel_example.xml
index 91b86c0d49..f8956a1ca9 100644
--- a/conf/control_panel_example.xml
+++ b/conf/control_panel_example.xml
@@ -41,11 +41,11 @@
-
+
-
+
-
+
@@ -68,8 +68,6 @@
-
-
@@ -78,7 +76,11 @@
-
+
+
+
+
+
diff --git a/conf/firmwares/subsystems/fixedwing/ins_gps_passthrough.makefile b/conf/firmwares/subsystems/fixedwing/ins_gps_passthrough.makefile
index 0ab3fc9cca..2afb6ad8d0 100644
--- a/conf/firmwares/subsystems/fixedwing/ins_gps_passthrough.makefile
+++ b/conf/firmwares/subsystems/fixedwing/ins_gps_passthrough.makefile
@@ -1,7 +1,7 @@
# Hey Emacs, this is a -*- makefile -*-
ins_srcs += $(SRC_SUBSYSTEMS)/ins.c
-ins_srcs += $(SRC_SUBSYSTEMS)/ins/ins_gps_passthrough.c
+ins_srcs += $(SRC_SUBSYSTEMS)/ins/ins_gps_passthrough_utm.c
ap.CFLAGS += $(ins_CFLAGS)
diff --git a/conf/firmwares/subsystems/rotorcraft/gps_datalink.makefile b/conf/firmwares/subsystems/rotorcraft/gps_datalink.makefile
new file mode 100644
index 0000000000..b674b38242
--- /dev/null
+++ b/conf/firmwares/subsystems/rotorcraft/gps_datalink.makefile
@@ -0,0 +1,18 @@
+# Hey Emacs, this is a -*- makefile -*-
+
+GPS_LED ?= none
+
+ap.srcs += $(SRC_SUBSYSTEMS)/gps.c
+ap.CFLAGS += -DGPS_TYPE_H=\"subsystems/gps/gps_datalink.h\"
+ap.srcs += $(SRC_SUBSYSTEMS)/gps/gps_datalink.c
+
+ap.CFLAGS += -DUSE_GPS -DGPS_DATALINK
+
+ifneq ($(GPS_LED),none)
+ ap.CFLAGS += -DGPS_LED=$(GPS_LED)
+endif
+
+nps.CFLAGS += -DUSE_GPS
+nps.srcs += $(SRC_SUBSYSTEMS)/gps.c
+nps.CFLAGS += -DGPS_TYPE_H=\"subsystems/gps/gps_sim_nps.h\"
+nps.srcs += $(SRC_SUBSYSTEMS)/gps/gps_sim_nps.c
diff --git a/conf/firmwares/subsystems/rotorcraft/gps_sim_hitl.makefile b/conf/firmwares/subsystems/rotorcraft/gps_sim_hitl.makefile
new file mode 100644
index 0000000000..c2ea1367a8
--- /dev/null
+++ b/conf/firmwares/subsystems/rotorcraft/gps_sim_hitl.makefile
@@ -0,0 +1,15 @@
+# Hey Emacs, this is a -*- makefile -*-
+
+ap.srcs += $(SRC_SUBSYSTEMS)/gps.c
+ap.CFLAGS += -DGPS_TYPE_H=\"subsystems/gps/gps_sim_hitl.h\"
+ap.srcs += $(SRC_SUBSYSTEMS)/gps/gps_sim_hitl.c
+ap.CFLAGS += -DUSE_GPS -DHITL
+
+ifneq ($(GPS_LED),none)
+ ap.CFLAGS += -DGPS_LED=$(GPS_LED)
+endif
+
+nps.CFLAGS += -DUSE_GPS
+nps.srcs += $(SRC_SUBSYSTEMS)/gps.c
+nps.CFLAGS += -DGPS_TYPE_H=\"subsystems/gps/gps_sim_nps.h\"
+nps.srcs += $(SRC_SUBSYSTEMS)/gps/gps_sim_nps.c
diff --git a/conf/firmwares/subsystems/rotorcraft/ins_gps_passthrough.makefile b/conf/firmwares/subsystems/rotorcraft/ins_gps_passthrough.makefile
new file mode 100644
index 0000000000..d9ede096ab
--- /dev/null
+++ b/conf/firmwares/subsystems/rotorcraft/ins_gps_passthrough.makefile
@@ -0,0 +1,11 @@
+# Hey Emacs, this is a -*- makefile -*-
+
+ins_srcs += $(SRC_SUBSYSTEMS)/ins.c
+ins_srcs += $(SRC_SUBSYSTEMS)/ins/ins_gps_passthrough.c
+
+
+ap.CFLAGS += $(ins_CFLAGS)
+ap.srcs += $(ins_srcs)
+
+nps.CFLAGS += $(ins_CFLAGS)
+nps.srcs += $(ins_srcs)
diff --git a/conf/firmwares/subsystems/shared/actuators_dualpwm.makefile b/conf/firmwares/subsystems/shared/actuators_dualpwm.makefile
new file mode 100644
index 0000000000..a0a1af7a3f
--- /dev/null
+++ b/conf/firmwares/subsystems/shared/actuators_dualpwm.makefile
@@ -0,0 +1,10 @@
+ifeq ($(ARCH), lpc21)
+$(error Error: dualpwm actuators only implemented for stm32)
+endif
+
+$(TARGET).CFLAGS += -DACTUATORS
+$(TARGET).srcs += $(SRC_ARCH)/subsystems/actuators/actuators_dualpwm_arch.c
+ifeq ($(ARCH), stm32)
+$(TARGET).srcs += $(SRC_ARCH)/subsystems/actuators/actuators_shared_arch.c
+endif
+
diff --git a/conf/firmwares/subsystems/shared/actuators_pwm.makefile b/conf/firmwares/subsystems/shared/actuators_pwm.makefile
index c476520918..cdb82abe1d 100644
--- a/conf/firmwares/subsystems/shared/actuators_pwm.makefile
+++ b/conf/firmwares/subsystems/shared/actuators_pwm.makefile
@@ -2,3 +2,6 @@
$(TARGET).CFLAGS += -DACTUATORS
$(TARGET).srcs += $(SRC_ARCH)/subsystems/actuators/actuators_pwm_arch.c
+ifeq ($(ARCH), stm32)
+$(TARGET).srcs += $(SRC_ARCH)/subsystems/actuators/actuators_shared_arch.c
+endif
diff --git a/conf/firmwares/subsystems/shared/imu_ardrone2.makefile b/conf/firmwares/subsystems/shared/imu_ardrone2.makefile
index ac06f5acf4..3a30478234 100644
--- a/conf/firmwares/subsystems/shared/imu_ardrone2.makefile
+++ b/conf/firmwares/subsystems/shared/imu_ardrone2.makefile
@@ -19,6 +19,8 @@ ap.srcs += $(imu_srcs)
# Set the AHRS propegation frequencies
AHRS_PROPAGATE_FREQUENCY ?= 200
AHRS_CORRECT_FREQUENCY ?= 200
+ap.CFLAGS += -DAHRS_PROPAGATE_FREQUENCY=$(AHRS_PROPAGATE_FREQUENCY)
+ap.CFLAGS += -DAHRS_CORRECT_FREQUENCY=$(AHRS_CORRECT_FREQUENCY)
#
# Simulator
diff --git a/conf/flight_plans/basic.xml b/conf/flight_plans/basic.xml
index 0b7465334e..778f0c9bbc 100644
--- a/conf/flight_plans/basic.xml
+++ b/conf/flight_plans/basic.xml
@@ -40,7 +40,7 @@
-
+
diff --git a/conf/flight_plans/flight_plan.dtd b/conf/flight_plans/flight_plan.dtd
index fb18d5ce0e..33599ac043 100644
--- a/conf/flight_plans/flight_plan.dtd
+++ b/conf/flight_plans/flight_plan.dtd
@@ -141,6 +141,7 @@ pitch CDATA #IMPLIED
alt CDATA #IMPLIED
height CDATA #IMPLIED
approaching_time CDATA #IMPLIED
+exceeding_time CDATA #IMPLIED
throttle CDATA #IMPLIED
climb CDATA #IMPLIED
until CDATA #IMPLIED>
@@ -151,6 +152,7 @@ vmode CDATA #IMPLIED
pitch CDATA #IMPLIED
alt CDATA #IMPLIED
approaching_time CDATA #IMPLIED
+exceeding_time CDATA #IMPLIED
throttle CDATA #IMPLIED
climb CDATA #IMPLIED>
diff --git a/conf/flight_plans/mission_fw.xml b/conf/flight_plans/mission_fw.xml
index daef0aaf3d..8359db5d26 100644
--- a/conf/flight_plans/mission_fw.xml
+++ b/conf/flight_plans/mission_fw.xml
@@ -31,7 +31,7 @@
-
+
diff --git a/conf/flight_plans/poles.xml b/conf/flight_plans/poles.xml
index 0d0e539340..7241254523 100644
--- a/conf/flight_plans/poles.xml
+++ b/conf/flight_plans/poles.xml
@@ -37,7 +37,7 @@
-
+
diff --git a/conf/flight_plans/zamboni_survey_test.xml b/conf/flight_plans/zamboni_survey_test.xml
index 7972b4d116..810c6a779d 100644
--- a/conf/flight_plans/zamboni_survey_test.xml
+++ b/conf/flight_plans/zamboni_survey_test.xml
@@ -75,7 +75,7 @@
-
+
diff --git a/conf/messages.xml b/conf/messages.xml
index 4be902ef3e..65af79ddc1 100644
--- a/conf/messages.xml
+++ b/conf/messages.xml
@@ -1498,8 +1498,7 @@
-
-
+
@@ -1889,7 +1888,27 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1947,7 +1966,7 @@
-
+
@@ -2430,35 +2449,21 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/conf/modules/digital_cam.xml b/conf/modules/digital_cam.xml
index 4bef1874e4..ca2e908b5f 100644
--- a/conf/modules/digital_cam.xml
+++ b/conf/modules/digital_cam.xml
@@ -1,44 +1,34 @@
-
-
- Digital camera control (trigger using led)
-
-
-
-
-
+ Digital camera control (trigger using GPIO)
+
+
+
+
+
+
+
+
-
+
-
+
-
-
+
-
-
+
-
diff --git a/conf/modules/digital_cam_servo.xml b/conf/modules/digital_cam_servo.xml
index 141ca80fa0..f6b75b0296 100644
--- a/conf/modules/digital_cam_servo.xml
+++ b/conf/modules/digital_cam_servo.xml
@@ -1,29 +1,15 @@
-
-
Digital camera control (trigger using servo)
-
-
+
+
+
+
+
+
+
@@ -35,14 +21,10 @@
-
-
+
-
-
+
-
-
diff --git a/conf/modules/follow.xml b/conf/modules/follow.xml
new file mode 100644
index 0000000000..c852b6c481
--- /dev/null
+++ b/conf/modules/follow.xml
@@ -0,0 +1,23 @@
+
+
+
+
+ Follow a certain AC_ID trough remote GPS
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/conf/modules/meteo_france_DAQ.xml b/conf/modules/meteo_france_DAQ.xml
index 945cf2abed..008b69bc51 100644
--- a/conf/modules/meteo_france_DAQ.xml
+++ b/conf/modules/meteo_france_DAQ.xml
@@ -10,7 +10,7 @@
-
+
diff --git a/conf/modules/rotorcraft_cam.xml b/conf/modules/rotorcraft_cam.xml
index b40f9896ce..fd734808ec 100644
--- a/conf/modules/rotorcraft_cam.xml
+++ b/conf/modules/rotorcraft_cam.xml
@@ -12,12 +12,16 @@ Four modes:
- HEADING: the servo position and the heading of the rotorcraft are set with angles
- WP: the camera is tracking a waypoint (Default: CAM)
-The CAM_SWITCH can be used to power the camera in normal modes and disable it when in NONE mode.
+If ROTORCRAFT_CAM_SWITCH_GPIO is defined, this gpio is set/cleared to switch the power
+of the camera on in normal modes and disable it when in NONE mode.
+On boards with CAM_SWITCH, ROTORCRAFT_CAM_SWITCH_GPIO can be defined to CAM_SWITCH_GPIO.
+
-
-
+
+
+
diff --git a/conf/modules/sonar_adc.xml b/conf/modules/sonar_adc.xml
index e0dd84eca3..83506640ff 100644
--- a/conf/modules/sonar_adc.xml
+++ b/conf/modules/sonar_adc.xml
@@ -7,8 +7,9 @@
Reads an anlog sonar sensor and outputs sonar distance in [m]
-
+
+
@@ -24,7 +25,6 @@
-
diff --git a/conf/modules/sonar_adc_ins.xml b/conf/modules/sonar_adc_ins.xml
deleted file mode 100644
index 7f0257f98e..0000000000
--- a/conf/modules/sonar_adc_ins.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
- Sonar ADC (INS bindings).
- Sonar ADC driver with INS binding, wich oes the same than sonar_adc module with an event function to feed INS subsystem.
- Even if SONAR_OFFSET and _SCALE can be set, currently only the raw value and the INS_SONAR_SENS will be used in ins filters.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/conf/radios/T10CG_SBUS.xml b/conf/radios/T10CG_SBUS.xml
index 137caa7b20..747b8329b3 100644
--- a/conf/radios/T10CG_SBUS.xml
+++ b/conf/radios/T10CG_SBUS.xml
@@ -45,11 +45,11 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/conf/settings/control/rotorcraft_guidance.xml b/conf/settings/control/rotorcraft_guidance.xml
index 114b18aa83..b8b7c49a1c 100644
--- a/conf/settings/control/rotorcraft_guidance.xml
+++ b/conf/settings/control/rotorcraft_guidance.xml
@@ -14,6 +14,7 @@
+
diff --git a/conf/settings/estimation/ins_sonar.xml b/conf/settings/estimation/ins_sonar.xml
index 0c016fa593..e709d2c6f5 100644
--- a/conf/settings/estimation/ins_sonar.xml
+++ b/conf/settings/estimation/ins_sonar.xml
@@ -3,7 +3,7 @@
-
+
diff --git a/doc/control_loops/fixedwing/README b/doc/control_loops/fixedwing/README
index 560d8c902e..b42204618f 100644
--- a/doc/control_loops/fixedwing/README
+++ b/doc/control_loops/fixedwing/README
@@ -1,3 +1,3 @@
Diagram of the control loops used on the fiwed-wing airframes
-Source files of the images used on the Wiki [http;//paparazzi.enac.fr/wiki/Control_loops]
+Source files of the images used on the Wiki [http://wiki.paparazziuav.org/wiki/Control_Loops]
diff --git a/doc/pprz_algebra/headfile.pdf b/doc/pprz_algebra/headfile.pdf
index 2f348026e4..5a7f2527be 100644
Binary files a/doc/pprz_algebra/headfile.pdf and b/doc/pprz_algebra/headfile.pdf differ
diff --git a/sw/airborne/Makefile b/sw/airborne/Makefile
index 8688244cfa..4da0867799 100644
--- a/sw/airborne/Makefile
+++ b/sw/airborne/Makefile
@@ -27,7 +27,7 @@ Q=@
OBJDIR = $(PAPARAZZI_HOME)/var/$(AIRCRAFT)/$(TARGET)
VARINCLUDE=$(PAPARAZZI_HOME)/var/include
-ACINCLUDE = $(PAPARAZZI_HOME)/var/$(AIRCRAFT)
+ACINCLUDE = $(PAPARAZZI_HOME)/var/$(AIRCRAFT)/$(TARGET)
INCLUDES = -I$(PAPARAZZI_SRC)/sw/include -I$(PAPARAZZI_SRC)/sw/airborne -I$(PAPARAZZI_SRC)/conf/autopilot -I$(PAPARAZZI_SRC)/sw/airborne/arch/$($(TARGET).ARCHDIR) -I$(VARINCLUDE) -I$(ACINCLUDE)
diff --git a/sw/airborne/arch/lpc21/usb_tunnel.c b/sw/airborne/arch/lpc21/usb_tunnel.c
index 055cf89a7c..c87e331fdc 100644
--- a/sw/airborne/arch/lpc21/usb_tunnel.c
+++ b/sw/airborne/arch/lpc21/usb_tunnel.c
@@ -38,6 +38,14 @@
/* minimum LED blink on time 10Hz = 100ms */
#define BLINK_MIN 10
+#ifndef USB_TUNNEL_UART
+#if USE_UART0
+#define USB_TUNNEL_UART uart0
+#else
+#define USB_TUNNEL_UART uart1
+#endif
+#endif
+
int main( void ) {
unsigned char inc;
unsigned int rx_time=0, tx_time=0;
@@ -53,44 +61,37 @@ int main( void ) {
mcu_int_enable();
+#if USE_LED_3
LED_ON(3);
-
-#if USE_UART0
- while(1) {
- if (T0TC > (rx_time+((PCLK / T0_PCLK_DIV) / BLINK_MIN))) LED_OFF(1);
- if (T0TC > (tx_time+((PCLK / T0_PCLK_DIV) / BLINK_MIN))) LED_OFF(2);
- if (uart_char_available(&uart0) && VCOM_check_free_space(1)) {
- LED_ON(1);
- rx_time = T0TC;
- inc = uart_getch(&uart0);
- VCOM_putchar(inc);
- }
- if (VCOM_check_available() && uart_check_free_space(&uart0, 1)) {
- LED_ON(2);
- tx_time = T0TC;
- inc = VCOM_getchar();
- uart_transmit(&uart0, inc);
- }
- }
-#else
- while(1) {
- if (T0TC > (rx_time+((PCLK / T0_PCLK_DIV) / BLINK_MIN))) LED_OFF(1);
- if (T0TC > (tx_time+((PCLK / T0_PCLK_DIV) / BLINK_MIN))) LED_OFF(2);
- if (uart_char_available(&uart1) && VCOM_check_free_space(1)) {
- LED_ON(1);
- rx_time = T0TC;
- inc = uart_getch(&uart1);
- VCOM_putchar(inc);
- }
- if (VCOM_check_available() && uart_check_free_space(&uart1, 1)) {
- LED_ON(2);
- tx_time = T0TC;
- inc = VCOM_getchar();
- uart_transmit(&uart1, inc);
- }
- }
#endif
+ while(1) {
+
+#if USE_LED_1
+ if (T0TC > (rx_time+((PCLK / T0_PCLK_DIV) / BLINK_MIN))) LED_OFF(1);
+#endif
+#if USE_LED_2
+ if (T0TC > (tx_time+((PCLK / T0_PCLK_DIV) / BLINK_MIN))) LED_OFF(2);
+#endif
+
+ if (uart_char_available(&USB_TUNNEL_UART) && VCOM_check_free_space(1)) {
+#if USE_LED_1
+ LED_ON(1);
+#endif
+ rx_time = T0TC;
+ inc = uart_getch(&USB_TUNNEL_UART);
+ VCOM_putchar(inc);
+ }
+ if (VCOM_check_available() && uart_check_free_space(&USB_TUNNEL_UART, 1)) {
+#if USE_LED_2
+ LED_ON(2);
+#endif
+ tx_time = T0TC;
+ inc = VCOM_getchar();
+ uart_transmit(&USB_TUNNEL_UART, inc);
+ }
+ }
+
return 0;
}
diff --git a/sw/airborne/arch/sim/ivy_transport.h b/sw/airborne/arch/sim/ivy_transport.h
index 1c406b3811..d84ff19234 100644
--- a/sw/airborne/arch/sim/ivy_transport.h
+++ b/sw/airborne/arch/sim/ivy_transport.h
@@ -18,6 +18,8 @@ extern int ivy_dl_enabled;
#define Space() ivy_p += sprintf(ivy_p, " ");
#define Comma() ivy_p += sprintf(ivy_p, ",");
+#define DelimStart() ivy_p += sprintf(ivy_p, "|");
+#define DelimEnd() ivy_p += sprintf(ivy_p, "|");
#define IvyTransportPutcByAddr(_dev,x) ivy_p += sprintf(ivy_p, "%c", *x);
#define IvyTransportPutCharByAddr(_dev,x) IvyTransportPutcByAddr(_dev,x) Space()
@@ -39,10 +41,11 @@ extern int ivy_dl_enabled;
#define IvyTransportPutArray(_dev,_put, _n, _x) { \
int __i; \
+ DelimStart(); \
for(__i = 0; __i < _n; __i++) { \
_put(_dev,&_x[__i]); \
Comma(); \
- } Space() \
+ } DelimEnd(); Space(); \
}
#define IvyTransportPutInt8Array(_dev,_n, _x) IvyTransportPutArray(_dev,IvyTransportPutIntByAddr, _n, _x)
diff --git a/sw/airborne/arch/sim/subsystems/actuators/actuators_dualpwm_arch.c b/sw/airborne/arch/sim/subsystems/actuators/actuators_dualpwm_arch.c
new file mode 100644
index 0000000000..9fcfc6c883
--- /dev/null
+++ b/sw/airborne/arch/sim/subsystems/actuators/actuators_dualpwm_arch.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2010 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 arch/sim/subsystems/actuators/actuators_dualpwm_arch.c
+ * dummy servos handling for sim
+ */
+
+#include "subsystems/actuators/actuators_dualpwm_arch.h"
+
+void actuators_dualpwm_arch_init(void) {
+
+}
+
diff --git a/sw/airborne/arch/sim/subsystems/actuators/actuators_dualpwm_arch.h b/sw/airborne/arch/sim/subsystems/actuators/actuators_dualpwm_arch.h
new file mode 100644
index 0000000000..2a22eee305
--- /dev/null
+++ b/sw/airborne/arch/sim/subsystems/actuators/actuators_dualpwm_arch.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2010 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 arch/sim/subsystems/actuators/actuators_dualpwm_arch.h
+ * dummy servos handling for sim
+ */
+
+#ifndef ACTUATORS_DUALPWM_ARCH_H
+#define ACTUATORS_DUALPWM_ARCH_H
+
+#define SERVOS_TICS_OF_USEC(_v) (_v)
+
+#define ActuatorDualpwmSet(_i, _v) {}
+#define ActuatorsDualPwmCommit() {}
+
+extern void actuators_dualpwm_arch_init(void);
+
+#endif /* ACTUATORS_DUALPWM_ARCH_H */
diff --git a/sw/airborne/arch/stm32/subsystems/actuators/actuators_dualpwm_arch.c b/sw/airborne/arch/stm32/subsystems/actuators/actuators_dualpwm_arch.c
new file mode 100644
index 0000000000..108bb9e834
--- /dev/null
+++ b/sw/airborne/arch/stm32/subsystems/actuators/actuators_dualpwm_arch.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2010 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 arch/stm32/subsystems/actuators/actuators_dualpwm_arch.c
+ * STM32 dual PWM servos handling.
+ */
+
+//VALID TIMERS IS TIM5 ON THE LISA/M
+
+#include "subsystems/actuators/actuators_shared_arch.h"
+#include "subsystems/actuators/actuators_dualpwm_arch.h"
+#include "subsystems/actuators/actuators_dualpwm.h"
+
+#include
+#include
+#include
+#include
+
+
+uint32_t ratio_4ms, ratio_16ms;
+
+
+uint32_t actuators_dualpwm_values[ACTUATORS_PWM_NB];
+
+/** PWM arch init called by generic pwm driver
+ */
+void actuators_dualpwm_arch_init(void) {
+
+ /*-----------------------------------
+ * Configure timer peripheral clocks
+ *-----------------------------------*/
+#if PWM_USE_TIM1
+ rcc_periph_clock_enable(RCC_TIM1);
+#endif
+#if PWM_USE_TIM2
+ rcc_periph_clock_enable(RCC_TIM2);
+#endif
+#if PWM_USE_TIM3
+ rcc_periph_clock_enable(RCC_TIM3);
+#endif
+#if PWM_USE_TIM4
+ rcc_periph_clock_enable(RCC_TIM4);
+#endif
+#if PWM_USE_TIM5
+ rcc_periph_clock_enable(RCC_TIM5);
+#endif
+#if PWM_USE_TIM8
+ rcc_periph_clock_enable(RCC_TIM8);
+#endif
+#if PWM_USE_TIM9
+ rcc_periph_clock_enable(RCC_TIM9);
+#endif
+#if PWM_USE_TIM12
+ rcc_periph_clock_enable(RCC_TIM12);
+#endif
+
+ /*----------------
+ * Configure GPIO
+ *----------------*/
+#if defined(STM32F1)
+ /* TIM3 GPIO for PWM1..4 */
+ AFIO_MAPR |= AFIO_MAPR_TIM3_REMAP_FULL_REMAP;
+#endif
+
+#ifdef DUAL_PWM_SERVO_5
+ set_servo_gpio(DUAL_PWM_SERVO_5_GPIO, DUAL_PWM_SERVO_5_PIN, DUAL_PWM_SERVO_5_AF, DUAL_PWM_SERVO_5_RCC);
+#endif
+#ifdef DUAL_PWM_SERVO_6
+ set_servo_gpio(DUAL_PWM_SERVO_6_GPIO, DUAL_PWM_SERVO_6_PIN, DUAL_PWM_SERVO_6_AF, DUAL_PWM_SERVO_6_RCC);
+#endif
+
+#if DUAL_PWM_USE_TIM5
+ set_servo_timer(TIM5, TIM5_SERVO_HZ, PWM_TIM5_CHAN_MASK);
+
+ nvic_set_priority(NVIC_TIM5_IRQ, 2);
+ nvic_enable_irq(NVIC_TIM5_IRQ);
+ timer_enable_irq(TIM5, TIM_DIER_CC1IE);
+#endif
+
+ //calculation the values to put into the timer registers to generate pulses every 4ms and 16ms.
+ ratio_4ms = (ONE_MHZ_CLK / 250)-1;
+ ratio_16ms = (ONE_MHZ_CLK / 62.5)-1;
+
+}
+
+
+/** Interuption called at the end of the timer. In our case alternatively very 4ms and 16ms (twice every 20ms)
+ */
+#if DUAL_PWM_USE_TIM5
+void tim5_isr(void){
+
+ dual_pwm_isr();
+}
+#endif
+
+
+
+
+/** Fonction that clears the flag of interuption in order to reactivate the interuption
+ */
+void clear_timer_flag(void){
+
+#if DUAL_PWM_USE_TIM5
+ timer_clear_flag(TIM5, TIM_SR_CC1IF);
+#endif
+}
+
+
+void set_dual_pwm_timer_s_period(uint32_t period){
+
+#if DUAL_PWM_USE_TIM5
+ timer_set_period(TIM5, period);
+#endif
+}
+
+
+void set_dual_pwm_timer_s_oc(uint32_t oc_value){
+
+#if DUAL_PWM_USE_TIM5
+ timer_set_oc_value(DUAL_PWM_SERVO_5_TIMER, DUAL_PWM_SERVO_5_OC, oc_value);
+#endif
+}
+
+
+
+
+void dual_pwm_isr(void){
+
+ static int num_pulse = 0; //status of the timer. Are we controling the first or the second servo
+
+ clear_timer_flag();
+
+ if(num_pulse == 1){
+
+ set_dual_pwm_timer_s_period(ratio_16ms);
+ set_dual_pwm_timer_s_oc(actuators_dualpwm_values[FIRST_DUAL_PWM_SERVO]);
+
+ num_pulse = 0;
+ }else{
+
+ set_dual_pwm_timer_s_period(ratio_4ms);
+ set_dual_pwm_timer_s_oc(actuators_dualpwm_values[SECOND_DUAL_PWM_SERVO]);
+
+ num_pulse = 1;
+ }
+}
+
+
+/** Set pulse widths from actuator values, assumed to be in us
+ */
+void actuators_dualpwm_commit(void) {
+
+ //we don't need to commit the values into this function as far as it's done in the interuption
+ //(wich is called every 4ms and 16ms alternatively (twice every 20ms))
+
+}
diff --git a/sw/airborne/arch/stm32/subsystems/actuators/actuators_dualpwm_arch.h b/sw/airborne/arch/stm32/subsystems/actuators/actuators_dualpwm_arch.h
new file mode 100644
index 0000000000..5f6bfbb139
--- /dev/null
+++ b/sw/airborne/arch/stm32/subsystems/actuators/actuators_dualpwm_arch.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2010 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 arch/stm32/subsystems/actuators/actuators_dualpwm_arch.h
+ * STM32 PWM servos handling.
+ */
+
+#ifndef ACTUATORS_dualpwm_ARCH_H
+#define ACTUATORS_dualpwm_ARCH_H
+
+#include "std.h"
+
+#include BOARD_CONFIG
+
+#ifndef ACTUATORS_dualpwm_NB
+#define ACTUATORS_dualpwm_NB 8
+#endif
+
+
+extern uint32_t actuators_dualpwm_values[ACTUATORS_PWM_NB];
+
+extern void actuators_dualpwm_commit(void);
+
+extern void dual_pwm_isr(void);
+
+extern void clear_timer_flag(void);
+
+extern void set_dual_pwm_timer_s_period(uint32_t period);
+
+extern void set_dual_pwm_timer_s_oc(uint32_t oc_value);
+
+#define SERVOS_TICS_OF_USEC(_v) (_v)
+
+#define ActuatorDualpwmSet(_i, _v) { actuators_dualpwm_values[_i] = _v; }
+#define ActuatorsDualpwmCommit actuators_dualpwm_commit
+
+#endif /* ACTUATORS_dualpwm_ARCH_H */
diff --git a/sw/airborne/arch/stm32/subsystems/actuators/actuators_pwm_arch.c b/sw/airborne/arch/stm32/subsystems/actuators/actuators_pwm_arch.c
index 0ce80993df..a47b6fed50 100644
--- a/sw/airborne/arch/stm32/subsystems/actuators/actuators_pwm_arch.c
+++ b/sw/airborne/arch/stm32/subsystems/actuators/actuators_pwm_arch.c
@@ -25,6 +25,7 @@
//VALID TIMERS ARE TIM1,2,3,4,5,8,9,12
+#include "subsystems/actuators/actuators_shared_arch.h"
#include "subsystems/actuators/actuators_pwm_arch.h"
#include "subsystems/actuators/actuators_pwm.h"
@@ -33,176 +34,9 @@
#include
-#if defined(STM32F1)
-//#define PCLK 72000000
-#define PCLK AHB_CLK
-#elif defined(STM32F4)
-//#define PCLK 84000000
-#define PCLK AHB_CLK/2
-#endif
-
-#define ONE_MHZ_CLK 1000000
-
-#ifdef STM32F1
-/**
- * HCLK = 72MHz, Timer clock also 72MHz since
- * TIM1_CLK = APB2 = 72MHz
- * TIM2_CLK = 2 * APB1 = 2 * 32MHz
- */
-#define TIMER_APB1_CLK AHB_CLK
-#define TIMER_APB2_CLK AHB_CLK
-#endif
-
-#ifdef STM32F4
-/* Since APB prescaler != 1 :
- * Timer clock frequency (before prescaling) is twice the frequency
- * of the APB domain to which the timer is connected.
- */
-#define TIMER_APB1_CLK (rcc_ppre1_frequency * 2)
-#define TIMER_APB2_CLK (rcc_ppre2_frequency * 2)
-#endif
-
-
-/** Default servo update rate in Hz */
-#ifndef SERVO_HZ
-#define SERVO_HZ 40
-#endif
-
-// Update rate can be adapted for each timer
-#ifndef TIM1_SERVO_HZ
-#define TIM1_SERVO_HZ SERVO_HZ
-#endif
-#ifndef TIM2_SERVO_HZ
-#define TIM2_SERVO_HZ SERVO_HZ
-#endif
-#ifndef TIM3_SERVO_HZ
-#define TIM3_SERVO_HZ SERVO_HZ
-#endif
-#ifndef TIM4_SERVO_HZ
-#define TIM4_SERVO_HZ SERVO_HZ
-#endif
-#ifndef TIM5_SERVO_HZ
-#define TIM5_SERVO_HZ SERVO_HZ
-#endif
-#ifndef TIM9_SERVO_HZ
-#define TIM9_SERVO_HZ SERVO_HZ
-#endif
-#ifndef TIM12_SERVO_HZ
-#define TIM12_SERVO_HZ SERVO_HZ
-#endif
-
-
-/** @todo: these should go into libopencm3 */
-#define TIM9 TIM9_BASE
-#define TIM12 TIM12_BASE
-
int32_t actuators_pwm_values[ACTUATORS_PWM_NB];
-/** Set PWM channel configuration
- */
-static inline void actuators_pwm_arch_channel_init(uint32_t timer_peripheral,
- enum tim_oc_id oc_id) {
-
- timer_disable_oc_output(timer_peripheral, oc_id);
- //There is no such register in TIM9 and 12.
- if (timer_peripheral != TIM9 && timer_peripheral != TIM12)
- timer_disable_oc_clear(timer_peripheral, oc_id);
- timer_enable_oc_preload(timer_peripheral, oc_id);
- timer_set_oc_slow_mode(timer_peripheral, oc_id);
- timer_set_oc_mode(timer_peripheral, oc_id, TIM_OCM_PWM1);
- timer_set_oc_polarity_high(timer_peripheral, oc_id);
- timer_enable_oc_output(timer_peripheral, oc_id);
- // Used for TIM1 and TIM8, the function does nothing if other timer is specified.
- timer_enable_break_main_output(timer_peripheral);
-}
-
-/** Set GPIO configuration
- */
-#if defined(STM32F4)
-static inline void set_servo_gpio(uint32_t gpioport, uint16_t pin, uint8_t af_num, enum rcc_periph_clken clken) {
- rcc_periph_clock_enable(clken);
- gpio_mode_setup(gpioport, GPIO_MODE_AF, GPIO_PUPD_NONE, pin);
- gpio_set_af(gpioport, af_num, pin);
-}
-#elif defined(STM32F1)
-static inline void set_servo_gpio(uint32_t gpioport, uint16_t pin, uint8_t none __attribute__((unused)), enum rcc_periph_clken clken) {
- rcc_periph_clock_enable(clken);
- rcc_periph_clock_enable(RCC_AFIO);
- gpio_set_mode(gpioport, GPIO_MODE_OUTPUT_50_MHZ,
- GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, pin);
-}
-#endif
-
-/** Set Timer configuration
- */
-static inline void set_servo_timer(uint32_t timer, uint32_t period, uint8_t channels_mask) {
- timer_reset(timer);
-
- /* Timer global mode:
- * - No divider.
- * - Alignement edge.
- * - Direction up.
- */
- if ((timer == TIM9) || (timer == TIM12))
- //There are no EDGE and DIR settings in TIM9 and TIM12
- timer_set_mode(timer, TIM_CR1_CKD_CK_INT, 0, 0);
- else
- timer_set_mode(timer, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
-
-
- // TIM1, 8 and 9 use APB2 clock, all others APB1
- if (timer != TIM1 && timer != TIM8 && timer != TIM9) {
- timer_set_prescaler(timer, (TIMER_APB1_CLK / ONE_MHZ_CLK) - 1); // 1uS
- } else {
- // TIM9, 1 and 8 use APB2 clock
- timer_set_prescaler(timer, (TIMER_APB2_CLK / ONE_MHZ_CLK) - 1);
- }
-
- timer_disable_preload(timer);
-
- timer_continuous_mode(timer);
-
- timer_set_period(timer, (ONE_MHZ_CLK / period) - 1);
-
- /* Disable outputs and configure channel if needed. */
- if (bit_is_set(channels_mask, 0)) {
- actuators_pwm_arch_channel_init(timer, TIM_OC1);
- }
- if (bit_is_set(channels_mask, 1)) {
- actuators_pwm_arch_channel_init(timer, TIM_OC2);
- }
- if (bit_is_set(channels_mask, 2)) {
- actuators_pwm_arch_channel_init(timer, TIM_OC3);
- }
- if (bit_is_set(channels_mask, 3)) {
- actuators_pwm_arch_channel_init(timer, TIM_OC4);
- }
-
- /*
- * Set initial output compare values.
- * Note: Maybe we should preload the compare registers with some sensible
- * values before we enable the timer?
- */
- //timer_set_oc_value(timer, TIM_OC1, 1000);
- //timer_set_oc_value(timer, TIM_OC2, 1000);
- //timer_set_oc_value(timer, TIM_OC3, 1000);
- //timer_set_oc_value(timer, TIM_OC4, 1000);
-
- /* -- Enable timer -- */
- /*
- * ARR reload enable.
- * Note: In our case it does not matter much if we do preload or not. As it
- * is unlikely we will want to change the frequency of the timer during
- * runtime anyways.
- */
- timer_enable_preload(timer);
-
- /* Counter enable. */
- timer_enable_counter(timer);
-
-}
-
/** PWM arch init called by generic pwm driver
*/
void actuators_pwm_arch_init(void) {
diff --git a/sw/airborne/arch/stm32/subsystems/actuators/actuators_shared_arch.c b/sw/airborne/arch/stm32/subsystems/actuators/actuators_shared_arch.c
new file mode 100644
index 0000000000..6c4cd624ce
--- /dev/null
+++ b/sw/airborne/arch/stm32/subsystems/actuators/actuators_shared_arch.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2010 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 arch/stm32/subsystems/actuators/actuators_shared_arch.c
+ * STM32 PWM and dualPWM servos shared functions.
+ */
+
+#include "subsystems/actuators/actuators_shared_arch.h"
+
+
+/** Set GPIO configuration
+ */
+#if defined(STM32F4)
+void set_servo_gpio(uint32_t gpioport, uint16_t pin, uint8_t af_num, enum rcc_periph_clken clken) {
+ rcc_periph_clock_enable(clken);
+ gpio_mode_setup(gpioport, GPIO_MODE_AF, GPIO_PUPD_NONE, pin);
+ gpio_set_af(gpioport, af_num, pin);
+}
+#elif defined(STM32F1)
+void set_servo_gpio(uint32_t gpioport, uint16_t pin, uint8_t none __attribute__((unused)), enum rcc_periph_clken clken) {
+ rcc_periph_clock_enable(clken);
+ rcc_periph_clock_enable(RCC_AFIO);
+ gpio_set_mode(gpioport, GPIO_MODE_OUTPUT_50_MHZ,
+ GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, pin);
+}
+#endif
+
+
+
+/** Set PWM channel configuration
+ */
+void actuators_pwm_arch_channel_init(uint32_t timer_peripheral,
+ enum tim_oc_id oc_id) {
+
+ timer_disable_oc_output(timer_peripheral, oc_id);
+ //There is no such register in TIM9 and 12.
+ if (timer_peripheral != TIM9 && timer_peripheral != TIM12)
+ timer_disable_oc_clear(timer_peripheral, oc_id);
+ timer_enable_oc_preload(timer_peripheral, oc_id);
+ timer_set_oc_slow_mode(timer_peripheral, oc_id);
+ timer_set_oc_mode(timer_peripheral, oc_id, TIM_OCM_PWM1);
+ timer_set_oc_polarity_high(timer_peripheral, oc_id);
+ timer_enable_oc_output(timer_peripheral, oc_id);
+ // Used for TIM1 and TIM8, the function does nothing if other timer is specified.
+ timer_enable_break_main_output(timer_peripheral);
+}
+
+
+/** Set Timer configuration
+ */
+void set_servo_timer(uint32_t timer, uint32_t period, uint8_t channels_mask) {
+ timer_reset(timer);
+
+ /* Timer global mode:
+ * - No divider.
+ * - Alignement edge.
+ * - Direction up.
+ */
+ if ((timer == TIM9) || (timer == TIM12))
+ //There are no EDGE and DIR settings in TIM9 and TIM12
+ timer_set_mode(timer, TIM_CR1_CKD_CK_INT, 0, 0);
+ else
+ timer_set_mode(timer, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
+
+
+ // TIM1, 8 and 9 use APB2 clock, all others APB1
+ if (timer != TIM1 && timer != TIM8 && timer != TIM9) {
+ timer_set_prescaler(timer, (TIMER_APB1_CLK / ONE_MHZ_CLK) - 1); // 1uS
+ } else {
+ // TIM9, 1 and 8 use APB2 clock
+ timer_set_prescaler(timer, (TIMER_APB2_CLK / ONE_MHZ_CLK) - 1);
+ }
+
+ timer_disable_preload(timer);
+
+ timer_continuous_mode(timer);
+
+ timer_set_period(timer, (ONE_MHZ_CLK / period) - 1);
+
+ /* Disable outputs and configure channel if needed. */
+ if (bit_is_set(channels_mask, 0)) {
+ actuators_pwm_arch_channel_init(timer, TIM_OC1);
+ }
+ if (bit_is_set(channels_mask, 1)) {
+ actuators_pwm_arch_channel_init(timer, TIM_OC2);
+ }
+ if (bit_is_set(channels_mask, 2)) {
+ actuators_pwm_arch_channel_init(timer, TIM_OC3);
+ }
+ if (bit_is_set(channels_mask, 3)) {
+ actuators_pwm_arch_channel_init(timer, TIM_OC4);
+ }
+
+ /*
+ * Set initial output compare values.
+ * Note: Maybe we should preload the compare registers with some sensible
+ * values before we enable the timer?
+ */
+ //timer_set_oc_value(timer, TIM_OC1, 1000);
+ //timer_set_oc_value(timer, TIM_OC2, 1000);
+ //timer_set_oc_value(timer, TIM_OC3, 1000);
+ //timer_set_oc_value(timer, TIM_OC4, 1000);
+
+ /* -- Enable timer -- */
+ /*
+ * ARR reload enable.
+ * Note: In our case it does not matter much if we do preload or not. As it
+ * is unlikely we will want to change the frequency of the timer during
+ * runtime anyways.
+ */
+ timer_enable_preload(timer);
+
+ /* Counter enable. */
+ timer_enable_counter(timer);
+
+}
+
diff --git a/sw/airborne/arch/stm32/subsystems/actuators/actuators_shared_arch.h b/sw/airborne/arch/stm32/subsystems/actuators/actuators_shared_arch.h
new file mode 100644
index 0000000000..7911b8ceab
--- /dev/null
+++ b/sw/airborne/arch/stm32/subsystems/actuators/actuators_shared_arch.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2010 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 arch/stm32/subsystems/actuators/actuators_shared_arch.h
+ * STM32 PWM and dualPWM servos shared functions.
+ */
+
+#ifndef ACTUATORS_PWM_SHARED_ARCH_H
+#define ACTUATORS_PWM_SHARED_ARCH_H
+
+#include "std.h"
+
+#include BOARD_CONFIG
+
+#include
+#include
+#include
+#include
+
+
+
+#if defined(STM32F1)
+//#define PCLK 72000000
+#define PCLK AHB_CLK
+#elif defined(STM32F4)
+//#define PCLK 84000000
+#define PCLK AHB_CLK/2
+#endif
+
+#define ONE_MHZ_CLK 1000000
+
+#ifdef STM32F1
+/**
+ * HCLK = 72MHz, Timer clock also 72MHz since
+ * TIM1_CLK = APB2 = 72MHz
+ * TIM2_CLK = 2 * APB1 = 2 * 32MHz
+ */
+#define TIMER_APB1_CLK AHB_CLK
+#define TIMER_APB2_CLK AHB_CLK
+#endif
+
+#ifdef STM32F4
+/* Since APB prescaler != 1 :
+ * Timer clock frequency (before prescaling) is twice the frequency
+ * of the APB domain to which the timer is connected.
+ */
+#define TIMER_APB1_CLK (rcc_ppre1_frequency * 2)
+#define TIMER_APB2_CLK (rcc_ppre2_frequency * 2)
+#endif
+
+/** Default servo update rate in Hz */
+#ifndef SERVO_HZ
+#define SERVO_HZ 40
+#endif
+
+// Update rate can be adapted for each timer
+#ifndef TIM1_SERVO_HZ
+#define TIM1_SERVO_HZ SERVO_HZ
+#endif
+#ifndef TIM2_SERVO_HZ
+#define TIM2_SERVO_HZ SERVO_HZ
+#endif
+#ifndef TIM3_SERVO_HZ
+#define TIM3_SERVO_HZ SERVO_HZ
+#endif
+#ifndef TIM4_SERVO_HZ
+#define TIM4_SERVO_HZ SERVO_HZ
+#endif
+#ifndef TIM5_SERVO_HZ
+#define TIM5_SERVO_HZ SERVO_HZ
+#endif
+#ifndef TIM9_SERVO_HZ
+#define TIM9_SERVO_HZ SERVO_HZ
+#endif
+#ifndef TIM12_SERVO_HZ
+#define TIM12_SERVO_HZ SERVO_HZ
+#endif
+
+
+/** @todo: these should go into libopencm3 */
+#define TIM9 TIM9_BASE
+#define TIM12 TIM12_BASE
+
+
+#if defined(STM32F4)
+extern void set_servo_gpio(uint32_t gpioport, uint16_t pin, uint8_t af_num, enum rcc_periph_clken clken);
+#elif defined(STM32F1)
+extern void set_servo_gpio(uint32_t gpioport, uint16_t pin, uint8_t none __attribute__((unused)), enum rcc_periph_clken clken);
+#endif
+
+extern void actuators_pwm_arch_channel_init(uint32_t timer_peripheral, enum tim_oc_id oc_id);
+
+extern void set_servo_timer(uint32_t timer, uint32_t period, uint8_t channels_mask);
+
+#endif /* ACTUATORS_PWM_SHARED_ARCH_H */
diff --git a/sw/airborne/boards/apogee_1.0.h b/sw/airborne/boards/apogee_1.0.h
index 7a6dedf61e..d68f10884b 100644
--- a/sw/airborne/boards/apogee_1.0.h
+++ b/sw/airborne/boards/apogee_1.0.h
@@ -91,17 +91,8 @@
#define LED_8_GPIO_OFF gpio_clear
#define LED_8_AFIO_REMAP ((void)0)
-/* Power Switch, on PB12, 1 on LED_ON, 0 on LED_OFF */
-#ifndef USE_LED_9
-#define USE_LED_9 1
-#endif
-#define LED_9_GPIO GPIOB
-#define LED_9_GPIO_PIN GPIO12
-#define LED_9_GPIO_ON gpio_set
-#define LED_9_GPIO_OFF gpio_clear
-#define LED_9_AFIO_REMAP ((void)0)
-
-#define POWER_SWITCH_LED 9
+/* Power Switch, on PB12 */
+#define POWER_SWITCH_GPIO GPIOB,GPIO12
/* Pint to set Uart2 RX polarity, on PB13, output high inverts, low doesn't */
diff --git a/sw/airborne/boards/ardrone/baro_board.c b/sw/airborne/boards/ardrone/baro_board.c
index 73c33868f3..67528f4761 100644
--- a/sw/airborne/boards/ardrone/baro_board.c
+++ b/sw/airborne/boards/ardrone/baro_board.c
@@ -31,10 +31,21 @@
#include "baro_board.h"
#include "navdata.h"
+/** Use an extra median filter to filter baro data
+ */
+#if USE_BARO_MEDIAN_FILTER
+#include "filters/median_filter.h"
+struct MedianFilterInt baro_median;
+#endif
+
#define BMP180_OSS 0 // Parrot ARDrone uses no oversampling
-void baro_init(void) {}
+void baro_init(void) {
+#if USE_BARO_MEDIAN_FILTER
+ init_median_filter(&baro_median);
+#endif
+}
void baro_periodic(void) {}
@@ -74,7 +85,11 @@ void ardrone_baro_event(void)
// 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);
+ int32_t press_raw = baro_apply_calibration(navdata.pressure);
+#if USE_BARO_MEDIAN_FILTER
+ press_raw = update_median_filter(&baro_median, press_raw);
+#endif
+ float pressure = (float)press_raw;
AbiSendMsgBARO_ABS(BARO_BOARD_SENDER_ID, &pressure);
}
navdata_baro_available = FALSE;
diff --git a/sw/airborne/boards/ardrone/navdata.c b/sw/airborne/boards/ardrone/navdata.c
index 099034a73c..7e30c91127 100644
--- a/sw/airborne/boards/ardrone/navdata.c
+++ b/sw/airborne/boards/ardrone/navdata.c
@@ -40,6 +40,7 @@
#include "std.h"
#include "navdata.h"
#include "subsystems/ins.h"
+#include "subsystems/abi.h"
#define NAVDATA_PACKET_SIZE 60
#define NAVDATA_START_BYTE 0x3a
@@ -51,9 +52,20 @@ navdata_port nav_port;
static int nav_fd = 0;
measures_t navdata;
-#include "subsystems/sonar.h"
-uint16_t sonar_meas = 0;
+/** Sonar offset.
+ * Offset value in ADC
+ * equals to the ADC value so that height is zero
+ */
+#ifndef SONAR_OFFSET
+#define SONAR_OFFSET 880
+#endif
+/** Sonar scale.
+ * Sensor sensitivity in m/adc (float)
+ */
+#ifndef SONAR_SCALE
+#define SONAR_SCALE 0.00047
+#endif
// FIXME(ben): there must be a better home for these
ssize_t full_write(int fd, const uint8_t *buf, size_t count)
@@ -469,8 +481,8 @@ void navdata_update()
// Check if there is a new sonar measurement and update the sonar
if (navdata.ultrasound >> 15)
{
- sonar_meas = (navdata.ultrasound & 0x7FFF);
- ins_update_sonar();
+ float sonar_meas = (float)((navdata.ultrasound & 0x7FFF) - SONAR_OFFSET) * SONAR_SCALE;
+ AbiSendMsgAGL(AGL_SONAR_ARDRONE2_ID, &sonar_meas);
}
#endif
diff --git a/sw/airborne/boards/booz_1.0.h b/sw/airborne/boards/booz_1.0.h
index 7877386dae..11bd4defaa 100644
--- a/sw/airborne/boards/booz_1.0.h
+++ b/sw/airborne/boards/booz_1.0.h
@@ -42,22 +42,9 @@
#define LED_4_BANK 1
#define LED_4_PIN 31
-#ifndef USE_LED_5
-#define USE_LED_5 1
-#endif
-#define LED_5_BANK 1
-#define LED_5_PIN 18
-
-#define POWER_SWITCH_LED 5
-
-#ifndef USE_LED_6
-#define USE_LED_6 1
-#endif
-#define LED_6_BANK 1
-#define LED_6_PIN 22
-
-#define CAM_SWITCH_LED 6
+#define POWER_SWITCH_GPIO GPIOB,GPIO18
+#define CAM_SWITCH_GPIO GPIOB,GPIO22
/* PPM : rc rx on P0.28 ( CAP0.2 ) */
#define PPM_PINSEL PINSEL1
diff --git a/sw/airborne/boards/hb_1.1.h b/sw/airborne/boards/hb_1.1.h
index 02f00187e0..ad0c7a6511 100644
--- a/sw/airborne/boards/hb_1.1.h
+++ b/sw/airborne/boards/hb_1.1.h
@@ -17,39 +17,13 @@
/* Peripheral bus clock freq. */
#define PCLK (CCLK / PBSD_VAL)
-/* Onboard LEDs */
-/* led 1 and led 2 are not seperate leds, but leds indicating the power switch status */
+/* power switch status */
+#define POWER_SWITCH_GPIO GPIOB,GPIO18
+#define POWER_SWITCH_2_GPIO GPIOB,GPIO19
-#ifndef USE_LED_1
-#define USE_LED_1 1
-#endif
-#define LED_1_BANK 1
-#define LED_1_PIN 18
-
-#ifndef USE_LED_2
-#define USE_LED_2 1
-#endif
-#define LED_2_BANK 1
-#define LED_2_PIN 19
-
-#define POWER_SWITCH_LED 1
-#define POWER_SWITCH_2_LED 2
-
-/* there are no actual leds 3 and 4, these defines are just to conveniently switch the buzzer and the cam switch */
-#ifndef USE_LED_3
-#define USE_LED_3 1
-#endif
-#define LED_3_BANK 1
-#define LED_3_PIN 20
-
-#ifndef USE_LED_4
-#define USE_LED_4 1
-#endif
-#define LED_4_BANK 1
-#define LED_4_PIN 25
-
-#define BUZZER_LED 3
-#define CAM_SWITCH_LED 4
+/* buzzer and cam switch */
+#define BUZZER_GPIO GPIOB,GPIO20
+#define CAM_SWITCH_GPIO GPIOB,GPIO25
/* P0.22 aka MAT0.0 */
#define SERVO_CLOCK_PIN 22
diff --git a/sw/airborne/boards/lisa_l_1.0.h b/sw/airborne/boards/lisa_l_1.0.h
index 3ef3a14c6d..b8aa6cba2f 100644
--- a/sw/airborne/boards/lisa_l_1.0.h
+++ b/sw/airborne/boards/lisa_l_1.0.h
@@ -13,9 +13,6 @@
#endif
#define LED_STP08
-// FIXME, this is just to make it compile
-#define POWER_SWITCH_LED 5
-
/* SPI slave mapping */
#define SPI_SELECT_SLAVE0_PERIPH RCC_GPIOA
diff --git a/sw/airborne/boards/lisa_m_common.h b/sw/airborne/boards/lisa_m_common.h
index 3fc39b5d0c..6f0a26da27 100644
--- a/sw/airborne/boards/lisa_m_common.h
+++ b/sw/airborne/boards/lisa_m_common.h
@@ -224,8 +224,18 @@
#define USE_PWM2 1
#define USE_PWM3 1
#define USE_PWM4 1
-#define USE_PWM5 1
-#define USE_PWM6 1
+
+#if DUAL_PWM_ON
+ #define DUAL_PWM_USE_TIM5 1
+
+ #define USE_DUAL_PWM5 1
+ #define USE_DUAL_PWM6 1
+#else
+ #define USE_PWM5 1
+ #define USE_PWM6 1
+#endif
+
+
#if USE_SERVOS_7AND8
#if USE_I2C1
@@ -296,31 +306,60 @@
#endif
#if USE_PWM5
-#define PWM_SERVO_5 4
-#define PWM_SERVO_5_TIMER TIM5
-#define PWM_SERVO_5_RCC RCC_GPIOA
-#define PWM_SERVO_5_GPIO GPIOA
-#define PWM_SERVO_5_PIN GPIO0
-#define PWM_SERVO_5_AF 0
-#define PWM_SERVO_5_OC TIM_OC1
-#define PWM_SERVO_5_OC_BIT (1<<0)
+ #define PWM_SERVO_5 4
+ #define PWM_SERVO_5_TIMER TIM5
+ #define PWM_SERVO_5_RCC RCC_GPIOA
+ #define PWM_SERVO_5_GPIO GPIOA
+ #define PWM_SERVO_5_PIN GPIO0
+ #define PWM_SERVO_5_AF 0
+ #define PWM_SERVO_5_OC TIM_OC1
+ #define PWM_SERVO_5_OC_BIT (1<<0)
+#elif USE_DUAL_PWM5
+ #define DUAL_PWM_SERVO_5 4
+
+ #define FIRST_DUAL_PWM_SERVO DUAL_PWM_SERVO_5
+
+ #define DUAL_PWM_SERVO_5_TIMER TIM5
+ #define DUAL_PWM_SERVO_5_RCC RCC_GPIOA
+ #define DUAL_PWM_SERVO_5_GPIO GPIOA
+ #define DUAL_PWM_SERVO_5_PIN GPIO0
+ #define DUAL_PWM_SERVO_5_AF 0
+ #define DUAL_PWM_SERVO_5_OC TIM_OC1
+ #define PWM_SERVO_5_OC_BIT (1<<0)
#else
-#define PWM_SERVO_5_OC_BIT 0
+ #define PWM_SERVO_5_OC_BIT 0
#endif
#if USE_PWM6
-#define PWM_SERVO_6 5
-#define PWM_SERVO_6_TIMER TIM5
-#define PWM_SERVO_6_RCC RCC_GPIOA
-#define PWM_SERVO_6_GPIO GPIOA
-#define PWM_SERVO_6_PIN GPIO1
-#define PWM_SERVO_6_AF 0
-#define PWM_SERVO_6_OC TIM_OC2
-#define PWM_SERVO_6_OC_BIT (1<<1)
+ #define PWM_SERVO_6 5
+ #define PWM_SERVO_6_TIMER TIM5
+ #define PWM_SERVO_6_RCC RCC_GPIOA
+ #define PWM_SERVO_6_GPIO GPIOA
+ #define PWM_SERVO_6_PIN GPIO1
+ #define PWM_SERVO_6_AF 0
+ #define PWM_SERVO_6_OC TIM_OC2
+ #define PWM_SERVO_6_OC_BIT (1<<1)
+#elif USE_DUAL_PWM6
+ #define DUAL_PWM_SERVO_6 5
+
+ #define SECOND_DUAL_PWM_SERVO DUAL_PWM_SERVO_6
+
+ #define DUAL_PWM_SERVO_6_TIMER TIM5
+ #define DUAL_PWM_SERVO_6_RCC RCC_GPIOA
+ #define DUAL_PWM_SERVO_6_GPIO GPIOA
+ #define DUAL_PWM_SERVO_6_PIN GPIO1
+ #define DUAL_PWM_SERVO_6_AF 0
+ #define DUAL_PWM_SERVO_6_OC TIM_OC2
+ #define PWM_SERVO_6_OC_BIT (1<<1)
#else
-#define PWM_SERVO_6_OC_BIT 0
+ #define PWM_SERVO_6_OC_BIT 0
#endif
+
+
+
+
+
#if USE_PWM7
#define PWM_SERVO_7 6
#define PWM_SERVO_7_TIMER TIM4
diff --git a/sw/airborne/boards/lisa_s_0.1.h b/sw/airborne/boards/lisa_s_0.1.h
index 827ad14917..c6c5449a5a 100644
--- a/sw/airborne/boards/lisa_s_0.1.h
+++ b/sw/airborne/boards/lisa_s_0.1.h
@@ -90,7 +90,10 @@
#define DefaultVoltageOfAdc(adc) (0.0045*adc)
-#define BOARD_HAS_BARO 1
+/* by default activate onboard baro */
+#ifndef USE_BARO_BOARD
+#define USE_BARO_BOARD 1
+#endif
/* SPI slave mapping */
@@ -290,8 +293,18 @@
#define USE_PWM3 1
#define USE_PWM4 1
-#define USE_PWM5 1
-#define USE_PWM6 1
+
+//TODO : test that part
+//TODO : merge the USE_SERVOS_1AND2 and DUAL_PWM_ON
+#if DUAL_PWM_ON
+ #define DUAL_PWM_USE_TIM5 1
+
+ #define USE_DUAL_PWM5 1
+ #define USE_DUAL_PWM6 1
+#else
+ #define USE_PWM5 1
+ #define USE_PWM6 1
+#endif
// Servo numbering on LisaM silkscreen/docs starts with 1
@@ -352,31 +365,56 @@
#endif
#if USE_PWM5
-#define PWM_SERVO_5 2
-#define PWM_SERVO_5_TIMER TIM5
-#define PWM_SERVO_5_RCC RCC_GPIOA
-#define PWM_SERVO_5_GPIO GPIOA
-#define PWM_SERVO_5_PIN GPIO0
-#define PWM_SERVO_5_AF 0
-#define PWM_SERVO_5_OC TIM_OC1
-#define PWM_SERVO_5_OC_BIT (1<<0)
+ #define PWM_SERVO_5 2
+ #define PWM_SERVO_5_TIMER TIM5
+ #define PWM_SERVO_5_RCC RCC_GPIOA
+ #define PWM_SERVO_5_GPIO GPIOA
+ #define PWM_SERVO_5_PIN GPIO0
+ #define PWM_SERVO_5_AF 0
+ #define PWM_SERVO_5_OC TIM_OC1
+ #define PWM_SERVO_5_OC_BIT (1<<0)
+#elif USE_DUAL_PWM5
+ #define DUAL_PWM_SERVO_5 2
+
+ #define FIRST_DUAL_PWM_SERVO DUAL_PWM_SERVO_5
+
+ #define DUAL_PWM_SERVO_5_TIMER TIM5
+ #define DUAL_PWM_SERVO_5_RCC RCC_GPIOA
+ #define DUAL_PWM_SERVO_5_GPIO GPIOA
+ #define DUAL_PWM_SERVO_5_PIN GPIO0
+ #define DUAL_PWM_SERVO_5_AF 0
+ #define DUAL_PWM_SERVO_5_OC TIM_OC1
+ #define PWM_SERVO_5_OC_BIT (1<<0)
#else
-#define PWM_SERVO_5_OC_BIT 0
+ #define PWM_SERVO_5_OC_BIT 0
#endif
#if USE_PWM6
-#define PWM_SERVO_6 3
-#define PWM_SERVO_6_TIMER TIM5
-#define PWM_SERVO_6_RCC RCC_GPIOA
-#define PWM_SERVO_6_GPIO GPIOA
-#define PWM_SERVO_6_PIN GPIO1
-#define PWM_SERVO_6_AF 0
-#define PWM_SERVO_6_OC TIM_OC2
-#define PWM_SERVO_6_OC_BIT (1<<1)
+ #define PWM_SERVO_6 3
+ #define PWM_SERVO_6_TIMER TIM5
+ #define PWM_SERVO_6_RCC RCC_GPIOA
+ #define PWM_SERVO_6_GPIO GPIOA
+ #define PWM_SERVO_6_PIN GPIO1
+ #define PWM_SERVO_6_AF 0
+ #define PWM_SERVO_6_OC TIM_OC2
+ #define PWM_SERVO_6_OC_BIT (1<<1)
+#elif USE_DUAL_PWM6
+ #define DUAL_PWM_SERVO_6 3
+
+ #define SECOND_DUAL_PWM_SERVO DUAL_PWM_SERVO_6
+
+ #define DUAL_PWM_SERVO_6_TIMER TIM5
+ #define DUAL_PWM_SERVO_6_RCC RCC_GPIOA
+ #define DUAL_PWM_SERVO_6_GPIO GPIOA
+ #define DUAL_PWM_SERVO_6_PIN GPIO1
+ #define DUAL_PWM_SERVO_6_AF 0
+ #define DUAL_PWM_SERVO_6_OC TIM_OC2
+ #define PWM_SERVO_6_OC_BIT (1<<1)
#else
-#define PWM_SERVO_6_OC_BIT 0
+ #define PWM_SERVO_6_OC_BIT 0
#endif
+
/* servos 1-4 or 3-4 on TIM4 depending on USE_SERVOS_1AND2 */
#define PWM_TIM4_CHAN_MASK (PWM_SERVO_1_OC_BIT|PWM_SERVO_2_OC_BIT|PWM_SERVO_3_OC_BIT|PWM_SERVO_4_OC_BIT)
/* servos 5-6 on TIM5 */
diff --git a/sw/airborne/boards/logom_2.6.h b/sw/airborne/boards/logom_2.6.h
index 1b6f716667..f3d11d99b8 100644
--- a/sw/airborne/boards/logom_2.6.h
+++ b/sw/airborne/boards/logom_2.6.h
@@ -53,33 +53,15 @@
#define LED_3_BANK 0
#define LED_3_PIN 11
-#ifndef USE_LED_4
-#define USE_LED_4 1
-#endif
-#define LED_4_BANK 1
-#define LED_4_PIN 17
+#define POWER_SWITCH_GPIO GPIOB,GPIO17
-#define POWER_SWITCH_LED 4
+#define CAM_SWITCH_GPIO GPIOB,GPIO18
-#ifndef USE_LED_5
-#define USE_LED_5 1
-#endif
-#define LED_5_BANK 1
-#define LED_5_PIN 18
+#define GPS_RESET_GPIO GPIOB,GPIO19
-#define CAM_SWITCH_LED 5
-
-#ifndef USE_LED_6
-#define USE_LED_6 1
-#endif
-#define LED_6_BANK 1
-#define LED_6_PIN 19
-
-#define GPS_RESET 6
-
-#define Configure_GPS_RESET_Pin() LED_INIT(GPS_RESET)
-#define Set_GPS_RESET_Pin_LOW() LED_ON(GPS_RESET)
-#define Open_GPS_RESET_Pin() ClearBit(LED_DIR(GPS_RESET), LED_PIN(GPS_RESET))
+#define Configure_GPS_RESET_Pin() gpio_setup_output(GPS_RESET_GPIO)
+#define Set_GPS_RESET_Pin_LOW() gpio_clear(GPS_RESET_GPIO)
+#define Open_GPS_RESET_Pin() gpio_setup_input(GPS_RESET_GPIO)
/* P0.29 aka MAT0.3 (P2) */
#define SERVO_CLOCK_PIN 29
diff --git a/sw/airborne/boards/px4fmu_1.7.h b/sw/airborne/boards/px4fmu_1.7.h
index 1b3baa27a4..12472111d1 100644
--- a/sw/airborne/boards/px4fmu_1.7.h
+++ b/sw/airborne/boards/px4fmu_1.7.h
@@ -199,9 +199,10 @@
-/* Activate onboard baro */
-#define BOARD_HAS_BARO 1
-
+/* Activate onboard baro by default */
+#ifndef USE_BARO_BOARD
+#define USE_BARO_BOARD 1
+#endif
/* Default actuators driver */
diff --git a/sw/airborne/boards/sdlog_1.0.h b/sw/airborne/boards/sdlog_1.0.h
index 74fd1cb368..0cd319b776 100644
--- a/sw/airborne/boards/sdlog_1.0.h
+++ b/sw/airborne/boards/sdlog_1.0.h
@@ -57,33 +57,15 @@
#define LED_3_BANK 1
#define LED_3_PIN 23
-#ifndef USE_LED_4
-#define USE_LED_4 1
-#endif
-#define LED_4_BANK 1
-#define LED_4_PIN 18
+#define POWER_SWITCH_GPIO GPIOB,GPIO18
-#define POWER_SWITCH_LED 4
+#define CAM_SWITCH_GPIO GPIOB,GPIO22
-#ifndef USE_LED_5
-#define USE_LED_5 1
-#endif
-#define LED_5_BANK 1
-#define LED_5_PIN 22
+#define GPS_RESET_GPIO GPIOB,GPIO21
-#define CAM_SWITCH_LED 5
-
-#ifndef USE_LED_6
-#define USE_LED_6 1
-#endif
-#define LED_6_BANK 1
-#define LED_6_PIN 21
-
-#define GPS_RESET 6
-
-#define Configure_GPS_RESET_Pin() LED_INIT(GPS_RESET)
-#define Set_GPS_RESET_Pin_LOW() LED_ON(GPS_RESET)
-#define Open_GPS_RESET_Pin() ClearBit(LED_DIR(GPS_RESET), LED_PIN(GPS_RESET))
+#define Configure_GPS_RESET_Pin() gpio_setup_output(GPS_RESET_GPIO)
+#define Set_GPS_RESET_Pin_LOW() gpio_clear(GPS_RESET_GPIO)
+#define Open_GPS_RESET_Pin() gpio_setup_input(GPS_RESET_GPIO)
/* P0.5 aka MAT0.1 */
#define SERVO_CLOCK_PIN 5
diff --git a/sw/airborne/boards/tiny_1.1.h b/sw/airborne/boards/tiny_1.1.h
index 5a79318107..c942521e61 100644
--- a/sw/airborne/boards/tiny_1.1.h
+++ b/sw/airborne/boards/tiny_1.1.h
@@ -38,13 +38,7 @@
#define LED_2_PIN 19
/* Switch pin */
-#ifndef USE_LED_3
-#define USE_LED_3 1
-#endif
-#define LED_3_BANK 0
-#define LED_3_PIN 11
-
-#define POWER_SWITCH_LED 3
+#define POWER_SWITCH_GPIO GPIOA,GPIO11
/* Default actuators driver */
#define DEFAULT_ACTUATORS "subsystems/actuators/actuators_4015.h"
diff --git a/sw/airborne/boards/tiny_2.0.h b/sw/airborne/boards/tiny_2.0.h
index 4f91c445b0..d205470a6d 100644
--- a/sw/airborne/boards/tiny_2.0.h
+++ b/sw/airborne/boards/tiny_2.0.h
@@ -41,13 +41,7 @@
#define LED_3_BANK 1
#define LED_3_PIN 23
-#ifndef USE_LED_4
-#define USE_LED_4 1
-#endif
-#define LED_4_BANK 1
-#define LED_4_PIN 18
-
-#define POWER_SWITCH_LED 4
+#define POWER_SWITCH_GPIO GPIOB,GPIO18
/* Default actuators driver */
#define DEFAULT_ACTUATORS "subsystems/actuators/actuators_4017.h"
diff --git a/sw/airborne/boards/tiny_2.1.h b/sw/airborne/boards/tiny_2.1.h
index 3ee8c1e7de..b16b12c983 100644
--- a/sw/airborne/boards/tiny_2.1.h
+++ b/sw/airborne/boards/tiny_2.1.h
@@ -58,33 +58,15 @@
#define LED_3_BANK 1
#define LED_3_PIN 23
-#ifndef USE_LED_4
-#define USE_LED_4 1
-#endif
-#define LED_4_BANK 1
-#define LED_4_PIN 18
+#define POWER_SWITCH_GPIO GPIOB,GPIO18
-#define POWER_SWITCH_LED 4
+#define CAM_SWITCH_GPIO GPIOB,GPIO22
-#ifndef USE_LED_5
-#define USE_LED_5 1
-#endif
-#define LED_5_BANK 1
-#define LED_5_PIN 22
+#define GPS_RESET_GPIO GPIOB,GPIO21
-#define CAM_SWITCH_LED 5
-
-#ifndef USE_LED_6
-#define USE_LED_6 1
-#endif
-#define LED_6_BANK 1
-#define LED_6_PIN 21
-
-#define GPS_RESET 6
-
-#define Configure_GPS_RESET_Pin() LED_INIT(GPS_RESET)
-#define Set_GPS_RESET_Pin_LOW() LED_ON(GPS_RESET)
-#define Open_GPS_RESET_Pin() ClearBit(LED_DIR(GPS_RESET), LED_PIN(GPS_RESET))
+#define Configure_GPS_RESET_Pin() gpio_setup_output(GPS_RESET_GPIO)
+#define Set_GPS_RESET_Pin_LOW() gpio_clear(GPS_RESET_GPIO)
+#define Open_GPS_RESET_Pin() gpio_setup_input(GPS_RESET_GPIO)
/* Default actuators driver */
#define DEFAULT_ACTUATORS "subsystems/actuators/actuators_4017.h"
diff --git a/sw/airborne/filters/low_pass_filter.h b/sw/airborne/filters/low_pass_filter.h
index 7191163cde..46f6e6fca1 100644
--- a/sw/airborne/filters/low_pass_filter.h
+++ b/sw/airborne/filters/low_pass_filter.h
@@ -29,6 +29,8 @@
#include "std.h"
+#define INT32_FILT_FRAC 8
+
/** First order low pass filter structure.
*
* using bilinear z transform
@@ -119,6 +121,7 @@ struct SecondOrderLowPass {
float o[2]; ///< output history
};
+
/** Init second order low pass filter.
*
* @param filter second order low pass filter structure
@@ -165,6 +168,72 @@ static inline float get_second_order_low_pass(struct SecondOrderLowPass * filter
return filter->o[0];
}
+struct SecondOrderLowPass_int {
+ int32_t a[2]; ///< denominator gains
+ int32_t b[2]; ///< numerator gains
+ int32_t i[2]; ///< input history
+ int32_t o[2]; ///< output history
+ int32_t loop_gain; ///< loop gain
+};
+
+/** Init second order low pass filter(fixed point version).
+ *
+ * @param filter second order low pass filter structure
+ * @param tau time constant of the second order low pass filter , 1/(2*pi*cut_off_3db)
+ * @param Q Q value of the second order low pass filter
+ * @param sample_time sampling period of the signal
+ * @param value initial value of the filter
+ */
+static inline void init_second_order_low_pass_int(struct SecondOrderLowPass_int* filter, float cut_off, float Q, float sample_time, int32_t value) {
+ struct SecondOrderLowPass filter_temp;
+ float tau = 7 / (44*cut_off);
+ float K = sample_time / (2*tau);
+ float poly = K*K + K/Q + 1.;
+ float loop_gain_f;
+
+ filter_temp.a[0] = 2.*(K*K - 1.) / poly;
+ filter_temp.a[1] = (K*K - K/Q + 1.) / poly;
+ filter_temp.b[0] = K*K / poly;
+ filter_temp.b[1] = 2*filter_temp.b[0];
+ loop_gain_f = 1/filter_temp.b[0];
+
+ filter->a[0] = BFP_OF_REAL((filter_temp.a[0] * loop_gain_f), INT32_FILT_FRAC);
+ filter->a[1] = BFP_OF_REAL((filter_temp.a[1] * loop_gain_f), INT32_FILT_FRAC);
+ filter->b[0] = BFP_OF_REAL(1, INT32_FILT_FRAC);
+ filter->b[1] = 2*filter->b[0];
+ filter->i[0] = filter->i[1] = filter->o[0] = filter->o[1] = value;
+ filter->loop_gain = BFP_OF_REAL(loop_gain_f, INT32_FILT_FRAC);
+}
+
+/** Update second order low pass filter state with a new value(fixed point version).
+ *
+ * @param filter second order low pass filter structure
+ * @param value new input value of the filter
+ * @return new filtered value
+ */
+static inline int32_t update_second_order_low_pass_int(struct SecondOrderLowPass_int* filter, int32_t value) {
+ int32_t out = filter->b[0] * value
+ + filter->b[1] * filter->i[0]
+ + filter->b[0] * filter->i[1]
+ - filter->a[0] * filter->o[0]
+ - filter->a[1] * filter->o[1];
+
+ filter->i[1] = filter->i[0];
+ filter->i[0] = value;
+ filter->o[1] = filter->o[0];
+ filter->o[0] = out / (filter->loop_gain);
+ return filter->o[0];
+}
+
+/** Get current value of the second order low pass filter(fixed point version).
+ *
+ * @param filter second order low pass filter structure
+ * @return current value of the filter
+ */
+static inline int32_t get_second_order_low_pass_int(struct SecondOrderLowPass_int * filter) {
+ return filter->o[0];
+}
+
/** Second order Butterworth low pass filter.
*/
typedef struct SecondOrderLowPass Butterworth2LowPass;
@@ -204,6 +273,45 @@ static inline float get_butterworth_2_low_pass(Butterworth2LowPass * filter) {
return filter->o[0];
}
+/** Second order Butterworth low pass filter(fixed point version).
+ */
+typedef struct SecondOrderLowPass_int Butterworth2LowPass_int;
+
+/** Init a second order Butterworth filter.
+ *
+ * based on the generic second order filter
+ * with Q = 0.7071 = 1/sqrt(2)
+ *
+ * http://en.wikipedia.org/wiki/Butterworth_filter
+ *
+ * @param filter second order Butterworth low pass filter structure
+ * @param tau time constant of the second order low pass filter
+ * @param sample_time sampling period of the signal
+ * @param value initial value of the filter
+ */
+static inline void init_butterworth_2_low_pass_int(Butterworth2LowPass_int* filter, float cut_off, float sample_time, int32_t value) {
+ init_second_order_low_pass_int((struct SecondOrderLowPass_int*)filter, cut_off, 0.7071, sample_time, value);
+}
+
+/** Update second order Butterworth low pass filter state with a new value(fixed point version).
+ *
+ * @param filter second order Butterworth low pass filter structure
+ * @param value new input value of the filter
+ * @return new filtered value
+ */
+static inline int32_t update_butterworth_2_low_pass_int(Butterworth2LowPass_int* filter, int32_t value) {
+ return update_second_order_low_pass_int((struct SecondOrderLowPass_int*)filter, value);
+}
+
+/** Get current value of the second order Butterworth low pass filter(fixed point version).
+ *
+ * @param filter second order Butterworth low pass filter structure
+ * @return current value of the filter
+ */
+static inline int32_t get_butterworth_2_low_pass_int(Butterworth2LowPass_int* filter) {
+ return filter->o[0];
+}
+
/** Fourth order Butterworth low pass filter.
*
* using two cascaded second order filters
@@ -253,5 +361,54 @@ static inline float get_butterworth_4_low_pass(Butterworth4LowPass * filter) {
return filter->lp2.o[0];
}
+/** Fourth order Butterworth low pass filter(fixed point version).
+ *
+ * using two cascaded second order filters
+ */
+typedef struct {
+ struct SecondOrderLowPass_int lp1;
+ struct SecondOrderLowPass_int lp2;
+} Butterworth4LowPass_int;
+
+/** Init a fourth order Butterworth filter(fixed point version).
+ *
+ * based on two generic second order filters
+ * with Q1 = 1.30651
+ * and Q2 = 0.541184
+ *
+ * http://en.wikipedia.org/wiki/Butterworth_filter
+ *
+ * @param filter fourth order Butterworth low pass filter structure
+ * @param tau time constant of the fourth order low pass filter
+ * @param sample_time sampling period of the signal
+ * @param value initial value of the filter
+ */
+static inline void init_butterworth_4_low_pass_int(Butterworth4LowPass_int * filter, float cut_off, float sample_time, int32_t value) {
+ init_second_order_low_pass_int(&filter->lp1, cut_off, 1.30651, sample_time, value);
+ init_second_order_low_pass_int(&filter->lp2, cut_off, 0.51184, sample_time, value);
+}
+
+/** Update fourth order Butterworth low pass filter state with a new value(fixed point version).
+ *
+ * using two cascaded second order filters
+ *
+ * @param filter fourth order Butterworth low pass filter structure
+ * @param value new input value of the filter
+ * @return new filtered value
+ */
+static inline int32_t update_butterworth_4_low_pass_int(Butterworth4LowPass_int * filter, int32_t value) {
+ int32_t tmp = update_second_order_low_pass_int(&filter->lp1, value);
+ return update_second_order_low_pass_int(&filter->lp2, tmp);
+}
+
+/** Get current value of the fourth order Butterworth low pass filter(fixed point version).
+ *
+ * @param filter fourth order Butterworth low pass filter structure
+ * @return current value of the filter
+ */
+static inline int32_t get_butterworth_4_low_pass_int(Butterworth4LowPass_int * filter) {
+ return filter->lp2.o[0];
+}
+
#endif
diff --git a/sw/airborne/firmwares/fixedwing/autopilot.c b/sw/airborne/firmwares/fixedwing/autopilot.c
index 2b2ada238f..d78c730936 100644
--- a/sw/airborne/firmwares/fixedwing/autopilot.c
+++ b/sw/airborne/firmwares/fixedwing/autopilot.c
@@ -33,6 +33,10 @@
#include "subsystems/nav.h"
#include "generated/settings.h"
+#ifdef POWER_SWITCH_GPIO
+#include "mcu_periph/gpio.h"
+#endif
+
uint8_t pprz_mode;
bool_t kill_throttle;
uint8_t mcu1_status;
@@ -146,6 +150,10 @@ void autopilot_init(void) {
gps_lost = FALSE;
power_switch = FALSE;
+#ifdef POWER_SWITCH_GPIO
+ gpio_setup_output(POWER_SWITCH_GPIO);
+ gpio_clear(POWER_SWITCH_GPIO);
+#endif
/* register some periodic message */
register_periodic_telemetry(DefaultPeriodic, "ALIVE", send_alive);
diff --git a/sw/airborne/firmwares/fixedwing/autopilot.h b/sw/airborne/firmwares/fixedwing/autopilot.h
index 035755af5d..42de3013ba 100644
--- a/sw/airborne/firmwares/fixedwing/autopilot.h
+++ b/sw/airborne/firmwares/fixedwing/autopilot.h
@@ -117,14 +117,16 @@ extern void autopilot_send_mode(void);
*/
extern bool_t power_switch;
-#ifdef POWER_SWITCH_LED
+#ifdef POWER_SWITCH_GPIO
+#include "mcu_periph/gpio.h"
#define autopilot_SetPowerSwitch(_x) { \
power_switch = _x; \
- if (_x) LED_ON(POWER_SWITCH_LED) else LED_OFF(POWER_SWITCH_LED); \
+ if (_x) { gpio_set(POWER_SWITCH_GPIO); } \
+ else { gpio_clear(POWER_SWITCH_GPIO); } \
}
-#else // POWER_SWITCH_LED
+#else // POWER_SWITCH_GPIO
#define autopilot_SetPowerSwitch(_x) { power_switch = _x; }
-#endif // POWER_SWITCH_LED
+#endif // POWER_SWITCH_GPIO
/* CONTROL_RATE will be removed in the next release
diff --git a/sw/airborne/firmwares/fixedwing/stabilization/stabilization_adaptive.c b/sw/airborne/firmwares/fixedwing/stabilization/stabilization_adaptive.c
index 629ffa1210..25d1dee48f 100644
--- a/sw/airborne/firmwares/fixedwing/stabilization/stabilization_adaptive.c
+++ b/sw/airborne/firmwares/fixedwing/stabilization/stabilization_adaptive.c
@@ -309,11 +309,6 @@ inline static void h_ctl_roll_loop( void ) {
// Compute errors
float err = h_ctl_ref_roll_angle - stateGetNedToBodyEulers_f()->phi;
struct FloatRates* body_rate = stateGetBodyRates_f();
-#ifdef SITL
- static float last_err = 0;
- body_rate->p = (err - last_err)/(1/60.); // FIXME should be done in ahrs sim
- last_err = err;
-#endif
float d_err = h_ctl_ref_roll_rate - body_rate->p;
if (pprz_mode == PPRZ_MODE_MANUAL || launch == 0) {
diff --git a/sw/airborne/firmwares/rotorcraft/autopilot.c b/sw/airborne/firmwares/rotorcraft/autopilot.c
index b1836658f9..08e5ad742c 100644
--- a/sw/airborne/firmwares/rotorcraft/autopilot.c
+++ b/sw/airborne/firmwares/rotorcraft/autopilot.c
@@ -39,7 +39,10 @@
#include "firmwares/rotorcraft/navigation.h"
#include "firmwares/rotorcraft/guidance.h"
#include "firmwares/rotorcraft/stabilization.h"
-#include "led.h"
+
+#ifdef POWER_SWITCH_GPIO
+#include "mcu_periph/gpio.h"
+#endif
uint8_t autopilot_mode;
uint8_t autopilot_mode_auto2;
@@ -116,9 +119,9 @@ static void send_alive(void) {
static void send_status(void) {
uint32_t imu_nb_err = 0;
#if USE_MOTOR_MIXING
- uint8_t _blmc_nb_err = motor_mixing.nb_failure;
+ uint8_t _motor_nb_err = motor_mixing.nb_saturation + motor_mixing.nb_failure * 10;
#else
- uint8_t _blmc_nb_err = 0;
+ uint8_t _motor_nb_err = 0;
#endif
#if USE_GPS
uint8_t fix = gps.fix;
@@ -127,7 +130,7 @@ static void send_status(void) {
#endif
uint16_t time_sec = sys_time.nb_sec;
DOWNLINK_SEND_ROTORCRAFT_STATUS(DefaultChannel, DefaultDevice,
- &imu_nb_err, &_blmc_nb_err,
+ &imu_nb_err, &_motor_nb_err,
&radio_control.status, &radio_control.frame_rate,
&fix, &autopilot_mode,
&autopilot_in_flight, &autopilot_motors_on,
@@ -217,8 +220,9 @@ void autopilot_init(void) {
autopilot_flight_time = 0;
autopilot_rc = TRUE;
autopilot_power_switch = FALSE;
-#ifdef POWER_SWITCH_LED
- LED_ON(POWER_SWITCH_LED); // POWER OFF
+#ifdef POWER_SWITCH_GPIO
+ gpio_setup_output(POWER_SWITCH_GPIO);
+ gpio_clear(POWER_SWITCH_GPIO); // POWER OFF
#endif
autopilot_arming_init();
diff --git a/sw/airborne/firmwares/rotorcraft/autopilot.h b/sw/airborne/firmwares/rotorcraft/autopilot.h
index 9203c6e43f..fa60e65afd 100644
--- a/sw/airborne/firmwares/rotorcraft/autopilot.h
+++ b/sw/airborne/firmwares/rotorcraft/autopilot.h
@@ -106,15 +106,16 @@ extern uint16_t autopilot_flight_time;
autopilot_set_motors_on(TRUE); \
}
-#ifdef POWER_SWITCH_LED
-#define autopilot_SetPowerSwitch(_v) { \
- autopilot_power_switch = _v; \
- if (_v) { LED_OFF(POWER_SWITCH_LED); } \
- else { LED_ON(POWER_SWITCH_LED); } \
+#ifdef POWER_SWITCH_GPIO
+#include "mcu_periph/gpio.h"
+#define autopilot_SetPowerSwitch(_v) { \
+ autopilot_power_switch = _v; \
+ if (_v) { gpio_set(POWER_SWITCH_GPIO); } \
+ else { gpio_clear(POWER_SWITCH_GPIO); } \
}
#else
-#define autopilot_SetPowerSwitch(_v) { \
- autopilot_power_switch = _v; \
+#define autopilot_SetPowerSwitch(_v) { \
+ autopilot_power_switch = _v; \
}
#endif
diff --git a/sw/airborne/firmwares/rotorcraft/datalink.c b/sw/airborne/firmwares/rotorcraft/datalink.c
index 96001f4198..928a35492e 100644
--- a/sw/airborne/firmwares/rotorcraft/datalink.c
+++ b/sw/airborne/firmwares/rotorcraft/datalink.c
@@ -46,10 +46,15 @@
#include "subsystems/radio_control.h"
#endif
+#if defined GPS_DATALINK
+#include "subsystems/gps/gps_datalink.h"
+#endif
+
#include "firmwares/rotorcraft/navigation.h"
#include "math/pprz_geodetic_int.h"
#include "state.h"
+#include "led.h"
#define IdOfMsg(x) (x[1])
@@ -134,6 +139,28 @@ void dl_parse_msg(void) {
DL_RC_4CH_yaw(dl_buffer));
break;
#endif // RADIO_CONTROL_TYPE_DATALINK
+#if defined GPS_DATALINK
+ case DL_REMOTE_GPS :
+ // Check if the GPS is for this AC
+ if (DL_REMOTE_GPS_ac_id(dl_buffer) != AC_ID) break;
+
+ // Parse the GPS
+ parse_gps_datalink(
+ DL_REMOTE_GPS_numsv(dl_buffer),
+ DL_REMOTE_GPS_ecef_x(dl_buffer),
+ DL_REMOTE_GPS_ecef_y(dl_buffer),
+ DL_REMOTE_GPS_ecef_z(dl_buffer),
+ DL_REMOTE_GPS_lat(dl_buffer),
+ DL_REMOTE_GPS_lon(dl_buffer),
+ DL_REMOTE_GPS_alt(dl_buffer),
+ DL_REMOTE_GPS_hmsl(dl_buffer),
+ DL_REMOTE_GPS_ecef_xd(dl_buffer),
+ DL_REMOTE_GPS_ecef_yd(dl_buffer),
+ DL_REMOTE_GPS_ecef_zd(dl_buffer),
+ DL_REMOTE_GPS_tow(dl_buffer),
+ DL_REMOTE_GPS_course(dl_buffer));
+ break;
+#endif
default:
break;
}
diff --git a/sw/airborne/firmwares/rotorcraft/guidance/guidance_h.h b/sw/airborne/firmwares/rotorcraft/guidance/guidance_h.h
index 4f43278139..bafea46816 100644
--- a/sw/airborne/firmwares/rotorcraft/guidance/guidance_h.h
+++ b/sw/airborne/firmwares/rotorcraft/guidance/guidance_h.h
@@ -112,4 +112,8 @@ extern void guidance_h_run(bool_t in_flight);
guidance_h_use_ref = _val && GUIDANCE_H_USE_REF; \
}
+#define guidance_h_SetMaxSpeed(_val) { \
+ gh_set_max_speed(_val); \
+ }
+
#endif /* GUIDANCE_H_H */
diff --git a/sw/airborne/firmwares/rotorcraft/guidance/guidance_h_ref.c b/sw/airborne/firmwares/rotorcraft/guidance/guidance_h_ref.c
index fb8be1fa67..fccf2df444 100644
--- a/sw/airborne/firmwares/rotorcraft/guidance/guidance_h_ref.c
+++ b/sw/airborne/firmwares/rotorcraft/guidance/guidance_h_ref.c
@@ -50,9 +50,13 @@ struct Int64Vect2 gh_pos_ref;
static const int32_t gh_max_accel = BFP_OF_REAL(GUIDANCE_H_REF_MAX_ACCEL, GH_ACCEL_REF_FRAC);
-/** @todo GH_MAX_SPEED must be limited to 2^14 to avoid overflow */
+float gh_max_speed = GUIDANCE_H_REF_MAX_SPEED;
+
#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);
+/** gh_max_speed in fixed point representation with #GH_MAX_SPEED_REF_FRAC
+ * must be limited to 2^14 to avoid overflow
+ */
+static int32_t gh_max_speed_int = BFP_OF_REAL(GUIDANCE_H_REF_MAX_SPEED, GH_MAX_SPEED_REF_FRAC);
/** second order model natural frequency */
#ifndef GUIDANCE_H_REF_OMEGA
@@ -88,6 +92,14 @@ static void gh_compute_ref_max_speed(struct Int32Vect2* ref_vector);
static void gh_saturate_ref_accel(void);
static void gh_saturate_ref_speed(void);
+
+float gh_set_max_speed(float max_speed) {
+ /* limit to 100m/s as int version would overflow at 2^14 = 128 m/s */
+ gh_max_speed = Min(fabs(max_speed), 100.0f);
+ gh_max_speed_int = BFP_OF_REAL(gh_max_speed, GH_MAX_SPEED_REF_FRAC);
+ return gh_max_speed;
+}
+
void gh_set_ref(struct Int32Vect2 pos, struct Int32Vect2 speed, struct Int32Vect2 accel) {
struct Int64Vect2 new_pos;
new_pos.x = ((int64_t)pos.x)<<(GH_POS_REF_FRAC - INT32_POS_FRAC);
@@ -174,9 +186,9 @@ static void gh_compute_ref_max(struct Int32Vect2* ref_vector) {
/* Compute maximum acceleration*/
gh_max_accel_ref.x = INT_MULT_RSHIFT(gh_max_accel, c_route_ref, INT32_TRIG_FRAC);
gh_max_accel_ref.y = INT_MULT_RSHIFT(gh_max_accel, s_route_ref, INT32_TRIG_FRAC);
- /* Compute maximum speed*/
- gh_max_speed_ref.x = INT_MULT_RSHIFT(gh_max_speed, c_route_ref, INT32_TRIG_FRAC);
- gh_max_speed_ref.y = INT_MULT_RSHIFT(gh_max_speed, s_route_ref, INT32_TRIG_FRAC);
+ /* Compute maximum reference x/y velocity from absolute max_speed */
+ gh_max_speed_ref.x = INT_MULT_RSHIFT(gh_max_speed_int, c_route_ref, INT32_TRIG_FRAC);
+ gh_max_speed_ref.y = INT_MULT_RSHIFT(gh_max_speed_int, s_route_ref, INT32_TRIG_FRAC);
/* restore gh_speed_ref range (Q14.17) */
INT32_VECT2_LSHIFT(gh_max_speed_ref, gh_max_speed_ref, (GH_SPEED_REF_FRAC - GH_MAX_SPEED_REF_FRAC));
}
@@ -204,9 +216,9 @@ static void gh_compute_ref_max_speed(struct Int32Vect2* ref_vector) {
}
else {
gh_compute_route_ref(ref_vector);
- /* Compute maximum speed*/
- gh_max_speed_ref.x = INT_MULT_RSHIFT(gh_max_speed, c_route_ref, INT32_TRIG_FRAC);
- gh_max_speed_ref.y = INT_MULT_RSHIFT(gh_max_speed, s_route_ref, INT32_TRIG_FRAC);
+ /* Compute maximum reference x/y velocity from absolute max_speed */
+ gh_max_speed_ref.x = INT_MULT_RSHIFT(gh_max_speed_int, c_route_ref, INT32_TRIG_FRAC);
+ gh_max_speed_ref.y = INT_MULT_RSHIFT(gh_max_speed_int, s_route_ref, INT32_TRIG_FRAC);
/* restore gh_speed_ref range (Q14.17) */
INT32_VECT2_LSHIFT(gh_max_speed_ref, gh_max_speed_ref, (GH_SPEED_REF_FRAC - 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 0c533cb6e8..76dbb25b64 100644
--- a/sw/airborne/firmwares/rotorcraft/guidance/guidance_h_ref.h
+++ b/sw/airborne/firmwares/rotorcraft/guidance/guidance_h_ref.h
@@ -32,11 +32,16 @@
#include "math/pprz_algebra_int.h"
#include "generated/airframe.h"
-/** Speed saturation */
+/** Default speed saturation */
#ifndef GUIDANCE_H_REF_MAX_SPEED
#define GUIDANCE_H_REF_MAX_SPEED 5.
#endif
+/** Current maximum speed for waypoint navigation.
+ * Defaults to #GUIDANCE_H_REF_MAX_SPEED
+ */
+extern float gh_max_speed;
+
/** Accel saturation.
* tanf(RadOfDeg(30.))*9.81 = 5.66
*/
@@ -76,4 +81,11 @@ extern void gh_set_ref(struct Int32Vect2 pos, struct Int32Vect2 speed, struct In
extern void gh_update_ref_from_pos_sp(struct Int32Vect2 pos_sp);
extern void gh_update_ref_from_speed_sp(struct Int32Vect2 speed_sp);
+/**
+ * Set a new maximum speed for waypoint navigation.
+ * @param max_speed speed saturation in m/s
+ * @return new maximum speed
+ */
+extern float gh_set_max_speed(float max_speed);
+
#endif /* GUIDANCE_H_REF_H */
diff --git a/sw/airborne/firmwares/vor/Makefile b/sw/airborne/firmwares/vor/Makefile
deleted file mode 100644
index d55b7cd51d..0000000000
--- a/sw/airborne/firmwares/vor/Makefile
+++ /dev/null
@@ -1,34 +0,0 @@
-# Quiet compilation
-Q=@
-
-all:
-
-CFLAGS = -Wall -I..
-LDFLAGS = -lm
-
-i86_vor_test_float_demod: i86_vor_test_float_demod.c vor_float_demod.c
- gcc $(CFLAGS) $^ -o $@ $(LDFLAGS) -lsndfile
-
-i86_vor_test_int_demod_decim: i86_vor_test_int_demod_decim.c vor_int_demod_decim.c
- gcc $(CFLAGS) $^ -o $@ $(LDFLAGS) -lsndfile
-
-i86_vor_test_int_demod: i86_vor_test_int_demod.c vor_int_demod.c
- gcc $(CFLAGS) $^ -o $@ $(LDFLAGS) -lsndfile
-
-i86_vor_test_filters: i86_vor_test_filters.c
- gcc $(CFLAGS) $^ -o $@ $(LDFLAGS) -lsndfile
-
-vor_filter_params.c:
- scilab -nw -nogui -nwni -f gen_filter_params.sce
-
-play_vor: play_vor.c
- gcc $(CFLAGS) $^ -o $@ $(LDFLAGS) -lsndfile -lasound
-
-play_audio: sndfile-play.c
- gcc $(CFLAGS) $^ -o $@ $(LDFLAGS) -lsndfile -lasound
-
-clean:
- $(Q)rm -f i86_vor_test_float_demod \
- i86_vor_test_int_demod \
- i86_vor_test_filters \
- *~ \#*
diff --git a/sw/airborne/firmwares/vor/display.sce b/sw/airborne/firmwares/vor/display.sce
deleted file mode 100644
index d5a7cbc6c2..0000000000
--- a/sw/airborne/firmwares/vor/display.sce
+++ /dev/null
@@ -1,20 +0,0 @@
-clear();
-M = fscanfMat('output.log');
-time = M(:,1);
-in_float = M(:,2);
-out_float = M(:,3);
-in_int = M(:,4);
-out_int = M(:,5);
-out_int_f = M(:,6);
-
-clf();
-drawlater
-subplot(2,1,1)
-plot2d(time, in_float, 2);
-plot2d(time, out_float, 3);
-plot2d(time, out_int_f, 5);
-
-subplot(2,1,2)
-plot2d(time, in_int, 2);
-plot2d(time, out_int, 3);
-drawnow
\ No newline at end of file
diff --git a/sw/airborne/firmwares/vor/i86_vor_audio.h b/sw/airborne/firmwares/vor/i86_vor_audio.h
deleted file mode 100644
index 7ef1c5be59..0000000000
--- a/sw/airborne/firmwares/vor/i86_vor_audio.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef I86_VOR_AUDIO_H
-#define I86_VOR_AUDIO_H
-
-#include
-#include
-#include
-
-static short* wav_buf;
-static float* float_buf;
-static uint16_t* adc_buf;
-unsigned nb_samples;
-
-static void vor_audio_read_wav(const char* filename) {
-
- SNDFILE *sndfile ;
- SF_INFO sfinfo ;
-
- sndfile = sf_open (filename, SFM_READ, &sfinfo);
- nb_samples = sfinfo.frames;
- wav_buf = malloc(sizeof(short)*nb_samples);
- sf_read_short (sndfile, wav_buf, nb_samples);
-
- float_buf = malloc(sizeof(float)*nb_samples);
- adc_buf = malloc(sizeof(uint16_t)*nb_samples);
-
- int i;
- for (i=0; i
-#include
-#include
-#include
-#include
-
-#include "i86_vor_audio.h"
-
-#include "vor_int_filters.h"
-#include "vor_float_filters.h"
-
-
-int main(int argc, char** argv) {
-
- vor_audio_read_wav("signal_VOR_BF_50_200dB.wav");
-
- int i;
- float te = 1/29880.;
-
- for (i=0; i> 24) & 0x07;
- vor_adc_sample = (uint16_t)(tmp >> 6) & 0x03FF;
- if (vor_adc_sample_available) {
- vor_adc_overrun++;
- LED_ON(1);
- }
- vor_adc_sample_available = TRUE;
-
- /* trigger next convertion */
- T0MR1 += PERIODIC_TASK_PERIOD;
- /* lower clock */
- T0EMR &= ~TEMR_EM1;
-
- VICVectAddr = 0x00000000; // clear this interrupt from the VIC
- ISR_EXIT(); // recover registers and return
-}
diff --git a/sw/airborne/firmwares/vor/lpc_vor_convertions.h b/sw/airborne/firmwares/vor/lpc_vor_convertions.h
deleted file mode 100644
index 6b1e967c35..0000000000
--- a/sw/airborne/firmwares/vor/lpc_vor_convertions.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef LPC_VOR_CONVERTIONS_H
-#define LPC_VOR_CONVERTIONS_H
-
-#include "LPC21xx.h"
-
-#include "std.h"
-
-
-extern volatile uint16_t vor_adc_sample;
-extern volatile bool_t vor_adc_sample_available;
-extern volatile uint32_t vor_adc_overrun;
-
-// DAC on P0.25
-#define VorDacInit() { \
- /* turn on DAC pins */ \
- PINSEL1 &= 1 << 19; \
- PINSEL1 |= ~(1 << 18); \
- }
-
-
-#define VorDacSet(a) { \
- DACR = a << 6; \
- }
-
-
-extern void vor_adc_init( void );
-
-#endif /* LPC_VOR_CONVERTIONS_H */
-
diff --git a/sw/airborne/firmwares/vor/lpc_vor_main.c b/sw/airborne/firmwares/vor/lpc_vor_main.c
deleted file mode 100644
index acbd00c390..0000000000
--- a/sw/airborne/firmwares/vor/lpc_vor_main.c
+++ /dev/null
@@ -1,101 +0,0 @@
-#include "std.h"
-#include "mcu.h"
-#include "mcu_periph/sys_time.h"
-#include "led.h"
-#include "interrupt_hw.h"
-#include "mcu_periph/uart.h"
-#include "subsystems/datalink/uart_print.h"
-//#include "messages.h"
-//#include "subsystems/datalink/downlink.h"
-
-#include "lpc_vor_convertions.h"
-#include "vor_int_demod_decim.h"
-
-
-static inline void main_init( void );
-static inline void main_report( void );
-
-int main( void ) {
- main_init();
-
- while(1) {
- if (vor_adc_sample_available) {
- int16_t off_sample = vor_adc_sample - 512;
- // off_sample *= 2;
-
- vor_int_demod_run (off_sample);
-
- if (vid_qdr_available) {
- vid_qdr_available = FALSE;
- main_report();
- }
-
- VorDacSet(vor_adc_sample);
- vor_adc_sample_available = FALSE;
- }
-
- }
- return 0;
-}
-
-/*//(vid_qdr*360.0)/(double)N_VAR_FM)49800*/
-static inline void main_report( void ) {
- static uint8_t cnt = 0;
- static int32_t my_qdr;
- static uint8_t tmp;
-
- switch (cnt) {
-
- case 0:
- my_qdr = vid_qdr * 360 / 4980;
- if (my_qdr < 0) my_qdr+=3600;
- if (my_qdr > 3600) my_qdr-=3600;
- uart_transmit(&uart0, '\r');
- break;
- case 1:
- tmp = my_qdr / 1000;
- my_qdr = my_qdr - 1000*tmp;
- uart_transmit(&uart0, '0'+tmp);
- break;
- case 2:
- tmp = my_qdr / 100;
- my_qdr = my_qdr - 100*tmp;
- uart_transmit(&uart0, '0'+tmp);
- break;
- case 3:
- tmp = my_qdr / 10;
- my_qdr = my_qdr - 10*tmp;
- uart_transmit(&uart0, '0'+tmp);
- break;
- case 4:
- uart_transmit(&uart0, '.');
- break;
- case 5:
- uart_transmit(&uart0, '0'+my_qdr);
- break;
- case 6:
- uart_transmit(&uart0, '\r');
- break;
- }
-
- cnt++;
- if (cnt >7) cnt = 0;
-}
-
-
-
-
-static inline void main_init( void ) {
- mcu_init();
- sys_time_init();
- led_init();
- uart0_init();
- vor_int_demod_init();
- VorDacInit();
- vor_adc_init();
- mcu_int_enable();
-}
-
-
-
-
diff --git a/sw/airborne/firmwares/vor/sci_gen_c_filters.sce b/sw/airborne/firmwares/vor/sci_gen_c_filters.sce
deleted file mode 100644
index 17326a5410..0000000000
--- a/sw/airborne/firmwares/vor/sci_gen_c_filters.sce
+++ /dev/null
@@ -1,73 +0,0 @@
-//
-//
-// Generates C file and corresponding headers for filters used in
-// C implementation
-//
-
-clear();
-
-exec('sci_vor_filters.sci');
-[filters] = vor_get_filters();
-
-filter_name = [ "BP_VAR"
- "BP_REF"
- "LP_DECIM"
- "LP_VAR"
- "LP_REF"
- "LP_FM" ];
-
-function print_poly(fid, name, p, header)
- c_p = coeff(p);
- l_p = length(c_p);
- l_ps = name+'_LEN';
- if (header)
- fprintf(fid, '#define %s %i\n', l_ps, l_p);
- fprintf(fid, 'extern FLOAT_T %s[];\n', name);
- else
- fprintf(fid, 'FLOAT_T %s[%s]={\n', name, l_ps);
- for i=l_p:-1:1
- fprintf(fid,'%10.40f,\n',c_p(i));
- end
- fprintf(fid,'};\n');
- end
-endfunction
-
-//
-// header
-//
-
-filename = 'vor_filter_params';
-fid = mopen(filename+'.h', 'w');
-
-fprintf(fid,'#ifndef VOR_LF_FILTER_PARAMS_H\n');
-fprintf(fid,'#define VOR_LF_FILTER_PARAMS_H\n\n');
-
-for i=1:FILTER_NB
- f = filters(i);
- fn = filter_name(i);
- fprintf(fid,'/* %s filter */\n', fn);
- print_poly(fid, fn+"_NUM", f.tf.num, 1);
- print_poly(fid, fn+"_DEN", f.tf.den, 1);
- fprintf(fid,'\n');
-end
-
-fprintf(fid,'#endif /* VOR_LF_FILTER_PARAMS_H */\n');
-mclose(fid);
-
-//
-// C
-//
-
-fid = mopen(filename+'.c', 'w');
- fprintf(fid,'#include ""%s.h""\n\n', filename);
-for i=1:FILTER_NB
- f = filters(i);
- fn = filter_name(i);
- print_poly(fid, fn+"_NUM", f.tf.num, 0);
- print_poly(fid, fn+"_DEN", f.tf.den, 0);
- fprintf(fid,'\n');
-end
-
-mclose(fid);
-
-
diff --git a/sw/airborne/firmwares/vor/sci_vor_audio.sci b/sw/airborne/firmwares/vor/sci_vor_audio.sci
deleted file mode 100644
index 7a315368fb..0000000000
--- a/sw/airborne/firmwares/vor/sci_vor_audio.sci
+++ /dev/null
@@ -1,39 +0,0 @@
-//
-// $Id$
-//
-// Copyright (C) 2008 Antoine Blais, Antoine Drouin
-//
-// 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.
-//
-
-//
-// Digital VOR ( VHF Omni-directional Radio Range ) receiver
-// audio files handling
-//
-
-
-// Load input signal from wav file ( 16 bits mono )
-function [time, samples] = vor_audio_read_wav(filename)
-
- [samples, Fe, nbits] = wavread(filename);
- samples = samples * 2^6;
- Te = 1/Fe;
- time = [0:length(samples)-1] * Te;
-
-endfunction
-
diff --git a/sw/airborne/firmwares/vor/sci_vor_demod.sce b/sw/airborne/firmwares/vor/sci_vor_demod.sce
deleted file mode 100644
index 63a2f4d7ae..0000000000
--- a/sw/airborne/firmwares/vor/sci_vor_demod.sce
+++ /dev/null
@@ -1,116 +0,0 @@
-//
-// $Id$
-//
-// Copyright (C) 2008 Antoine Blais, Antoine Drouin
-//
-// 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.
-//
-
-//
-// Digital VOR ( VHF Omni-directional Radio Range ) receiver
-// demodulator mainloop
-//
-
-clear();
-//xdel(winsid());
-
-exec('sci_vor_audio.sci');
-[time, in_sig] = vor_audio_read_wav('signal_VOR_BF_50_200dB.wav');
-
-exec('sci_vor_filters.sci');
-[filters] = vor_get_filters();
-
-// our 3 PLLs variables
-
-// 30 REF
-freq_REF = vor_F0;// oscillator base frequency
-phi_REF = %pi; // oscillator phase
-err_REF = 0; // phase error
-alpha_REF = -1.2; // error re-injection coeeficient.
-
-// 30 VAR
-freq_VAR = vor_Fvor;
-phi_VAR = %pi;
-err_VAR = 0;
-alpha_VAR = -0.5;
-
-// DEMODULATED 30 REF
-freq_FM = vor_Fvor;
-phi_FM = %pi;
-err_FM = 0;
-alpha_FM = -1;
-
-
-// display frequency
-f_display = 2.;
-n_affich = round(vor_Fe / f_display);
-
-//-----------------------------------------------------------------//
-// PLL - called at FE
-for i=1:length(time);
-
- ti = time(i);
-
- phi_REF = phi_REF - alpha_REF * err_REF; // phase error re-injection
- phaseREF = 2 * %pi * freq_REF * ti + phi_REF; // local oscillator phase
- loREF = sin(phaseREF); // local oscillator signal
-
- // get REF signal by bandpassing input signal
- [signal_REF, filters(BP_REF)] = vor_filter_run(filters(BP_REF), in_sig(i));
-
- // multiply REF signal by local oscillator signal
- yREF = signal_REF * loREF;
-
- // get phase error by low passing the result of the multiplication.
- [err_REF, filters(LP_REF)] = vor_filter_run(filters(LP_REF), yREF);
-
- // filter 30 REF before decimating it
- [eREFdecim, filters(LP_DECIM)] = vor_filter_run(filters(LP_DECIM), err_REF);
-
- // get VAR signal by bandpassing input signal
- [signal_VAR, filters(BP_VAR)] = vor_filter_run(filters(BP_VAR), in_sig(i));
-
- if (modulo(i, vor_decim_factor) == 1)
-
- phi_VAR = phi_VAR - alpha_VAR * err_VAR; // phase error re-injection
- phaseVAR = 2 * %pi * freq_VAR * ti + phi_VAR; // local oscillator phase
- loVAR = -sin(phaseVAR); // Local carrier
- yVAR = signal_VAR * loVAR;
-
- [err_VAR, filters(LP_VAR)] = vor_filter_run(filters(LP_VAR), yVAR);
-
- phi_FM = phi_FM - alpha_FM * err_FM; // phase error re-injection
- phaseFM = 2 * %pi * freq_FM * ti + phi_FM; // local oscillator phase
- loFM = -sin(phaseFM); // Local carrier
- yFM = eREFdecim * loFM;
-
- [err_FM, filters(LP_FM)] = vor_filter_run(filters(LP_FM), yFM);
-
- end
-
-
- if (modulo(i, n_affich) == 0)
- leVAR = pmodulo(phi_VAR*180/%pi - filters(BP_VAR).Dphi,360);
- leREF = pmodulo(phi_FM*180/%pi - filters(LP_REF).Dphi - filters(BP_REF).Dphi - filters(BP_VAR).Dphi,360);
- leQDR = pmodulo((phi_VAR-phi_FM)*180/%pi + filters(LP_REF).Dphi + filters(BP_REF).Dphi,360);
- mprintf("Phase variable %2.2f",leVAR);
- mprintf(" Phase reference %2.2f",leREF);
- mprintf(" QDR %2.2f",leQDR);disp("");
- end
-
-end
diff --git a/sw/airborne/firmwares/vor/sci_vor_filters.sci b/sw/airborne/firmwares/vor/sci_vor_filters.sci
deleted file mode 100644
index 6b9769c7c7..0000000000
--- a/sw/airborne/firmwares/vor/sci_vor_filters.sci
+++ /dev/null
@@ -1,107 +0,0 @@
-//
-// $Id$
-//
-// Copyright (C) 2008 Antoine Blais, Antoine Drouin
-//
-// 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.
-//
-
-//
-// Digital VOR ( VHF Omni-directional Radio Range ) receiver
-// filters stuff
-//
-
-// VOR signal parameters
-vor_Fvor = 30;
-vor_F0 = 9960;
-// Frequency modulation ratio of 30 REF
-vor_n = 16;
-// Frequency excursion produced by 30 REF
-vor_Df = vor_n * vor_Fvor;
-// Sampling frequency
-vor_Fe = 3. * vor_F0;
-// decimation factor of 30 VAR and demodulated 30 REF (FM)
-vor_decim_factor = 83*3;
-
-BP_VAR = 1;
-BP_REF = 2;
-LP_DECIM = 3;
-LP_VAR = 4;
-LP_REF = 5;
-LP_FM = 6;
-FILTER_NB = 6;
-
-function [filters] = vor_get_filters()
-
- vor_filter_format = ['vor_filter';'tf'; 'ss'; 'state'; 'Dphi'];
-
-
- _tf = iir(3,'lp','butt',[800/vor_Fe 0],[0 0]);
- _ss = tf2ss(_tf);
- [foo, state0] = flts(0, _ss);
- [_dB, _Dphi] = dbphi(repfreq(_tf, vor_Fvor/vor_Fe));
- tl_BP_VAR = tlist(vor_filter_format, _tf, _ss, state0, _Dphi);
-
-
- fc1 = (vor_F0-vor_Df)/vor_Fe*0.9;
- fc2 = (vor_F0+vor_Df)/vor_Fe*1.1;
- _tf = iir(3,'bp','butt',[fc1 fc2],[0 0]);
- _ss = tf2ss(_tf);
- [foo, state0] = flts(0, _ss);
- [_dB, _Dphi] = dbphi(repfreq(_tf,-0.5,vor_F0 / vor_Fe));
- _Dphi = modulo(_Dphi($) / vor_F0 * vor_Fvor,360);
- tl_BP_REF = tlist(vor_filter_format, _tf, _ss, state0, _Dphi);
-
-
- _tf = iir(3,'lp','butt',[800/vor_Fe 0],[0 0]);
- _ss = tf2ss(_tf);
- [foo, state0] = flts(0, _ss);
- _Dphi = 0.;
- tl_LP_DECIM = tlist(vor_filter_format, _tf, _ss, state0, _Dphi);
-
-
- _tf = iir(6,'lp','butt',[10/vor_Fe*vor_decim_factor 0],[0 0]);
- _ss = tf2ss(_tf);
- [foo, state0] = flts(0, _ss);
- _Dphi = 0.;
- tl_LP_VAR = tlist(vor_filter_format, _tf, _ss, state0, _Dphi);
-
-
- _tf = iir(3,'lp','butt',[3000/vor_Fe 0],[0 0]);
- _ss = tf2ss(_tf);
- [foo, state0] = flts(0, _ss);
- [_dB,_Dphi] = dbphi(repfreq(_tf, vor_Fvor / vor_Fe));
- tl_LP_REF = tlist(vor_filter_format, _tf, _ss, state0, _Dphi);
-
-
- _tf = iir(6,'lp','butt',[10/vor_Fe*vor_decim_factor 0],[0 0]);
- _ss = tf2ss(_tf);
- [foo, state0] = flts(0, _ss);
- _Dphi = 0.;
- tl_LP_FM = tlist(vor_filter_format, _tf, _ss, state0, _Dphi);
-
-
- filters = list(tl_BP_VAR, tl_BP_REF, tl_LP_DECIM, tl_LP_VAR, tl_LP_REF, tl_LP_FM);
-
-endfunction
-
-
-function [out, filter] = vor_filter_run(filter, in)
- [out, filter.state] = flts(in, filter.ss, filter.state);
-endfunction
-
diff --git a/sw/airborne/firmwares/vor/signal_VOR_BF_50_200dB.wav b/sw/airborne/firmwares/vor/signal_VOR_BF_50_200dB.wav
deleted file mode 100644
index 2ac0605fa6..0000000000
Binary files a/sw/airborne/firmwares/vor/signal_VOR_BF_50_200dB.wav and /dev/null differ
diff --git a/sw/airborne/firmwares/vor/vor_float_demod.c b/sw/airborne/firmwares/vor/vor_float_demod.c
deleted file mode 100644
index b12303ff5c..0000000000
--- a/sw/airborne/firmwares/vor/vor_float_demod.c
+++ /dev/null
@@ -1,99 +0,0 @@
-#include "vor_float_demod.h"
-
-#include
-#include
-
-#include "vor_float_filters.h"
-
-const float vfd_te = 1./29880.;
-
-const float vfd_ref_freq = 9960.;
- float vfd_ref_phi;
- float vfd_ref_err;
-const float vfd_ref_alpha = -1.2;
-
-const float vfd_var_freq = 30.0;
- float vfd_var_phi;
- float vfd_var_err;
-const float vfd_var_alpha = -0.5;
-
-const float vfd_fm_freq = 30.0;
- float vfd_fm_phi;
- float vfd_fm_err;
-const float vfd_fm_alpha = -1.0;
-
- float vfd_qdr;
-
- float vfd_var_sig;
- float vfd_fm_local_sig;
-
-static uint32_t i;
-static uint32_t decim;
-static uint32_t vfd_DECIM = 3 * 83;
-
-void vor_float_demod_init( void) {
-
- i = 0;
-
- vfd_ref_phi = M_PI;
- vfd_ref_err = 0.;
-
- vfd_var_phi = M_PI;
- vfd_var_err = 0.;
-
- vfd_fm_phi = M_PI;
- vfd_fm_err = 0.;
-
-}
-
-void vor_float_demod_run ( float sample) {
-
- const float ti = i * vfd_te;
-
- // phase error re-injection
- vfd_ref_phi -= vfd_ref_alpha * vfd_ref_err;
- // local oscillator phase
- const float vfd_ref_phase = 2. * M_PI * vfd_ref_freq * ti + vfd_ref_phi;
- // local oscillator signal
- const float vfd_ref_local_sig = sin(vfd_ref_phase);
-
- // get REF signal by bandpassing input signal
- const float vfd_ref_sig = vor_float_filter_bp_ref(sample);
-
- // multiply input signal by local oscillator signal
- const float vfd_ref_y = vfd_ref_sig * vfd_ref_local_sig;
-
- // get phase error by low passing the result of the multiplication.
- vfd_ref_err = vor_float_filter_lp_ref(vfd_ref_y);
-
- // filter 30 REF before decimating it
- const float vfd_ref_err_decim = vor_float_filter_lp_decim(vfd_ref_err);
-
- // get VAR signal by bandpassing input signal
- // const float vfd_var_sig = vor_float_filter_bp_var(sample);
- vfd_var_sig = vor_float_filter_bp_var(sample);
-
- if (decim >= vfd_DECIM) {
- decim = 0;
-
- vfd_var_phi -= vfd_var_alpha * vfd_var_err;
- const float vfd_var_phase = 2. * M_PI * vfd_var_freq * ti + vfd_var_phi;
- const float vfd_var_local_sig = -sin( vfd_var_phase);
- const float vfd_var_y = vfd_var_sig * vfd_var_local_sig;
- vfd_var_err = vor_float_filter_lp_var(vfd_var_y);
-
- vfd_fm_phi -= vfd_fm_alpha * vfd_fm_err;
- const float vfd_fm_phase = 2. * M_PI * vfd_fm_freq * ti + vfd_fm_phi;
- // const float vfd_fm_local_sig = -sin( vfd_fm_phase );
- vfd_fm_local_sig = -sin( vfd_fm_phase );
- const float vfd_fm_y = vfd_ref_err_decim * vfd_fm_local_sig;
- vfd_fm_err = vor_float_filter_lp_fm(vfd_fm_y);
-
- vfd_qdr = vfd_var_phi - vfd_fm_phi;
- }
-
-
- i++;
- decim++;
-
-}
diff --git a/sw/airborne/firmwares/vor/vor_float_filters.h b/sw/airborne/firmwares/vor/vor_float_filters.h
deleted file mode 100644
index 19cb21ccac..0000000000
--- a/sw/airborne/firmwares/vor/vor_float_filters.h
+++ /dev/null
@@ -1,310 +0,0 @@
-#ifndef VOR_FLOAT_FILTERS_H
-#define VOR_FLOAT_FILTERS_H
-
-//typedef float (*vor_float_filter_fun)( float xn);
-
-inline float vor_float_filter_bp_var( float xn) {
-
- const float a0 = 0.0000294918571461433008684162315748977790;
- const float a1 = 0.0000884755714384299093815122727590960494;
- const float a2 = 0.0000884755714384299093815122727590960494;
- const float a3 = 0.0000294918571461433008684162315748977790;
-
- const float b1 = -2.8738524677701420273479016032069921493530;
- const float b2 = 2.7555363566291544152875303552718833088875;
- const float b3 = -0.8814479540018430592240861187747213989496;
-
- static float x1 = 0;
- static float x2 = 0;
- static float x3 = 0;
-
- static float y1 = 0;
- static float y2 = 0;
- static float y3 = 0;
-
- float yn = a0 * xn
- + a1 * x1
- + a2 * x2
- + a3 * x3
- - b1 * y1
- - b2 * y2
- - b3 * y3;
-
- x3 = x2;
- x2 = x1;
- x1 = xn;
-
- y3 = y2;
- y2 = y1;
- y1 = yn;
-
- return yn;
-}
-
-inline float vor_float_filter_bp_ref( float xn) {
-
- const float a0 = 0.0175489156490784836694984960558940656483;
- // const float a1 = 0.0000000000000000000000000000000000000000;
- const float a2 = -0.0526467469472354510084954881676821969450;
- // const float a3 = 0.0000000000000000000000000000000000000000;
- const float a4 = 0.0526467469472354510084954881676821969450;
- // const float a5 = 0.0000000000000000000000000000000000000000;
- const float a6 = -0.0175489156490784836694984960558940656483;
-
- const float b1 = 2.5508195725874163173330089193768799304962;
- const float b2 = 3.9857308274503626677187639870680868625641;
- const float b3 = 3.8245798569419009460546021728077903389931;
- const float b4 = 2.6296760724926846464200025366153568029404;
- const float b5 = 1.0926715614934312537087635064381174743176;
- const float b6 = 0.2825578543465128156242371915141120553017;
-
- static float x1 = 0;
- static float x2 = 0;
- static float x3 = 0;
- static float x4 = 0;
- static float x5 = 0;
- static float x6 = 0;
-
- static float y1 = 0;
- static float y2 = 0;
- static float y3 = 0;
- static float y4 = 0;
- static float y5 = 0;
- static float y6 = 0;
-
- float yn = a0 * xn
- // + a1 * x1
- + a2 * x2
- // + a3 * x3
- + a4 * x4
- // + a5 * x5
- + a6 * x6
- - b1 * y1
- - b2 * y2
- - b3 * y3
- - b4 * y4
- - b5 * y5
- - b6 * y6;
-
- x6 = x5;
- x5 = x4;
- x4 = x3;
- x3 = x2;
- x2 = x1;
- x1 = xn;
-
- y6 = y5;
- y5 = y4;
- y4 = y3;
- y3 = y2;
- y2 = y1;
- y1 = yn;
-
- return yn;
-}
-
-
-inline float vor_float_filter_lp_decim( float xn) {
-
- const float a0 = 0.0000294918571461433008684162315748977790;
- const float a1 = 0.0000884755714384299093815122727590960494;
- const float a2 = 0.0000884755714384299093815122727590960494;
- const float a3 = 0.0000294918571461433008684162315748977790;
-
- const float b1 = -2.8738524677701420273479016032069921493530;
- const float b2 = 2.7555363566291544152875303552718833088875;
- const float b3 = -0.8814479540018430592240861187747213989496;
-
- static float x1 = 0.;
- static float x2 = 0.;
- static float x3 = 0.;
-
- static float y1 = 0.;
- static float y2 = 0.;
- static float y3 = 0.;
-
- float yn = a0 * xn
- + a1 * x1
- + a2 * x2
- + a3 * x3
- - b1 * y1
- - b2 * y2
- - b3 * y3;
-
- x3 = x2;
- x2 = x1;
- x1 = xn;
-
- y3 = y2;
- y2 = y1;
- y1 = yn;
-
- return yn;
-}
-
-inline float vor_float_filter_lp_var( float xn) {
-
- const float a0 = 0.0001325928962621713658003030911203268261;
- const float a1 = 0.0007955573775730281948018185467219609563;
- const float a2 = 0.0019888934439325706496348722396305674920;
- const float a3 = 0.0026518579252434275328464963195074233226;
- const float a4 = 0.0019888934439325706496348722396305674920;
- const float a5 = 0.0007955573775730281948018185467219609563;
- const float a6 = 0.0001325928962621713658003030911203268261;
-
- const float b1 = -3.9811884900947003274040980613790452480316;
- const float b2 = 6.8452604202756832663112618320155888795853;
- const float b3 = -6.4498289229953256196381516929250210523605;
- const float b4 = 3.4951386512490887348292289971141144633293;
- const float b5 = -1.0292502263335985279724127394729293882847;
- const float b6 = 0.1283545132596315418993526691338047385216;
-
- static float x1 = 0.;
- static float x2 = 0.;
- static float x3 = 0.;
- static float x4 = 0.;
- static float x5 = 0.;
- static float x6 = 0.;
-
- static float y1 = 0.;
- static float y2 = 0.;
- static float y3 = 0.;
- static float y4 = 0.;
- static float y5 = 0.;
- static float y6 = 0.;
-
- float yn = a0 * xn
- + a1 * x1
- + a2 * x2
- + a3 * x3
- + a4 * x4
- + a5 * x5
- + a6 * x6
- - b1 * y1
- - b2 * y2
- - b3 * y3
- - b4 * y4
- - b5 * y5
- - b6 * y6;
-
- x6 = x5;
- x5 = x4;
- x4 = x3;
- x3 = x2;
- x2 = x1;
- x1 = xn;
-
- y6 = y5;
- y5 = y4;
- y4 = y3;
- y3 = y2;
- y2 = y1;
- y1 = yn;
-
- return yn;
-}
-
-
-inline float vor_float_filter_lp_ref( float xn) {
-
- const float a0 = 0.0182843871571847782497854950634064152837;
- const float a1 = 0.0548531614715543347493564851902192458510;
- const float a2 = 0.0548531614715543347493564851902192458510;
- const float a3 = 0.0182843871571847782497854950634064152837;
-
- const float b1 = -1.7551740553005390488294779061106964945793;
- const float b2 = 1.1780240265537846866550353297498077154160;
- const float b3 = -0.2765748739957675783607271569053409621119;
-
- static float x1 = 0.;
- static float x2 = 0.;
- static float x3 = 0.;
-
- static float y1 = 0.;
- static float y2 = 0.;
- static float y3 = 0.;
-
- float yn = a0 * xn
- + a1 * x1
- + a2 * x2
- + a3 * x3
- - b1 * y1
- - b2 * y2
- - b3 * y3;
-
- x3 = x2;
- x2 = x1;
- x1 = xn;
-
- y3 = y2;
- y2 = y1;
- y1 = yn;
-
- return yn;
-}
-
-
-inline float vor_float_filter_lp_fm( float xn) {
-
- const float a0 = 0.0001325928962621713658003030911203268261;
- const float a1 = 0.0007955573775730281948018185467219609563;
- const float a2 = 0.0019888934439325706496348722396305674920;
- const float a3 = 0.0026518579252434275328464963195074233226;
- const float a4 = 0.0019888934439325706496348722396305674920;
- const float a5 = 0.0007955573775730281948018185467219609563;
- const float a6 = 0.0001325928962621713658003030911203268261;
-
- const float b1 = -3.9811884900947003274040980613790452480316;
- const float b2 = 6.8452604202756832663112618320155888795853;
- const float b3 = -6.4498289229953256196381516929250210523605;
- const float b4 = 3.4951386512490887348292289971141144633293;
- const float b5 = -1.0292502263335985279724127394729293882847;
- const float b6 = 0.1283545132596315418993526691338047385216;
-
- static float x1 = 0.;
- static float x2 = 0.;
- static float x3 = 0.;
- static float x4 = 0.;
- static float x5 = 0.;
- static float x6 = 0.;
-
- static float y1 = 0.;
- static float y2 = 0.;
- static float y3 = 0.;
- static float y4 = 0.;
- static float y5 = 0.;
- static float y6 = 0.;
-
- float yn = a0 * xn
- + a1 * x1
- + a2 * x2
- + a3 * x3
- + a4 * x4
- + a5 * x5
- + a6 * x6
- - b1 * y1
- - b2 * y2
- - b3 * y3
- - b4 * y4
- - b5 * y5
- - b6 * y6;
-
- x6 = x5;
- x5 = x4;
- x4 = x3;
- x3 = x2;
- x2 = x1;
- x1 = xn;
-
- y6 = y5;
- y5 = y4;
- y4 = y3;
- y3 = y2;
- y2 = y1;
- y1 = yn;
-
- return yn;
-
-}
-
-#endif /* VOR_FLOAT_FILTERS_H */
diff --git a/sw/airborne/firmwares/vor/vor_int_demod.c b/sw/airborne/firmwares/vor/vor_int_demod.c
deleted file mode 100644
index 49ba9e4471..0000000000
--- a/sw/airborne/firmwares/vor/vor_int_demod.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (C) 2008 Antoine Blais, Antoine Drouin
- *
- * 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.
- *
- */
-
-
-// timing
-// 30khz 33 us
-// processing 30Kz with sine 100 us
-// processing 30Kz without sine 23-26 us
-//
-// total processing : 270us
-// total processing without sine 54us
-//
-
-#include "vor_int_demod.h"
-
-#include
-
-#include "vor_int_filters.h"
-
-
-#define INT_OF_FLOAT(f,r) ((f) * (float)r)
-
-
-#define VID_REF_DANGLE VID_ANGLE_INT_OF_PFLOAT(2. * M_PI * 9960. * 502. / 15000000.)
-#define VID_VAR_DANGLE VID_ANGLE_INT_OF_PFLOAT(2. * M_PI * 30. * 502. / 15000000. * 3 * 83)
-#define VID_FM_DANGLE VID_VAR_DANGLE
-
-#define VID_TWO_PI VID_ANGLE_INT_OF_PFLOAT(2. * M_PI)
-
-// Variables pour la démodulation REF
- int32_t vid_ref_angle;
- int32_t vid_ref_phi;
- float vid_ref_local_sig_float;
-const int32_t vid_ref_alpha = INT_OF_FLOAT(-1.2, 15);
- int32_t vid_ref_sig;
- int32_t vid_ref_err;
-
-// Variable pour la décimation REF
-int32_t vid_ref_err_decim;
-
-// Variable pour la démodulation du VAR
- int32_t vid_var_angle;
- int32_t vid_var_phi;
- float vid_var_local_sig_float;
-const int32_t vid_var_alpha = INT_OF_FLOAT(-0.5, 15);
- int32_t vid_var_sig;
- int32_t vid_var_err;
-
-// Variable pour la démodulation FM
- int32_t vid_fm_angle;
- int32_t vid_fm_phi;
- float vid_fm_local_sig_float;
-const int32_t vid_fm_alpha = INT_OF_FLOAT(-1., 15);
- int32_t vid_fm_sig;
- int32_t vid_fm_err;
-
- int32_t vid_qdr;
-
-
-int32_t vid_ref_local_sig;
-int32_t vid_ref_y;
-
-static uint32_t i;
-static uint32_t decim;
-static uint32_t vid_DECIM = 3 * 83;
-
-void vor_int_demod_init( void) {
-
- i = 0;
- vid_ref_angle = 0;
- vid_ref_phi = VID_ANGLE_INT_OF_PFLOAT(M_PI);
- vid_ref_err = 0;
-
-}
-
-
-void vor_int_demod_run ( int16_t sample) {
-
- // phase error re-injection
- int32_t dphi = vid_ref_alpha * vid_ref_err;
- dphi = dphi <<3;
- vid_ref_phi -= dphi ;
-
- // local oscillator phase
- vid_ref_angle += VID_REF_DANGLE;
- if (vid_ref_angle >= VID_TWO_PI) vid_ref_angle -= VID_TWO_PI;
- int32_t vid_ref_phase = vid_ref_angle + vid_ref_phi;
- if (vid_ref_phase >= VID_TWO_PI) vid_ref_phase -= VID_TWO_PI;
-
- // local oscillator signal
- const float vid_ref_phase_float = VID_ANGLE_FLOAT_OF_INT(vid_ref_phase);
- vid_ref_local_sig_float = sin(vid_ref_phase_float);
-
- // test sign ?
- /// const int32_t vid_ref_local_sig = VID_ANGLE_INT_OF_PFLOAT(vid_ref_local_sig_float);
- vid_ref_local_sig = vid_ref_local_sig_float * (float)(1<<15);
- // get REF signal by bandpassing input signal
- /// const int32_t vid_ref_sig = vor_int_filter_bp_ref(sample);
- vid_ref_sig = vor_int_filter_bp_ref(sample);
- // multiply input signal by local oscillator signal
- // const int32_t vid_ref_y = vid_ref_sig * vid_ref_local_sig;
- vid_ref_y = vid_ref_sig * vid_ref_local_sig;
- vid_ref_y = vid_ref_y >> 15;
- // get phase error by low passing the result of the multiplication.
- vid_ref_err = vor_int_filter_lp_ref(vid_ref_y);
-
- // filter 30 REF before decimating it
- // const int32_t vid_ref_err_decim = vor_int_filter_lp_decim(vid_ref_err);
- vid_ref_err_decim = vor_int_filter_lp_decim(vid_ref_err<<3);
- vid_ref_err_decim = vid_ref_err_decim >> 3;
-
- // get VAR signal by bandpassing input signal
- vid_var_sig = vor_int_filter_bp_var(sample);
-
- if (1) {
- // if (decim >= vid_DECIM) {
- decim = 0;
-
- // phase error re-injection
- int32_t dvar_phi = vid_var_alpha * vid_var_err;
- dvar_phi = dvar_phi <<3;
- vid_var_phi -= dvar_phi;
-
- // local var oscillator phase
- vid_var_angle += VID_VAR_DANGLE;
-
- if (vid_var_angle >= VID_TWO_PI) vid_var_angle -= VID_TWO_PI;
- int32_t vid_var_phase = vid_var_angle + vid_var_phi;
- if (vid_var_phase >= VID_TWO_PI) vid_var_phase -= VID_TWO_PI;
-
- // local var oscillator signal
- const float vid_var_phase_float = VID_ANGLE_FLOAT_OF_INT(vid_var_phase);
- vid_var_local_sig_float = -sin(vid_var_phase_float);
-
- // FIXME - INT mult multiply input signal by local oscillator signal
- const int32_t vid_var_y = vid_var_sig * vid_var_local_sig_float;
- // get phase error by low passing the result of the multiplication.
- vid_var_err = vor_int_filter_lp_var(vid_var_y);
-
-
- // phase error re-injection
- int32_t dfm_phi = vid_fm_alpha * vid_fm_err;
- dfm_phi = dfm_phi <<3;
- vid_fm_phi -= dfm_phi;
-
- // local var oscillator phase
- vid_fm_angle += VID_FM_DANGLE;
-
- if (vid_fm_angle >= VID_TWO_PI) vid_fm_angle -= VID_TWO_PI;
- int32_t vid_fm_phase = vid_fm_angle + vid_fm_phi;
- if (vid_fm_phase >= VID_TWO_PI) vid_fm_phase -= VID_TWO_PI;
-
- // local var oscillator signal
- const float vid_fm_phase_float = VID_ANGLE_FLOAT_OF_INT(vid_fm_phase);
- vid_fm_local_sig_float = -sin(vid_fm_phase_float);
-
- // FIXME - INT mult multiply input signal by local oscillator signal
- const int32_t vid_fm_y = vid_ref_err_decim * vid_fm_local_sig_float;
- // get phase error by low passing the result of the multiplication.
- vid_fm_err = vor_int_filter_lp_fm(vid_fm_y);
-
- vid_qdr = vid_var_phi - vid_fm_phi;
-
- }
-
- i++;
- decim++;
-}
-
diff --git a/sw/airborne/firmwares/vor/vor_int_demod.h b/sw/airborne/firmwares/vor/vor_int_demod.h
deleted file mode 100644
index 78d5159327..0000000000
--- a/sw/airborne/firmwares/vor/vor_int_demod.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2008 Antoine Blais, Antoine Drouin
- *
- * This file is part of paparazzi.
- *
- * paparazzi is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * paparazzi is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with paparazzi; see the file COPYING. If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- */
-
-#ifndef VOR_INT_DEMOD_H
-#define VOR_INT_DEMOD_H
-
-#include
-
-extern void vor_int_demod_init( void);
-extern void vor_int_demod_run ( int16_t sample);
-
-extern int32_t vid_ref_angle;
-extern int32_t vid_ref_phi;
-extern int32_t vid_ref_err;
-extern const int32_t vid_ref_alpha;
-
-
-extern int32_t vid_ref_err_decim;
-
-extern int32_t vid_var_phi;
-extern float vid_var_local_sig_float;
-
-extern int32_t vid_fm_phi;
-extern float vid_fm_local_sig_float;
-
-extern int32_t vid_qdr;
-
-#define VID_ANGLE_RES 16
-#define VID_ANGLE_FACT (1 << VID_ANGLE_RES)
-#define VID_ANGLE_INT_OF_PFLOAT(a) ((a) * (float)VID_ANGLE_FACT + 0.5)
-#define VID_ANGLE_INT_OF_NFLOAT(a) ((a) * (float)VID_ANGLE_FACT - 0.5)
-#define VID_ANGLE_FLOAT_OF_INT(a) ((float)(a) / (float)VID_ANGLE_FACT)
-
-extern float vid_ref_local_sig_float;
-extern int32_t vid_ref_sig;
-extern int32_t vid_ref_local_sig;
-extern int32_t vid_var_sig;
-extern int32_t vid_fm_local_sig;
-extern int32_t vid_ref_y;
-
-#endif /* VOR_INT_DEMOD_H */
diff --git a/sw/airborne/firmwares/vor/vor_int_demod_decim.c b/sw/airborne/firmwares/vor/vor_int_demod_decim.c
deleted file mode 100644
index 8112cc2013..0000000000
--- a/sw/airborne/firmwares/vor/vor_int_demod_decim.c
+++ /dev/null
@@ -1,257 +0,0 @@
-#include "vor_int_demod_decim.h"
-
-#include "vor_int_filters_decim.h"
-
-#include "lo.h"
-
-// Variables pour la démodulation REF
-int32_t vid_ref_sig;
-
-int32_t vid_loREF;
-int32_t vid_phaseREF;
-int32_t vid_ref_err;
-int32_t vid_yREF;
-
-#undef VIF_RES
-#define VIF_RES 10
-#define VID_REF (1<<10)
-const int32_t vid_alphaREF = VIF_PCOEF(0.003);
-const int32_t vid_DELTA_9960 = 500*1;
-
-// Variable pour la décimation REF
-int32_t vid_ref_err_decim1;
-int32_t vid_ref_err_decim2;
-
-// Variable pour la démodulation du VAR
-int32_t vid_var_sig;
-
-int32_t vid_var_err_decim1;
-int32_t vid_var_err_decim2;
-
-int32_t vid_loVAR;
-int32_t vid_phaseVAR;
-int32_t vid_var_err;
-int32_t vid_yVAR;
-int32_t vid_cumVAR;
-
-#define VID_VAR (1<<5)
-const int32_t vid_DELTA_30 = 27*300;
-
-// Variable pour la démodulation FM
-int32_t vid_loFM;
-int32_t vid_phaseFM;
-int32_t vid_fm_err;
-int32_t vid_yFM;
-int32_t vid_cumFM;
-
-#define VID_FM (1<<5)
-
-// Le QDR
-int32_t vid_qdr;
-uint8_t vid_qdr_available;
-const int32_t correcQDR = 454; // 5
-
-uint32_t decim1 = 0;
-#define vid_DECIM1 2
-uint32_t decim2 = 0;
-#define vid_DECIM2 9
-uint32_t decim3 = 0;
-#define vid_DECIM3 9
-
-// Variables liées au séquencement des switchs
-int32_t fix_var_sig;
-int32_t fix_var_err_decim1;
-int32_t fix_var_err_decim2;
-
-#define pllREF() { \
- int32_t vid_phiREF = -vid_alphaREF*vid_ref_err; \
- vid_phiREF /= VID_REF; \
- vid_phaseREF += vid_DELTA_9960 + vid_phiREF; \
- if (vid_phaseREF >= N_REF) { \
- vid_phaseREF -= N_REF; \
- } \
- vid_loREF = loREF[vid_phaseREF]; \
- vid_yREF = vid_ref_sig*vid_loREF; \
- vid_yREF /= VID_LO; \
- vid_ref_err = vor_int_filter_lp_ref(vid_yREF); \
- }
-
-#define pllVAR() { \
- vid_var_err /= VID_VAR; \
- vid_cumVAR += vid_var_err; \
- vid_phaseVAR += vid_DELTA_30 + vid_var_err; \
- if (vid_phaseVAR >= N_VAR_FM) { \
- vid_phaseVAR -= N_VAR_FM; \
- } \
- vid_loVAR = lo[vid_phaseVAR]; \
- vid_yVAR = vid_var_err_decim2*vid_loVAR; \
- vid_yVAR /= VID_LO; \
- vid_var_err = vor_int_filter_lp_var4(vid_yVAR); \
- }
-
-#define pllFM() { \
- vid_fm_err /= VID_FM; \
- vid_cumFM += vid_fm_err; \
- vid_phaseFM += vid_DELTA_30 + vid_fm_err; \
- if (vid_phaseFM >= N_VAR_FM) { \
- vid_phaseFM -= N_VAR_FM; \
- } \
- vid_loFM = lo[vid_phaseFM]; \
- vid_yFM = vid_ref_err_decim2*vid_loFM; \
- vid_yFM /= VID_LO; \
- vid_fm_err = vor_int_filter_lp_fm4(vid_yFM); \
- }
-
-#define calculQDR() { \
- vid_qdr = vid_cumVAR - vid_cumFM; \
- \
- if (vid_qdr >= N_VAR_FM) { \
- vid_qdr -= N_VAR_FM; \
- vid_cumVAR = vid_qdr; \
- vid_cumFM = 0; \
- } \
- else { \
- if (vid_qdr <= -N_VAR_FM) { \
- vid_qdr += N_VAR_FM; \
- vid_cumVAR = 0; \
- vid_cumFM = vid_qdr; \
- } \
- else { \
- vid_cumVAR = vid_qdr; \
- vid_cumFM = 0; \
- } \
- } \
- \
- vid_qdr -= correcQDR; \
- }
-
-void vor_int_demod_init( void) {
- vid_qdr_available = FALSE;
-}
-
-void vor_int_demod_run ( int16_t sample) {
-
- decim1++;
-
- // Le signal arrive sur 10 bits, on le met sur 16 bits
- sample = sample*(1<<6);
-
- // get VAR signal by bandpassing input signal
- vid_var_sig = vor_int_filter_bp_var(sample);
-
- // get REF signal by bandpassing input signal
- vid_ref_sig = vor_int_filter_bp_ref(sample);
-
- //=================================================================
- switch (decim1) {
-
- //---------------------------------------------------------------
- case 1 : {
-
- decim2++;
-
- pllREF()
-
- // filter 30 REF before decimation 2
- vid_ref_err_decim1 = vor_int_filter_lp_decim1r(vid_ref_err);
-
- fix_var_sig = vid_var_sig;
-
- break;
- }
- //---------------------------------------------------------------
-
- //---------------------------------------------------------------
- case vid_DECIM1 : {
-
- decim1 = 0;
-
- // filter 30 VAR before decimation 2
- vid_var_err_decim1 = vor_int_filter_lp_decim1v(fix_var_sig);
-
- //=============================================================
- switch (decim2) {
-
- //-----------------------------------------------------------
- case (vid_DECIM2-2) : {
-
- decim3++;
-
- // filter 30 REF before decimation 3
- vid_ref_err_decim2 =
- vor_int_filter_lp_decim2r(vid_ref_err_decim1);
-
- fix_var_err_decim1 = vid_var_err_decim1;
-
- break;
- }
- //-----------------------------------------------------------
-
- //-----------------------------------------------------------
- case (vid_DECIM2-1) : {
-
- // filter 30 VAR before decimation 3
- vid_var_err_decim2 =
- vor_int_filter_lp_decim2v(fix_var_err_decim1);
-
- break;
- }
- //-----------------------------------------------------------
-
- //-----------------------------------------------------------
- case (vid_DECIM2) : {
-
- decim2 = 0;
-
- //=========================================================
- switch (decim3) {
-
- //-------------------------------------------------------
- case (vid_DECIM3-2) : {
-
- pllFM();
-
- fix_var_err_decim2 = vid_var_err_decim2;
-
- break;
- }
- //-------------------------------------------------------
-
- //-------------------------------------------------------
- case (vid_DECIM3-1) : {
-
- vid_var_err_decim2 = fix_var_err_decim2;
-
- pllVAR();
-
- break;
- }
- //-------------------------------------------------------
-
- //-------------------------------------------------------
- case vid_DECIM3 : {
-
- decim3 = 0;
-
- calculQDR();
- vid_qdr_available = TRUE;
- break;
- }
- //-------------------------------------------------------
- }
- //=========================================================
-
- break;
- }
- //-----------------------------------------------------------
- }
- //=============================================================
-
- break;
- }
- //---------------------------------------------------------------
- }
- //=================================================================
-
-}
-
diff --git a/sw/airborne/firmwares/vor/vor_int_demod_decim.h b/sw/airborne/firmwares/vor/vor_int_demod_decim.h
deleted file mode 100644
index 010062be1d..0000000000
--- a/sw/airborne/firmwares/vor/vor_int_demod_decim.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef VOR_INT_DEMOD_DECIM_H
-#define VOR_INT_DEMOD_DECIM_H
-
-#include
-#include "std.h"
-
-
-extern void vor_int_demod_init( void);
-extern void vor_int_demod_run( int16_t sample);
-
-extern int32_t vid_ref_sig;
-
-extern int32_t vid_loREF;
-extern int32_t vid_yREF;
-extern int32_t vid_ref_err;
-extern int32_t vid_ref_err_decim1;
-extern int32_t vid_ref_err_decim2;
-
-extern int32_t vid_var_sig;
-extern int32_t vid_var_err_decim1;
-extern int32_t vid_var_err_decim2;
-
-extern int32_t vid_loVAR;
-extern int32_t vid_yVAR;
-extern int32_t vid_var_err;
-extern int32_t vid_cumVAR;
-
-extern int32_t vid_loFM;
-extern int32_t vid_yFM;
-extern int32_t vid_fm_err;
-extern int32_t vid_cumFM;
-
-extern int32_t vid_qdr;
-extern uint8_t vid_qdr_available;
-
-
-extern const int32_t N_VAR_FM;
-
-#endif /* VOR_INT_DEMOD_DECIM_H */
diff --git a/sw/airborne/firmwares/vor/vor_int_filters.h b/sw/airborne/firmwares/vor/vor_int_filters.h
deleted file mode 100644
index 73b5c80790..0000000000
--- a/sw/airborne/firmwares/vor/vor_int_filters.h
+++ /dev/null
@@ -1,379 +0,0 @@
-#ifndef VOR_INT_FILTERS_H
-#define VOR_INT_FILTERS_H
-
-
-#define VIF_CRES 16
-#define VIF_CFACT (1<> VIF_CRES);
-
- x3 = x2;
- x2 = x1;
- x1 = xn;
-
- y3 = y2;
- y2 = _y1;
- _y1 = _yn;
-
- return (_yn >> VIF_SSCALE);
-}
-
-inline int32_t vor_int_filter_bp_ref( int16_t xn) {
-
- const int32_t a0 = VIF_PCOEF( 0.0175489156490784836694984960558940656483);
- // const int32_t a1 = VIF_PCOEF( 0.0000000000000000000000000000000000000000);
- const int32_t a2 = VIF_NCOEF(-0.0526467469472354510084954881676821969450);
- // const int32_t a3 = VIF_PCOEF( 0.0000000000000000000000000000000000000000);
- const int32_t a4 = VIF_PCOEF( 0.0526467469472354510084954881676821969450);
- // const int32_t a5 = VIF_PCOEF( 0.0000000000000000000000000000000000000000);
- const int32_t a6 = VIF_NCOEF(-0.0175489156490784836694984960558940656483);
-
- const int32_t b1 = VIF_PCOEF( 2.5508195725874163173330089193768799304962);
- const int32_t b2 = VIF_PCOEF( 3.9857308274503626677187639870680868625641);
- const int32_t b3 = VIF_PCOEF( 3.8245798569419009460546021728077903389931);
- const int32_t b4 = VIF_PCOEF( 2.6296760724926846464200025366153568029404);
- const int32_t b5 = VIF_PCOEF( 1.0926715614934312537087635064381174743176);
- const int32_t b6 = VIF_PCOEF( 0.2825578543465128156242371915141120553017);
-
- // printf("%d %d %d %d %d %d %d\n", a0, a1, a2, a3, a4, a5, a6);
- // printf("%d %d %d %d %d %d\n", b1, b2, b3, b4, b5, b6);
-
- static int16_t x1 = 0;
- static int16_t x2 = 0;
- static int16_t x3 = 0;
- static int16_t x4 = 0;
- static int16_t x5 = 0;
- static int16_t x6 = 0;
-
- static int32_t _y1 = 0;
- static int32_t y2 = 0;
- static int32_t y3 = 0;
- static int32_t y4 = 0;
- static int32_t y5 = 0;
- static int32_t y6 = 0;
-
- /* scale input */
- xn = (xn << VIF_SSCALE);
-
- int32_t _yn = a0 * xn
- // + a1 * x1
- + a2 * x2
- // + a3 * x3
- + a4 * x4
- // + a5 * x5
- + a6 * x6
- - b1 * _y1
- - b2 * y2
- - b3 * y3
- - b4 * y4
- - b5 * y5
- - b6 * y6;
- // printf("%d\n", _yn);
- _yn = (_yn >> VIF_CRES);
-
- x6 = x5;
- x5 = x4;
- x4 = x3;
- x3 = x2;
- x2 = x1;
- x1 = xn;
-
- y6 = y5;
- y5 = y4;
- y4 = y3;
- y3 = y2;
- y2 = _y1;
- _y1 = _yn;
-
- return (_yn >> VIF_SSCALE);
-}
-
-
-
-#define VIF_CRES_t 16
-#define VIF_CFACT_t (1<> VIF_CRES);
-
- x3 = x2;
- x2 = x1;
- x1 = xn;
-
- y3 = y2;
- y2 = _y1;
- _y1 = _yn;
-
- return (_yn >> VIF_SSCALE);
-}
-
-
-inline int32_t vor_int_filter_lp_var( int32_t xn) {
-
- const int32_t a0 = VIF_PCOEF( 0.0001325928962621713658003030911203268261);
- const int32_t a1 = VIF_PCOEF( 0.0007955573775730281948018185467219609563);
- const int32_t a2 = VIF_PCOEF( 0.0019888934439325706496348722396305674920);
- const int32_t a3 = VIF_PCOEF( 0.0026518579252434275328464963195074233226);
- const int32_t a4 = VIF_PCOEF( 0.0019888934439325706496348722396305674920);
- const int32_t a5 = VIF_PCOEF( 0.0007955573775730281948018185467219609563);
- const int32_t a6 = VIF_PCOEF( 0.0001325928962621713658003030911203268261);
-
- const int32_t b1 = VIF_NCOEF(-3.9811884900947003274040980613790452480316);
- const int32_t b2 = VIF_PCOEF( 6.8452604202756832663112618320155888795853);
- const int32_t b3 = VIF_NCOEF(-6.4498289229953256196381516929250210523605);
- const int32_t b4 = VIF_PCOEF( 3.4951386512490887348292289971141144633293);
- const int32_t b5 = VIF_NCOEF(-1.0292502263335985279724127394729293882847);
- const int32_t b6 = VIF_PCOEF( 0.1283545132596315418993526691338047385216);
-
- // printf("%d %d %d %d %d %d %d\n", a0, a1, a2, a3, a4, a5, a6);
- // printf("%d %d %d %d %d %d\n", b1, b2, b3, b4, b5, b6);
-
- static int16_t x1 = 0;
- static int16_t x2 = 0;
- static int16_t x3 = 0;
- static int16_t x4 = 0;
- static int16_t x5 = 0;
- static int16_t x6 = 0;
-
- static int32_t _y1 = 0;
- static int32_t y2 = 0;
- static int32_t y3 = 0;
- static int32_t y4 = 0;
- static int32_t y5 = 0;
- static int32_t y6 = 0;
-
- /* scale input */
- xn = (xn << VIF_SSCALE);
-
- int32_t _yn = a0 * xn
- + a1 * x1
- + a2 * x2
- + a3 * x3
- + a4 * x4
- + a5 * x5
- + a6 * x6
- - b1 * _y1
- - b2 * y2
- - b3 * y3
- - b4 * y4
- - b5 * y5
- - b6 * y6;
- // printf("%d\n", _yn);
- _yn = (_yn >> VIF_CRES);
-
- x6 = x5;
- x5 = x4;
- x4 = x3;
- x3 = x2;
- x2 = x1;
- x1 = xn;
-
- y6 = y5;
- y5 = y4;
- y4 = y3;
- y3 = y2;
- y2 = _y1;
- _y1 = _yn;
-
- return (_yn >> VIF_SSCALE);
-}
-
-inline int32_t vor_int_filter_lp_ref( int32_t xn) {
-
- const int32_t a0 = VIF_PCOEF( 0.0182843871571847782497854950634064152837);
- const int32_t a1 = VIF_PCOEF( 0.0548531614715543347493564851902192458510);
- const int32_t a2 = VIF_PCOEF( 0.0548531614715543347493564851902192458510);
- const int32_t a3 = VIF_PCOEF( 0.0182843871571847782497854950634064152837);
-
- const int32_t b1 = VIF_NCOEF(-1.7551740553005390488294779061106964945793);
- const int32_t b2 = VIF_PCOEF( 1.1780240265537846866550353297498077154160);
- const int32_t b3 = VIF_NCOEF(-0.2765748739957675783607271569053409621119);
-
- // printf("%d %d %d %d\n", a0, a1, a2, a3);
- // printf("%d %d %d\n", b1, b2, b3);
-
- static int16_t x1 = 0;
- static int16_t x2 = 0;
- static int16_t x3 = 0;
-
- static int32_t _y1 = 0;
- static int32_t y2 = 0;
- static int32_t y3 = 0;
-
- /* scale input */
- xn = (xn << VIF_SSCALE);
-
- int32_t _yn = a0 * xn
- + a1 * x1
- + a2 * x2
- + a3 * x3
- - b1 * _y1
- - b2 * y2
- - b3 * y3;
- // printf("%d\n", _yn);
- _yn = (_yn >> VIF_CRES);
-
- x3 = x2;
- x2 = x1;
- x1 = xn;
-
- y3 = y2;
- y2 = _y1;
- _y1 = _yn;
-
- return (_yn >> VIF_SSCALE);
-}
-
-inline int32_t vor_int_filter_lp_fm( int32_t xn) {
-
- const int32_t a0 = VIF_PCOEF( 0.0001325928962621713658003030911203268261);
- const int32_t a1 = VIF_PCOEF( 0.0007955573775730281948018185467219609563);
- const int32_t a2 = VIF_PCOEF( 0.0019888934439325706496348722396305674920);
- const int32_t a3 = VIF_PCOEF( 0.0026518579252434275328464963195074233226);
- const int32_t a4 = VIF_PCOEF( 0.0019888934439325706496348722396305674920);
- const int32_t a5 = VIF_PCOEF( 0.0007955573775730281948018185467219609563);
- const int32_t a6 = VIF_PCOEF( 0.0001325928962621713658003030911203268261);
-
- const int32_t b1 = VIF_NCOEF(-3.9811884900947003274040980613790452480316);
- const int32_t b2 = VIF_PCOEF( 6.8452604202756832663112618320155888795853);
- const int32_t b3 = VIF_NCOEF(-6.4498289229953256196381516929250210523605);
- const int32_t b4 = VIF_PCOEF( 3.4951386512490887348292289971141144633293);
- const int32_t b5 = VIF_NCOEF(-1.0292502263335985279724127394729293882847);
- const int32_t b6 = VIF_PCOEF( 0.1283545132596315418993526691338047385216);
-
- // printf("%d %d %d %d %d %d %d\n", a0, a1, a2, a3, a4, a5, a6);
- // printf("%d %d %d %d %d %d\n", b1, b2, b3, b4, b5, b6);
-
- static int16_t x1 = 0;
- static int16_t x2 = 0;
- static int16_t x3 = 0;
- static int16_t x4 = 0;
- static int16_t x5 = 0;
- static int16_t x6 = 0;
-
- static int32_t _y1 = 0;
- static int32_t y2 = 0;
- static int32_t y3 = 0;
- static int32_t y4 = 0;
- static int32_t y5 = 0;
- static int32_t y6 = 0;
-
- /* scale input */
- xn = (xn << VIF_SSCALE);
-
- int32_t _yn = a0 * xn
- + a1 * x1
- + a2 * x2
- + a3 * x3
- + a4 * x4
- + a5 * x5
- + a6 * x6
- - b1 * _y1
- - b2 * y2
- - b3 * y3
- - b4 * y4
- - b5 * y5
- - b6 * y6;
- // printf("%d\n", _yn);
- _yn = (_yn >> VIF_CRES);
-
- x6 = x5;
- x5 = x4;
- x4 = x3;
- x3 = x2;
- x2 = x1;
- x1 = xn;
-
- y6 = y5;
- y5 = y4;
- y4 = y3;
- y3 = y2;
- y2 = _y1;
- _y1 = _yn;
-
- return (_yn >> VIF_SSCALE);
-
-}
-
-#endif /* VOR_INT_FILTERS_H */
diff --git a/sw/airborne/firmwares/vor/vor_int_filters_decim.h b/sw/airborne/firmwares/vor/vor_int_filters_decim.h
deleted file mode 100644
index 6f0c867701..0000000000
--- a/sw/airborne/firmwares/vor/vor_int_filters_decim.h
+++ /dev/null
@@ -1,592 +0,0 @@
-#ifndef VOR_INT_FILTERS_DECIM_H
-#define VOR_INT_FILTERS_DECIM_H
-
-extern inline int32_t vor_int_filter_bp_ref( int16_t xn);
-extern inline int32_t vor_int_filter_lp_ref( int16_t xn);
-extern inline int32_t vor_int_filter_bp_var( int16_t xn);
-extern inline int32_t vor_int_filter_lp_decim1v( int16_t xn);
-extern inline int32_t vor_int_filter_lp_decim1r( int16_t xn);
-extern inline int32_t vor_int_filter_lp_decim2v( int16_t xn);
-extern inline int32_t vor_int_filter_lp_decim2r( int16_t xn);
-extern inline int32_t vor_int_filter_lp_var3( int16_t xn);
-extern inline int32_t vor_int_filter_lp_fm3( int16_t xn);
-extern inline int32_t vor_int_filter_lp_var4( int16_t xn);
-extern inline int32_t vor_int_filter_lp_fm4( int16_t xn);
-
-#undef VIF_RES
-#define VIF_RES 14
-#define VIF_FACT (1<socket_out = socket( PF_INET, SOCK_DGRAM, pte->p_proto);
- setsockopt(me->socket_out, SOL_SOCKET, SO_REUSEADDR,
- &so_reuseaddr, sizeof(so_reuseaddr));
+ if(port_out >= 0) {
+ // Create the output socket (enable reuse of the address, and broadcast if necessary)
+ create_socket(&me->socket_out, 0, 1, broadcast);
- /* only set broadcast option if explicitly enabled */
- if (broadcast)
- setsockopt(me->socket_out, SOL_SOCKET, SO_BROADCAST,
- &broadcast, sizeof(broadcast));
+ // Setup the output address
+ me->addr_out.sin_family = PF_INET;
+ me->addr_out.sin_port = htons(port_out);
+ me->addr_out.sin_addr.s_addr = inet_addr(str_ip_out);
+ }
- me->addr_out.sin_family = PF_INET;
- me->addr_out.sin_port = htons(port_out);
- me->addr_out.sin_addr.s_addr = inet_addr(str_ip_out);
+ if(port_in >= 0) {
+ // Creat the input socket (enable reuse of the address, and disable broadcast)
+ create_socket(&me->socket_in, 0, 1, 0);
- me->socket_in = socket( PF_INET, SOCK_DGRAM, pte->p_proto);
- setsockopt(me->socket_in, SOL_SOCKET, SO_REUSEADDR,
- &so_reuseaddr, sizeof(so_reuseaddr));
+ // Create the input address
+ me->addr_in.sin_family = PF_INET;
+ me->addr_in.sin_port = htons(port_in);
+ me->addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
- me->addr_in.sin_family = PF_INET;
- me->addr_in.sin_port = htons(port_in);
- me->addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
-
- bind(me->socket_in, (struct sockaddr *)&me->addr_in, sizeof(me->addr_in));
+ bind(me->socket_in, (struct sockaddr *)&me->addr_in, sizeof(me->addr_in));
+ }
return me;
+}
+int network_subscribe_multicast(struct FmsNetwork* me, const char* multicast_addr) {
+ // Create the request
+ struct ip_mreq mreq;
+ mreq.imr_multiaddr.s_addr = inet_addr(multicast_addr);
+ mreq.imr_interface.s_addr = htonl(INADDR_ANY);
+
+ // Send the request
+ return setsockopt(me->socket_in, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq));
+}
+
+int network_set_recvbuf(struct FmsNetwork* me, int buf_size) {
+ // Set and check
+ unsigned int optval_size = 4;
+ int buf_ret;
+ setsockopt(me->socket_in, SOL_SOCKET, SO_RCVBUF, (char *)&buf_size, optval_size);
+ getsockopt(me->socket_in, SOL_SOCKET, SO_RCVBUF, (char *)&buf_ret, &optval_size);
+
+ if(buf_size != buf_ret)
+ return -1;
+
+ return 0;
}
int network_write(struct FmsNetwork* me, char* buf, int len) {
+ // Check if the output address is set
+ if(!me->socket_out)
+ return -1;
+
ssize_t byte_written = sendto(me->socket_out, buf, len, MSG_DONTWAIT,
(struct sockaddr*)&me->addr_out, sizeof(me->addr_out));
if ( byte_written != len) {
@@ -52,6 +88,9 @@ int network_write(struct FmsNetwork* me, char* buf, int len) {
///< returns: -1 = error, 0 = no data, >0 = nrofbytesread
int network_read(struct FmsNetwork* me, unsigned char* buf, int len) {
+ // Check if the input address is set
+ if(!me->socket_in)
+ return -1;
socklen_t slen = sizeof(struct sockaddr_in);
// MSG_DONTWAIT => nonblocking flag
diff --git a/sw/airborne/fms/fms_network.h b/sw/airborne/fms/fms_network.h
index 347fa99368..df28d8371c 100644
--- a/sw/airborne/fms/fms_network.h
+++ b/sw/airborne/fms/fms_network.h
@@ -16,6 +16,8 @@ struct FmsNetwork {
extern struct FmsNetwork* network_new(const char* str_ip_out, const int port_out, const int port_in, const int broadcast);
+extern int network_subscribe_multicast(struct FmsNetwork* me, const char* multicast_addr);
+extern int network_set_recvbuf(struct FmsNetwork* me, int buf_size);
extern int network_write(struct FmsNetwork* me, char* buf, int len);
extern int network_read(struct FmsNetwork* me, unsigned char* buf, int len);
diff --git a/sw/airborne/lisa/lisa_stm_passthrough_main.c b/sw/airborne/lisa/lisa_stm_passthrough_main.c
index d87ff7ee0b..c9054966e8 100644
--- a/sw/airborne/lisa/lisa_stm_passthrough_main.c
+++ b/sw/airborne/lisa/lisa_stm_passthrough_main.c
@@ -27,6 +27,7 @@
#include "subsystems/commands.h"
#include "subsystems/actuators.h"
#include "subsystems/actuators/actuators_pwm.h"
+#include "subsystems/actuators/actuators_dualpwm.h"
#include "subsystems/imu.h"
#include "subsystems/radio_control.h"
#include "autopilot.h"
diff --git a/sw/airborne/math/pprz_geodetic_int.c b/sw/airborne/math/pprz_geodetic_int.c
index 44f5cb6fed..e98cdc4136 100644
--- a/sw/airborne/math/pprz_geodetic_int.c
+++ b/sw/airborne/math/pprz_geodetic_int.c
@@ -22,7 +22,6 @@
#include "pprz_geodetic_int.h"
#include "pprz_algebra_int.h"
-#define HIGH_RES_TRIG_FRAC 20
void ltp_of_ecef_rmat_from_lla_i(struct Int32Mat33* ltp_of_ecef, struct LlaCoor_i* lla) {
diff --git a/sw/airborne/math/pprz_geodetic_int.h b/sw/airborne/math/pprz_geodetic_int.h
index cbeac4ac5f..413026a78e 100644
--- a/sw/airborne/math/pprz_geodetic_int.h
+++ b/sw/airborne/math/pprz_geodetic_int.h
@@ -126,6 +126,8 @@ extern void ecef_of_ned_vect_i(struct EcefCoor_i* ecef, struct LtpDef_i* def, st
#define EM7RAD_OF_RAD(_r) ((_r)*1e7)
#define RAD_OF_EM7RAD(_r) ((_r)/1e7)
+#define HIGH_RES_TRIG_FRAC 20
+
#define VECT3_ENU_OF_NED(_o, _i) { \
(_o).x = (_i).y; \
(_o).y = (_i).x; \
@@ -183,4 +185,28 @@ extern void ecef_of_ned_vect_i(struct EcefCoor_i* ecef, struct LtpDef_i* def, st
#define INT32_VECT2_NED_OF_ENU(_o, _i) INT32_VECT2_ENU_OF_NED(_o,_i)
+#define HIGH_RES_RMAT_BFP_OF_REAL(_ei, _ef) { \
+ (_ei).m[0] = BFP_OF_REAL((_ef).m[0], HIGH_RES_TRIG_FRAC); \
+ (_ei).m[1] = BFP_OF_REAL((_ef).m[1], HIGH_RES_TRIG_FRAC); \
+ (_ei).m[2] = BFP_OF_REAL((_ef).m[2], HIGH_RES_TRIG_FRAC); \
+ (_ei).m[3] = BFP_OF_REAL((_ef).m[3], HIGH_RES_TRIG_FRAC); \
+ (_ei).m[4] = BFP_OF_REAL((_ef).m[4], HIGH_RES_TRIG_FRAC); \
+ (_ei).m[5] = BFP_OF_REAL((_ef).m[5], HIGH_RES_TRIG_FRAC); \
+ (_ei).m[6] = BFP_OF_REAL((_ef).m[6], HIGH_RES_TRIG_FRAC); \
+ (_ei).m[7] = BFP_OF_REAL((_ef).m[7], HIGH_RES_TRIG_FRAC); \
+ (_ei).m[8] = BFP_OF_REAL((_ef).m[8], HIGH_RES_TRIG_FRAC); \
+ }
+
+#define HIGH_RES_RMAT_FLOAT_OF_BFP(_ef, _ei) { \
+ (_ef).m[0] = FLOAT_OF_BFP((_ei).m[0], HIGH_RES_TRIG_FRAC); \
+ (_ef).m[1] = FLOAT_OF_BFP((_ei).m[1], HIGH_RES_TRIG_FRAC); \
+ (_ef).m[2] = FLOAT_OF_BFP((_ei).m[2], HIGH_RES_TRIG_FRAC); \
+ (_ef).m[3] = FLOAT_OF_BFP((_ei).m[3], HIGH_RES_TRIG_FRAC); \
+ (_ef).m[4] = FLOAT_OF_BFP((_ei).m[4], HIGH_RES_TRIG_FRAC); \
+ (_ef).m[5] = FLOAT_OF_BFP((_ei).m[5], HIGH_RES_TRIG_FRAC); \
+ (_ef).m[6] = FLOAT_OF_BFP((_ei).m[6], HIGH_RES_TRIG_FRAC); \
+ (_ef).m[7] = FLOAT_OF_BFP((_ei).m[7], HIGH_RES_TRIG_FRAC); \
+ (_ef).m[8] = FLOAT_OF_BFP((_ei).m[8], HIGH_RES_TRIG_FRAC); \
+ }
+
#endif /* PPRZ_GEODETIC_INT_H */
diff --git a/sw/airborne/modules/airborne_ant_track/airborne_ant_track.c b/sw/airborne/modules/airborne_ant_track/airborne_ant_track.c
index c40a5cb84f..ecfd075b88 100644
--- a/sw/airborne/modules/airborne_ant_track/airborne_ant_track.c
+++ b/sw/airborne/modules/airborne_ant_track/airborne_ant_track.c
@@ -87,7 +87,7 @@ float airborne_ant_pan_servo = 0;
svPlanePosition.fx = stateGetPositionEnu_f()->y;
svPlanePosition.fy = stateGetPositionEnu_f()->x;
- svPlanePosition.fz = stateGetPositionEnu_f()->z;
+ svPlanePosition.fz = stateGetPositionUtm_f()->alt;
Home_Position.fx = WaypointY(WP_HOME);
Home_Position.fy = WaypointX(WP_HOME);
diff --git a/sw/airborne/modules/benchmark/flight_benchmark.c b/sw/airborne/modules/benchmark/flight_benchmark.c
index a2eaa74d57..00e67b5c6c 100644
--- a/sw/airborne/modules/benchmark/flight_benchmark.c
+++ b/sw/airborne/modules/benchmark/flight_benchmark.c
@@ -65,7 +65,7 @@ void flight_benchmark_periodic( void ) {
#endif
#ifdef BENCHMARK_ALTITUDE
- Err_altitude = fabs(stateGetPositionEnu_f()->z - v_ctl_altitude_setpoint);
+ Err_altitude = fabs(stateGetPositionUtm_f()->alt - v_ctl_altitude_setpoint);
if (Err_altitude>ToleranceAltitude){
Err_altitude = Err_altitude-ToleranceAltitude;
SquareSumErr_altitude += (Err_altitude * Err_altitude);
diff --git a/sw/airborne/modules/cam_control/cam.c b/sw/airborne/modules/cam_control/cam.c
index 19cf19d53e..d72b7e0dbe 100644
--- a/sw/airborne/modules/cam_control/cam.c
+++ b/sw/airborne/modules/cam_control/cam.c
@@ -252,7 +252,7 @@ void cam_target( void ) {
#else
struct EnuCoor_f* pos = stateGetPositionEnu_f();
struct FloatEulers* att = stateGetNedToBodyEulers_f();
- vPoint(pos->x, pos->y, pos->z,
+ vPoint(pos->x, pos->y, stateGetPositionUtm_f()->alt,
att->phi, att->theta, *stateGetHorizontalSpeedDir_f(),
cam_target_x, cam_target_y, cam_target_alt,
&cam_pan_c, &cam_tilt_c);
diff --git a/sw/airborne/modules/cam_control/rotorcraft_cam.c b/sw/airborne/modules/cam_control/rotorcraft_cam.c
index 31764b36a2..4110212852 100644
--- a/sw/airborne/modules/cam_control/rotorcraft_cam.c
+++ b/sw/airborne/modules/cam_control/rotorcraft_cam.c
@@ -33,8 +33,9 @@
* - HEADING: the servo position and the heading of the rotorcraft are set with angles
* - WP: the camera is tracking a waypoint (Default: CAM)
*
- * The CAM_SWITCH can be used to power the camera in normal modes
- * and disable it when in NONE mode
+ * If ROTORCRAFT_CAM_SWITCH_GPIO is defined, this gpio is set/cleared to switch the power
+ * of the camera on in normal modes and disable it when in NONE mode.
+ * On boards with CAM_SWITCH, ROTORCRAFT_CAM_SWITCH_GPIO can be defined to CAM_SWITCH_GPIO.
*/
#include "modules/cam_control/rotorcraft_cam.h"
@@ -46,6 +47,25 @@
#include "subsystems/datalink/telemetry.h"
+
+/** Gpio output to turn camera power power on.
+ * Control whether to set or clear the ROTORCRAFT_CAM_SWITCH_GPIO to turn on the camera power.
+ * Should be defined to either gpio_set (default) or gpio_clear.
+ * Not used if ROTORCRAFT_CAM_SWITCH_GPIO is not defined.
+ */
+#ifndef ROTORCRAFT_CAM_ON
+#define ROTORCRAFT_CAM_ON gpio_set
+#endif
+
+/** Gpio output to turn camera power power off.
+ * Control whether to set or clear the ROTORCRAFT_CAM_SWITCH_GPIO to turn off the camera power.
+ * Should be defined to either gpio_set or gpio_clear (default).
+ * Not used if ROTORCRAFT_CAM_SWITCH_GPIO is not defined.
+ */
+#ifndef ROTORCRAFT_CAM_OFF
+#define ROTORCRAFT_CAM_OFF gpio_clear
+#endif
+
uint8_t rotorcraft_cam_mode;
#define _SERVO_PARAM(_s,_p) SERVO_ ## _s ## _ ## _p
@@ -73,7 +93,22 @@ static void send_cam(void) {
&rotorcraft_cam_tilt,&rotorcraft_cam_pan);
}
+void rotorcraft_cam_set_mode(uint8_t mode) {
+ rotorcraft_cam_mode = mode;
+#ifdef ROTORCRAFT_CAM_SWITCH_GPIO
+ if (rotorcraft_cam_mode == ROTORCRAFT_CAM_MODE_NONE) {
+ ROTORCRAFT_CAM_OFF(ROTORCRAFT_CAM_SWITCH_GPIO);
+ }
+ else {
+ ROTORCRAFT_CAM_ON(ROTORCRAFT_CAM_SWITCH_GPIO);
+ }
+#endif
+}
+
void rotorcraft_cam_init(void) {
+#ifdef ROTORCRAFT_CAM_SWITCH_GPIO
+ gpio_setup_output(ROTORCRAFT_CAM_SWITCH_GPIO);
+#endif
rotorcraft_cam_SetCamMode(ROTORCRAFT_CAM_DEFAULT_MODE);
#if ROTORCRAFT_CAM_USE_TILT
rotorcraft_cam_tilt_pwm = ROTORCRAFT_CAM_TILT_NEUTRAL;
@@ -137,4 +172,3 @@ void rotorcraft_cam_periodic(void) {
ActuatorSet(ROTORCRAFT_CAM_TILT_SERVO, rotorcraft_cam_tilt_pwm);
#endif
}
-
diff --git a/sw/airborne/modules/cam_control/rotorcraft_cam.h b/sw/airborne/modules/cam_control/rotorcraft_cam.h
index 9a95a9b4c8..0fb3c422c2 100644
--- a/sw/airborne/modules/cam_control/rotorcraft_cam.h
+++ b/sw/airborne/modules/cam_control/rotorcraft_cam.h
@@ -40,11 +40,11 @@
#ifndef ROTORCRAFT_CAM_H
#define ROTORCRAFT_CAM_H
+#include "std.h"
#include "generated/airframe.h"
#include "generated/flight_plan.h"
#include "math/pprz_algebra_int.h"
-#include "std.h"
-#include "led.h"
+#include "mcu_periph/gpio.h"
#define ROTORCRAFT_CAM_MODE_NONE 0
#define ROTORCRAFT_CAM_MODE_MANUAL 1
@@ -56,27 +56,6 @@
#define ROTORCRAFT_CAM_DEFAULT_MODE ROTORCRAFT_CAM_MODE_NONE
#endif
-/** Cam power control.
- * By default CAM_SWITCH is used
- * Warning:
- * LED_ON set GPIO low on some boards (lpc)
- * LED_OFF set GPIO high on some boards (lpc)
- */
-#ifndef ROTORCRAFT_CAM_ON
-#ifdef CAM_SWITCH_LED
-#define ROTORCRAFT_CAM_ON LED_OFF(CAM_SWITCH_LED)
-#else
-#define ROTORCRAFT_CAM_ON {}
-#endif
-#endif
-#ifndef ROTORCRAFT_CAM_OFF
-#ifdef CAM_SWITCH_LED
-#define ROTORCRAFT_CAM_OFF LED_ON(CAM_SWITCH_LED)
-#else
-#define ROTORCRAFT_CAM_OFF {}
-#endif
-#endif
-
/** Cam tilt control.
* By default use tilt control if a servo is assigned
*/
@@ -118,14 +97,13 @@ extern int16_t rotorcraft_cam_tilt_pwm;
extern void rotorcraft_cam_init(void);
extern void rotorcraft_cam_periodic(void);
+extern void rotorcraft_cam_set_mode(uint8_t mode);
/** Set camera mode.
* Camera is powered down in NONE mode if CAM_{ON|OFF} are defined
*/
#define rotorcraft_cam_SetCamMode(_v) { \
- rotorcraft_cam_mode = _v; \
- if (rotorcraft_cam_mode == ROTORCRAFT_CAM_MODE_NONE) { ROTORCRAFT_CAM_OFF; } \
- else { ROTORCRAFT_CAM_ON; } \
+ rotorcraft_cam_set_mode(_v); \
}
/** Cam control from datalink message.
diff --git a/sw/airborne/modules/cartography/photogrammetry_calculator.c b/sw/airborne/modules/cartography/photogrammetry_calculator.c
index f18bd57ce4..e6a8580f03 100644
--- a/sw/airborne/modules/cartography/photogrammetry_calculator.c
+++ b/sw/airborne/modules/cartography/photogrammetry_calculator.c
@@ -25,19 +25,22 @@
#include "generated/airframe.h"
#include "generated/flight_plan.h"
-// Flightplan Variables
+/** Default sweep angle in radians from north */
#ifndef PHOTOGRAMMETRY_SWEEP_ANGLE
#define PHOTOGRAMMETRY_SWEEP_ANGLE 0
#endif
+/** overlap 1-99 percent */
#ifndef PHOTOGRAMMETRY_OVERLAP
#define PHOTOGRAMMETRY_OVERLAP 50
#endif
+/** sidelap 1-99 percent */
#ifndef PHOTOGRAMMETRY_SIDELAP
#define PHOTOGRAMMETRY_SIDELAP 50
#endif
+/** mm pixel projection size */
#ifndef PHOTOGRAMMETRY_RESOLUTION
#define PHOTOGRAMMETRY_RESOLUTION 50
#endif
diff --git a/sw/airborne/modules/cartography/photogrammetry_calculator.h b/sw/airborne/modules/cartography/photogrammetry_calculator.h
index 36bbf00e0a..14e3a52dd7 100644
--- a/sw/airborne/modules/cartography/photogrammetry_calculator.h
+++ b/sw/airborne/modules/cartography/photogrammetry_calculator.h
@@ -54,10 +54,10 @@ Add to flightplan or airframe file:
Add to flightplan
@verbatim
-#define PHOTOGRAMMETRY_SWEEP_ANGLE 53 // Degrees from the North
-#define PHOTOGRAMMETRY_OVERLAP 50 // 1-99 Procent
-#define PHOTOGRAMMETRY_SIDELAP 50 // 1-99 Procent
-#define PHOTOGRAMMETRY_RESOLUTION 80 // mm pixel projection size
+#define PHOTOGRAMMETRY_SWEEP_ANGLE RadOfDeg(53) // angle in radians from the North
+#define PHOTOGRAMMETRY_OVERLAP 50 // 1-99 Procent
+#define PHOTOGRAMMETRY_SIDELAP 50 // 1-99 Procent
+#define PHOTOGRAMMETRY_RESOLUTION 80 // mm pixel projection size
@@ -139,7 +139,7 @@ void photogrammetry_calculator_update_flightplan2camera(void);
#define PhotogrammetryCalculatorPolygonSurvey(_WP, _COUNT) { \
WaypointAlt(_WP) = photogrammetry_height + GROUND_ALT; \
int _ang = 90 - DegOfRad(photogrammetry_sweep_angle); \
- if (_ang > 90) _ang -= 180; if (_ang < -90) _ang += 180; \
+ while (_ang > 90) _ang -= 180; while (_ang < -90) _ang += 180; \
InitializePolygonSurvey((_WP), (_COUNT), 2*photogrammetry_sidestep, _ang); \
}
diff --git a/sw/airborne/modules/digital_cam/gpio_cam_ctrl.c b/sw/airborne/modules/digital_cam/gpio_cam_ctrl.c
new file mode 100644
index 0000000000..44b0a8c68b
--- /dev/null
+++ b/sw/airborne/modules/digital_cam/gpio_cam_ctrl.c
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2010-2014 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 modules/digital_cam/gpio_cam_ctrl.c
+ * Control the camera via GPIO pins.
+ *
+ * Configuration (DC_SHUTTER is mandatory, others optional):
+ * @code{.xml}
+ *
+ *
+ *
+ *
+ *
+ * @endcode
+ */
+
+#include "gpio_cam_ctrl.h"
+#include "generated/airframe.h"
+
+// Include Standard Camera Control Interface
+#include "dc.h"
+
+#include "mcu_periph/gpio.h"
+
+#ifndef DC_PUSH
+#define DC_PUSH gpio_set
+#endif
+
+#ifndef DC_RELEASE
+#define DC_RELEASE gpio_clear
+#endif
+
+#ifndef DC_SHUTTER_DELAY
+#define DC_SHUTTER_DELAY 2 /* 4Hz -> 0.5s */
+#endif
+
+#ifndef DC_POWER_OFF_DELAY
+#define DC_POWER_OFF_DELAY 3
+#endif
+
+#ifdef DC_SHUTTER_LED
+#warning DC_SHUTTER_LED is obsolete, please use DC_SHUTTER_GPIO
+#endif
+#ifndef DC_SHUTTER_GPIO
+#error DC: Please specify at least a DC_SHUTTER_GPIO (e.g. )
+#endif
+
+
+// Button Timer
+uint8_t dc_timer;
+
+void gpio_cam_ctrl_init(void)
+{
+ // Call common DC init
+ dc_init();
+
+ // Do gpio specific DC init
+ dc_timer = 0;
+
+ gpio_setup_output(DC_SHUTTER_GPIO);
+ DC_RELEASE(DC_SHUTTER_GPIO);
+#ifdef DC_ZOOM_IN_GPIO
+ gpio_setup_output(DC_ZOOM_IN_GPIO);
+ DC_RELEASE(DC_ZOOM_IN_GPIO);
+#endif
+#ifdef DC_ZOOM_OUT_GPIO
+ gpio_setup_output(DC_ZOOM_OUT_GPIO);
+ DC_RELEASE(DC_ZOOM_OUT_GPIO);
+#endif
+#ifdef DC_POWER_GPIO
+ gpio_setup_output(DC_POWER_GPIO);
+ DC_RELEASE(DC_POWER_GPIO);
+#endif
+#ifdef DC_POWER_OFF_GPIO
+ gpio_setup_output(DC_POWER_OFF_GPIO);
+ DC_RELEASE(DC_POWER_OFF_GPIO);
+#endif
+}
+
+void gpio_cam_ctrl_periodic( void )
+{
+#ifdef DC_SHOOT_ON_BUTTON_RELEASE
+ if (dc_timer==1) {
+ dc_send_shot_position();
+ }
+#endif
+
+ if (dc_timer) {
+ dc_timer--;
+ } else {
+ DC_RELEASE(DC_SHUTTER_GPIO);
+#ifdef DC_ZOOM_IN_GPIO
+ DC_RELEASE(DC_ZOOM_IN_GPIO);
+#endif
+#ifdef DC_ZOOM_OUT_GPIO
+ DC_RELEASE(DC_ZOOM_OUT_GPIO);
+#endif
+#ifdef DC_POWER_GPIO
+ DC_RELEASE(DC_POWER_GPIO);
+#endif
+#ifdef DC_POWER_OFF_GPIO
+ DC_RELEASE(DC_POWER_OFF_GPIO);
+#endif
+ }
+
+ // Common DC Periodic task
+ dc_periodic_4Hz();
+}
+
+/* Command The Camera */
+void dc_send_command(uint8_t cmd)
+{
+ dc_timer = DC_SHUTTER_DELAY;
+ switch (cmd)
+ {
+ case DC_SHOOT:
+ DC_PUSH(DC_SHUTTER_GPIO);
+#ifndef DC_SHOOT_ON_BUTTON_RELEASE
+ dc_send_shot_position();
+#endif
+ break;
+#ifdef DC_ZOOM_IN_GPIO
+ case DC_TALLER:
+ DC_PUSH(DC_ZOOM_IN_GPIO);
+ break;
+#endif
+#ifdef DC_ZOOM_OUT_GPIO
+ case DC_WIDER:
+ DC_PUSH(DC_ZOOM_OUT_GPIO);
+ break;
+#endif
+#ifdef DC_POWER_GPIO
+ case DC_ON:
+ DC_PUSH(DC_POWER_GPIO);
+ break;
+#endif
+#ifdef DC_POWER_OFF_GPIO
+ case DC_OFF:
+ DC_PUSH(DC_POWER_OFF_GPIO);
+ dc_timer = DC_POWER_OFF_DELAY;
+ break;
+#endif
+ default:
+ break;
+ }
+}
diff --git a/sw/airborne/firmwares/vor/vor_float_demod.h b/sw/airborne/modules/digital_cam/gpio_cam_ctrl.h
similarity index 50%
rename from sw/airborne/firmwares/vor/vor_float_demod.h
rename to sw/airborne/modules/digital_cam/gpio_cam_ctrl.h
index b78d9ff949..442dba0563 100644
--- a/sw/airborne/firmwares/vor/vor_float_demod.h
+++ b/sw/airborne/modules/digital_cam/gpio_cam_ctrl.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Antoine Blais, Antoine Drouin
+ * Copyright (C) 2010-2014 The Paparazzi Team
*
* This file is part of paparazzi.
*
@@ -17,37 +17,23 @@
* along with paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
- *
*/
-#ifndef VOR_FLOAT_DEMOD_H
-#define VOR_FLOAT_DEMOD_H
+/** @file modules/digital_cam/gpio_cam_ctrl.h
+ * @brief Digital Camera Control
+ *
+ * Provides the control of the shutter and the zoom of a digital camera
+ * through standard binary IOs of the board.
+ *
+ * The required initialization (dc_init()) and periodic (4Hz) process.
+ */
-extern void vor_float_demod_init( void);
-extern void vor_float_demod_run ( float sample);
+#ifndef GPIO_CAM_CTRL_H
+#define GPIO_CAM_CTRL_H
-extern const float vfd_te;
+extern void gpio_cam_ctrl_init(void);
-extern const float vfd_ref_freq;
-extern float vfd_ref_phi;
-extern float vfd_ref_err;
-extern const float vfd_ref_alpha;
-
-extern const float vfd_var_freq;
-extern float vfd_var_phi;
-extern float vfd_var_err;
-extern const float vfd_var_alpha;
-
-extern const float vfd_fm_freq;
-extern float vfd_fm_phi;
-extern float vfd_fm_err;
-extern const float vfd_fm_alpha;
-
-extern float vfd_qdr;
-
-
-extern float vfd_var_sig;
-extern float vfd_fm_local_sig;
-
-#endif /* VOR_FLOAT_DEMOD_H */
+/** 4Hz Periodic */
+extern void gpio_cam_ctrl_periodic(void);
+#endif // GPIO_CAM_CTRL_H
diff --git a/sw/airborne/modules/digital_cam/led_cam_ctrl.c b/sw/airborne/modules/digital_cam/led_cam_ctrl.c
deleted file mode 100644
index 81b701f6af..0000000000
--- a/sw/airborne/modules/digital_cam/led_cam_ctrl.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2010 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 "led_cam_ctrl.h"
-
-// Button Timer
-uint8_t dc_timer;
-
-
-/* Command The Camera */
-void dc_send_command(uint8_t cmd)
-{
- dc_timer = DC_SHUTTER_DELAY;
- switch (cmd)
- {
- case DC_SHOOT:
- DC_PUSH(DC_SHUTTER_LED);
-#ifndef DC_SHOOT_ON_BUTTON_RELEASE
- dc_send_shot_position();
-#endif
- break;
-#ifdef DC_ZOOM_IN_LED
- case DC_TALLER:
- DC_PUSH(DC_ZOOM_IN_LED);
- break;
-#endif
-#ifdef DC_ZOOM_OUT_LED
- case DC_WIDER:
- DC_PUSH(DC_ZOOM_OUT_LED);
- break;
-#endif
-#ifdef DC_POWER_LED
- case DC_ON:
- DC_PUSH(DC_POWER_LED);
- break;
-#endif
-#ifdef DC_POWER_OFF_LED
- case DC_OFF:
- DC_PUSH(DC_POWER_OFF_LED);
- dc_timer = DC_POWER_OFF_DELAY;
- break;
-#endif
- default:
- break;
- }
-}
-
-
diff --git a/sw/airborne/modules/digital_cam/led_cam_ctrl.h b/sw/airborne/modules/digital_cam/led_cam_ctrl.h
deleted file mode 100644
index fde5cb4aa7..0000000000
--- a/sw/airborne/modules/digital_cam/led_cam_ctrl.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2010 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 modules/digital_cam/led_cam_ctrl.h
- * @brief Digital Camera Control
- *
- * Provides the control of the shutter and the zoom of a digital camera
- * through standard binary IOs of the board.
- *
- * Configuration:
- * Since the API of led.h is used, connected pins must be defined as led
- * numbers (usually in the airframe file):
- * @verbatim
- *
- *
- *
- *
- *
- * @endverbatim
- * Related bank and pin must also be defined:
- * @verbatim
- *
- *
- * @endverbatim
- * The required initialization (dc_init()) and periodic (4Hz) process
- *
- */
-
-#ifndef LED_CAM_CTRL_H
-#define LED_CAM_CTRL_H
-
-// Include Standard Camera Control Interface
-#include "dc.h"
-
-// Include Digital IO
-#include "led.h"
-
-extern uint8_t dc_timer;
-
-#ifndef DC_PUSH
-#define DC_PUSH LED_ON
-#endif
-
-#ifndef DC_RELEASE
-#define DC_RELEASE LED_OFF
-#endif
-
-#ifndef DC_SHUTTER_DELAY
-#define DC_SHUTTER_DELAY 2 /* 4Hz -> 0.5s */
-#endif
-
-#ifndef DC_POWER_OFF_DELAY
-#define DC_POWER_OFF_DELAY 3
-#endif
-
-#ifndef DC_SHUTTER_LED
-#error DC: Please specify at least a SHUTTER LED
-#endif
-
-static inline void led_cam_ctrl_init(void)
-{
- // Call common DC init
- dc_init();
-
- // Do LED specific DC init
- dc_timer = 0;
-
- DC_RELEASE(DC_SHUTTER_LED);
-#ifdef DC_ZOOM_IN_LED
- DC_RELEASE(DC_ZOOM_IN_LED);
-#endif
-#ifdef DC_ZOOM_OUT_LED
- DC_RELEASE(DC_ZOOM_OUT_LED);
-#endif
-#ifdef DC_POWER_LED
- DC_RELEASE(DC_POWER_LED);
-#endif
-#ifdef DC_POWER_OFF_LED
- DC_RELEASE(DC_POWER_OFF_LED);
-#endif
-}
-
-
-/* 4Hz Periodic */
-static inline void led_cam_ctrl_periodic( void )
-{
-#ifdef DC_SHOOT_ON_BUTTON_RELEASE
- if (dc_timer==1) {
- dc_send_shot_position();
- }
-#endif
-
- if (dc_timer) {
- dc_timer--;
- } else {
- DC_RELEASE(DC_SHUTTER_LED);
-#ifdef DC_ZOOM_IN_LED
- DC_RELEASE(DC_ZOOM_IN_LED);
-#endif
-#ifdef DC_ZOOM_OUT_LED
- DC_RELEASE(DC_ZOOM_OUT_LED);
-#endif
-#ifdef DC_POWER_LED
- DC_RELEASE(DC_POWER_LED);
-#endif
-#ifdef DC_POWER_OFF_LED
- DC_RELEASE(DC_POWER_OFF_LED);
-#endif
- }
-
- // Common DC Periodic task
- dc_periodic_4Hz();
-}
-
-
-
-
-
-#endif // DC_H
diff --git a/sw/airborne/modules/digital_cam/servo_cam_ctrl.h b/sw/airborne/modules/digital_cam/servo_cam_ctrl.h
index 99caa82862..739d6471c9 100644
--- a/sw/airborne/modules/digital_cam/servo_cam_ctrl.h
+++ b/sw/airborne/modules/digital_cam/servo_cam_ctrl.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 The Paparazzi Team
+ * Copyright (C) 2010-2014 The Paparazzi Team
*
* This file is part of paparazzi.
*
@@ -17,36 +17,27 @@
* 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/digital_cam/servo_cam_ctrl.h
* @brief Digital Camera Control
*
* Provides the control of the shutter and the zoom of a digital camera
- * through standard binary IOs of the board.
+ * via servos.
*
- * Configuration:
- * Since the API of led.h is used, connected pins must be defined as led
- * numbers (usually in the airframe file):
- * @verbatim
- *
- *
- *
- *
- * @endverbatim
- * Related bank and pin must also be defined:
- * @verbatim
- *
- *
- * @endverbatim
- * The required initialization (dc_init()) and periodic (4Hz) process
+ * Configuration in airframe file (DC_SHUTTER is mandatory, others optional):
+ * @code{.xml]
+ *
+ *
+ *
+ *
+ * @endcode
*
+ * Provides the required initialization (dc_init()) and periodic (4Hz) process.
*/
-#ifndef servo_cam_ctrl_H
-#define servo_cam_ctrl_H
+#ifndef SERVO_CAM_CTRL_H
+#define SERVO_CAM_CTRL_H
// Include Standard Camera Control Interface
#include "dc.h"
@@ -75,7 +66,7 @@ static inline void servo_cam_ctrl_init(void)
#endif
#ifndef DC_SHUTTER_SERVO
-#error DC: Please specify at least a SHUTTER SERVO
+#error DC: Please specify at least a DC_SHUTTER_SERVO
#endif
@@ -107,8 +98,4 @@ static inline void servo_cam_ctrl_periodic( void )
dc_periodic_4Hz();
}
-
-
-
-
-#endif // DC_H
+#endif // SERVO_CAM_CONTROL_H
diff --git a/sw/airborne/modules/gps/gps_ubx_ucenter.c b/sw/airborne/modules/gps/gps_ubx_ucenter.c
index 41313390a7..8cc26cf9c8 100644
--- a/sw/airborne/modules/gps/gps_ubx_ucenter.c
+++ b/sw/airborne/modules/gps/gps_ubx_ucenter.c
@@ -32,7 +32,7 @@
#include "subsystems/datalink/downlink.h"
#include
-#if DEBUG_GPS_UBX_UCENTER
+#if PRINT_DEBUG_GPS_UBX_UCENTER
#define DEBUG_PRINT(...) printf(__VA_ARGS__)
#else
#define DEBUG_PRINT(...) {}
@@ -102,7 +102,7 @@ void gps_ubx_ucenter_periodic(void)
{
gps_ubx_ucenter.status = GPS_UBX_UCENTER_STATUS_CONFIG;
gps_ubx_ucenter.cnt = 0;
-#if DEBUG_GPS_UBX_UCENTER
+#if PRINT_DEBUG_GPS_UBX_UCENTER
if (gps_ubx_ucenter.baud_init > 0) {
DEBUG_PRINT("Initial ublox baudrate found: %u\n", gps_ubx_ucenter.baud_init);
}
@@ -442,7 +442,7 @@ static bool_t gps_ubx_ucenter_configure(uint8_t nr)
gps_ubx_ucenter_config_port();
break;
case 1:
-#if DEBUG_GPS_UBX_UCENTER
+#if PRINT_DEBUG_GPS_UBX_UCENTER
if (gps_ubx_ucenter.reply != GPS_UBX_UCENTER_REPLY_ACK) {
DEBUG_PRINT("ublox did not acknowledge port configuration.\n");
}
diff --git a/sw/airborne/modules/meteo/meteo_france_DAQ.c b/sw/airborne/modules/meteo/meteo_france_DAQ.c
index 0f3549bd9f..c0eda56ec6 100644
--- a/sw/airborne/modules/meteo/meteo_france_DAQ.c
+++ b/sw/airborne/modules/meteo/meteo_france_DAQ.c
@@ -35,7 +35,6 @@
#include "state.h"
#include "autopilot.h"
-#include "generated/airframe.h"
#include "subsystems/datalink/datalink.h"
#include "subsystems/datalink/downlink.h"
#include "subsystems/chibios-libopencm3/sdLog.h"
@@ -87,7 +86,7 @@ void mf_daq_send_state(void) {
void mf_daq_send_report(void) {
// Send report over normal telemetry
if (mf_daq.nb > 0) {
- DOWNLINK_SEND_PAYLOAD_FLOAT(DefaultChannel, DefaultDevice, mf_daq.nb, mf_daq.values);
+ DOWNLINK_SEND_PAYLOAD_FLOAT(DefaultChannel, DefaultDevice, 9, mf_daq.values);
}
// Test if log is started
if (pprzLogFile.fs != NULL) {
@@ -110,6 +109,7 @@ void mf_daq_send_report(void) {
void parse_mf_daq_msg(void) {
mf_daq.nb = DL_PAYLOAD_FLOAT_values_length(dl_buffer);
if (mf_daq.nb > 0) {
+ if (mf_daq.nb > MF_DAQ_SIZE) mf_daq.nb = MF_DAQ_SIZE;
// Store data struct directly from dl_buffer
memcpy(mf_daq.values, DL_PAYLOAD_FLOAT_values(dl_buffer), mf_daq.nb * sizeof(float));
// Log on SD card
diff --git a/sw/airborne/modules/meteo/meteo_france_DAQ.h b/sw/airborne/modules/meteo/meteo_france_DAQ.h
index 6a852ec4fd..aa2d9da46f 100644
--- a/sw/airborne/modules/meteo/meteo_france_DAQ.h
+++ b/sw/airborne/modules/meteo/meteo_france_DAQ.h
@@ -36,6 +36,7 @@
#include "std.h"
#include "mcu_periph/gpio.h"
+#include "generated/airframe.h"
#define MF_DAQ_SIZE 32
@@ -59,6 +60,7 @@ extern void parse_mf_daq_msg(void);
else { gpio_clear(MF_DAQ_POWER_PORT, MF_DAQ_POWER_PIN); } \
}
#else // POWER PORT and PIN undefined
+INFO("MF_DAQ power pin is not defined");
#define meteo_france_DAQ_SetPower(_x) {}
#endif
diff --git a/sw/airborne/modules/multi/follow.c b/sw/airborne/modules/multi/follow.c
new file mode 100644
index 0000000000..5adfdf6832
--- /dev/null
+++ b/sw/airborne/modules/multi/follow.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2014 Freek van Tienen
+ *
+ * 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 follow.c
+ * \brief Follow a certain AC ID
+ *
+ */
+
+#include "multi/follow.h"
+#include "generated/flight_plan.h"
+#include "generated/airframe.h"
+
+#include "state.h"
+#include "subsystems/ins/ins_int.h"
+#include "navigation.h"
+#include "messages.h"
+#include "dl_protocol.h"
+
+#ifndef FOLLOW_OFFSET_X
+#define FOLLOW_OFFSET_X 0.0
+#endif
+
+#ifndef FOLLOW_OFFSET_Y
+#define FOLLOW_OFFSET_Y 0.0
+#endif
+
+#ifndef FOLLOW_OFFSET_Z
+#define FOLLOW_OFFSET_Z 0.0
+#endif
+
+void follow_init( void ) {
+
+}
+
+void follow_change_wp( unsigned char* buffer ) {
+ struct EcefCoor_i new_pos;
+ struct EnuCoor_i enu;
+ new_pos.x = DL_REMOTE_GPS_ecef_x(buffer);
+ new_pos.y = DL_REMOTE_GPS_ecef_y(buffer);
+ new_pos.z = DL_REMOTE_GPS_ecef_z(buffer);
+
+ // Translate to ENU
+ enu_of_ecef_point_i(&enu, &ins_impl.ltp_def, &new_pos);
+ INT32_VECT3_SCALE_2(enu, enu, INT32_POS_OF_CM_NUM, INT32_POS_OF_CM_DEN);
+
+ // TODO: Add the angle to the north
+
+ // Update the offsets
+ enu.x += POS_BFP_OF_REAL(FOLLOW_OFFSET_X);
+ enu.y += POS_BFP_OF_REAL(FOLLOW_OFFSET_Y);
+ enu.z += POS_BFP_OF_REAL(FOLLOW_OFFSET_Z);
+
+ // TODO: Remove the angle to the north
+
+ // Move the waypoint
+ INT32_VECT3_COPY(waypoints[FOLLOW_WAYPOINT_ID], enu);
+}
diff --git a/sw/airborne/modules/multi/follow.h b/sw/airborne/modules/multi/follow.h
new file mode 100644
index 0000000000..92f3d76f26
--- /dev/null
+++ b/sw/airborne/modules/multi/follow.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2014 Freek van Tienen
+ *
+ * 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 follow.h
+ * \brief Follow a certain AC id
+ */
+
+#ifndef FOLLOW_H
+#define FOLLOW_H
+
+extern void follow_init( void );
+extern void follow_change_wp( unsigned char* buffer );
+
+#define ParseRemoteGps() { \
+ if (DL_REMOTE_GPS_ac_id(dl_buffer) == FOLLOW_AC_ID) { \
+ follow_change_wp(dl_buffer); \
+ } \
+}
+
+#endif // FOLLOW
diff --git a/sw/airborne/modules/multi/formation.c b/sw/airborne/modules/multi/formation.c
index 30d4f0ca89..c56c48b572 100644
--- a/sw/airborne/modules/multi/formation.c
+++ b/sw/airborne/modules/multi/formation.c
@@ -139,7 +139,7 @@ int formation_flight(void) {
stateGetPositionEnu_f()->y += formation[the_acs_id[AC_ID]].north;
}
// set info for this AC
- SetAcInfo(AC_ID, stateGetPositionEnu_f()->x, stateGetPositionEnu_f()->y, (*stateGetHorizontalSpeedDir_f()), stateGetPositionEnu_f()->z, (*stateGetHorizontalSpeedNorm_f()), stateGetSpeedEnu_f()->z, gps.tow);
+ SetAcInfo(AC_ID, stateGetPositionEnu_f()->x, stateGetPositionEnu_f()->y, (*stateGetHorizontalSpeedDir_f()), stateGetPositionUtm_f()->alt, (*stateGetHorizontalSpeedNorm_f()), stateGetSpeedEnu_f()->z, gps.tow);
// broadcast info
uint8_t ac_id = AC_ID;
@@ -185,12 +185,12 @@ int formation_flight(void) {
}
else formation[i].status = ACTIVE;
// compute control if AC is ACTIVE and around the same altitude (maybe not so usefull)
- if (formation[i].status == ACTIVE && fabs(stateGetPositionEnu_f()->z - ac->alt) < form_prox && ac->alt > 0) {
+ if (formation[i].status == ACTIVE && fabs(stateGetPositionUtm_f()->alt - ac->alt) < form_prox && ac->alt > 0) {
form_e += (ac->east + ac->gspeed*sinf(ac->course)*delta_t - stateGetPositionEnu_f()->x)
- (form[i].east - form[the_acs_id[AC_ID]].east);
form_n += (ac->north + ac->gspeed*cosf(ac->course)*delta_t - stateGetPositionEnu_f()->y)
- (form[i].north - form[the_acs_id[AC_ID]].north);
- form_a += (ac->alt - stateGetPositionEnu_f()->z) - (formation[i].alt - formation[the_acs_id[AC_ID]].alt);
+ form_a += (ac->alt - stateGetPositionUtm_f()->alt) - (formation[i].alt - formation[the_acs_id[AC_ID]].alt);
form_speed += ac->gspeed;
//form_speed_e += ac->gspeed * sinf(ac->course);
//form_speed_n += ac->gspeed * cosf(ac->course);
diff --git a/sw/airborne/modules/multi/potential.c b/sw/airborne/modules/multi/potential.c
index d4e3006112..f1756b4d90 100644
--- a/sw/airborne/modules/multi/potential.c
+++ b/sw/airborne/modules/multi/potential.c
@@ -77,7 +77,7 @@ int potential_task(void) {
if (de > FORCE_MAX_DIST || de < -FORCE_MAX_DIST) continue;
float dn = ac->north + cha*delta_t - stateGetPositionEnu_f()->y;
if (dn > FORCE_MAX_DIST || dn < -FORCE_MAX_DIST) continue;
- float da = ac->alt + ac->climb*delta_t - stateGetPositionEnu_f()->z;
+ float da = ac->alt + ac->climb*delta_t - stateGetPositionUtm_f()->alt;
if (da > FORCE_MAX_DIST || da < -FORCE_MAX_DIST) continue;
float dist = sqrtf(de*de + dn*dn + da*da);
if (dist == 0.) continue;
diff --git a/sw/airborne/modules/multi/tcas.c b/sw/airborne/modules/multi/tcas.c
index f55adf0571..819c0e0451 100644
--- a/sw/airborne/modules/multi/tcas.c
+++ b/sw/airborne/modules/multi/tcas.c
@@ -86,7 +86,7 @@ void tcas_init( void ) {
static inline enum tcas_resolve tcas_test_direction(uint8_t id) {
struct ac_info_ * ac = get_ac_info(id);
- float dz = ac->alt - stateGetPositionEnu_f()->z;
+ float dz = ac->alt - stateGetPositionUtm_f()->alt;
if (dz > tcas_alim/2) return RA_DESCEND;
else if (dz < -tcas_alim/2) return RA_CLIMB;
else // AC with the smallest ID descend
@@ -100,7 +100,7 @@ static inline enum tcas_resolve tcas_test_direction(uint8_t id) {
/* conflicts detection and monitoring */
void tcas_periodic_task_1Hz( void ) {
// no TCAS under security_height
- if (stateGetPositionEnu_f()->z < GROUND_ALT + SECURITY_HEIGHT) {
+ if (stateGetPositionUtm_f()->alt < GROUND_ALT + SECURITY_HEIGHT) {
uint8_t i;
for (i = 0; i < NB_ACS; i++) tcas_acs_status[i].status = TCAS_NO_ALARM;
return;
@@ -121,7 +121,7 @@ void tcas_periodic_task_1Hz( void ) {
if (dt > TCAS_DT_MAX) continue; // lost com but keep current status
float dx = the_acs[i].east - stateGetPositionEnu_f()->x;
float dy = the_acs[i].north - stateGetPositionEnu_f()->y;
- float dz = the_acs[i].alt - stateGetPositionEnu_f()->z;
+ float dz = the_acs[i].alt - stateGetPositionUtm_f()->alt;
float dvx = vx - the_acs[i].gspeed * sinf(the_acs[i].course);
float dvy = vy - the_acs[i].gspeed * cosf(the_acs[i].course);
float dvz = stateGetSpeedEnu_f()->z - the_acs[i].climb;
@@ -217,7 +217,7 @@ void tcas_periodic_task_1Hz( void ) {
/* altitude control loop */
void tcas_periodic_task_4Hz( void ) {
// set alt setpoint
- if (stateGetPositionEnu_f()->z > GROUND_ALT + SECURITY_HEIGHT && tcas_status == TCAS_RA) {
+ if (stateGetPositionUtm_f()->alt > GROUND_ALT + SECURITY_HEIGHT && tcas_status == TCAS_RA) {
struct ac_info_ * ac = get_ac_info(tcas_ac_RA);
switch (tcas_resolve) {
case RA_CLIMB :
diff --git a/sw/airborne/modules/nav/nav_bungee_takeoff.c b/sw/airborne/modules/nav/nav_bungee_takeoff.c
index 33488fa8a2..cdae8f0a2e 100644
--- a/sw/airborne/modules/nav/nav_bungee_takeoff.c
+++ b/sw/airborne/modules/nav/nav_bungee_takeoff.c
@@ -208,7 +208,7 @@ bool_t nav_bungee_takeoff_run(void)
nav_route_xy(initialx,initialy,throttlePx,throttlePy);
kill_throttle = 0;
- if((stateGetPositionEnu_f()->z > BungeeAlt+Takeoff_Height-10) && ((*stateGetHorizontalSpeedNorm_f()) > Takeoff_Speed))
+ if((stateGetPositionUtm_f()->alt > BungeeAlt+Takeoff_Height-10) && ((*stateGetHorizontalSpeedNorm_f()) > Takeoff_Speed))
{
CTakeoffStatus = Finished;
return FALSE;
diff --git a/sw/airborne/modules/nav/nav_drop.c b/sw/airborne/modules/nav/nav_drop.c
index 17e436fa60..9bd8b209cb 100644
--- a/sw/airborne/modules/nav/nav_drop.c
+++ b/sw/airborne/modules/nav/nav_drop.c
@@ -45,7 +45,6 @@
#ifndef MASS
#define MASS 3.31e-3
#endif
-
#define ALPHA_M (ALPHA / MASS)
#define DT 0.1
#define MAX_STEPS 100
@@ -101,7 +100,7 @@ static void integrate( uint8_t wp_target ) {
/** Update the RELEASE location with the actual ground speed and altitude */
unit_t nav_drop_update_release( uint8_t wp_target ) {
- nav_drop_z = stateGetPositionEnu_f()->z - waypoints[wp_target].a;
+ nav_drop_z = stateGetPositionUtm_f()->alt - waypoints[wp_target].a;
nav_drop_x = 0.;
nav_drop_y = 0.;
diff --git a/sw/airborne/modules/nav/nav_spiral.c b/sw/airborne/modules/nav/nav_spiral.c
index 5c3703040b..907d3e59c5 100644
--- a/sw/airborne/modules/nav/nav_spiral.c
+++ b/sw/airborne/modules/nav/nav_spiral.c
@@ -67,7 +67,8 @@ bool_t nav_spiral_start(uint8_t center_wp, uint8_t edge_wp, float radius_start,
struct EnuCoor_f pos_enu;
memcpy(&pos_enu, stateGetPositionEnu_f(), sizeof(struct EnuCoor_f));
- VECT3_DIFF(nav_spiral.trans_current, pos_enu, nav_spiral.center);
+ VECT2_DIFF(nav_spiral.trans_current, pos_enu, nav_spiral.center);
+ nav_spiral.trans_current.z = stateGetPositionUtm_f()->alt - nav_spiral.center.z;
nav_spiral.dist_from_center = FLOAT_VECT3_NORM(nav_spiral.trans_current);
@@ -147,7 +148,7 @@ bool_t nav_spiral_run(void)
#ifdef DIGITAL_CAM
if (dc_cam_tracing) {
// calculating Cam angle for camera alignment
- nav_spiral.trans_current.z = pos_enu.z - nav_spiral.center.z;
+ nav_spiral.trans_current.z = stateGetPositionUtm_f()->alt - nav_spiral.center.z;
dc_cam_angle = atan(nav_spiral.radius_start/nav_spiral.trans_current.z) * 180 / M_PI;
}
#endif
diff --git a/sw/airborne/modules/nav/nav_survey_poly_osam.c b/sw/airborne/modules/nav/nav_survey_poly_osam.c
index d3dcb49d70..b805ffc91c 100644
--- a/sw/airborne/modules/nav/nav_survey_poly_osam.c
+++ b/sw/airborne/modules/nav/nav_survey_poly_osam.c
@@ -302,7 +302,7 @@ bool_t nav_survey_poly_osam_run(void)
//follow the circle
nav_circle_XY(C.x, C.y, SurveyRadius);
- if(NavQdrCloseTo(SurveyCircleQdr) && NavCircleCountNoRewind() > .1 && stateGetPositionEnu_f()->z > waypoints[SurveyEntryWP].a-10)
+ if(NavQdrCloseTo(SurveyCircleQdr) && NavCircleCountNoRewind() > .1 && stateGetPositionUtm_f()->alt > waypoints[SurveyEntryWP].a-10)
{
CSurveyStatus = Sweep;
nav_init_stage();
diff --git a/sw/airborne/modules/nav/nav_survey_polygon.c b/sw/airborne/modules/nav/nav_survey_polygon.c
index 3597010842..bd6593326d 100644
--- a/sw/airborne/modules/nav/nav_survey_polygon.c
+++ b/sw/airborne/modules/nav/nav_survey_polygon.c
@@ -240,7 +240,7 @@ bool_t nav_survey_polygon_run(void)
nav_circle_XY(survey.entry_center.x, survey.entry_center.y, -survey.psa_min_rad);
if (NavCourseCloseTo(survey.segment_angle)
&& nav_approaching_xy(survey.seg_start.x, survey.seg_start.y, last_x, last_y, CARROT)
- && fabs(stateGetPositionEnu_f()->z - survey.psa_altitude) <= 20) {
+ && fabs(stateGetPositionUtm_f()->alt - survey.psa_altitude) <= 20) {
survey.stage = SEG;
nav_init_stage();
#ifdef DIGITAL_CAM
diff --git a/sw/airborne/modules/nav/nav_vertical_raster.c b/sw/airborne/modules/nav/nav_vertical_raster.c
index c04705c5ed..63c6ec2f40 100644
--- a/sw/airborne/modules/nav/nav_vertical_raster.c
+++ b/sw/airborne/modules/nav/nav_vertical_raster.c
@@ -105,7 +105,7 @@ bool_t nav_vertical_raster_run(uint8_t l1, uint8_t l2, float radius, float AltSw
break;
case LTC2:
nav_circle_XY(l2_c2.x, l2_c2.y, -radius);
- if (NavQdrCloseTo(DegOfRad(qdr_out_2_2)+10) && stateGetPositionEnu_f()->z >= (waypoints[l1].a-10)) {
+ if (NavQdrCloseTo(DegOfRad(qdr_out_2_2)+10) && stateGetPositionUtm_f()->alt >= (waypoints[l1].a-10)) {
line_status = LQC22;
nav_init_stage();
}
@@ -134,7 +134,7 @@ bool_t nav_vertical_raster_run(uint8_t l1, uint8_t l2, float radius, float AltSw
break;
case LTC1:
nav_circle_XY(l1_c2.x, l1_c2.y, -radius);
- if (NavQdrCloseTo(DegOfRad(qdr_out_2_2 + M_PI)+10) && stateGetPositionEnu_f()->z >= (waypoints[l1].a-5)) {
+ if (NavQdrCloseTo(DegOfRad(qdr_out_2_2 + M_PI)+10) && stateGetPositionUtm_f()->alt >= (waypoints[l1].a-5)) {
line_status = LQC11;
nav_init_stage();
}
diff --git a/sw/airborne/modules/sonar/sonar_adc.c b/sw/airborne/modules/sonar/sonar_adc.c
index 189cf079eb..14268aa27a 100644
--- a/sw/airborne/modules/sonar/sonar_adc.c
+++ b/sw/airborne/modules/sonar/sonar_adc.c
@@ -23,6 +23,7 @@
#include "modules/sonar/sonar_adc.h"
#include "generated/airframe.h"
#include "mcu_periph/adc.h"
+#include "subsystems/abi.h"
#ifdef SITL
#include "state.h"
#endif
@@ -32,11 +33,11 @@
#include "subsystems/datalink/downlink.h"
/** Sonar offset.
- * Offset value in m (float)
- * equals to the height when the ADC gives 0
+ * Offset value in ADC
+ * equals to the ADC value so that height is zero
*/
#ifndef SONAR_OFFSET
-#define SONAR_OFFSET 0.
+#define SONAR_OFFSET 0
#endif
/** Sonar scale.
@@ -46,43 +47,39 @@
#define SONAR_SCALE 0.0166
#endif
-uint16_t sonar_meas;
-bool_t sonar_data_available;
-float sonar_distance;
-float sonar_offset;
-float sonar_scale;
+struct SonarAdc sonar_adc;
#ifndef SITL
-static struct adc_buf sonar_adc;
+static struct adc_buf sonar_adc_buf;
#endif
void sonar_adc_init(void) {
- sonar_meas = 0;
- sonar_data_available = FALSE;
- sonar_distance = 0;
- sonar_offset = SONAR_OFFSET;
- sonar_scale = SONAR_SCALE;
+ sonar_adc.meas = 0;
+ sonar_adc.offset = SONAR_OFFSET;
#ifndef SITL
- adc_buf_channel(ADC_CHANNEL_SONAR, &sonar_adc, DEFAULT_AV_NB_SAMPLE);
+ adc_buf_channel(ADC_CHANNEL_SONAR, &sonar_adc_buf, DEFAULT_AV_NB_SAMPLE);
#endif
}
/** Read ADC value to update sonar measurement
*/
void sonar_adc_read(void) {
+ float sonar_distance;
#ifndef SITL
- sonar_meas = sonar_adc.sum / sonar_adc.av_nb_sample;
- sonar_data_available = TRUE;
- sonar_distance = ((float)sonar_meas * sonar_scale) + sonar_offset;
-
+ sonar_adc.meas = sonar_adc_buf.sum / sonar_adc_buf.av_nb_sample;
+ sonar_distance = (float)(sonar_adc.meas - sonar_adc.offset) * SONAR_SCALE;
#else // SITL
sonar_distance = stateGetPositionEnu_f()->z;
Bound(sonar_distance, 0.1f, 7.0f);
#endif // SITL
+ // Send ABI message
+ AbiSendMsgAGL(AGL_SONAR_ADC_ID, &sonar_distance);
+
#ifdef SENSOR_SYNC_SEND_SONAR
- DOWNLINK_SEND_SONAR(DefaultChannel, DefaultDevice, &sonar_meas, &sonar_distance);
+ // Send Telemetry report
+ DOWNLINK_SEND_SONAR(DefaultChannel, DefaultDevice, &sonar_adc.meas, &sonar_distance);
#endif
}
diff --git a/sw/airborne/modules/sonar/sonar_adc.h b/sw/airborne/modules/sonar/sonar_adc.h
index ec5a8c06cb..1bccbe0ea6 100644
--- a/sw/airborne/modules/sonar/sonar_adc.h
+++ b/sw/airborne/modules/sonar/sonar_adc.h
@@ -29,26 +29,14 @@
#include "std.h"
-/** Raw ADC value.
- */
-extern uint16_t sonar_meas;
+struct SonarAdc {
+ uint16_t meas; ///< Raw ADC value
+ uint16_t offset; ///< Sonar offset in ADC
+};
-/** New data available.
- */
-extern bool_t sonar_data_available;
-
-/** Sonar distance in m.
- */
-extern float sonar_distance;
+extern struct SonarAdc sonar_adc;
extern void sonar_adc_init(void);
extern void sonar_adc_read(void);
-#define SonarEvent(_handler) { \
- if (sonar_data_available) { \
- _handler(); \
- sonar_data_available = FALSE; \
- } \
-}
-
#endif
diff --git a/sw/airborne/state.h b/sw/airborne/state.h
index ee1436f1c4..6f9cd473f2 100644
--- a/sw/airborne/state.h
+++ b/sw/airborne/state.h
@@ -442,7 +442,7 @@ static inline void stateSetLocalOrigin_i(struct LtpDef_i* ltp_def) {
/* convert to float */
ECEF_FLOAT_OF_BFP(state.ned_origin_f.ecef, state.ned_origin_i.ecef);
LLA_FLOAT_OF_BFP(state.ned_origin_f.lla, state.ned_origin_i.lla);
- RMAT_FLOAT_OF_BFP(state.ned_origin_f.ltp_of_ecef, state.ned_origin_i.ltp_of_ecef);
+ HIGH_RES_RMAT_FLOAT_OF_BFP(state.ned_origin_f.ltp_of_ecef, state.ned_origin_i.ltp_of_ecef);
state.ned_origin_f.hmsl = M_OF_MM(state.ned_origin_i.hmsl);
/* clear bits for all local frame representations */
diff --git a/sw/airborne/subsystems/abi_sender_ids.h b/sw/airborne/subsystems/abi_sender_ids.h
index f87b5298b8..b4f29738d5 100644
--- a/sw/airborne/subsystems/abi_sender_ids.h
+++ b/sw/airborne/subsystems/abi_sender_ids.h
@@ -76,4 +76,16 @@
#define BARO_SIM_SENDER_ID 19
#endif
+/*
+ * IDs of AGL measurment modules that can be loaded (sonars,...)
+ */
+#ifndef AGL_SONAR_ADC_ID
+#define AGL_SONAR_ADC_ID 1
+#endif
+
+#ifndef AGL_SONAR_ARDRONE2_ID
+#define AGL_SONAR_ARDRONE2_ID 2
+#endif
+
+
#endif /* ABI_SENDER_IDS_H */
diff --git a/sw/airborne/subsystems/actuators/actuators_dualpwm.h b/sw/airborne/subsystems/actuators/actuators_dualpwm.h
new file mode 100644
index 0000000000..46e6c52b3e
--- /dev/null
+++ b/sw/airborne/subsystems/actuators/actuators_dualpwm.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#ifndef ACTUATORS_dualpwm_H
+#define ACTUATORS_dualpwm_H
+
+#include "subsystems/actuators/actuators_dualpwm_arch.h"
+
+/** Arch dependent init file.
+ * implemented in arch files
+ */
+extern void actuators_dualpwm_arch_init(void);
+
+#define ActuatorsDualpwmInit() actuators_dualpwm_arch_init()
+
+#endif /* ACTUATORS_PWM_H */
diff --git a/sw/airborne/subsystems/actuators/motor_mixing.c b/sw/airborne/subsystems/actuators/motor_mixing.c
index 9cd978f250..c96812cc78 100644
--- a/sw/airborne/subsystems/actuators/motor_mixing.c
+++ b/sw/airborne/subsystems/actuators/motor_mixing.c
@@ -93,6 +93,7 @@ void motor_mixing_init(void) {
motor_mixing.override_value[i] = MOTOR_MIXING_STOP_MOTOR;
}
motor_mixing.nb_failure = 0;
+ motor_mixing.nb_saturation = 0;
}
__attribute__ ((always_inline)) static inline void offset_commands(int32_t offset) {
@@ -157,7 +158,11 @@ void motor_mixing_run_spinup(uint32_t counter, uint32_t max_counter)
void motor_mixing_run(bool_t motors_on, bool_t override_on, pprz_t in_cmd[] ) {
uint8_t i;
+#if !HITL
if (motors_on) {
+#else
+ if (FALSE) {
+#endif
int32_t min_cmd = INT32_MAX;
int32_t max_cmd = INT32_MIN;
/* do the mixing in float to avoid overflows, implicitly casted back to int32_t */
@@ -186,11 +191,13 @@ void motor_mixing_run(bool_t motors_on, bool_t override_on, pprz_t in_cmd[] ) {
int32_t saturation_offset = MOTOR_MIXING_MAX_MOTOR - max_cmd;
BoundAbs(saturation_offset, MOTOR_MIXING_MAX_SATURATION_OFFSET);
offset_commands(saturation_offset);
+ motor_mixing.nb_saturation++;
}
else if (min_cmd < MOTOR_MIXING_MIN_MOTOR) {
int32_t saturation_offset = MOTOR_MIXING_MIN_MOTOR - min_cmd;
BoundAbs(saturation_offset, MOTOR_MIXING_MAX_SATURATION_OFFSET);
offset_commands(saturation_offset);
+ motor_mixing.nb_saturation++;
}
/* For testing motor failure */
diff --git a/sw/airborne/subsystems/actuators/motor_mixing.h b/sw/airborne/subsystems/actuators/motor_mixing.h
index 3283983c3e..e62027609a 100644
--- a/sw/airborne/subsystems/actuators/motor_mixing.h
+++ b/sw/airborne/subsystems/actuators/motor_mixing.h
@@ -37,6 +37,7 @@ struct MotorMixing {
int32_t trim[MOTOR_MIXING_NB_MOTOR];
bool_t override_enabled[MOTOR_MIXING_NB_MOTOR];
int32_t override_value[MOTOR_MIXING_NB_MOTOR];
+ uint32_t nb_saturation;
uint32_t nb_failure;
};
diff --git a/sw/airborne/subsystems/ahrs/ahrs_int_cmpl_quat.c b/sw/airborne/subsystems/ahrs/ahrs_int_cmpl_quat.c
index 2216644305..f10bcfd9e5 100644
--- a/sw/airborne/subsystems/ahrs/ahrs_int_cmpl_quat.c
+++ b/sw/airborne/subsystems/ahrs/ahrs_int_cmpl_quat.c
@@ -272,7 +272,7 @@ void ahrs_set_accel_gains(void) {
*/
ahrs_impl.accel_inv_kp = 4096 * 9.81 /
(2 * ahrs_impl.accel_omega * ahrs_impl.accel_zeta *
- AHRS_PROPAGATE_FREQUENCY / AHRS_PROPAGATE_FREQUENCY);
+ AHRS_PROPAGATE_FREQUENCY / AHRS_CORRECT_FREQUENCY);
/* Complementary filter integral gain
* Ki = omega^2 / AHRS_CORRECT_FREQUENCY
@@ -547,8 +547,8 @@ void ahrs_update_gps(void) {
#endif
#if AHRS_USE_GPS_HEADING && USE_GPS
- //got a 3d fix,ground speed > 0.5 m/s and course accuracy is better than 10deg
- if(gps.fix == GPS_FIX_3D &&
+ //got a 3d fix, ground speed > 5.0 m/s and course accuracy is better than 10deg
+ if (gps.fix == GPS_FIX_3D &&
gps.gspeed >= 500 &&
gps.cacc <= RadOfDeg(10*1e7)) {
diff --git a/sw/airborne/subsystems/datalink/Makefile b/sw/airborne/subsystems/datalink/Makefile
index 467f254a15..f6a3891f8e 100644
--- a/sw/airborne/subsystems/datalink/Makefile
+++ b/sw/airborne/subsystems/datalink/Makefile
@@ -48,6 +48,7 @@ EXPORT_FILES = \
transport.h \
datalink.h \
$(PAPARAZZI_SRC)/sw/include/std.h \
+ $(PAPARAZZI_SRC)/sw/include/message_pragmas.h \
$(PAPARAZZI_HOME)/var/include/messages.h \
$(PAPARAZZI_HOME)/var/include/dl_protocol.h
diff --git a/sw/airborne/subsystems/datalink/superbitrf.c b/sw/airborne/subsystems/datalink/superbitrf.c
index dca6705d1d..e44cf6983d 100644
--- a/sw/airborne/subsystems/datalink/superbitrf.c
+++ b/sw/airborne/subsystems/datalink/superbitrf.c
@@ -28,6 +28,7 @@
#include
#include "paparazzi.h"
+#include "led.h"
#include "mcu_periph/spi.h"
#include "mcu_periph/sys_time.h"
#include "mcu_periph/gpio.h"
@@ -232,6 +233,10 @@ void superbitrf_event(void) {
static uint8_t packet_size, tx_packet[16];
static bool_t start_transfer = TRUE;
+#ifdef RADIO_CONTROL_LED
+ static uint32_t slowLedCpt = 0;
+#endif
+
// Check if the cyrf6936 isn't busy and the uperbitrf is initialized
if(superbitrf.cyrf6936.status != CYRF6936_IDLE)
return;
@@ -322,6 +327,16 @@ void superbitrf_event(void) {
/* When the superbitrf is in binding mode */
case SUPERBITRF_BINDING:
+
+#ifdef RADIO_CONTROL_LED
+ slowLedCpt++;
+ if(slowLedCpt>100000){
+
+ LED_TOGGLE(RADIO_CONTROL_LED);
+ slowLedCpt = 0;
+ }
+#endif
+
/* Switch the different states */
switch (superbitrf.state) {
case 0:
@@ -396,6 +411,16 @@ void superbitrf_event(void) {
/* When the receiver is synchronizing with the transmitter */
case SUPERBITRF_SYNCING_A:
case SUPERBITRF_SYNCING_B:
+
+#ifdef RADIO_CONTROL_LED
+ slowLedCpt++;
+ if(slowLedCpt>5000){
+
+ LED_TOGGLE(RADIO_CONTROL_LED);
+ slowLedCpt = 0;
+ }
+#endif
+
/* Switch the different states */
switch (superbitrf.state) {
case 0:
@@ -499,6 +524,11 @@ void superbitrf_event(void) {
/* Normal transfer mode */
case SUPERBITRF_TRANSFER:
+
+#ifdef RADIO_CONTROL_LED
+ LED_ON(RADIO_CONTROL_LED);
+#endif
+
/* Switch the different states */
switch (superbitrf.state) {
case 0:
diff --git a/sw/airborne/subsystems/datalink/udp.c b/sw/airborne/subsystems/datalink/udp.c
index 88ab870c1d..264a508294 100644
--- a/sw/airborne/subsystems/datalink/udp.c
+++ b/sw/airborne/subsystems/datalink/udp.c
@@ -67,28 +67,29 @@ void udp_receive( void ) {
}
//Read from the network
- network_read(network, udp_read_buffer, TRANSPORT_PAYLOAD_LEN);
+ uint16_t read = network_read(network, udp_read_buffer, TRANSPORT_PAYLOAD_LEN);
+ if(read > 0) {
- //Parse the packet
- if(udp_read_buffer[0] == STX) {
- uint8_t size = udp_read_buffer[1]-4; // minus STX, LENGTH, CK_A, CK_B
- uint8_t ck_aa, ck_bb;
- ck_aa = ck_bb = size+4;
+ //Parse the packet
+ if(udp_read_buffer[0] == STX) {
+ uint8_t size = udp_read_buffer[1]-4; // minus STX, LENGTH, CK_A, CK_B
+ uint8_t ck_aa, ck_bb;
+ ck_aa = ck_bb = size+4;
- // index-offset plus 2 for STX and LENGTH
- for (int i = 2; i < size+2; i++) {
- dl_buffer[i-2] = udp_read_buffer[i];
- ck_aa += udp_read_buffer[i];
- ck_bb += ck_aa;
- }
-
- // if both checksums are good, tell datalink that the message is available
- if (udp_read_buffer[2+size] == ck_aa && udp_read_buffer[2+size+1] == ck_bb) {
- dl_msg_available = TRUE;
+ // index-offset plus 2 for STX and LENGTH
+ for (int i = 2; i < size+2; i++) {
+ dl_buffer[i-2] = udp_read_buffer[i];
+ ck_aa += udp_read_buffer[i];
+ ck_bb += ck_aa;
+ }
+
+ // if both checksums are good, tell datalink that the message is available
+ if (udp_read_buffer[2+size] == ck_aa && udp_read_buffer[2+size+1] == ck_bb) {
+ dl_msg_available = TRUE;
+ }
}
+ memset(&udp_read_buffer[0], 0, sizeof(udp_read_buffer));
}
-
- memset(&udp_read_buffer[0], 0, sizeof(udp_read_buffer));
}
diff --git a/sw/airborne/subsystems/gps/gps_datalink.c b/sw/airborne/subsystems/gps/gps_datalink.c
new file mode 100644
index 0000000000..09987daeeb
--- /dev/null
+++ b/sw/airborne/subsystems/gps/gps_datalink.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2014 Freek van Tienen
+ *
+ * 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 gps_datalink.c
+ * @brief GPS system based on datalink
+ *
+ * This GPS parses the datalink REMOTE_GPS packet and sets the
+ * GPS structure to the values received.
+ */
+
+#include "subsystems/gps.h"
+
+bool_t gps_available; ///< Is set to TRUE when a new REMOTE_GPS packet is received and parsed
+
+/** GPS initialization */
+void gps_impl_init(void) {
+ gps.fix = GPS_FIX_NONE;
+ gps_available = FALSE;
+ gps.gspeed = 700; // To enable course setting
+ gps.cacc = 0; // To enable course setting
+}
+
+/** Parse the REMOTE_GPS datalink packet */
+void parse_gps_datalink(uint8_t numsv, int32_t ecef_x, int32_t ecef_y, int32_t ecef_z, int32_t lat, int32_t lon, int32_t alt,
+ int32_t hmsl, int32_t ecef_xd, int32_t ecef_yd, int32_t ecef_zd, uint32_t tow, int32_t course) {
+
+ gps.lla_pos.lat = RadOfDeg(lat);
+ gps.lla_pos.lon = RadOfDeg(lon);
+ gps.lla_pos.alt = alt;
+ gps.hmsl = hmsl;
+
+ gps.ecef_pos.x = ecef_x;
+ gps.ecef_pos.y = ecef_y;
+ gps.ecef_pos.z = ecef_z;
+
+ gps.ecef_vel.x = ecef_xd;
+ gps.ecef_vel.y = ecef_yd;
+ gps.ecef_vel.z = ecef_zd;
+
+ gps.course = course;
+ gps.num_sv = numsv;
+ gps.tow = tow;
+ gps.fix = GPS_FIX_3D;
+ gps_available = TRUE;
+
+#if GPS_USE_LATLONG
+ // Computes from (lat, long) in the referenced UTM zone
+ struct LlaCoor_f lla_f;
+ lla_f.lat = ((float) gps.lla_pos.lat) / 1e7;
+ lla_f.lon = ((float) gps.lla_pos.lon) / 1e7;
+ struct UtmCoor_f utm_f;
+ utm_f.zone = nav_utm_zone0;
+ // convert to utm
+ utm_of_lla_f(&utm_f, &lla_f);
+ // copy results of utm conversion
+ gps.utm_pos.east = utm_f.east*100;
+ gps.utm_pos.north = utm_f.north*100;
+ gps.utm_pos.alt = gps.lla_pos.alt;
+ gps.utm_pos.zone = nav_utm_zone0;
+#endif
+}
+
diff --git a/sw/airborne/subsystems/gps/gps_datalink.h b/sw/airborne/subsystems/gps/gps_datalink.h
new file mode 100644
index 0000000000..3eb1800844
--- /dev/null
+++ b/sw/airborne/subsystems/gps/gps_datalink.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2014 Freek van Tienen
+ *
+ * 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 gps_datalink.h
+ * @brief GPS system based on datalink
+ *
+ * This GPS parses the datalink REMOTE_GPS packet and sets the
+ * GPS structure to the values received.
+ */
+
+#ifndef GPS_DATALINK_H
+#define GPS_DATALINK_H
+
+#include "std.h"
+#define GPS_NB_CHANNELS 0
+
+extern bool_t gps_available;
+extern void parse_gps_datalink(uint8_t numsv, int32_t ecef_x, int32_t ecef_y, int32_t ecef_z, int32_t lat, int32_t lon, int32_t alt,
+ int32_t hmsl, int32_t ecef_xd, int32_t ecef_yd, int32_t ecef_zd, uint32_t tow, int32_t course);
+
+
+#define GpsEvent(_sol_available_callback) { \
+ if (gps_available) { \
+ gps.last_msg_ticks = sys_time.nb_sec_rem; \
+ gps.last_msg_time = sys_time.nb_sec; \
+ if (gps.fix == GPS_FIX_3D) { \
+ gps.last_3dfix_ticks = sys_time.nb_sec_rem; \
+ gps.last_3dfix_time = sys_time.nb_sec; \
+ } \
+ _sol_available_callback(); \
+ gps_available = FALSE; \
+ } \
+ }
+
+
+#endif /* GPS_DATALINK_H */
diff --git a/sw/airborne/subsystems/gps/gps_sim_hitl.c b/sw/airborne/subsystems/gps/gps_sim_hitl.c
new file mode 100644
index 0000000000..87ed9082a9
--- /dev/null
+++ b/sw/airborne/subsystems/gps/gps_sim_hitl.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2014 Sergey Krukowski
+ *
+ * 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/gps/gps_sim_hitl.c
+ * GPS subsystem simulation from rotorcrafts horizontal/vertical reference system
+ */
+
+#include "subsystems/gps.h"
+
+bool_t gps_available;
+uint32_t gps_sim_hitl_timer;
+
+void gps_impl_init(void) {
+ gps.fix = GPS_FIX_NONE;
+ gps_available = FALSE;
+}
diff --git a/sw/airborne/subsystems/gps/gps_sim_hitl.h b/sw/airborne/subsystems/gps/gps_sim_hitl.h
new file mode 100644
index 0000000000..b3e6395bc4
--- /dev/null
+++ b/sw/airborne/subsystems/gps/gps_sim_hitl.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 Sergey Krukowski
+ *
+ * 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/gps/gps_sim_hitl.h
+ * GPS subsystem simulation from rotorcrafts horizontal/vertical reference system
+ */
+
+#ifndef GPS_SIM_HITL_H
+#define GPS_SIM_HITL_H
+
+#include "std.h"
+#include "state.h"
+#include "guidance/guidance_h.h"
+#include "guidance/guidance_v.h"
+
+extern bool_t gps_available;
+extern uint32_t gps_sim_hitl_timer;
+
+#define GpsEvent(_sol_available_callback) { \
+ if (SysTimeTimer(gps_sim_hitl_timer) > 100000) { \
+ SysTimeTimerStart(gps_sim_hitl_timer); \
+ gps.last_msg_ticks = sys_time.nb_sec_rem; \
+ gps.last_msg_time = sys_time.nb_sec; \
+ if (state.ned_initialized_i) { \
+ if (!autopilot_in_flight) { \
+ struct Int32Vect2 zero_vector; \
+ INT_VECT2_ZERO(zero_vector); \
+ gh_set_ref(zero_vector, zero_vector, zero_vector); \
+ INT_VECT2_ZERO(guidance_h_pos_ref); \
+ INT_VECT2_ZERO(guidance_h_speed_ref); \
+ INT_VECT2_ZERO(guidance_h_accel_ref); \
+ gv_set_ref(0, 0, 0); \
+ guidance_v_z_ref = 0; \
+ guidance_v_zd_ref = 0; \
+ guidance_v_zdd_ref = 0; \
+ } \
+ struct NedCoor_i ned_c; \
+ ned_c.x = guidance_h_pos_ref.x * INT32_POS_OF_CM_DEN / INT32_POS_OF_CM_NUM; \
+ ned_c.y = guidance_h_pos_ref.y * INT32_POS_OF_CM_DEN / INT32_POS_OF_CM_NUM; \
+ ned_c.z = guidance_v_z_ref * INT32_POS_OF_CM_DEN / INT32_POS_OF_CM_NUM; \
+ ecef_of_ned_point_i(&gps.ecef_pos, &state.ned_origin_i, &ned_c); \
+ gps.lla_pos.alt = state.ned_origin_i.lla.alt - ned_c.z; \
+ gps.hmsl = state.ned_origin_i.hmsl - ned_c.z; \
+ ned_c.x = guidance_h_speed_ref.x * INT32_SPEED_OF_CM_S_DEN / INT32_SPEED_OF_CM_S_NUM; \
+ ned_c.y = guidance_h_speed_ref.y * INT32_SPEED_OF_CM_S_DEN / INT32_SPEED_OF_CM_S_NUM; \
+ ned_c.z = guidance_v_zd_ref * INT32_SPEED_OF_CM_S_DEN / INT32_SPEED_OF_CM_S_NUM; \
+ ecef_of_ned_vect_i(&gps.ecef_vel, &state.ned_origin_i, &ned_c); \
+ gps.fix = GPS_FIX_3D; \
+ gps.last_3dfix_ticks = sys_time.nb_sec_rem; \
+ gps.last_3dfix_time = sys_time.nb_sec; \
+ gps_available = TRUE; \
+ } \
+ else { \
+ struct Int32Vect2 zero_vector; \
+ INT_VECT2_ZERO(zero_vector); \
+ gh_set_ref(zero_vector, zero_vector, zero_vector); \
+ gv_set_ref(0, 0, 0); \
+ } \
+ _sol_available_callback(); \
+ gps_available = FALSE; \
+ } \
+ }
+
+#endif /* GPS_SIM_HITL_H */
diff --git a/sw/airborne/subsystems/ins.c b/sw/airborne/subsystems/ins.c
index e99e8d0b84..c60ddc05fd 100644
--- a/sw/airborne/subsystems/ins.c
+++ b/sw/airborne/subsystems/ins.c
@@ -64,8 +64,5 @@ void WEAK ins_reset_utm_zone(struct UtmCoor_f * utm __attribute__((unused))) {}
void WEAK ins_propagate(void) {}
-void WEAK ins_update_baro(void) {}
-
void WEAK ins_update_gps(void) {}
-void WEAK ins_update_sonar(void) {}
diff --git a/sw/airborne/subsystems/ins.h b/sw/airborne/subsystems/ins.h
index 899eeb70dc..dbc8d500ea 100644
--- a/sw/airborne/subsystems/ins.h
+++ b/sw/airborne/subsystems/ins.h
@@ -86,21 +86,10 @@ extern void ins_reset_utm_zone(struct UtmCoor_f * utm);
*/
extern void ins_propagate(void);
-/** Update INS state with barometer measurements.
- * Does nothing if not implemented by specific INS algorithm.
- */
-extern void ins_update_baro(void);
-
/** Update INS state with GPS measurements.
* Reads the global #gps data struct.
* Does nothing if not implemented by specific INS algorithm.
*/
extern void ins_update_gps(void);
-/** Update INS state with sonar measurements.
- * Does nothing if not implemented by specific INS algorithm.
- */
-extern void ins_update_sonar(void);
-
-
#endif /* INS_H */
diff --git a/sw/airborne/subsystems/ins/hf_float.c b/sw/airborne/subsystems/ins/hf_float.c
index 27cc1c5de3..3c6d44506d 100644
--- a/sw/airborne/subsystems/ins/hf_float.c
+++ b/sw/airborne/subsystems/ins/hf_float.c
@@ -32,7 +32,7 @@
#include "state.h"
#include "subsystems/gps.h"
#include
-
+#include "filters/low_pass_filter.h"
#include "generated/airframe.h"
#ifdef SITL
@@ -71,6 +71,11 @@
#define HFF_R_SPEED_MIN 1.
#endif
+/* low pass filter variables */
+Butterworth2LowPass_int filter_x;
+Butterworth2LowPass_int filter_y;
+Butterworth2LowPass_int filter_z;
+
/* gps measurement noise */
float Rgps_pos, Rgps_vel;
@@ -100,54 +105,6 @@ float b2_hff_y_meas;
/* counter for hff propagation*/
int b2_hff_ps_counter;
-
-/*
- * accel(in body frame) buffer
- */
-#define ACC_RB_MAXN 64
-struct AccBuf {
- struct Int32Vect3 buf[ACC_RB_MAXN];
- int r; /* pos to read from, oldest measurement */
- int w; /* pos to write to */
- int n; /* number of elements in rb */
- int size;
-};
-struct AccBuf acc_body;
-struct Int32Vect3 acc_body_mean;
-
-void b2_hff_store_accel_body(void) {
- INT32_RMAT_TRANSP_VMULT(acc_body.buf[acc_body.w], imu.body_to_imu_rmat, imu.accel);
- acc_body.w = (acc_body.w + 1) < acc_body.size ? (acc_body.w + 1) : 0;
-
- /* once the buffer is full it always has the last acc_body.size accel measurements */
- if (acc_body.n < acc_body.size) {
- acc_body.n++;
- } else {
- acc_body.r = (acc_body.r + 1) < acc_body.size ? (acc_body.r + 1) : 0;
- }
-}
-
-/** compute the mean of the last n accel measurements */
-static inline void b2_hff_compute_accel_body_mean(uint8_t n) {
- struct Int32Vect3 sum;
- int i, j;
-
- INT_VECT3_ZERO(sum);
-
- if (n > 1) {
- if (n > acc_body.n) {
- n = acc_body.n;
- }
- for (i = 1; i <= n; i++) {
- j = (acc_body.w - i) > 0 ? (acc_body.w - i) : (acc_body.w - i + acc_body.size);
- VECT3_ADD(sum, acc_body.buf[j]);
- }
- VECT3_SDIV(acc_body_mean, sum, n);
- } else {
- VECT3_COPY(acc_body_mean, sum);
- }
-}
-
/*
* For GPS lag compensation
*
@@ -216,25 +173,24 @@ uint16_t b2_hff_lost_limit;
uint16_t b2_hff_lost_counter;
#ifdef GPS_LAG
-static inline void b2_hff_get_past_accel(unsigned int back_n);
-static inline void b2_hff_rb_put_state(struct HfilterFloat* source);
-static inline void b2_hff_rb_drop_last(void);
-static inline void b2_hff_set_state(struct HfilterFloat* dest, struct HfilterFloat* source);
+static void b2_hff_get_past_accel(unsigned int back_n);
+static void b2_hff_rb_put_state(struct HfilterFloat* source);
+static void b2_hff_rb_drop_last(void);
+static void b2_hff_set_state(struct HfilterFloat* dest, struct HfilterFloat* source);
#endif
+static void b2_hff_init_x(float init_x, float init_xdot);
+static void b2_hff_init_y(float init_y, float init_ydot);
-static inline void b2_hff_init_x(float init_x, float init_xdot);
-static inline void b2_hff_init_y(float init_y, float init_ydot);
+static void b2_hff_propagate_x(struct HfilterFloat* hff_work);
+static void b2_hff_propagate_y(struct HfilterFloat* hff_work);
-static inline void b2_hff_propagate_x(struct HfilterFloat* hff_work);
-static inline void b2_hff_propagate_y(struct HfilterFloat* hff_work);
+static void b2_hff_update_x(struct HfilterFloat* hff_work, float x_meas, float Rpos);
+static void b2_hff_update_y(struct HfilterFloat* hff_work, float y_meas, float Rpos);
-static inline void b2_hff_update_x(struct HfilterFloat* hff_work, float x_meas, float Rpos);
-static inline void b2_hff_update_y(struct HfilterFloat* hff_work, float y_meas, float Rpos);
-
-static inline void b2_hff_update_xdot(struct HfilterFloat* hff_work, float vel, float Rvel);
-static inline void b2_hff_update_ydot(struct HfilterFloat* hff_work, float vel, float Rvel);
+static void b2_hff_update_xdot(struct HfilterFloat* hff_work, float vel, float Rvel);
+static void b2_hff_update_ydot(struct HfilterFloat* hff_work, float vel, float Rvel);
#if PERIODIC_TELEMETRY
#include "subsystems/datalink/telemetry.h"
@@ -277,11 +233,6 @@ void b2_hff_init(float init_x, float init_xdot, float init_y, float init_ydot) {
Rgps_vel = HFF_R_SPEED;
b2_hff_init_x(init_x, init_xdot);
b2_hff_init_y(init_y, init_ydot);
- /* init buffer for mean accel calculation */
- acc_body.r = 0;
- acc_body.w = 0;
- acc_body.n = 0;
- acc_body.size = ACC_RB_MAXN;
#ifdef GPS_LAG
/* init buffer for past mean accel values */
acc_buf_r = 0;
@@ -319,9 +270,13 @@ void b2_hff_init(float init_x, float init_xdot, float init_y, float init_ydot) {
register_periodic_telemetry(DefaultPeriodic, "HFF_GPS", send_hff_gps);
#endif
#endif
+
+ init_butterworth_2_low_pass_int(&filter_x, 14., (1. /AHRS_PROPAGATE_FREQUENCY), 0);
+ init_butterworth_2_low_pass_int(&filter_y, 14., (1. /AHRS_PROPAGATE_FREQUENCY), 0);
+ init_butterworth_2_low_pass_int(&filter_z, 14., (1. /AHRS_PROPAGATE_FREQUENCY), 0);
}
-static inline void b2_hff_init_x(float init_x, float init_xdot) {
+static void b2_hff_init_x(float init_x, float init_xdot) {
b2_hff_state.x = init_x;
b2_hff_state.xdot = init_xdot;
int i, j;
@@ -330,10 +285,9 @@ static inline void b2_hff_init_x(float init_x, float init_xdot) {
b2_hff_state.xP[i][j] = 0.;
b2_hff_state.xP[i][i] = INIT_PXX;
}
-
}
-static inline void b2_hff_init_y(float init_y, float init_ydot) {
+static void b2_hff_init_y(float init_y, float init_ydot) {
b2_hff_state.y = init_y;
b2_hff_state.ydot = init_ydot;
int i, j;
@@ -345,7 +299,7 @@ static inline void b2_hff_init_y(float init_y, float init_ydot) {
}
#ifdef GPS_LAG
-static inline void b2_hff_store_accel_ltp(float x, float y) {
+static void b2_hff_store_accel_ltp(float x, float y) {
past_accel[acc_buf_w].x = x;
past_accel[acc_buf_w].y = y;
INC_ACC_IDX(acc_buf_w);
@@ -358,7 +312,7 @@ static inline void b2_hff_store_accel_ltp(float x, float y) {
}
/* get the accel values from back_n steps ago */
-static inline void b2_hff_get_past_accel(unsigned int back_n) {
+static void b2_hff_get_past_accel(unsigned int back_n) {
int i;
if (back_n > acc_buf_n) {
PRINT_DBG(1, ("Cannot go back %d steps, going back only %d instead!\n", back_n, acc_buf_n));
@@ -376,7 +330,7 @@ static inline void b2_hff_get_past_accel(unsigned int back_n) {
PRINT_DBG(3, ("get past accel. buf_n: %2d \tbuf_w: %2d \tback_n: %2d \ti: %2d \txdd: %f \tydd: %f\n", acc_buf_n, acc_buf_w, back_n, i, b2_hff_xdd_meas, b2_hff_ydd_meas));
}
-static inline void b2_hff_rb_put_state(struct HfilterFloat* source) {
+static void b2_hff_rb_put_state(struct HfilterFloat* source) {
/* copy state from source into buffer */
b2_hff_set_state(b2_hff_rb_put, source);
b2_hff_rb_put->lag_counter = 0;
@@ -394,7 +348,7 @@ static inline void b2_hff_rb_put_state(struct HfilterFloat* source) {
PRINT_DBG(2, ("put state. fill count now: %d\n", b2_hff_rb_n));
}
-static inline void b2_hff_rb_drop_last(void) {
+static void b2_hff_rb_drop_last(void) {
if (b2_hff_rb_n > 0) {
INC_RB_POINTER(b2_hff_rb_last);
b2_hff_rb_n--;
@@ -406,9 +360,8 @@ static inline void b2_hff_rb_drop_last(void) {
PRINT_DBG(2, ("drop last state. fill count now: %d\n", b2_hff_rb_n));
}
-
/* copy source state to dest state */
-static inline void b2_hff_set_state(struct HfilterFloat* dest, struct HfilterFloat* source) {
+static void b2_hff_set_state(struct HfilterFloat* dest, struct HfilterFloat* source) {
dest->x = source->x;
dest->xdot = source->xdot;
dest->xdotdot = source->xdotdot;
@@ -423,7 +376,7 @@ static inline void b2_hff_set_state(struct HfilterFloat* dest, struct HfilterFlo
}
}
-static inline void b2_hff_propagate_past(struct HfilterFloat* hff_past) {
+static void b2_hff_propagate_past(struct HfilterFloat* hff_past) {
PRINT_DBG(1, ("enter propagate past: %d\n", hff_past->lag_counter));
/* run max MAX_PP_STEPS propagation steps */
for (int i=0; i < MAX_PP_STEPS; i++) {
@@ -463,7 +416,6 @@ static inline void b2_hff_propagate_past(struct HfilterFloat* hff_past) {
#endif /* GPS_LAG */
-
void b2_hff_propagate(void) {
if (b2_hff_lost_counter < b2_hff_lost_limit)
b2_hff_lost_counter++;
@@ -475,25 +427,27 @@ void b2_hff_propagate(void) {
}
#endif
- /* store body accelerations for mean computation */
- b2_hff_store_accel_body();
+ /* rotate imu accel measurement to body frame and filter */
+ struct Int32Vect3 acc_meas_body;
+ INT32_RMAT_TRANSP_VMULT(acc_meas_body, imu.body_to_imu_rmat, imu.accel);
+
+ struct Int32Vect3 acc_body_filtered;
+ acc_body_filtered.x = update_butterworth_2_low_pass_int(&filter_x, acc_meas_body.x);
+ acc_body_filtered.y = update_butterworth_2_low_pass_int(&filter_y, acc_meas_body.y);
+ acc_body_filtered.z = update_butterworth_2_low_pass_int(&filter_z, acc_meas_body.z);
/* propagate current state if it is time */
if (b2_hff_ps_counter == HFF_PRESCALER) {
b2_hff_ps_counter = 1;
-
if (b2_hff_lost_counter < b2_hff_lost_limit) {
- /* compute float ltp mean acceleration */
- b2_hff_compute_accel_body_mean(HFF_PRESCALER);
- struct Int32Vect3 mean_accel_ltp;
+ struct Int32Vect3 filtered_accel_ltp;
struct Int32RMat* ltp_to_body_rmat = stateGetNedToBodyRMat_i();
- INT32_RMAT_TRANSP_VMULT(mean_accel_ltp, (*ltp_to_body_rmat), acc_body_mean);
- b2_hff_xdd_meas = ACCEL_FLOAT_OF_BFP(mean_accel_ltp.x);
- b2_hff_ydd_meas = ACCEL_FLOAT_OF_BFP(mean_accel_ltp.y);
+ INT32_RMAT_TRANSP_VMULT(filtered_accel_ltp, (*ltp_to_body_rmat), acc_body_filtered);
+ b2_hff_xdd_meas = ACCEL_FLOAT_OF_BFP(filtered_accel_ltp.x);
+ b2_hff_ydd_meas = ACCEL_FLOAT_OF_BFP(filtered_accel_ltp.y);
#ifdef GPS_LAG
b2_hff_store_accel_ltp(b2_hff_xdd_meas, b2_hff_ydd_meas);
#endif
-
/*
* propagate current state
*/
@@ -520,9 +474,6 @@ void b2_hff_propagate(void) {
}
}
-
-
-
void b2_hff_update_gps(struct FloatVect2* pos_ned, struct FloatVect2* speed_ned) {
b2_hff_lost_counter = 0;
@@ -569,7 +520,7 @@ void b2_hff_update_gps(struct FloatVect2* pos_ned, struct FloatVect2* speed_ned)
/* apparently missed a GPS update, try next saved state */
PRINT_DBG(2, ("try next saved state\n"));
b2_hff_rb_drop_last();
- b2_hff_update_gps();
+ b2_hff_update_gps(pos_ned, speed_ned);
}
} else if (save_counter < 0) {
/* ringbuffer empty -> save output filter state at next GPS validity point in time */
@@ -615,7 +566,7 @@ void b2_hff_realign(struct FloatVect2 pos, struct FloatVect2 vel) {
Pk1 = F * Pk0 * F' + Q;
*/
-static inline void b2_hff_propagate_x(struct HfilterFloat* hff_work) {
+static void b2_hff_propagate_x(struct HfilterFloat* hff_work) {
/* update state */
hff_work->xdotdot = b2_hff_xdd_meas;
hff_work->x = hff_work->x + DT_HFILTER * hff_work->xdot + DT_HFILTER*DT_HFILTER/2 * hff_work->xdotdot;
@@ -632,7 +583,7 @@ static inline void b2_hff_propagate_x(struct HfilterFloat* hff_work) {
hff_work->xP[1][1] = FPF11 + Qdotdot;
}
-static inline void b2_hff_propagate_y(struct HfilterFloat* hff_work) {
+static void b2_hff_propagate_y(struct HfilterFloat* hff_work) {
/* update state */
hff_work->ydotdot = b2_hff_ydd_meas;
hff_work->y = hff_work->y + DT_HFILTER * hff_work->ydot + DT_HFILTER*DT_HFILTER/2 * hff_work->ydotdot;
@@ -674,7 +625,7 @@ void b2_hff_update_pos (struct FloatVect2 pos, struct FloatVect2 Rpos) {
b2_hff_update_y(&b2_hff_state, pos.y, Rpos.y);
}
-static inline void b2_hff_update_x(struct HfilterFloat* hff_work, float x_meas, float Rpos) {
+static void b2_hff_update_x(struct HfilterFloat* hff_work, float x_meas, float Rpos) {
b2_hff_x_meas = x_meas;
const float y = x_meas - hff_work->x;
@@ -696,7 +647,7 @@ static inline void b2_hff_update_x(struct HfilterFloat* hff_work, float x_meas,
hff_work->xP[1][1] = P22;
}
-static inline void b2_hff_update_y(struct HfilterFloat* hff_work, float y_meas, float Rpos) {
+static void b2_hff_update_y(struct HfilterFloat* hff_work, float y_meas, float Rpos) {
b2_hff_y_meas = y_meas;
const float y = y_meas - hff_work->y;
@@ -719,8 +670,6 @@ static inline void b2_hff_update_y(struct HfilterFloat* hff_work, float y_meas,
}
-
-
/*
*
* Update velocity
@@ -745,7 +694,7 @@ void b2_hff_update_vel(struct FloatVect2 vel, struct FloatVect2 Rvel) {
b2_hff_update_ydot(&b2_hff_state, vel.y, Rvel.y);
}
-static inline void b2_hff_update_xdot(struct HfilterFloat* hff_work, float vel, float Rvel) {
+static void b2_hff_update_xdot(struct HfilterFloat* hff_work, float vel, float Rvel) {
b2_hff_xd_meas = vel;
const float yd = vel - hff_work->xdot;
@@ -767,7 +716,7 @@ static inline void b2_hff_update_xdot(struct HfilterFloat* hff_work, float vel,
hff_work->xP[1][1] = P22;
}
-static inline void b2_hff_update_ydot(struct HfilterFloat* hff_work, float vel, float Rvel) {
+static void b2_hff_update_ydot(struct HfilterFloat* hff_work, float vel, float Rvel) {
b2_hff_yd_meas = vel;
const float yd = vel - hff_work->ydot;
diff --git a/sw/airborne/subsystems/ins/ins_float_invariant.c b/sw/airborne/subsystems/ins/ins_float_invariant.c
index 9a6966c081..36773d21d7 100644
--- a/sw/airborne/subsystems/ins/ins_float_invariant.c
+++ b/sw/airborne/subsystems/ins/ins_float_invariant.c
@@ -459,15 +459,11 @@ void ahrs_update_gps(void) {
}
#else
if (state.ned_initialized_f) {
- struct NedCoor_f gps_pos_cm_ned;
struct EcefCoor_f ecef_pos, ecef_vel;
ECEF_FLOAT_OF_BFP(ecef_pos, gps.ecef_pos);
- ned_of_ecef_point_f(&gps_pos_cm_ned, &state.ned_origin_f, &ecef_pos);
- VECT3_SDIV(ins_impl.meas.pos_gps, gps_pos_cm_ned, 100.0f);
- struct NedCoor_f gps_speed_cm_s_ned;
+ ned_of_ecef_point_f(&ins_impl.meas.pos_gps, &state.ned_origin_f, &ecef_pos);
ECEF_FLOAT_OF_BFP(ecef_vel, gps.ecef_vel);
- ned_of_ecef_vect_f(&gps_speed_cm_s_ned, &state.ned_origin_f, &ecef_vel);
- VECT3_SDIV(ins_impl.meas.speed_gps, gps_speed_cm_s_ned, 100.0f);
+ ned_of_ecef_vect_f(&ins_impl.meas.speed_gps, &state.ned_origin_f, &ecef_vel);
}
#endif
}
diff --git a/sw/airborne/subsystems/ins/ins_gps_passthrough.c b/sw/airborne/subsystems/ins/ins_gps_passthrough.c
index 9723fa5d7e..f0d8e16cfa 100644
--- a/sw/airborne/subsystems/ins/ins_gps_passthrough.c
+++ b/sw/airborne/subsystems/ins/ins_gps_passthrough.c
@@ -22,7 +22,8 @@
/**
* @file subsystems/ins/ins_gps_passthrough.c
*
- * Simply passes GPS position and velocity through to the state interface.
+ * Simply converts GPS ECEF position and velocity to NED
+ * and passes it through to the state interface.
*/
#include "subsystems/ins.h"
@@ -32,57 +33,124 @@
#include "state.h"
#include "subsystems/gps.h"
-#include "subsystems/nav.h"
-void ins_init(void) {
- struct UtmCoor_f utm0 = { nav_utm_north0, nav_utm_east0, 0., nav_utm_zone0 };
- stateSetLocalUtmOrigin_f(&utm0);
- stateSetPositionUtm_f(&utm0);
+#ifndef USE_INS_NAV_INIT
+#define USE_INS_NAV_INIT TRUE
+PRINT_CONFIG_MSG("USE_INS_NAV_INIT defaulting to TRUE")
+#endif
- ins.status = INS_RUNNING;
+#if USE_INS_NAV_INIT
+#include "generated/flight_plan.h"
+#endif
+
+struct InsGpsPassthrough {
+ struct LtpDef_i ltp_def;
+ bool_t ltp_initialized;
+
+ /* output LTP NED */
+ struct NedCoor_i ltp_pos;
+ struct NedCoor_i ltp_speed;
+ struct NedCoor_i ltp_accel;
+};
+
+struct InsGpsPassthrough ins_impl;
+
+#if PERIODIC_TELEMETRY
+#include "subsystems/datalink/telemetry.h"
+
+static void send_ins(void) {
+ DOWNLINK_SEND_INS(DefaultChannel, DefaultDevice,
+ &ins_impl.ltp_pos.x, &ins_impl.ltp_pos.y, &ins_impl.ltp_pos.z,
+ &ins_impl.ltp_speed.x, &ins_impl.ltp_speed.y, &ins_impl.ltp_speed.z,
+ &ins_impl.ltp_accel.x, &ins_impl.ltp_accel.y, &ins_impl.ltp_accel.z);
}
-void ins_reset_local_origin(void) {
- struct UtmCoor_f utm;
-#ifdef GPS_USE_LATLONG
- /* Recompute UTM coordinates in this zone */
- struct LlaCoor_f lla;
- lla.lat = gps.lla_pos.lat/1e7;
- lla.lon = gps.lla_pos.lon/1e7;
- utm.zone = (DegOfRad(gps.lla_pos.lon/1e7)+180) / 6 + 1;
- utm_of_lla_f(&utm, &lla);
-#else
- utm.zone = gps.utm_pos.zone;
- utm.east = gps.utm_pos.east / 100.0f;
- utm.north = gps.utm_pos.north / 100.0f;
+static void send_ins_z(void) {
+ static const float fake_baro_z = 0.0;
+ DOWNLINK_SEND_INS_Z(DefaultChannel, DefaultDevice,
+ &fake_baro_z, &ins_impl.ltp_pos.z, &ins_impl.ltp_speed.z, &ins_impl.ltp_accel.z);
+}
+
+static void send_ins_ref(void) {
+ static const float fake_qfe = 0.0;
+ if (ins_impl.ltp_initialized) {
+ DOWNLINK_SEND_INS_REF(DefaultChannel, DefaultDevice,
+ &ins_impl.ltp_def.ecef.x, &ins_impl.ltp_def.ecef.y, &ins_impl.ltp_def.ecef.z,
+ &ins_impl.ltp_def.lla.lat, &ins_impl.ltp_def.lla.lon, &ins_impl.ltp_def.lla.alt,
+ &ins_impl.ltp_def.hmsl, &fake_qfe);
+ }
+}
#endif
- // ground_alt
- utm.alt = gps.hmsl / 1000.0f;
- // reset state UTM ref
- stateSetLocalUtmOrigin_f(&utm);
+
+void ins_init(void) {
+
+#if USE_INS_NAV_INIT
+ 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);
+
+ ins_impl.ltp_initialized = TRUE;
+#else
+ ins_impl.ltp_initialized = FALSE;
+#endif
+
+ INT32_VECT3_ZERO(ins_impl.ltp_pos);
+ INT32_VECT3_ZERO(ins_impl.ltp_speed);
+ INT32_VECT3_ZERO(ins_impl.ltp_accel);
+
+#if PERIODIC_TELEMETRY
+ register_periodic_telemetry(DefaultPeriodic, "INS", send_ins);
+ register_periodic_telemetry(DefaultPeriodic, "INS_Z", send_ins_z);
+ register_periodic_telemetry(DefaultPeriodic, "INS_REF", send_ins_ref);
+#endif
+}
+
+void ins_periodic(void) {
+ if (ins_impl.ltp_initialized)
+ ins.status = INS_RUNNING;
+}
+
+
+void ins_reset_local_origin(void) {
+ 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;
+ stateSetLocalOrigin_i(&ins_impl.ltp_def);
+ ins_impl.ltp_initialized = TRUE;
}
void ins_reset_altitude_ref(void) {
- struct UtmCoor_f utm = state.utm_origin_f;
- utm.alt = gps.hmsl / 1000.0f;
- stateSetLocalUtmOrigin_f(&utm);
+ ins_impl.ltp_def.lla.alt = gps.lla_pos.alt;
+ ins_impl.ltp_def.hmsl = gps.hmsl;
+ stateSetLocalOrigin_i(&ins_impl.ltp_def);
}
void ins_update_gps(void) {
- struct UtmCoor_f utm;
- utm.east = gps.utm_pos.east / 100.0f;
- utm.north = gps.utm_pos.north / 100.0f;
- utm.zone = nav_utm_zone0;
- utm.alt = gps.hmsl / 1000.0f;
+ if (gps.fix == GPS_FIX_3D) {
+ if (!ins_impl.ltp_initialized) {
+ ins_reset_local_origin();
+ }
- // set position
- stateSetPositionUtm_f(&utm);
+ /* simply scale and copy pos/speed from gps */
+ struct NedCoor_i gps_pos_cm_ned;
+ ned_of_ecef_point_i(&gps_pos_cm_ned, &ins_impl.ltp_def, &gps.ecef_pos);
+ INT32_VECT3_SCALE_2(ins_impl.ltp_pos, gps_pos_cm_ned,
+ INT32_POS_OF_CM_NUM, INT32_POS_OF_CM_DEN);
+ stateSetPositionNed_i(&ins_impl.ltp_pos);
- struct NedCoor_f ned_vel = {
- gps.ned_vel.x / 100.0f,
- gps.ned_vel.y / 100.0f,
- gps.ned_vel.z / 100.0f
- };
- // set velocity
- stateSetSpeedNed_f(&ned_vel);
+ 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);
+ INT32_VECT3_SCALE_2(ins_impl.ltp_speed, gps_speed_cm_s_ned,
+ INT32_SPEED_OF_CM_S_NUM, INT32_SPEED_OF_CM_S_DEN);
+ stateSetSpeedNed_i(&ins_impl.ltp_speed);
+ }
}
diff --git a/sw/airborne/subsystems/ins/ins_gps_passthrough_utm.c b/sw/airborne/subsystems/ins/ins_gps_passthrough_utm.c
new file mode 100644
index 0000000000..eb209ff789
--- /dev/null
+++ b/sw/airborne/subsystems/ins/ins_gps_passthrough_utm.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2004-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_gps_passthrough_utm.c
+ *
+ * Simply passes GPS UTM position and velocity through to the state interface.
+ * For fixedwing firmware since it sets UTM pos only.
+ */
+
+#include "subsystems/ins.h"
+
+#include
+#include
+
+#include "state.h"
+#include "subsystems/gps.h"
+#include "subsystems/nav.h"
+
+void ins_init(void) {
+ 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_reset_local_origin(void) {
+ struct UtmCoor_f utm;
+#ifdef GPS_USE_LATLONG
+ /* Recompute UTM coordinates in this zone */
+ struct LlaCoor_f lla;
+ lla.lat = gps.lla_pos.lat/1e7;
+ lla.lon = gps.lla_pos.lon/1e7;
+ utm.zone = (DegOfRad(gps.lla_pos.lon/1e7)+180) / 6 + 1;
+ utm_of_lla_f(&utm, &lla);
+#else
+ utm.zone = gps.utm_pos.zone;
+ utm.east = gps.utm_pos.east / 100.0f;
+ utm.north = gps.utm_pos.north / 100.0f;
+#endif
+ // ground_alt
+ utm.alt = gps.hmsl / 1000.0f;
+ // reset state UTM ref
+ stateSetLocalUtmOrigin_f(&utm);
+}
+
+void ins_reset_altitude_ref(void) {
+ struct UtmCoor_f utm = state.utm_origin_f;
+ utm.alt = gps.hmsl / 1000.0f;
+ stateSetLocalUtmOrigin_f(&utm);
+}
+
+void ins_update_gps(void) {
+ struct UtmCoor_f utm;
+ utm.east = gps.utm_pos.east / 100.0f;
+ utm.north = gps.utm_pos.north / 100.0f;
+ utm.zone = nav_utm_zone0;
+ utm.alt = gps.hmsl / 1000.0f;
+
+ // set position
+ stateSetPositionUtm_f(&utm);
+
+ struct NedCoor_f ned_vel = {
+ gps.ned_vel.x / 100.0f,
+ gps.ned_vel.y / 100.0f,
+ gps.ned_vel.z / 100.0f
+ };
+ // set velocity
+ stateSetSpeedNed_f(&ned_vel);
+}
diff --git a/sw/airborne/subsystems/ins/ins_int.c b/sw/airborne/subsystems/ins/ins_int.c
index 8693feef2e..d07af572fd 100644
--- a/sw/airborne/subsystems/ins/ins_int.c
+++ b/sw/airborne/subsystems/ins/ins_int.c
@@ -58,18 +58,23 @@
#if USE_SONAR
- #include "subsystems/sonar.h"
-
#if !USE_VFF_EXTENDED
#error USE_SONAR needs USE_VFF_EXTENDED
#endif
+/** default sonar to use in INS */
+#ifndef INS_SONAR_ID
+#define INS_SONAR_ID ABI_BROADCAST
+#endif
+abi_event sonar_ev;
+static void sonar_cb(uint8_t sender_id, const float *distance);
+
#ifdef INS_SONAR_THROTTLE_THRESHOLD
#include "firmwares/rotorcraft/stabilization.h"
#endif
#ifndef INS_SONAR_OFFSET
-#define INS_SONAR_OFFSET 0
+#define INS_SONAR_OFFSET 0.
#endif
#define VFF_R_SONAR_0 0.1
#define VFF_R_SONAR_OF_M 0.2
@@ -79,6 +84,10 @@
PRINT_CONFIG_MSG("INS_SONAR_UPDATE_ON_AGL defaulting to FALSE")
#endif
+#ifndef INS_VFF_R_GPS
+#define INS_VFF_R_GPS 2.0
+#endif
+
#endif // USE_SONAR
#ifndef USE_INS_NAV_INIT
@@ -147,8 +156,8 @@ void ins_init(void) {
#if USE_SONAR
ins_impl.update_on_agl = INS_SONAR_UPDATE_ON_AGL;
- init_median_filter(&ins_impl.sonar_median);
- ins_impl.sonar_offset = INS_SONAR_OFFSET;
+ // Bind to AGL message
+ AbiBindMsgAGL(INS_SONAR_ID, &sonar_ev, sonar_cb);
#endif
ins_impl.vf_reset = FALSE;
@@ -225,25 +234,29 @@ void ins_propagate(void) {
}
static void baro_cb(uint8_t __attribute__((unused)) sender_id, const float *pressure) {
- if (!ins_impl.baro_initialized) {
+ if (!ins_impl.baro_initialized && *pressure > 1e-7) {
+ // wait for a first positive value
ins_impl.qfe = *pressure;
ins_impl.baro_initialized = TRUE;
}
- if (ins_impl.vf_reset) {
- ins_impl.vf_reset = FALSE;
- ins_impl.qfe = *pressure;
- vff_realign(0.);
- ins_update_from_vff();
- }
- else {
- ins_impl.baro_z = -pprz_isa_height_of_pressure(*pressure, ins_impl.qfe);
+
+ if (ins_impl.baro_initialized) {
+ if (ins_impl.vf_reset) {
+ ins_impl.vf_reset = FALSE;
+ ins_impl.qfe = *pressure;
+ vff_realign(0.);
+ ins_update_from_vff();
+ }
+ 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);
+ vff_update_baro(ins_impl.baro_z);
#else
- vff_update(ins_impl.baro_z);
+ vff_update(ins_impl.baro_z);
#endif
+ }
+ ins_ned_to_state();
}
- ins_ned_to_state();
}
#if USE_GPS
@@ -263,6 +276,10 @@ void ins_update_gps(void) {
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 INS_USE_GPS_ALT
+ vff_update_z_conf((float)gps_pos_cm_ned.z / 100.0, INS_VFF_R_GPS);
+#endif
+
#if USE_HFF
/* horizontal gps transformed to NED in meters as float */
struct FloatVect2 gps_pos_m_ned;
@@ -313,38 +330,26 @@ uint8_t var_idx = 0;
#if USE_SONAR
-void ins_update_sonar(void) {
+static void sonar_cb(uint8_t __attribute__((unused)) sender_id, const float *distance) {
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 !!!!
+ float err = *distance + 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);
+ DOWNLINK_SEND_INS_SONAR(DefaultChannel,DefaultDevice, distance, &var);
#endif
/* update filter assuming a flat ground */
- if (sonar < INS_SONAR_MAX_RANGE
+ if (*distance < INS_SONAR_MAX_RANGE
#ifdef INS_SONAR_MIN_RANGE
- && sonar > INS_SONAR_MIN_RANGE
+ && *distance > 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
@@ -353,7 +358,7 @@ void ins_update_sonar(void) {
#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));
+ vff_update_z_conf(-(*distance), VFF_R_SONAR_0 + VFF_R_SONAR_OF_M * fabsf(*distance));
last_offset = vff.offset;
}
else {
diff --git a/sw/airborne/subsystems/ins/ins_int.h b/sw/airborne/subsystems/ins/ins_int.h
index d04ef30c6e..0dfa18eb34 100644
--- a/sw/airborne/subsystems/ins/ins_int.h
+++ b/sw/airborne/subsystems/ins/ins_int.h
@@ -34,10 +34,6 @@
#include "math/pprz_geodetic_int.h"
#include "math/pprz_algebra_float.h"
-#if USE_SONAR
-#include "filters/median_filter.h"
-#endif
-
/** Ins implementation state (fixed point) */
struct InsInt {
struct LtpDef_i ltp_def;
@@ -64,10 +60,7 @@ struct InsInt {
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;
+ bool_t update_on_agl; ///< use sonar to update agl if available
#endif
};
diff --git a/sw/airborne/subsystems/ins/vf_extended_float.c b/sw/airborne/subsystems/ins/vf_extended_float.c
index 04555bd674..e8d4eba633 100644
--- a/sw/airborne/subsystems/ins/vf_extended_float.c
+++ b/sw/airborne/subsystems/ins/vf_extended_float.c
@@ -278,11 +278,11 @@ static void update_alt_conf(float z_meas, float conf) {
vff.P[3][3] -= K3 * P3;
}
-void vff_update_alt(float z_meas) {
+void vff_update_z(float z_meas) {
update_alt_conf(z_meas, R_ALT);
}
-void vff_update_alt_conf(float z_meas, float conf) {
+void vff_update_z_conf(float z_meas, float conf) {
update_alt_conf(z_meas, conf);
}
diff --git a/sw/airborne/subsystems/ins/vf_extended_float.h b/sw/airborne/subsystems/ins/vf_extended_float.h
index c8900e698c..41f5226310 100644
--- a/sw/airborne/subsystems/ins/vf_extended_float.h
+++ b/sw/airborne/subsystems/ins/vf_extended_float.h
@@ -52,10 +52,10 @@ extern void vff_init_zero(void);
extern void vff_init(float z, float zdot, float accel_bias, float baro_offset);
extern void vff_propagate(float accel);
extern void vff_update_baro(float z_meas);
-extern void vff_update_alt(float z_meas);
+extern void vff_update_z(float z_meas);
extern void vff_update_offset(float offset);
extern void vff_update_baro_conf(float z_meas, float conf);
-extern void vff_update_alt_conf(float z_meas, float conf);
+extern void vff_update_z_conf(float z_meas, float conf);
//extern void vff_update_vz_conf(float vz_meas, float conf);
extern void vff_realign(float z_meas);
diff --git a/sw/airborne/subsystems/nav.c b/sw/airborne/subsystems/nav.c
index 435b405af5..a9ed8a50e4 100644
--- a/sw/airborne/subsystems/nav.c
+++ b/sw/airborne/subsystems/nav.c
@@ -109,7 +109,7 @@ void nav_init_stage( void ) {
void nav_circle_XY(float x, float y, float radius) {
struct EnuCoor_f* pos = stateGetPositionEnu_f();
float last_trigo_qdr = nav_circle_trigo_qdr;
- nav_circle_trigo_qdr = atan2(pos->y - y, pos->x - x);
+ nav_circle_trigo_qdr = atan2f(pos->y - y, pos->x - x);
float sign_radius = radius > 0 ? 1 : -1;
if (nav_in_circle) {
@@ -133,7 +133,7 @@ void nav_circle_XY(float x, float y, float radius) {
(dist2_center > Square(abs_radius + dist_carrot)
|| dist2_center < Square(abs_radius - dist_carrot)) ?
0 :
- atan((*stateGetHorizontalSpeedNorm_f())*(*stateGetHorizontalSpeedNorm_f()) / (NAV_GRAVITY*radius));
+ atanf((*stateGetHorizontalSpeedNorm_f())*(*stateGetHorizontalSpeedNorm_f()) / (NAV_GRAVITY*radius));
float carrot_angle = dist_carrot / abs_radius;
carrot_angle = Min(carrot_angle, M_PI/4);
@@ -142,10 +142,10 @@ void nav_circle_XY(float x, float y, float radius) {
horizontal_mode = HORIZONTAL_MODE_CIRCLE;
float radius_carrot = abs_radius;
if (nav_mode == NAV_MODE_COURSE) {
- radius_carrot += (abs_radius / cos(carrot_angle) - abs_radius);
+ radius_carrot += (abs_radius / cosf(carrot_angle) - abs_radius);
}
- fly_to_xy(x+cos(alpha_carrot)*radius_carrot,
- y+sin(alpha_carrot)*radius_carrot);
+ fly_to_xy(x+cosf(alpha_carrot)*radius_carrot,
+ y+sinf(alpha_carrot)*radius_carrot);
nav_in_circle = TRUE;
nav_circle_x = x;
nav_circle_y = y;
@@ -226,14 +226,14 @@ static inline bool_t nav_compute_baseleg(uint8_t wp_af, uint8_t wp_td, uint8_t w
float y_0 = waypoints[wp_td].y - waypoints[wp_af].y;
/* Unit vector from AF to TD */
- float d = sqrt(x_0*x_0+y_0*y_0);
+ float d = sqrtf(x_0*x_0+y_0*y_0);
float x_1 = x_0 / d;
float y_1 = y_0 / d;
waypoints[wp_baseleg].x = waypoints[wp_af].x + y_1 * nav_radius;
waypoints[wp_baseleg].y = waypoints[wp_af].y - x_1 * nav_radius;
waypoints[wp_baseleg].a = waypoints[wp_af].a;
- baseleg_out_qdr = M_PI - atan2(-y_1, -x_1);
+ baseleg_out_qdr = M_PI - atan2f(-y_1, -x_1);
if (nav_radius < 0)
baseleg_out_qdr += M_PI;
@@ -247,7 +247,7 @@ static inline bool_t nav_compute_final_from_glide(uint8_t wp_af, uint8_t wp_td,
float h_0 = waypoints[wp_td].a - waypoints[wp_af].a;
/* Unit vector from AF to TD */
- float d = sqrt(x_0*x_0+y_0*y_0);
+ float d = sqrtf(x_0*x_0+y_0*y_0);
float x_1 = x_0 / d;
float y_1 = y_0 / d;
@@ -266,8 +266,8 @@ static inline bool_t compute_TOD(uint8_t _af, uint8_t _td, uint8_t _tod, float g
struct FloatVect2* wind = stateGetHorizontalWindspeed_f();
float td_af_x = WaypointX(_af) - WaypointX(_td);
float td_af_y = WaypointY(_af) - WaypointY(_td);
- float td_af = sqrt( td_af_x*td_af_x + td_af_y*td_af_y);
- float td_tod = (WaypointAlt(_af) - WaypointAlt(_td)) / glide_vspeed * (glide_airspeed - sqrt(wind->x*wind->x + wind->y*wind->y));
+ float td_af = sqrtf( td_af_x*td_af_x + td_af_y*td_af_y);
+ float td_tod = (WaypointAlt(_af) - WaypointAlt(_td)) / glide_vspeed * (glide_airspeed - sqrtf(wind->x*wind->x + wind->y*wind->y));
WaypointX(_tod) = WaypointX(_td) + td_af_x / td_af * td_tod;
WaypointY(_tod) = WaypointY(_td) + td_af_y / td_af * td_tod;
WaypointAlt(_tod) = WaypointAlt(_af);
@@ -292,7 +292,7 @@ static inline void nav_follow(uint8_t _ac_id, float _distance, float _height) {
NavVerticalAutoThrottleMode(0.);
NavVerticalAltitudeMode(Max(ac->alt + _height, ground_alt+SECURITY_HEIGHT), 0.);
float alpha = M_PI/2 - ac->course;
- float ca = cos(alpha), sa = sin(alpha);
+ float ca = cosf(alpha), sa = sinf(alpha);
float x = ac->east - _distance*ca;
float y = ac->north - _distance*sa;
fly_to_xy(x, y);
@@ -314,7 +314,10 @@ float fp_pitch; /* deg */
* Computes \a dist2_to_wp and compare it to square \a carrot.
* Return true if it is smaller. Else computes by scalar products if
* uav has not gone past waypoint.
- * Return true if it is the case.
+ * \a approaching_time can be negative and in this case, the UAV will
+ * fly after the waypoint for the given number of seconds.
+ *
+ * @return true if the position (x, y) is reached
*/
bool_t nav_approaching_xy(float x, float y, float from_x, float from_y, float approaching_time) {
/** distance to waypoint in x */
@@ -322,14 +325,25 @@ bool_t nav_approaching_xy(float x, float y, float from_x, float from_y, float ap
/** distance to waypoint in y */
float pw_y = y - stateGetPositionEnu_f()->y;
- dist2_to_wp = pw_x*pw_x + pw_y *pw_y;
- float min_dist = approaching_time * (*stateGetHorizontalSpeedNorm_f());
- if (dist2_to_wp < min_dist*min_dist)
- return TRUE;
-
- float scal_prod = (x - from_x) * pw_x + (y - from_y) * pw_y;
-
- return (scal_prod < 0.);
+ if (approaching_time < 0.) {
+ // fly after the destination waypoint
+ float leg_x = x - from_x;
+ float leg_y = y - from_y;
+ float leg = sqrtf(Max(leg_x * leg_x + leg_y * leg_y, 1.));
+ float exceed_dist = approaching_time * (*stateGetHorizontalSpeedNorm_f()); // negative value
+ float scal_prod = (leg_x * pw_x + leg_y * pw_y) / leg;
+ return (scal_prod < exceed_dist);
+ }
+ else {
+ // fly close enough of the waypoint or cross it
+ dist2_to_wp = pw_x*pw_x + pw_y *pw_y;
+ float min_dist = approaching_time * (*stateGetHorizontalSpeedNorm_f());
+ if (dist2_to_wp < min_dist*min_dist) {
+ return TRUE;
+ }
+ float scal_prod = (x - from_x) * pw_x + (y - from_y) * pw_y;
+ return (scal_prod < 0.);
+ }
}
@@ -342,17 +356,17 @@ void fly_to_xy(float x, float y) {
desired_x = x;
desired_y = y;
if (nav_mode == NAV_MODE_COURSE) {
- h_ctl_course_setpoint = atan2(x - pos->x, y - pos->y);
+ h_ctl_course_setpoint = atan2f(x - pos->x, y - pos->y);
if (h_ctl_course_setpoint < 0.)
h_ctl_course_setpoint += 2 * M_PI;
lateral_mode = LATERAL_MODE_COURSE;
} else {
- float diff = atan2(x - pos->x, y - pos->y) - (*stateGetHorizontalSpeedDir_f());
+ float diff = atan2f(x - pos->x, y - pos->y) - (*stateGetHorizontalSpeedDir_f());
NormRadAngle(diff);
BoundAbs(diff,M_PI/2.);
- float s = sin(diff);
+ float s = sinf(diff);
float speed = *stateGetHorizontalSpeedNorm_f();
- h_ctl_roll_setpoint = atan(2 * speed * speed * s * h_ctl_course_pgain / (CARROT * NOMINAL_AIRSPEED * 9.81) );
+ h_ctl_roll_setpoint = atanf(2 * speed * speed * s * h_ctl_course_pgain / (CARROT * NOMINAL_AIRSPEED * 9.81) );
BoundAbs(h_ctl_roll_setpoint, h_ctl_roll_max_setpoint);
lateral_mode = LATERAL_MODE_ROLL;
}
@@ -366,7 +380,7 @@ void nav_route_xy(float last_wp_x, float last_wp_y, float wp_x, float wp_y) {
float leg_y = wp_y - last_wp_y;
float leg2 = Max(leg_x * leg_x + leg_y * leg_y, 1.);
nav_leg_progress = ((stateGetPositionEnu_f()->x - last_wp_x) * leg_x + (stateGetPositionEnu_f()->y - last_wp_y) * leg_y) / leg2;
- nav_leg_length = sqrt(leg2);
+ nav_leg_length = sqrtf(leg2);
/** distance of carrot (in meter) */
float carrot = CARROT * NOMINAL_AIRSPEED;
@@ -548,7 +562,7 @@ void nav_eight(uint8_t target, uint8_t c1, float radius) {
float target_c1_x = waypoints[c1].x - waypoints[target].x;
float target_c1_y = waypoints[c1].y - waypoints[target].y;
- float d = sqrt(target_c1_x*target_c1_x+target_c1_y*target_c1_y);
+ float d = sqrtf(target_c1_x*target_c1_x+target_c1_y*target_c1_y);
d = Max(d, 1.); /* To prevent a division by zero */
/* Unit vector from target to c1 */
@@ -586,7 +600,7 @@ void nav_eight(uint8_t target, uint8_t c1, float radius) {
c2.y - radius * u_x,
alt };
- float qdr_out = M_PI - atan2(u_y, u_x);
+ float qdr_out = M_PI - atan2f(u_y, u_x);
if (radius < 0)
qdr_out += M_PI;
@@ -670,7 +684,7 @@ void nav_oval(uint8_t p1, uint8_t p2, float radius) {
float p2_p1_x = waypoints[p1].x - waypoints[p2].x;
float p2_p1_y = waypoints[p1].y - waypoints[p2].y;
- float d = sqrt(p2_p1_x*p2_p1_x+p2_p1_y*p2_p1_y);
+ float d = sqrtf(p2_p1_x*p2_p1_x+p2_p1_y*p2_p1_y);
/* Unit vector from p1 to p2 */
float u_x = p2_p1_x / d;
@@ -691,7 +705,7 @@ void nav_oval(uint8_t p1, uint8_t p2, float radius) {
waypoints[p2].y + radius * u_x,
alt };
- float qdr_out_2 = M_PI - atan2(u_y, u_x);
+ float qdr_out_2 = M_PI - atan2f(u_y, u_x);
float qdr_out_1 = qdr_out_2 + M_PI;
if (radius < 0) {
qdr_out_2 += M_PI;
diff --git a/sw/airborne/subsystems/navigation/common_nav.c b/sw/airborne/subsystems/navigation/common_nav.c
index 103ff761e1..cd87bb558b 100644
--- a/sw/airborne/subsystems/navigation/common_nav.c
+++ b/sw/airborne/subsystems/navigation/common_nav.c
@@ -44,8 +44,8 @@ int32_t nav_utm_north0 = NAV_UTM_NORTH0;
uint8_t nav_utm_zone0 = NAV_UTM_ZONE0;
float max_dist_from_home = MAX_DIST_FROM_HOME;
-/** \brief Computes square distance to the HOME waypoint potentially sets
- * \a too_far_from_home
+/** Computes squared distance to the HOME waypoint.
+ * Updates #dist2_to_home and potentially sets #too_far_from_home
*/
void compute_dist2_to_home(void) {
struct EnuCoor_f* pos = stateGetPositionEnu_f();
@@ -80,7 +80,7 @@ unit_t nav_reset_utm_zone(void) {
}
/** Reset the geographic reference to the current GPS fix */
-unit_t nav_reset_reference( void ) {
+unit_t nav_reset_reference(void) {
/* realign INS */
ins_reset_local_origin();
@@ -97,7 +97,7 @@ unit_t nav_reset_reference( void ) {
}
/** Shift altitude of the waypoint according to a new ground altitude */
-unit_t nav_update_waypoints_alt( void ) {
+unit_t nav_update_waypoints_alt(void) {
uint8_t i;
for(i = 0; i < NB_WAYPOINT; i++) {
waypoints[i].a += ground_alt - previous_ground_alt;
@@ -109,6 +109,12 @@ void common_nav_periodic_task_4Hz() {
RunOnceEvery(4, { stage_time++; block_time++; });
}
+/** Move a waypoint to given UTM coordinates.
+ * @param[in] wp_id Waypoint ID
+ * @param[in] ux UTM x (east) coordinate
+ * @param[in] uy UTM y (north) coordinate
+ * @param[in] alt Altitude above MSL.
+ */
void nav_move_waypoint(uint8_t wp_id, float ux, float uy, float alt) {
if (wp_id < nb_waypoint) {
float dx, dy;
diff --git a/sw/airborne/subsystems/radio_control/sbus.c b/sw/airborne/subsystems/radio_control/sbus.c
index f704fee093..7dff0b4467 100644
--- a/sw/airborne/subsystems/radio_control/sbus.c
+++ b/sw/airborne/subsystems/radio_control/sbus.c
@@ -70,9 +70,9 @@ struct _sbus sbus;
#include "subsystems/datalink/telemetry.h"
static void send_sbus(void) {
- // Using PPM message for simplicity
+ // Using PPM message
DOWNLINK_SEND_PPM(DefaultChannel, DefaultDevice,
- &radio_control.frame_rate, SBUS_NB_CHANNEL, sbus.pulses);
+ &radio_control.frame_rate, SBUS_NB_CHANNEL, sbus.ppm);
}
#endif
@@ -99,7 +99,7 @@ void radio_control_impl_init(void) {
/** Decode the raw buffer */
-static void decode_sbus_buffer (const uint8_t *src, uint16_t *dst, bool_t *available)
+static void decode_sbus_buffer (const uint8_t *src, uint16_t *dst, bool_t *available, uint16_t *dstppm)
{
// reset counters
uint8_t byteInRawBuf = 0;
@@ -124,6 +124,9 @@ static void decode_sbus_buffer (const uint8_t *src, uint16_t *dst, bool_t *avail
}
if (bitInChannel == SBUS_BIT_PER_CHANNEL) {
bitInChannel = 0;
+#if PERIODIC_TELEMETRY
+ dstppm[channel] = USEC_OF_RC_PPM_TICKS(dst[channel]);
+#endif
channel++;
}
}
@@ -153,7 +156,7 @@ void sbus_decode_event(void) {
if (sbus.idx == SBUS_BUF_LENGTH) {
// Decode if last byte is the correct end byte
if (rbyte == SBUS_END_BYTE) {
- decode_sbus_buffer(sbus.buffer, sbus.pulses, &sbus.frame_available);
+ decode_sbus_buffer(sbus.buffer, sbus.pulses, &sbus.frame_available, sbus.ppm);
}
sbus.status = SBUS_STATUS_UNINIT;
}
diff --git a/sw/airborne/subsystems/radio_control/sbus.h b/sw/airborne/subsystems/radio_control/sbus.h
index 3f344194a7..4cfc202551 100644
--- a/sw/airborne/subsystems/radio_control/sbus.h
+++ b/sw/airborne/subsystems/radio_control/sbus.h
@@ -30,11 +30,14 @@
#include "std.h"
/**
- * Dummy macro to use radio.h file
+ * Macro to use radio.h file
+ *
+ * SBUS: 0..1024..2047 (sweep 2048)
+ * PPM: 880..1520..2160 (sweep 1280)
*/
-#define RC_PPM_TICKS_OF_USEC(_v) (_v)
-#define RC_PPM_SIGNED_TICKS_OF_USEC(_v) (_v)
-#define USEC_OF_RC_PPM_TICKS(_v) (_v)
+#define RC_PPM_TICKS_OF_USEC(_v) ((((_v) - 880) * 8) / 5)
+#define RC_PPM_SIGNED_TICKS_OF_USEC(_v) (((_v) * 8) / 5)
+#define USEC_OF_RC_PPM_TICKS(_v) ((((_v) * 5) / 8) + 880)
/**
* Generated code holding the description of a given
@@ -60,6 +63,7 @@
*/
struct _sbus {
uint16_t pulses[SBUS_NB_CHANNEL]; ///< decoded values
+ uint16_t ppm[SBUS_NB_CHANNEL]; ///< decoded and converted values
bool_t frame_available; ///< new frame available
uint8_t buffer[SBUS_BUF_LENGTH]; ///< input buffer
uint8_t idx; ///< input index
diff --git a/sw/airborne/subsystems/sonar.h b/sw/airborne/subsystems/sonar.h
deleted file mode 100644
index daf310400d..0000000000
--- a/sw/airborne/subsystems/sonar.h
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-extern uint16_t sonar_meas;
diff --git a/sw/cgi/configuration.cgi b/sw/cgi/configuration.cgi
deleted file mode 100755
index 089040cd00..0000000000
--- a/sw/cgi/configuration.cgi
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/usr/bin/perl
-
-# displays the current configuration
-
-use strict;
-use warnings;
-
-use Cwd;
-use CGI ':standard', '*table';
-
-my $paparazzi_src;
-my $paparazzi_lib;
-BEGIN {
- $paparazzi_src = getcwd()."/../..";
- $paparazzi_lib = $paparazzi_src."/sw/lib/perl";
-}
-use lib ($paparazzi_lib);
-my $paparazzi_home = $paparazzi_src;
-
-use Paparazzi::Environment;
-Paparazzi::Environment::set_env($paparazzi_src, $paparazzi_home);
-
-use Paparazzi::Configuration;
-
-print
- header(),
- start_html("Paparazzi configuration");
-
-my $configuration = Paparazzi::Configuration::read_current();
-print
- h1 ("Paparazzi Configuration"),
- h2 ("Aircrafts");
-print
- start_table({border => undef}),
- Tr(th(["Id", "Name", "Airframe", "Radio", "Flight plan"]));
-foreach my $ac (@{$configuration->{aircrafts}}) {
- print
- Tr(td([$ac->{ac_id}, $ac->{name},
- a({href=>"../conf/$ac->{airframe}"}, foo($ac->{airframe}) ),
- a({href=>"../conf/$ac->{radio}"}, foo($ac->{radio}) ),
- a({href=>"../conf/$ac->{flight_plan}"}, foo($ac->{flight_plan}) )]));
-}
-print end_table();
-
-print
- h2 ("Ground"),
- ul(li (["name : ".$configuration->{ground}->{name},
- "ivy bus : ".$configuration->{ground}->{ivy_bus}
- ])),
- hr(),
- a({href=>"../index.html"}, "home"),
- end_html();
-
-
-sub foo {
- return ($_[0] =~ /([^\/]*)$/ );
-}
diff --git a/sw/cgi/logs.cgi b/sw/cgi/logs.cgi
deleted file mode 100755
index a86ebc7ba0..0000000000
--- a/sw/cgi/logs.cgi
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/perl
-
-# displays available logs
-
-use strict;
-use warnings;
-
-use Cwd;
-use CGI ":standard";
-my $paparazzi_src;
-my $paparazzi_lib;
-BEGIN {
- $paparazzi_src = getcwd()."/../..";
- $paparazzi_lib = $paparazzi_src."/sw/lib/perl";
-}
-use lib ($paparazzi_lib);
-my $paparazzi_home = $paparazzi_src;
-
-use Paparazzi::Environment;
-Paparazzi::Environment::set_env($paparazzi_src, $paparazzi_home);
-
-use Paparazzi::Log;
-
-my $query = new CGI();
-print $query->header();
-print $query->start_html("Paparazzi Logs");
-
-my @logs = Paparazzi::Log::get_available();
-
-my $log_info = undef;
-my $log_data = undef;
-my @files = $query->param('file');
-if ($#files >=0 ) {
- $log_info = Paparazzi::Log::read_infos($files[0]);
- $log_data = Paparazzi::Log::read_data($log_info->{data_file});
-}
-
-print "\n Paparazzi Logs.
\n";
-print " Logs.
\n";
-print $query->startform();
-print $query->popup_menu('file', \@logs, $logs[0]);
-print $query->submit('Action','Update');
-print $query->endform();
-if (defined $log_info) {
- print $query->path_info()."
";
- Paparazzi::Log::html_print_summary($log_info, $log_data);
- my $url = Paparazzi::Log::gen_activity_plot($log_info, $log_data);
- print"
\n";
-}
-print "
\n";
-print "home
\n";
-print "
\n";
-print "Poine.
\n";
-
diff --git a/sw/ground_segment/cockpit/Makefile b/sw/ground_segment/cockpit/Makefile
index 8a38286eb7..97ad612d90 100644
--- a/sw/ground_segment/cockpit/Makefile
+++ b/sw/ground_segment/cockpit/Makefile
@@ -49,11 +49,11 @@ all : $(MAIN)
opt : $(MAIN).opt
-$(MAIN) : $(CMO) $(XLIBPPRZCMA)
+$(MAIN) : $(CMO) $(LIBPPRZCMA) $(XLIBPPRZCMA)
@echo OL $@
$(Q)$(OCAMLC) $(OCAMLCFLAGS) $(INCLUDES) $(LIBS) $(LINKPKG) myGtkInit.cmo $(CMO) -o $@
-$(MAIN).opt : $(CMX) $(XLIBPPRZCMXA)
+$(MAIN).opt : $(CMX) $(LIBPPRZCMXA) $(XLIBPPRZCMXA)
@echo OOL $@
$(Q)$(OCAMLOPT) $(OCAMLCFLAGS) $(INCLUDES) $(LIBSX) -package pprz.xlib,$(LABLGTK2INIT) -linkpkg $(CMX) -o $@
@@ -119,7 +119,8 @@ actuators : actuators.c
#
.depend: Makefile
- $(OCAMLDEP) -I $(LIBPPRZDIR) *.ml* > .depend
+ @echo DEPEND $@
+ $(Q)$(OCAMLDEP) -I $(LIBPPRZDIR) *.ml* > .depend
ifneq ($(MAKECMDGOALS),clean)
-include .depend
diff --git a/sw/ground_segment/cockpit/editFP.ml b/sw/ground_segment/cockpit/editFP.ml
index 3a3673736f..641ccc8868 100644
--- a/sw/ground_segment/cockpit/editFP.ml
+++ b/sw/ground_segment/cockpit/editFP.ml
@@ -1,9 +1,7 @@
-(***************** Editing ONE (single) flight plan **************************)open Printf
+(***************** Editing ONE (single) flight plan **************************)
+open Printf
open Latlong
-module G2D = Geometry_2d
-
-
let (//) = Filename.concat
let fp_example = Env.flight_plans_path // "example.xml"
let default_path_maps = Env.paparazzi_home // "data" // "maps"
diff --git a/sw/ground_segment/cockpit/live.ml b/sw/ground_segment/cockpit/live.ml
index 2949ca0ae8..0668a56045 100644
--- a/sw/ground_segment/cockpit/live.ml
+++ b/sw/ground_segment/cockpit/live.ml
@@ -525,7 +525,7 @@ let create_ac = fun alert (geomap:G.widget) (acs_notebook:GPack.notebook) (ac_id
let id = ExtXml.int_attrib block "no" in
begin (* Is it a key short cut ? *)
try
- let key, modifiers = GtkData.AccelGroup.parse (Xml.attrib block "key") in
+ let key, modifiers = GtkData.AccelGroup.parse (Pprz.key_modifiers_of_string (Xml.attrib block "key")) in
keys := (key, (modifiers, id)) :: !keys
with
_ -> ()
diff --git a/sw/ground_segment/cockpit/page_settings.ml b/sw/ground_segment/cockpit/page_settings.ml
index 9468fba30b..063fa15239 100644
--- a/sw/ground_segment/cockpit/page_settings.ml
+++ b/sw/ground_segment/cockpit/page_settings.ml
@@ -58,7 +58,7 @@ let search_index = fun value array ->
let add_key = fun xml do_change keys ->
- let key, modifiers = GtkData.AccelGroup.parse (Xml.attrib xml "key")
+ let key, modifiers = GtkData.AccelGroup.parse (Pprz.key_modifiers_of_string (Xml.attrib xml "key"))
and value = ExtXml.float_attrib xml "value" in
keys := (key, (modifiers, fun () -> do_change value)) :: !keys
diff --git a/sw/ground_segment/joystick/Makefile b/sw/ground_segment/joystick/Makefile
index 9c7e84afb6..9375dd3f25 100644
--- a/sw/ground_segment/joystick/Makefile
+++ b/sw/ground_segment/joystick/Makefile
@@ -25,11 +25,9 @@
Q=@
include ../../Makefile.ocaml
-TOOLSDIR = ../../tools
CC = gcc
-OCAMLINCLUDES= -I $(TOOLSDIR)
PKG = -package pprz,glibivy
LINKPKG = $(PKG) -linkpkg -dllpath-pkg pprz
@@ -72,9 +70,9 @@ test_stick: test_sdl_stick.o
@echo BUILD $@
$(Q)$(CC) -g -O2 -DSTICK_DBG $(GLIB_CFLAGS) -o $@ $^ sdl_stick.c $(GLIB_LDFLAGS) $(SDL_LDFLAGS)
-input2ivy: $(TOOLSDIR)/fp_proc.cmo $(INPUT2IVY_DEPS)
+input2ivy: $(LIBPPRZCMA) $(INPUT2IVY_DEPS)
@echo OL $@
- $(Q)$(OCAMLC) $(OCAMLINCLUDES) -o $@ $(LINKPKG) $^ $(ML_SDL_OCAMLFLAGS) $(ML_SDL_LFLAGS)
+ $(Q)$(OCAMLC) -o $@ $(LINKPKG) $^ $(ML_SDL_OCAMLFLAGS) $(ML_SDL_LFLAGS)
sdl_stick.so : $(SDL_STICK_DEPS)
@@ -87,7 +85,7 @@ sdl_stick.so : $(SDL_STICK_DEPS)
%.cmo : %.ml
@echo OC $<
- $(Q)$(OCAMLC) $(OCAMLINCLUDES) -c $(PKG) $<
+ $(Q)$(OCAMLC) -c $(PKG) $<
clean:
$(Q)rm -f *~ core *.o *.bak .depend test*stick *.cmo *.cmi input2ivy
@@ -99,7 +97,8 @@ clean:
#
.depend: Makefile
- $(OCAMLDEP) -I $(LIBPPRZDIR) *.ml* > .depend
+ @echo DEPEND $@
+ $(Q)$(OCAMLDEP) -I $(LIBPPRZDIR) *.ml* > .depend
ifneq ($(MAKECMDGOALS),clean)
-include .depend
diff --git a/sw/ground_segment/lpc21iap/Makefile b/sw/ground_segment/lpc21iap/Makefile
index 19ffb61af5..a65cd0a9f6 100644
--- a/sw/ground_segment/lpc21iap/Makefile
+++ b/sw/ground_segment/lpc21iap/Makefile
@@ -39,7 +39,8 @@ clean:
app: $(APPNAME)
$(APPNAME): $(SOURCES) Makefile
- $(CC) $(CFLAGS) $(SOURCES) -o $(APPNAME) -l$(LIBNAME)
+ @echo LD $@
+ $(Q)$(CC) $(CFLAGS) $(SOURCES) -o $(APPNAME) -l$(LIBNAME)
# Builds archive tar file
arch: clean
diff --git a/sw/ground_segment/misc/Makefile b/sw/ground_segment/misc/Makefile
index b703963916..5e7b421af3 100644
--- a/sw/ground_segment/misc/Makefile
+++ b/sw/ground_segment/misc/Makefile
@@ -25,6 +25,7 @@ Q=@
CC = gcc
+PAPARAZZI_SRC=../../..
UNAME = $(shell uname -s)
ifeq ("$(UNAME)","Darwin")
@@ -34,11 +35,14 @@ else
LIBRARYS = -s
endif
+# Optitrack specific librarys and includes
+NATNET_LIBRARYS = $(shell pkg-config glib-2.0 --libs) -lglibivy -lm $(shell pcre-config --libs)
+INCLUDES += $(shell pkg-config glib-2.0 --cflags) -I$(PAPARAZZI_SRC)/sw/airborne/ -I$(PAPARAZZI_SRC)/sw/include/
-all: davis2ivy kestrel2ivy
+all: davis2ivy kestrel2ivy natnet2ivy
clean:
- $(Q)rm -f *.o davis2ivy kestrel2ivy
+ $(Q)rm -f *.o davis2ivy kestrel2ivy natnet2ivy
davis2ivy: davis2ivy.o
$(Q)$(CC) -o davis2ivy davis2ivy.o $(LIBRARYS) -livy
@@ -46,6 +50,9 @@ davis2ivy: davis2ivy.o
kestrel2ivy: kestrel2ivy.o
$(Q)$(CC) -o kestrel2ivy kestrel2ivy.o $(LIBRARYS) -livy
+natnet2ivy: natnet2ivy.o $(PAPARAZZI_SRC)/sw/airborne/math/pprz_geodetic_double.o $(PAPARAZZI_SRC)/sw/airborne/fms/fms_network.o
+ $(Q)$(CC) -o natnet2ivy natnet2ivy.o pprz_geodetic_double.o fms_network.o $(LIBRARYS) $(NATNET_LIBRARYS) -livy
+
%.o : %.c
$(Q)$(CC) -c -O2 -Wall $(INCLUDES) $<
diff --git a/sw/ground_segment/misc/natnet2ivy.c b/sw/ground_segment/misc/natnet2ivy.c
new file mode 100644
index 0000000000..a5709070e4
--- /dev/null
+++ b/sw/ground_segment/misc/natnet2ivy.c
@@ -0,0 +1,726 @@
+/*
+ * Copyright (C) 2014 Freek van Tienen
+ *
+ * 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 natnet2ivy.c
+ * \brief NatNet (GPS) to ivy forwarder
+ *
+ * This receives aircraft position information through the Optitrack system
+ * NatNet UDP stream and forwards it to the ivy bus. An aircraft with the gps
+ * subsystem "datalink" is then able to parse the GPS position and use it to
+ * navigate inside the Optitrack system.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "std.h"
+#include "fms/fms_network.h"
+#include "math/pprz_geodetic_double.h"
+#include "math/pprz_algebra_double.h"
+
+/** Debugging options */
+uint8_t verbose = 0;
+#define printf_natnet if(verbose > 1) printf
+#define printf_debug if(verbose > 0) printf
+
+/** NatNet defaults */
+char *natnet_addr = "255.255.255.255";
+char *natnet_multicast_addr = "239.255.42.99";
+uint16_t natnet_cmd_port = 1510;
+uint16_t natnet_data_port = 1511;
+uint8_t natnet_major = 2;
+uint8_t natnet_minor = 5;
+
+/** Ivy Bus default */
+#ifdef __APPLE__
+char *ivy_bus = "224.255.255.255";
+#else
+char *ivy_bus = "127.255.255.255:2010";
+#endif
+
+/** Sample frequency and derevitive defaults */
+uint32_t freq_transmit = 30; ///< Transmitting frequency in Hz
+uint16_t min_velocity_samples = 4; ///< The amount of position samples needed for a valid velocity
+
+/** NatNet parsing defines */
+#define MAX_PACKETSIZE 100000
+#define MAX_NAMELENGTH 256
+#define MAX_RIGIDBODIES 128
+
+#define NAT_PING 0
+#define NAT_PINGRESPONSE 1
+#define NAT_REQUEST 2
+#define NAT_RESPONSE 3
+#define NAT_REQUEST_MODELDEF 4
+#define NAT_MODELDEF 5
+#define NAT_REQUEST_FRAMEOFDATA 6
+#define NAT_FRAMEOFDATA 7
+#define NAT_MESSAGESTRING 8
+#define NAT_UNRECOGNIZED_REQUEST 100
+#define UNDEFINED 999999.9999
+
+/** Tracked rigid bodies */
+struct RigidBody {
+ int id; ///< Rigid body ID from the tracking system
+ float x, y, z; ///< Rigid body x, y and z coordinates in meters (note y and z are swapped)
+ float qx, qy, qz, qw; ///< Rigid body qx, qy, qz and qw rotations (note qy and qz are swapped)
+ int nMarkers; ///< Number of markers inside the rigid body (both visible and not visible)
+ float error; ///< Error of the position in cm
+ int nSamples; ///< Number of samples since last transmit
+ bool posSampled; ///< If the position is sampled last sampling
+
+ double vel_x, vel_y, vel_z; ///< Sum of the (last_vel_* - current_vel_*) during nVelocitySamples
+ struct EcefCoor_d ecef_vel; ///< Last valid ECEF velocity in meters
+ int nVelocitySamples; ///< Number of velocity samples gathered
+ int totalVelocitySamples; ///< Total amount of velocity samples possible
+ int nVelocityTransmit; ///< Amount of transmits since last valid velocity transmit
+};
+struct RigidBody rigidBodies[MAX_RIGIDBODIES]; ///< All rigid bodies which are tracked
+uint8_t ac_ids[MAX_RIGIDBODIES]; ///< Mapping from rigid body ID to aircraft ID
+
+/** Natnet socket connections */
+struct FmsNetwork *natnet_data, *natnet_cmd;
+
+/** Tracking location LTP and angle offset from north */
+struct LtpDef_d tracking_ltp; ///< The tracking system LTP definition
+double tracking_offset_angle; ///< The offset from the tracking system to the North in degrees
+
+/** Save the latency from natnet */
+float natnet_latency;
+
+/** Parse the packet from NatNet */
+void natnet_parse(unsigned char *in) {
+ int i,j,k;
+
+ // Create a pointer to go trough the packet
+ char *ptr = (char *)in;
+ printf_natnet("Begin Packet\n-------\n");
+
+ // Message ID
+ int MessageID = 0;
+ memcpy(&MessageID, ptr, 2); ptr += 2;
+ printf_natnet("Message ID : %d\n", MessageID);
+
+ // Packet size
+ int nBytes = 0;
+ memcpy(&nBytes, ptr, 2); ptr += 2;
+ printf_natnet("Byte count : %d\n", nBytes);
+
+ if(MessageID == NAT_FRAMEOFDATA) // FRAME OF MOCAP DATA packet
+ {
+ // Frame number
+ int frameNumber = 0; memcpy(&frameNumber, ptr, 4); ptr += 4;
+ printf_natnet("Frame # : %d\n", frameNumber);
+
+ // ========== MARKERSETS ==========
+ // Number of data sets (markersets, rigidbodies, etc)
+ int nMarkerSets = 0; memcpy(&nMarkerSets, ptr, 4); ptr += 4;
+ printf_natnet("Marker Set Count : %d\n", nMarkerSets);
+
+ for (i=0; i < nMarkerSets; i++)
+ {
+ // Markerset name
+ char szName[256];
+ strcpy(szName, ptr);
+ int nDataBytes = (int) strlen(szName) + 1;
+ ptr += nDataBytes;
+ printf_natnet("Model Name: %s\n", szName);
+
+ // marker data
+ int nMarkers = 0; memcpy(&nMarkers, ptr, 4); ptr += 4;
+ printf_natnet("Marker Count : %d\n", nMarkers);
+
+ for(j=0; j < nMarkers; j++)
+ {
+ float x = 0; memcpy(&x, ptr, 4); ptr += 4;
+ float y = 0; memcpy(&y, ptr, 4); ptr += 4;
+ float z = 0; memcpy(&z, ptr, 4); ptr += 4;
+ printf_natnet("\tMarker %d : [x=%3.2f,y=%3.2f,z=%3.2f]\n",j,x,y,z);
+ }
+ }
+
+ // Unidentified markers
+ int nOtherMarkers = 0; memcpy(&nOtherMarkers, ptr, 4); ptr += 4;
+ printf_natnet("Unidentified Marker Count : %d\n", nOtherMarkers);
+ for(j=0; j < nOtherMarkers; j++)
+ {
+ float x = 0.0f; memcpy(&x, ptr, 4); ptr += 4;
+ float y = 0.0f; memcpy(&y, ptr, 4); ptr += 4;
+ float z = 0.0f; memcpy(&z, ptr, 4); ptr += 4;
+ printf_natnet("\tMarker %d : pos = [%3.2f,%3.2f,%3.2f]\n",j,x,y,z);
+ }
+
+ // ========== RIGID BODIES ==========
+ // Rigid bodies
+ int nRigidBodies = 0;
+ memcpy(&nRigidBodies, ptr, 4); ptr += 4;
+ printf_natnet("Rigid Body Count : %d\n", nRigidBodies);
+
+ // Check if there ie enough space for the rigid bodies
+ if(nRigidBodies > MAX_RIGIDBODIES) {
+ fprintf(stderr, "Could not sample all the rigid bodies because the amount of rigid bodies is bigger then %d (MAX_RIGIDBODIES).\r\n", MAX_RIGIDBODIES);
+ exit(EXIT_FAILURE);
+ }
+
+ for (j=0; j < nRigidBodies; j++)
+ {
+ // rigid body pos/ori
+ struct RigidBody old_rigid;
+ memcpy(&old_rigid, &rigidBodies[j], sizeof(struct RigidBody));
+
+ memcpy(&rigidBodies[j].id, ptr, 4); ptr += 4;
+ memcpy(&rigidBodies[j].x, ptr, 4); ptr += 4; //x --> X
+ memcpy(&rigidBodies[j].z, ptr, 4); ptr += 4; //y --> Z
+ memcpy(&rigidBodies[j].y, ptr, 4); ptr += 4; //z --> Y
+ memcpy(&rigidBodies[j].qx, ptr, 4); ptr += 4; //qx --> QX
+ memcpy(&rigidBodies[j].qz, ptr, 4); ptr += 4; //qy --> QZ
+ memcpy(&rigidBodies[j].qy, ptr, 4); ptr += 4; //qz --> QY
+ memcpy(&rigidBodies[j].qw, ptr, 4); ptr += 4; //qw --> QW
+ printf_natnet("ID (%d) : %d\n", j, rigidBodies[j].id);
+ printf_natnet("pos: [%3.2f,%3.2f,%3.2f]\n", rigidBodies[j].x,rigidBodies[j].y,rigidBodies[j].z);
+ printf_natnet("ori: [%3.2f,%3.2f,%3.2f,%3.2f]\n", rigidBodies[j].qx,rigidBodies[j].qy,rigidBodies[j].qz,rigidBodies[j].qw);
+
+ // Differentiate the position to get the speed (TODO: crossreference with labeled markers for occlussion)
+ rigidBodies[j].totalVelocitySamples++;
+ if(old_rigid.x != rigidBodies[j].x || old_rigid.y != rigidBodies[j].y || old_rigid.z != rigidBodies[j].z
+ || old_rigid.qx != rigidBodies[j].qx || old_rigid.qy != rigidBodies[j].qy || old_rigid.qz != rigidBodies[j].qz || old_rigid.qw != rigidBodies[j].qw) {
+
+ if(old_rigid.posSampled) {
+ rigidBodies[j].vel_x += (rigidBodies[j].x - old_rigid.x);
+ rigidBodies[j].vel_y += (rigidBodies[j].y - old_rigid.y);
+ rigidBodies[j].vel_z += (rigidBodies[j].z - old_rigid.z);
+ rigidBodies[j].nVelocitySamples++;
+ }
+
+ rigidBodies[j].nSamples++;
+ rigidBodies[j].posSampled = TRUE;
+ }
+ else
+ rigidBodies[j].posSampled = FALSE;
+
+ // When marker id changed, reset the velocity
+ if(old_rigid.id != rigidBodies[j].id) {
+ rigidBodies[j].vel_x = 0;
+ rigidBodies[j].vel_y = 0;
+ rigidBodies[j].vel_z = 0;
+ rigidBodies[j].nSamples = 0;
+ rigidBodies[j].nVelocitySamples = 0;
+ rigidBodies[j].totalVelocitySamples = 0;
+ rigidBodies[j].posSampled = FALSE;
+ }
+
+ // Associated marker positions
+ memcpy(&rigidBodies[j].nMarkers, ptr, 4); ptr += 4;
+ printf_natnet("Marker Count: %d\n", rigidBodies[j].nMarkers);
+ int nBytes = rigidBodies[j].nMarkers*3*sizeof(float);
+ float* markerData = (float*)malloc(nBytes);
+ memcpy(markerData, ptr, nBytes);
+ ptr += nBytes;
+
+ if(natnet_major >= 2)
+ {
+ // Associated marker IDs
+ nBytes = rigidBodies[j].nMarkers*sizeof(int);
+ int* markerIDs = (int*)malloc(nBytes);
+ memcpy(markerIDs, ptr, nBytes);
+ ptr += nBytes;
+
+ // Associated marker sizes
+ nBytes = rigidBodies[j].nMarkers*sizeof(float);
+ float* markerSizes = (float*)malloc(nBytes);
+ memcpy(markerSizes, ptr, nBytes);
+ ptr += nBytes;
+
+ for(k=0; k < rigidBodies[j].nMarkers; k++)
+ {
+ printf_natnet("\tMarker %d: id=%d\tsize=%3.1f\tpos=[%3.2f,%3.2f,%3.2f]\n", k, markerIDs[k], markerSizes[k], markerData[k*3], markerData[k*3+1],markerData[k*3+2]);
+ }
+
+ if(markerIDs)
+ free(markerIDs);
+ if(markerSizes)
+ free(markerSizes);
+
+ }
+ else
+ {
+ for(k=0; k < rigidBodies[j].nMarkers; k++)
+ {
+ printf_natnet("\tMarker %d: pos = [%3.2f,%3.2f,%3.2f]\n", k, markerData[k*3], markerData[k*3+1],markerData[k*3+2]);
+ }
+ }
+ if(markerData)
+ free(markerData);
+
+ if(natnet_major >= 2)
+ {
+ // Mean marker error
+ memcpy(&rigidBodies[j].error, ptr, 4); ptr += 4;
+ printf_natnet("Mean marker error: %3.8f\n", rigidBodies[j].error);
+ }
+ } // next rigid body
+
+ // ========== SKELETONS ==========
+ // Skeletons (version 2.1 and later)
+ if(((natnet_major == 2) && (natnet_minor>0)) || (natnet_major>2))
+ {
+ int nSkeletons = 0;
+ memcpy(&nSkeletons, ptr, 4); ptr += 4;
+ printf_natnet("Skeleton Count : %d\n", nSkeletons);
+ for (j=0; j < nSkeletons; j++)
+ {
+ // Skeleton id
+ int skeletonID = 0;
+ memcpy(&skeletonID, ptr, 4); ptr += 4;
+ // # of rigid bodies (bones) in skeleton
+ int nRigidBodies = 0;
+ memcpy(&nRigidBodies, ptr, 4); ptr += 4;
+ printf_natnet("Rigid Body Count : %d\n", nRigidBodies);
+ for (j=0; j < nRigidBodies; j++)
+ {
+ // Rigid body pos/ori
+ int ID = 0; memcpy(&ID, ptr, 4); ptr += 4;
+ float x = 0.0f; memcpy(&x, ptr, 4); ptr += 4;
+ float y = 0.0f; memcpy(&y, ptr, 4); ptr += 4;
+ float z = 0.0f; memcpy(&z, ptr, 4); ptr += 4;
+ float qx = 0; memcpy(&qx, ptr, 4); ptr += 4;
+ float qy = 0; memcpy(&qy, ptr, 4); ptr += 4;
+ float qz = 0; memcpy(&qz, ptr, 4); ptr += 4;
+ float qw = 0; memcpy(&qw, ptr, 4); ptr += 4;
+ printf_natnet("ID : %d\n", ID);
+ printf_natnet("pos: [%3.2f,%3.2f,%3.2f]\n", x,y,z);
+ printf_natnet("ori: [%3.2f,%3.2f,%3.2f,%3.2f]\n", qx,qy,qz,qw);
+
+ // Sssociated marker positions
+ int nRigidMarkers = 0; memcpy(&nRigidMarkers, ptr, 4); ptr += 4;
+ printf_natnet("Marker Count: %d\n", nRigidMarkers);
+ int nBytes = nRigidMarkers*3*sizeof(float);
+ float* markerData = (float*)malloc(nBytes);
+ memcpy(markerData, ptr, nBytes);
+ ptr += nBytes;
+
+ // Associated marker IDs
+ nBytes = nRigidMarkers*sizeof(int);
+ int* markerIDs = (int*)malloc(nBytes);
+ memcpy(markerIDs, ptr, nBytes);
+ ptr += nBytes;
+
+ // Associated marker sizes
+ nBytes = nRigidMarkers*sizeof(float);
+ float* markerSizes = (float*)malloc(nBytes);
+ memcpy(markerSizes, ptr, nBytes);
+ ptr += nBytes;
+
+ for(k=0; k < nRigidMarkers; k++)
+ {
+ printf_natnet("\tMarker %d: id=%d\tsize=%3.1f\tpos=[%3.2f,%3.2f,%3.2f]\n", k, markerIDs[k], markerSizes[k], markerData[k*3], markerData[k*3+1],markerData[k*3+2]);
+ }
+
+ // Mean marker error
+ float fError = 0.0f; memcpy(&fError, ptr, 4); ptr += 4;
+ printf_natnet("Mean marker error: %3.2f\n", fError);
+
+ // Release resources
+ if(markerIDs)
+ free(markerIDs);
+ if(markerSizes)
+ free(markerSizes);
+ if(markerData)
+ free(markerData);
+ } // next rigid body
+ } // next skeleton
+ }
+
+ // ========== LABELED MARKERS ==========
+ // Labeled markers (version 2.3 and later)
+ if( ((natnet_major == 2)&&(natnet_minor>=3)) || (natnet_major>2))
+ {
+ int nLabeledMarkers = 0;
+ memcpy(&nLabeledMarkers, ptr, 4); ptr += 4;
+ printf_natnet("Labeled Marker Count : %d\n", nLabeledMarkers);
+ for (j=0; j < nLabeledMarkers; j++)
+ {
+ int ID = 0; memcpy(&ID, ptr, 4); ptr += 4;
+ float x = 0.0f; memcpy(&x, ptr, 4); ptr += 4;
+ float y = 0.0f; memcpy(&y, ptr, 4); ptr += 4;
+ float z = 0.0f; memcpy(&z, ptr, 4); ptr += 4;
+ float size = 0.0f; memcpy(&size, ptr, 4); ptr += 4;
+
+ printf_natnet("ID : %d\n", ID);
+ printf_natnet("pos : [%3.2f,%3.2f,%3.2f]\n", x,y,z);
+ printf_natnet("size: [%3.2f]\n", size);
+ }
+ }
+
+ // Latency
+ natnet_latency = 0.0f; memcpy(&natnet_latency, ptr, 4); ptr += 4;
+ printf_natnet("latency : %3.3f\n", natnet_latency);
+
+ // Timecode
+ unsigned int timecode = 0; memcpy(&timecode, ptr, 4); ptr += 4;
+ unsigned int timecodeSub = 0; memcpy(&timecodeSub, ptr, 4); ptr += 4;
+ printf_natnet("timecode : %d %d", timecode, timecodeSub);
+
+ // End of data tag
+ int eod = 0; memcpy(&eod, ptr, 4); ptr += 4;
+ printf_natnet("End Packet\n-------------\n");
+ }
+ else
+ {
+ printf("Error: Unrecognized packet type from Optitrack NatNet.\n");
+ }
+}
+
+/** The transmitter periodic function */
+gboolean timeout_transmit_callback(gpointer data) {
+ int i;
+
+ // Loop trough all the available rigidbodies (TODO: optimize)
+ for(i = 0; i < MAX_RIGIDBODIES; i++) {
+ // Check if ID's are correct
+ if(rigidBodies[i].id >= MAX_RIGIDBODIES) {
+ fprintf(stderr, "Could not parse rigid body %d from NatNet, because ID is higher then or equal to %d (MAX_RIGIDBODIES-1).\r\n", rigidBodies[i].id, MAX_RIGIDBODIES-1);
+ exit(EXIT_FAILURE);
+ }
+ // Check if we want to transmit this rigid and it was sampled
+ if(ac_ids[rigidBodies[i].id] == 0 || rigidBodies[i].nSamples < 1)
+ continue;
+
+ // Defines to make easy use of paparazzi math
+ struct EnuCoor_d pos, speed;
+ struct EcefCoor_d ecef_pos;
+ struct LlaCoor_d lla_pos;
+ struct DoubleQuat orient;
+ struct DoubleEulers orient_eulers;
+
+ // Add the Optitrack angle to the x and y positions
+ pos.x = cos(tracking_offset_angle) * rigidBodies[i].x + sin(tracking_offset_angle) * rigidBodies[i].y;
+ pos.y = sin(tracking_offset_angle) * rigidBodies[i].x - cos(tracking_offset_angle) * rigidBodies[i].y;
+ pos.z = rigidBodies[i].z;
+
+ // Convert the position to ecef and lla based on the Optitrack LTP
+ ecef_of_enu_point_d(&ecef_pos ,&tracking_ltp ,&pos);
+ lla_of_ecef_d(&lla_pos, &ecef_pos);
+
+ // Check if we have enough samples to estimate the velocity
+ rigidBodies[i].nVelocityTransmit++;
+ if(rigidBodies[i].nVelocitySamples >= min_velocity_samples) {
+ // Calculate the derevative of the sum to get the correct velocity (1 / freq_transmit) * (samples / total_samples)
+ double sample_time = //((double)rigidBodies[i].nVelocitySamples / (double)rigidBodies[i].totalVelocitySamples) /
+ ((double)rigidBodies[i].nVelocityTransmit / (double)freq_transmit);
+ rigidBodies[i].vel_x = rigidBodies[i].vel_x / sample_time;
+ rigidBodies[i].vel_y = rigidBodies[i].vel_y / sample_time;
+ rigidBodies[i].vel_z = rigidBodies[i].vel_z / sample_time;
+
+ // Add the Optitrack angle to the x and y velocities
+ speed.x = cos(tracking_offset_angle) * rigidBodies[i].vel_x + sin(tracking_offset_angle) * rigidBodies[i].vel_y;
+ speed.y = sin(tracking_offset_angle) * rigidBodies[i].vel_x - cos(tracking_offset_angle) * rigidBodies[i].vel_y;
+ speed.z = rigidBodies[i].vel_z;
+
+ // Conver the speed to ecef based on the Optitrack LTP
+ ecef_of_enu_vect_d(&rigidBodies[i].ecef_vel ,&tracking_ltp ,&speed);
+ }
+
+ // Copy the quaternions and convert to euler angles for the heading
+ orient.qi = rigidBodies[i].qw;
+ orient.qx = rigidBodies[i].qx;
+ orient.qy = rigidBodies[i].qy;
+ orient.qz = rigidBodies[i].qz;
+ DOUBLE_EULERS_OF_QUAT(orient_eulers, orient);
+
+ // Calculate the heading by adding the Natnet offset angle and normalizing it
+ double heading = -orient_eulers.psi-tracking_offset_angle;
+ NormRadAngle(heading);
+
+ printf_debug("[%d -> %d]Samples: %d\t%d\t\tTiming: %3.3f latency\n", rigidBodies[i].id, ac_ids[rigidBodies[i].id]
+ , rigidBodies[i].nSamples, rigidBodies[i].nVelocitySamples, natnet_latency);
+ printf_debug(" Heading: %f\t\tPosition: %f\t%f\t%f\t\tVelocity: %f\t%f\t%f\n", DegOfRad(heading),
+ rigidBodies[i].x, rigidBodies[i].y, rigidBodies[i].z,
+ rigidBodies[i].ecef_vel.x, rigidBodies[i].ecef_vel.y, rigidBodies[i].ecef_vel.z);
+
+ // Transmit the REMOTE_GPS packet on the ivy bus
+ IvySendMsg("0 REMOTE_GPS %d %d %d %d %d %d %d %d %d %d %d %d %d %d", ac_ids[rigidBodies[i].id],
+ rigidBodies[i].nMarkers, //uint8 Number of markers (sv_num)
+ (int)(ecef_pos.x*100.0), //int32 ECEF X in CM
+ (int)(ecef_pos.y*100.0), //int32 ECEF Y in CM
+ (int)(ecef_pos.z*100.0), //int32 ECEF Z in CM
+ (int)(lla_pos.lat*10000000.0), //int32 LLA latitude in rad*1e7
+ (int)(lla_pos.lon*10000000.0), //int32 LLA longitude in rad*1e7
+ (int)(rigidBodies[i].z*1000.0), //int32 LLA altitude in mm above elipsoid
+ (int)(rigidBodies[i].z*1000.0), //int32 HMSL height above mean sea level in mm
+ (int)(rigidBodies[i].ecef_vel.x*100.0), //int32 ECEF velocity X in m/s
+ (int)(rigidBodies[i].ecef_vel.y*100.0), //int32 ECEF velocity Y in m/s
+ (int)(rigidBodies[i].ecef_vel.z*100.0), //int32 ECEF velocity Z in m/s
+ 0,
+ (int)(heading*10000000.0)); //int32 Course in rad*1e7
+
+ // Reset the velocity differentiator if we calculated the velocity
+ if(rigidBodies[i].nVelocitySamples >= min_velocity_samples) {
+ rigidBodies[i].vel_x = 0;
+ rigidBodies[i].vel_y = 0;
+ rigidBodies[i].vel_z = 0;
+ rigidBodies[i].nVelocitySamples = 0;
+ rigidBodies[i].totalVelocitySamples = 0;
+ rigidBodies[i].nVelocityTransmit = 0;
+ }
+
+ rigidBodies[i].nSamples = 0;
+ }
+
+ return TRUE;
+}
+
+/** The NatNet sampler periodic function */
+static gboolean sample_data(GIOChannel *chan, GIOCondition cond, gpointer data) {
+ static unsigned char buffer_data[MAX_PACKETSIZE];
+ static int bytes_data = 0;
+
+ // Keep on reading until we have the whole packet
+ bytes_data += network_read(natnet_data, buffer_data, MAX_PACKETSIZE);
+
+ // Parse NatNet data
+ if(bytes_data >= 2 && bytes_data >= buffer_data[1]) {
+ natnet_parse(buffer_data);
+ bytes_data = 0;
+ }
+
+ return TRUE;
+}
+
+
+/** Print the program help */
+void print_help(char* filename) {
+ static const char *usage =
+ "Usage: %s [options]\n"
+ " Options :\n"
+ " -h, --help Display this help\n"
+ " -v, --verbose Verbosity level 0-2 (0)\n\n"
+
+ " -ac Use rigid ID for GPS of ac_id (multiple possible)\n\n"
+
+ " -multicast_addr NatNet server multicast address (239.255.42.99)\n"
+ " -server NatNet server IP address (255.255.255.255)\n"
+ " -version NatNet server version (2.5)\n"
+ " -data_port NatNet server data socket UDP port (1510)\n"
+ " -cmd_port NatNet server command socket UDP port (1511)\n\n"
+
+ " -ecef ECEF coordinates of the tracking system\n"
+ " -lla Latitude, longitude and altitude of the tracking system\n"
+ " -offset_angle Tracking system angle offset compared to the North in degrees\n\n"
+
+ " -tf Transmit frequency to the ivy bus in hertz (60)\n"
+ " -vel_samples Minimum amount of samples for the velocity differentiator (4)\n\n"
+
+ " -ivy_bus Ivy bus address and port (127.255.255.255:2010)\n";
+ fprintf(stderr, usage, filename);
+}
+
+/** Check the amount of arguments */
+void check_argcount(int argc, char** argv, int i, int expected) {
+ if(i+expected >= argc) {
+ fprintf(stderr, "Option %s expected %d arguments\r\n\r\n", argv[i], expected);
+ print_help(argv[0]);
+ exit(0);
+ }
+}
+
+/** Parse the options from the commandline */
+static void parse_options(int argc, char** argv) {
+ int i, count_ac = 0;
+ for(i = 1; i < argc; ++i) {
+
+ // Print help
+ if(strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
+ print_help(argv[0]);
+ exit(0);
+ }
+ // Set the verbosity level
+ if(strcmp(argv[i], "--verbosity") == 0 || strcmp(argv[i], "-v") == 0) {
+ check_argcount(argc, argv, i, 1);
+
+ verbose = atoi(argv[++i]);
+ }
+
+ // Set an rigid body to ivy ac_id
+ else if(strcmp(argv[i], "-ac") == 0) {
+ check_argcount(argc, argv, i, 2);
+
+ int rigid_id = atoi(argv[++i]);
+ uint8_t ac_id = atoi(argv[++i]);
+
+ if(rigid_id >= MAX_RIGIDBODIES) {
+ fprintf(stderr, "Rigid body ID must be less then %d (MAX_RIGIDBODIES)\n\n", MAX_RIGIDBODIES);
+ print_help(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+ ac_ids[rigid_id] = ac_id;
+ count_ac++;
+ }
+
+ // Set the NatNet multicast address
+ else if(strcmp(argv[i], "-multicast_addr") == 0) {
+ check_argcount(argc, argv, i, 1);
+
+ natnet_multicast_addr = argv[++i];
+ }
+ // Set the NatNet server ip address
+ else if(strcmp(argv[i], "-server") == 0) {
+ check_argcount(argc, argv, i, 1);
+
+ natnet_addr = argv[++i];
+ }
+ // Set the NatNet server version
+ else if(strcmp(argv[i], "-version") == 0) {
+ check_argcount(argc, argv, i, 1);
+
+ float version = atof(argv[++i]);
+ natnet_major = (uint8_t)version;
+ natnet_minor = (uint8_t)(version * 10.0) % 10;
+ }
+ // Set the NatNet server data port
+ else if(strcmp(argv[i], "-data_port") == 0) {
+ check_argcount(argc, argv, i, 1);
+
+ natnet_data_port = atoi(argv[++i]);
+ }
+ // Set the NatNet server command port
+ else if(strcmp(argv[i], "-cmd_port") == 0) {
+ check_argcount(argc, argv, i, 1);
+
+ natnet_cmd_port = atoi(argv[++i]);
+ }
+
+ // Set the Tracking system position in ECEF
+ else if (strcmp(argv[i], "-ecef") == 0) {
+ check_argcount(argc, argv, i, 3);
+
+ struct EcefCoor_d tracking_ecef;
+ tracking_ecef.x = atof(argv[++i]);
+ tracking_ecef.y = atof(argv[++i]);
+ tracking_ecef.z = atof(argv[++i]);
+ ltp_def_from_ecef_d(&tracking_ltp, &tracking_ecef);
+ }
+ // Set the tracking system position in LLA
+ else if (strcmp(argv[i], "-lla") == 0) {
+ check_argcount(argc, argv, i, 3);
+
+ struct EcefCoor_d tracking_ecef;
+ struct LlaCoor_d tracking_lla;
+ tracking_lla.lat = atof(argv[++i]);
+ tracking_lla.lon = atof(argv[++i]);
+ tracking_lla.alt = atof(argv[++i]);
+ ecef_of_lla_d(&tracking_ecef, &tracking_lla);
+ ltp_def_from_ecef_d(&tracking_ltp, &tracking_ecef);
+ }
+ // Set the tracking system offset angle in degrees
+ else if(strcmp(argv[i], "-offset_angle") == 0) {
+ check_argcount(argc, argv, i, 1);
+
+ tracking_offset_angle = atof(argv[++i]);
+ }
+
+ // Set the transmit frequency
+ else if(strcmp(argv[i], "-tf") == 0) {
+ check_argcount(argc, argv, i, 1);
+
+ freq_transmit = atoi(argv[++i]);
+ }
+ // Set the minimum amount of velocity samples for the differentiator
+ else if(strcmp(argv[i], "-vel_samples") == 0) {
+ check_argcount(argc, argv, i, 1);
+
+ min_velocity_samples = atoi(argv[++i]);
+ }
+
+ // Set the ivy bus
+ else if(strcmp(argv[i], "-ivy_bus") == 0) {
+ check_argcount(argc, argv, i, 1);
+
+ ivy_bus = argv[++i];
+ }
+
+ // Unknown option
+ else {
+ fprintf(stderr, "Unknown option %s\r\n\r\n", argv[i]);
+ print_help(argv[0]);
+ exit(0);
+ }
+ }
+
+ // Check if at least one aircraft is set
+ if(count_ac < 1) {
+ fprintf(stderr, "You must specify at least one aircraft (-ac )\n\n");
+ print_help(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+}
+
+int main(int argc, char** argv)
+{
+ // Set the default tracking system position and angle
+ struct EcefCoor_d tracking_ecef;
+ tracking_ecef.x = 3924304;
+ tracking_ecef.y = 300360;
+ tracking_ecef.z = 5002162;
+ tracking_offset_angle = 123.0 / 57.6;
+ ltp_def_from_ecef_d(&tracking_ltp, &tracking_ecef);
+
+ // Parse the options from cmdline
+ parse_options(argc, argv);
+ printf_debug("Tracking system Latitude: %f Longitude: %f Offset to North: %f degrees\n", DegOfRad(tracking_ltp.lla.lat), DegOfRad(tracking_ltp.lla.lon), DegOfRad(tracking_offset_angle));
+
+ // Create the network connections
+ printf_debug("Starting NatNet listening (multicast address: %s, data port: %d, version: %d.%d)\n", natnet_multicast_addr, natnet_data_port, natnet_major, natnet_minor);
+ natnet_data = network_new("", -1, natnet_data_port, 0); // Only receiving
+ network_subscribe_multicast(natnet_data, natnet_multicast_addr);
+ network_set_recvbuf(natnet_data, 0x100000); // 1MB
+
+ printf_debug("Starting NatNet command socket (server address: %s, command port: %d)\n", natnet_addr, natnet_cmd_port);
+ natnet_cmd = network_new(natnet_addr, natnet_cmd_port, 0, 1);
+ network_set_recvbuf(natnet_cmd, 0x100000); // 1MB
+
+ // Create the Ivy Client
+ GMainLoop *ml = g_main_loop_new(NULL, FALSE);
+ IvyInit("natnet2ivy", "natnet2ivy READY", 0, 0, 0, 0);
+ IvyStart(ivy_bus);
+
+ // Create the main timers
+ printf_debug("Starting transmitting and sampling timeouts (transmitting frequency: %dHz, minimum velocity samples: %d)\n",
+ freq_transmit, min_velocity_samples);
+ g_timeout_add(1000/freq_transmit, timeout_transmit_callback, NULL);
+
+ GIOChannel *sk = g_io_channel_unix_new(natnet_data->socket_in);
+ g_io_add_watch(sk, G_IO_IN | G_IO_NVAL | G_IO_HUP,
+ sample_data, NULL);
+
+ // Run the main loop
+ g_main_loop_run(ml);
+
+ return 0;
+}
diff --git a/sw/ground_segment/multimon/Makefile b/sw/ground_segment/multimon/Makefile
index 6f2fb1675f..03f60be811 100644
--- a/sw/ground_segment/multimon/Makefile
+++ b/sw/ground_segment/multimon/Makefile
@@ -106,13 +106,16 @@ $(BINDIR)/multimon: $(OBJ_L2) $(OBJ_L1) $(OBJ_MISC)
$(Q)$(CC) $^ $(LDFLAGS) $(LDFLAGSX) -o $@
$(BINDIR)/gen: $(OBJ_GEN)
- $(CC) $^ $(LDFLAGS) -o $@
+ @echo LD $@
+ $(Q)$(CC) $^ $(LDFLAGS) -o $@
$(BINDIR)/mkcostab: $(BINDIR)/mkcostab.o
- $(CC) $^ $(LDFLAGS) -o $@
+ @echo LD $@
+ $(Q)$(CC) $^ $(LDFLAGS) -o $@
costabi.c costabf.c: $(BINDIR)/mkcostab
- $(BINDIR)/mkcostab
+ @echo EXEC $<
+ $(Q)$(BINDIR)/mkcostab
libtest: pprzlib.o demodml.c demod.ml test.ml
@@ -124,10 +127,12 @@ hdlc_test : multimon.cma test_gen_hdlc.ml
hdlc.cmo : hdlc.cmi
%.cmo : %.ml
- $(OCAMLC) -c $<
+ @echo OC $<
+ $(Q)$(OCAMLC) -c $<
%.cmi : %.mli
- $(OCAMLC) $<
+ @echo OC $<
+ $(Q)$(OCAMLC) $<
clean:
$(Q)rm -fr *.cm* mkcostab .depend
diff --git a/sw/ground_segment/tmtc/Makefile b/sw/ground_segment/tmtc/Makefile
index 77a51e6cd6..6aa0368644 100644
--- a/sw/ground_segment/tmtc/Makefile
+++ b/sw/ground_segment/tmtc/Makefile
@@ -41,71 +41,66 @@ SERVERCMO = server_globals.cmo aircraft.cmo wind.cmo airprox.cmo kml.cmo fw_serv
SERVERCMX = $(SERVERCMO:.cmo=.cmx)
-all: link server messages settings dia diadec $(VAR)/boa.conf ivy_tcp_aircraft ivy_tcp_controller broadcaster ivy2udp ivy_serial_bridge
+all: link server messages settings dia diadec ivy_tcp_aircraft ivy_tcp_controller broadcaster ivy2udp ivy_serial_bridge app_server
opt: server.opt
clean:
- $(Q)rm -f link server messages settings dia diadec *.bak *~ core *.o .depend *.opt *.out *.cm* ivy_tcp_aircraft ivy_tcp_controller broadcaster ivy2udp ivy_serial_bridge gpsd2ivy c_ivy_client_example_1 c_ivy_client_example_2 c_ivy_client_example_3
+ $(Q)rm -f link server messages settings dia diadec *.bak *~ core *.o .depend *.opt *.out *.cm* ivy_tcp_aircraft ivy_tcp_controller broadcaster ivy2udp ivy_serial_bridge app_server gpsd2ivy c_ivy_client_example_1 c_ivy_client_example_2 c_ivy_client_example_3
-$(VAR)/boa.conf :$(CONF)/boa.conf
- mkdir -p $(VAR)
- sed 's|PAPARAZZI_HOME|$(PAPARAZZI_HOME)|' < $< > $@
-
-
-messages : messages.cmo
+messages : messages.cmo $(LIBPPRZCMA)
@echo OL $@
$(Q)$(OCAMLC) $(INCLUDES) -o $@ $(LINKPKG) gtkInit.cmo $<
-settings : settings.cmo ../cockpit/page_settings.cmo
+settings : settings.cmo ../cockpit/page_settings.cmo $(LIBPPRZCMA)
@echo OL $@
$(Q)$(OCAMLC) $(INCLUDES) -o $@ $(XLINKPKG) gtkInit.cmo -I ../cockpit gtk_save_settings.cmo saveSettings.cmo page_settings.cmo $<
-server : $(SERVERCMO)
+server : $(SERVERCMO) $(LIBPPRZCMA)
@echo OL $@
$(Q)$(OCAMLC) $(INCLUDES) -o $@ $(LINKPKG) $(SERVERCMO)
-server.opt : $(SERVERCMX)
+server.opt : $(SERVERCMX) $(LIBPPRZCMXA)
@echo OOL $@
$(Q)$(OCAMLOPT) $(INCLUDES) -o $@ -package glibivy,pprz -linkpkg $(SERVERCMX)
-link : link.cmo $(LIBMULTIMONCMA)
+link : link.cmo $(LIBMULTIMONCMA) $(LIBPPRZCMA)
@echo OL $@
$(Q)$(OCAMLC) $(INCLUDES) -o $@ $(LINKPKG) $(LIBMULTIMONDLL) $<
-ivy_tcp_aircraft : ivy_tcp_aircraft.cmo $(LIBMULTIMONCMA)
+ivy_tcp_aircraft : ivy_tcp_aircraft.cmo $(LIBMULTIMONCMA) $(LIBPPRZCMA)
@echo OL $@
$(Q)$(OCAMLC) $(INCLUDES) -o $@ $(LINKPKG) $(LIBMULTIMONDLL) $<
-ivy_tcp_controller : ivy_tcp_controller.cmo $(LIBMULTIMONCMA)
+ivy_tcp_controller : ivy_tcp_controller.cmo $(LIBMULTIMONCMA) $(LIBPPRZCMA)
@echo OL $@
$(Q)$(OCAMLC) $(INCLUDES) -o $@ $(LINKPKG) $(LIBMULTIMONDLL) $<
-broadcaster : broadcaster.cmo $(LIBMULTIMONCMA)
+broadcaster : broadcaster.cmo $(LIBMULTIMONCMA) $(LIBPPRZCMA)
@echo OL $@
$(Q)$(OCAMLC) $(INCLUDES) -o $@ $(LINKPKG) $(LIBMULTIMONDLL) $<
-ivy2udp : ivy2udp.cmo
+ivy2udp : ivy2udp.cmo $(LIBPPRZCMA)
@echo OL $@
$(Q)$(OCAMLC) $(INCLUDES) -o $@ $(LINKPKG) $<
-dia : dia.cmo $(LIBMULTIMONCMA)
+dia : dia.cmo $(LIBMULTIMONCMA) $(LIBPPRZCMA)
@echo OL $@
$(Q)$(OCAMLC) $(INCLUDES) -o $@ $(LINKPKG) $(LIBMULTIMONDLL) $<
-diadec : diadec.cmo $(LIBMULTIMONCMA)
+diadec : diadec.cmo $(LIBMULTIMONCMA) $(LIBPPRZCMA)
@echo OL $@
$(Q)$(OCAMLC) $(INCLUDES) -o $@ $(LINKPKG) $(LIBMULTIMONDLL) $<
-150m : 150m.cmo
+150m : 150m.cmo $(LIBPPRZCMA)
@echo OL $@
$(Q)$(OCAMLC) $(INCLUDES) -o $@ $(LINKPKG) gtkInit.cmo $<
@@ -138,6 +133,10 @@ ifeq ("$(UNAME)","Darwin")
C_INCLUDES = $(shell if test -d /opt/paparazzi/include; then echo "-I/opt/paparazzi/include"; elif test -d /opt/local/include; then echo "-I/opt/local/include"; fi)
endif
+app_server: app_server.c
+ @echo OL $@
+ $(Q)$(CC) $(GLIB_CFLAGS) $(shell pkg-config libxml-2.0 gio-2.0 ivy-glib --cflags) -o $@ $^ -lm -lz $(shell pkg-config libxml-2.0 gio-2.0 ivy-glib libpcre --libs)
+
gpsd2ivy: gpsd2ivy.c
$(CC) $(GLIB_CFLAGS) $(C_LIBRARYS) $(C_INCLUDES) -o $@ $< $(GLIB_LDFLAGS) -lgps
@@ -151,7 +150,8 @@ c_ivy_client_example_3: c_ivy_client_example_3.c
$(CC) $(GTK_CFLAGS) $(C_LIBRARYS) $(C_INCLUDES) -o $@ $< $(GTK_LDFLAGS)
ivy_serial_bridge: ivy_serial_bridge.c
- $(CC) $(GTK_CFLAGS) $(C_LIBRARYS) $(C_INCLUDES) -o $@ $< $(GTK_LDFLAGS)
+ @echo OL $@
+ $(Q)$(CC) $(GTK_CFLAGS) $(C_LIBRARYS) $(C_INCLUDES) -o $@ $< $(GTK_LDFLAGS)
.PHONY: all opt clean
@@ -161,7 +161,8 @@ ivy_serial_bridge: ivy_serial_bridge.c
#
.depend: Makefile
- $(OCAMLDEP) -I $(LIBPPRZDIR) -I ../multimon *.ml* > .depend
+ @echo DEPEND $@
+ $(Q)$(OCAMLDEP) -I $(LIBPPRZDIR) -I ../multimon *.ml* > .depend
ifneq ($(MAKECMDGOALS),clean)
-include .depend
diff --git a/sw/ground_segment/tmtc/app_server.c b/sw/ground_segment/tmtc/app_server.c
new file mode 100644
index 0000000000..e703dbc1a3
--- /dev/null
+++ b/sw/ground_segment/tmtc/app_server.c
@@ -0,0 +1,812 @@
+/*
+ * Copyright (C) 2014
+ *
+ * Created by: Savas Sen - ENAC UAV Lab
+ *
+ * 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.
+ *
+ */
+
+/*
+ * Server application for remote devices such as Android.
+ *
+ * It forwards paparazzi ground class messages to remote app
+ * and receives commands from allowed clients to control the aircraft
+ *
+ * Several clients can be connected at the same time with full or restricted access
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+// assuming local path from sw/ground_segment/tmtc
+char defaultPprzFolder[] = "../../..";
+
+char defaultAppPass[] = "1234"; //4 char password to control ac's over app "pass ground stg stg stg..
+char* AppPass;
+
+#define BUFLEN 2048
+#define MAXCLIENT 20
+#define MAXIPLEN 50
+#define MAXNAMELENGTH 500
+#define MAXDEVICENUMB 255
+
+#define MAXWPNUMB 50 //NUMBER OF WP PER AC (MAX)
+#define MAXWPNUMB 50 //NUMBER OF WP PER AC (MAX)
+#define MAXWPNAMELEN 50 //WP NAME LENGTH (MAX)
+
+// Default TCP port (listen clients commands)
+int tcp_port = 5010;
+// Default UDP port (broadcast data to clients)
+int udp_port = 5005;
+
+#ifdef __APPLE__
+char defaultIvyBus[] = "224.255.255.255:2010";
+#else
+char defaultIvyBus[] = "127.255.255.255:2010";
+#endif
+char* IvyBus;
+
+char ivybuffer[BUFLEN];
+
+// verbose flag
+int verbose = 0;
+
+//Block structure
+typedef struct {
+ //Will we need any more block data?
+ char Bl_Name[MAXWPNAMELEN];
+} bl_data;
+
+//Waypoint structure
+typedef struct {
+ //Will we need any more waypoint data?
+ char Wp_Name[MAXWPNAMELEN];
+} wp_data;
+
+//Aircraft Data Structure
+typedef struct {
+ int device_id;
+ char name[MAXNAMELENGTH];
+ char type[MAXNAMELENGTH];
+ char color[MAXNAMELENGTH];
+ char flight_plan_path[MAXNAMELENGTH];
+ char airframe_path[MAXNAMELENGTH];
+ char settings_path[MAXNAMELENGTH];
+ int dl_launch_ind;
+ int kill_thr_ind;
+ wp_data AcWp[MAXWPNUMB];
+ bl_data AcBl[MAXWPNUMB];
+} device_names;
+
+device_names DevNames[MAXDEVICENUMB];
+
+//Connected Clients Data Structure
+typedef struct {
+ int used ;
+ int client_port; //do we need that??
+ char client_ip[MAXIPLEN];
+} client_data;
+
+client_data ConnectedClients[MAXCLIENT]; //Holds all status of devices
+
+
+//Remove Client from UdpBroadcast list
+void remove_client(char* RemClientIpAd) {
+ //remove client from client list
+ int i=0;
+ for (; i < MAXCLIENT; i++) {
+ //Search thru the client list
+
+ if ( (ConnectedClients[i].used > 0) ) {
+ //Client list is being used
+ if ( g_strcmp0(RemClientIpAd , ConnectedClients[i].client_ip) == 0 ) {
+ //record found clean it!!
+ ConnectedClients[i].client_ip[0]='\0';
+ ConnectedClients[i].used=0;
+ if (verbose) {
+ printf("App Server: Client removed from client list %s\n", RemClientIpAd);
+ fflush(stdout);
+ }
+ return;
+ }
+ }
+ }
+ //no record found!
+ if (verbose) {
+ printf("App Server: No record found to be removed from client list\n");
+ fflush(stdout);
+ }
+}
+
+//Record client (if new)
+void add_client(char* ClientIpAd) {
+ /* Check if client exists. If exists return else record it */
+ int i;
+ for (i = 0; i < MAXCLIENT; i++) {
+ //Search thru the client list
+ if ( (ConnectedClients[i].used > 0) ) {
+ //Client list is being used
+ if ( g_strcmp0(ClientIpAd , ConnectedClients[i].client_ip) == 0 ) {
+ //Already in client list return
+ return;
+ }
+ continue;
+ }
+ //no record found!
+
+ //record new client ip
+ g_stpcpy(ConnectedClients[i].client_ip,ClientIpAd);
+ //
+ ConnectedClients[i].used = 1;
+ if (verbose) {
+ printf("App Server: New client added to client list %s\n", ConnectedClients[i].client_ip);
+ fflush(stdout);
+ }
+ break;
+ }
+}
+
+//Get aircraft name and color
+int get_ac_data(char* InStr, char* RetBuf) {
+ const char delimiters[] = " ";
+ int AcID;
+ char StrBuf[BUFLEN];
+
+ //Make writable copy
+ strcpy(StrBuf, InStr);
+ strtok(StrBuf, delimiters);
+
+ //Get id from command string
+ AcID = atoi(strtok(NULL, delimiters));
+ //Get & create return string
+ if ( AcID > 0 ) {
+ //Dont search it, it is thereeee :)
+ sprintf(RetBuf, "AppServer ACd %d %s %s %s %d %d\n", AcID,
+ DevNames[AcID].name,
+ DevNames[AcID].type,
+ DevNames[AcID].color,
+ DevNames[AcID].dl_launch_ind,
+ DevNames[AcID].kill_thr_ind);
+ }
+ return AcID;
+}
+
+//Get aircraft name waypoint names,ids
+int get_wp_data(char* InStr, char* RetBuf) {
+ //Input command
+ const char delimiters[] = " ";
+ int AcID;
+ char StrBuf[BUFLEN];
+
+ //Make writable copy
+ strcpy(StrBuf, InStr);
+ strtok(StrBuf, delimiters);
+
+ //Get id from command string
+ AcID = atoi(strtok(NULL, delimiters));
+ //Get & create return string
+ if ( AcID > 0 ) {
+ //create wp data string
+ char WpStr[BUFLEN] = "";
+ int i = 1;
+ while ( strlen(DevNames[AcID].AcWp[i].Wp_Name) > 0 ) {
+ //Read & add wp data to return string
+ sprintf(WpStr, "%s%d,%s ", WpStr, i, DevNames[AcID].AcWp[i].Wp_Name);
+ i++;
+ }
+ sprintf(RetBuf, "AppServer WPs %d %s\n", AcID, WpStr);
+ }
+ return AcID;
+}
+
+//Get block names,ids
+int get_bl_data(char* InStr, char* RetBuf) {
+ //Input command
+ const char delimiters[] = " ";
+ int AcID;
+ char StrBuf[BUFLEN];
+
+ //Make writable copy
+ strcpy(StrBuf, InStr);
+ strtok(StrBuf, delimiters);
+
+ //Get id from command string
+ AcID = atoi(strtok (NULL, delimiters));
+ //Get & create return string
+ if ( AcID > 0 ) {
+ //create wp data string
+ char BlStr[BUFLEN] ="";
+ int i=1;
+ while ( strlen(DevNames[AcID].AcBl[i].Bl_Name) > 0 ) {
+ sprintf(BlStr, "%s%s", BlStr, DevNames[AcID].AcBl[i].Bl_Name);
+ i++;
+ }
+ sprintf(RetBuf, "AppServer BLs %d %s\n", AcID, BlStr);
+ }
+ return AcID;
+}
+
+//Bfoadcast ivy msgs to clients
+void broadcast_to_clients () {
+
+ int i;
+ for (i = 0; i < MAXCLIENT; i++) {
+ if (ConnectedClients[i].used > 0) {
+
+ //Send data
+ GInetAddress *udpAddress;
+ GSocketAddress *udpSocketAddress;
+ GSocket *udpSocket;
+
+ udpAddress = g_inet_address_new_from_string(ConnectedClients[i].client_ip);
+
+ udpSocketAddress = g_inet_socket_address_new(udpAddress, udp_port);
+
+ udpSocket = g_socket_new(G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, 17, NULL);
+
+ if (g_socket_connect(udpSocket, udpSocketAddress, NULL, NULL) == FALSE) {
+ printf("App Server: stg wrong with socket connect\n");
+ fflush(stdout);
+ }
+ if (g_socket_send(udpSocket, ivybuffer, strlen(ivybuffer) , NULL, NULL) < 0) {
+ printf("App Server: stg wrong with send func\n");
+ fflush(stdout);
+ }
+ if (g_socket_close(udpSocket, NULL) == FALSE) {
+ printf("App Server: stg wrong with socket close\n");
+ fflush(stdout);
+ }
+ //Unref objects
+ g_object_unref(udpAddress);
+ g_object_unref(udpSocketAddress);
+ g_object_unref(udpSocket);
+ }
+ }
+}
+
+//Read tcp requests of connected clients
+gboolean network_read(GIOChannel *source, GIOCondition cond, gpointer data) {
+
+ GString *s = g_string_new(NULL);
+ GError *error = NULL;
+ GIOStatus ret = g_io_channel_read_line_string(source, s, NULL, &error);
+
+ if (ret == G_IO_STATUS_ERROR) {
+ //unref connection
+ g_object_unref (data);
+ g_string_free (s,TRUE);
+ return FALSE;
+ }
+ else{
+ //Read request command
+ gchar *RecString;
+ RecString=s->str;
+ //check client password
+ if ((strncmp(RecString, AppPass, strlen(AppPass))) == 0) {
+ //Password ok can send command
+ GString *incs = g_string_new(s->str);
+ incs = g_string_erase(s,0,(strlen(AppPass)+1));
+ IvySendMsg("%s",incs->str);
+ if (verbose) {
+ printf("App Server: Command passed to ivy.. %s\n",incs->str);
+ fflush(stdout);
+ }
+ }
+ //AC data request. (Ignore client password)
+ else if ((strncmp(RecString, "getac ", strlen("getac "))) == 0) {
+ //AC data request
+ char AcData[BUFLEN];
+ //Read ac data
+ if (get_ac_data(RecString, AcData)) {
+ //Send requested data to client
+ GOutputStream * ostream = g_io_stream_get_output_stream (data);
+ g_output_stream_write(ostream, AcData, strlen(AcData), NULL, &error);
+ }
+ }
+ //Waypoint data request (Ignore client password)
+ else if ((strncmp(RecString, "getwp ", strlen("getwp "))) == 0) {
+ char AcData[BUFLEN];
+ //Read wp data of ac
+ if (get_wp_data(RecString, AcData)) {
+ //Send requested data to client
+ GOutputStream * ostream = g_io_stream_get_output_stream (data);
+ g_output_stream_write(ostream, AcData, strlen(AcData), NULL, &error);
+ }
+ }
+ //Waypoint data request (Ignore client password)
+ else if ((strncmp(RecString, "getbl ", strlen("getbl "))) == 0) {
+ char AcData[BUFLEN];
+ //Read block data of AC
+ if (get_bl_data(RecString, AcData)) {
+ //Send requested data to client
+ GOutputStream * ostream = g_io_stream_get_output_stream (data);
+ g_output_stream_write(ostream, AcData, strlen(AcData), NULL, &error);
+ }
+ }
+
+ //If client sends removeme command, remove it from broadcast list
+ else if ((strncmp( RecString, "removeme", strlen("removeme"))) == 0) {
+ GSocketAddress *sockaddr = g_socket_connection_get_remote_address(data, NULL);
+ GInetAddress *addr = g_inet_socket_address_get_address(G_INET_SOCKET_ADDRESS(sockaddr));
+ //Read sender ip
+ if (verbose) {
+ printf("App Server: need to remove %s\n", g_inet_address_to_string(addr));
+ fflush(stdout);
+ }
+ //Remove client
+ remove_client(g_inet_address_to_string(addr));
+ //Free objects
+ g_string_free(s, TRUE);
+ g_object_unref(sockaddr);
+ g_object_unref(addr);
+ g_object_unref(data);
+ //Return false to stop listening this socket
+ return FALSE;
+ }
+ else {
+ //Unknown command
+ if (verbose) {
+ printf("App Server: Client send an unknown command: %s\n",RecString);
+ fflush(stdout);
+ }
+ }
+ }
+
+ if (ret == G_IO_STATUS_EOF) {
+ //Client disconnected
+ if (verbose) {
+ printf("App Server: Client disconnected without saying 'bye':(\n");
+ fflush(stdout);
+ }
+ g_string_free(s, TRUE);
+ //Unref the socket and return false to allow the client to reconnect
+ g_object_unref(data);
+ return FALSE;
+ }
+ //None above.. Keep listening the socket
+ g_string_free(s, TRUE);
+ return TRUE;
+}
+
+//New tcp conection
+gboolean new_connection(GSocketService *service, GSocketConnection *connection, GObject *source_object, gpointer user_data) {
+
+ //New client connected
+ GSocketAddress *sockaddr = g_socket_connection_get_remote_address(connection, NULL);
+ GInetAddress *addr = g_inet_socket_address_get_address(G_INET_SOCKET_ADDRESS(sockaddr));
+ guint16 port = g_inet_socket_address_get_port(G_INET_SOCKET_ADDRESS(sockaddr));
+
+ if (verbose) {
+ printf("App Server: New Connection from %s:%d\n", g_inet_address_to_string(addr), port);
+ fflush(stdout);
+ }
+
+ //Record client (if new)
+ add_client(g_inet_address_to_string(addr));
+
+ g_object_ref (connection);
+ GSocket *socket = g_socket_connection_get_socket(connection);
+
+ gint fd = g_socket_get_fd(socket);
+ GIOChannel *channel = g_io_channel_unix_new(fd);
+ g_io_add_watch(channel, G_IO_IN, (GIOFunc) network_read, connection);
+ return TRUE;
+}
+
+//Ivy msg function
+void Ivy_All_Msgs(IvyClientPtr app, void *user_data, int argc, char *argv[]){
+ //Ivy msg received broadcast to clients..
+ sprintf(ivybuffer, "%s", argv[0]);
+ broadcast_to_clients();
+}
+
+//Parse AC flight plan xml (block & waypoint names
+void parse_ac_fp(int DevNameIndex, char *filename) {
+ xmlTextReaderPtr reader;
+ int ret;
+
+ reader = xmlReaderForFile(filename, NULL, XML_PARSE_NOWARNING | XML_PARSE_NOERROR); /* Dont validate with the DTD */
+
+ xmlChar *name, *value;
+ if (reader != NULL) {
+ ret = xmlTextReaderRead(reader);
+
+ int wp_queue=1;
+ int bl_queue=1;
+ while (ret == 1) {
+ name = xmlTextReaderName(reader);
+ if (name == NULL) {
+ name = xmlStrdup(BAD_CAST "--");
+ }
+
+ //read waypoint names
+ if (xmlStrEqual(name, (const xmlChar *)"waypoint")) {
+ //waypoint node read name attr.
+ xmlTextReaderMoveToAttribute(reader,(const xmlChar *)"name");
+ value = xmlTextReaderValue(reader);
+ //copy it to DevNames[] structure
+ strcpy(DevNames[DevNameIndex].AcWp[wp_queue].Wp_Name, (char *) value);
+ wp_queue++;
+ }
+
+ if (xmlStrEqual(name, (const xmlChar *)"block")) {
+ //Read block names
+ if ( xmlTextReaderAttributeCount(reader) >= 1 ) {
+ xmlTextReaderMoveToAttribute(reader,(const xmlChar *)"name");
+ value = xmlTextReaderValue(reader);
+ strcpy(DevNames[DevNameIndex].AcBl[bl_queue].Bl_Name, (char *) value);
+ bl_queue++;
+ }
+ }
+
+ ret = xmlTextReaderRead(reader);
+ }
+
+ xmlFreeTextReader(reader);
+ if (ret != 0) {
+ if (verbose) {
+ printf("App Server: failed to parse %s\n", filename);
+ fflush(stdout);
+ }
+ }
+ }
+ else
+ {
+ if (verbose) {
+ printf("App Server: Unable to open %s\n", filename);
+ fflush(stdout);
+ }
+ }
+
+}
+
+//check firmware type
+//return true if "acceptable" type (e.g. fixedwing or rotorcraft)
+int check_firmware_type (xmlChar* firmware) {
+ return (xmlStrEqual(firmware, (const xmlChar *)"fixedwing")
+ || xmlStrEqual(firmware, (const xmlChar *)"rotorcraft"));
+}
+
+void parse_ac_af(int DevNameIndex, char *filename) {
+ xmlTextReaderPtr reader;
+ int ret;
+
+ reader = xmlReaderForFile(filename, NULL, XML_PARSE_NOWARNING | XML_PARSE_NOERROR); /* Dont validate with the DTD */
+
+ xmlChar *name, *value;
+ if (reader != NULL) {
+ ret = xmlTextReaderRead(reader);
+
+ while (ret == 1) {
+ name = xmlTextReaderName(reader);
+
+ if (name == NULL) {
+ name = xmlStrdup(BAD_CAST "--");
+ }
+
+ if (xmlStrEqual(name, (const xmlChar *)"firmware")) {
+ xmlTextReaderMoveToAttribute(reader,(const xmlChar *)"name");
+ value = xmlTextReaderValue(reader);
+ //check if firmware name is accaptable
+ if (check_firmware_type(value)>0) {
+ strcpy(DevNames[DevNameIndex].type, (char *) value);
+ }
+
+ }
+
+ if (xmlStrEqual(name, (const xmlChar *)"define")) {
+ xmlTextReaderMoveToAttribute(reader,(const xmlChar *)"name");
+ value = xmlTextReaderValue(reader);
+
+ if (xmlStrEqual(value, (const xmlChar *)"AC_ICON")) {
+ xmlTextReaderMoveToAttribute(reader,(const xmlChar *)"value");
+ value = xmlTextReaderValue(reader);
+ strcpy(DevNames[DevNameIndex].type, (char *) value);
+ return;
+ }
+ }
+
+ ret = xmlTextReaderRead(reader);
+ }
+
+ xmlFreeTextReader(reader);
+ if (ret != 0) {
+ if (verbose) {
+ printf("App Server: failed to parse %s\n", filename);
+ fflush(stdout);
+ }
+ }
+ } else {
+ if (verbose) {
+ printf("App Server: Unable to open %s\n", filename);
+ fflush(stdout);
+ }
+ }
+
+}
+
+//Parse dl values
+void parse_dl_settings(int DevNameIndex, char *filename) {
+
+ xmlTextReaderPtr reader;
+ int ret;
+
+ reader = xmlReaderForFile(filename, NULL, XML_PARSE_NOWARNING | XML_PARSE_NOERROR); /* Dont validate with the DTD */
+
+ xmlChar *name, *value;
+ if (reader != NULL) {
+ ret = xmlTextReaderRead(reader);
+
+ int valind = 0;
+ while (ret == 1) {
+ name = xmlTextReaderName(reader);
+ if (name == NULL) {
+ name = xmlStrdup(BAD_CAST "--");
+ }
+
+ if (xmlStrEqual(name, (const xmlChar *)"dl_setting")) {
+ xmlTextReaderMoveToAttribute(reader,(const xmlChar *)"var");
+
+ value = xmlTextReaderValue(reader);
+ if (xmlStrEqual(value, (const xmlChar *)"launch")) {
+ DevNames[DevNameIndex].dl_launch_ind=valind;
+ }
+
+ if (xmlStrEqual(value, (const xmlChar *)"kill_throttle")) {
+ DevNames[DevNameIndex].kill_thr_ind=valind;
+ }
+ xmlTextReaderNext(reader);
+ valind+=1;
+ }
+ ret = xmlTextReaderRead(reader);
+ }
+ xmlFreeTextReader(reader);
+ if (ret != 0) {
+ if (verbose) {
+ printf("App Server: %s : failed to parse\n", filename);
+ fflush(stdout);
+ }
+ }
+ }
+ else {
+ if (verbose) {
+ printf("App Server: Unable to open %s\n", filename);
+ fflush(stdout);
+ }
+ }
+}
+
+//Parse ac data from conf.xml
+void parse_ac_data (char *PprzFolder) {
+ xmlTextReaderPtr reader;
+ int ret;
+
+ //Create full file path
+ char xmlFileName[BUFLEN];
+ strcpy(xmlFileName, PprzFolder);
+ strcat(xmlFileName, "/conf/conf.xml");
+
+ reader = xmlReaderForFile(xmlFileName, NULL, XML_PARSE_NOWARNING | XML_PARSE_NOERROR); /* Dont validate with the DTD */
+
+ xmlChar *AcName, *AcInd, *FpPath, *AcColor, *name, *AfPath;
+ if (reader != NULL) {
+ ret = xmlTextReaderRead(reader);
+ int AcId;
+
+ while (ret == 1) {
+ name = xmlTextReaderName(reader);
+ if (name == NULL) {
+ name = xmlStrdup(BAD_CAST "--");
+ }
+ //read waypoint names
+
+ if (xmlStrEqual(name, (const xmlChar *)"aircraft")) {
+
+ xmlTextReaderMoveToAttribute(reader,(const xmlChar *)"ac_id");
+ AcInd = xmlTextReaderValue(reader);
+
+ xmlTextReaderMoveToAttribute(reader,(const xmlChar *)"name");
+ AcName = xmlTextReaderValue(reader);
+
+ xmlTextReaderMoveToAttribute(reader,(const xmlChar *)"airframe");
+ AfPath = xmlTextReaderValue(reader);
+
+ xmlTextReaderMoveToAttribute(reader,(const xmlChar *)"flight_plan");
+ FpPath = xmlTextReaderValue(reader);
+
+ xmlTextReaderMoveToAttribute(reader,(const xmlChar *)"gui_color");
+ AcColor = xmlTextReaderValue(reader);
+
+ //Get Device Id
+ AcId = atoi(((char *) AcInd));
+
+ //Save Device Name
+ strcpy(DevNames[AcId].name, ((char *) AcName));
+
+ //Save color
+ strcpy(DevNames[AcId].color, (char *) AcColor);
+
+ //Save Flight Plan Path
+ strcpy(DevNames[AcId].flight_plan_path, "/conf/");
+ strcat(DevNames[AcId].flight_plan_path , (char *) FpPath);
+
+ //Save airframe Path
+ strcpy(DevNames[AcId].airframe_path, "/conf/");
+ strcat(DevNames[AcId].airframe_path , (char *) AfPath);
+
+ //Save Settings Path
+ sprintf(DevNames[AcId].settings_path, "/var/%s/settings.xml", (char *) AcName);
+
+ //parse flight plan file for waypoint and block names
+ char FlightPlanPath[BUFLEN];
+ strcpy(FlightPlanPath, PprzFolder);
+ strcat(FlightPlanPath, DevNames[AcId].flight_plan_path);
+ parse_ac_fp(AcId, FlightPlanPath);
+
+ //parse airframe file
+ char AirframePath[BUFLEN];
+ strcpy(AirframePath, PprzFolder);
+ strcat(AirframePath, DevNames[AcId].airframe_path);
+ parse_ac_af(AcId, AirframePath);
+
+ //parse dl_settings for launch & kill throttle
+ char SettingsPath[BUFLEN];
+ strcpy(SettingsPath, PprzFolder);
+ strcat(SettingsPath, DevNames[AcId].settings_path);
+ parse_dl_settings(AcId, SettingsPath);
+ }
+
+ ret = xmlTextReaderRead(reader);
+ }
+
+ xmlFreeTextReader(reader);
+ if (ret != 0) {
+ if (verbose) {
+ printf("App Server: failed to parse %s\n", xmlFileName);
+ fflush(stdout);
+ }
+ }
+ }
+ else{
+ if (verbose) {
+ printf("App Server: Unable to open %s\n", xmlFileName);
+ fflush(stdout);
+ }
+ }
+
+ return;
+} // end of XMLParseDoc function
+
+// Print help message
+void print_help() {
+ printf("Usage: app_server [options]\n");
+ printf(" Options :\n");
+ printf(" -t \tfor receiving devices commands (default: %d)\n", tcp_port);
+ printf(" -u \tfor sending AC data (default: %d)\n", udp_port);
+ printf(" -b \tdefault is %s\n", defaultIvyBus);
+ printf(" -p \tpassword for connection with control capabilities (default is %s)\n", defaultAppPass);
+ printf(" -v\tverbose\n");
+ printf(" -h --help show this help\n");
+}
+
+int main(int argc, char **argv) {
+
+ // default password
+ AppPass = defaultAppPass;
+
+ // try environment variable first, set to default if failed
+ IvyBus = getenv("IVYBUS");
+ if (IvyBus == NULL) IvyBus = defaultIvyBus;
+
+ // Look for paparazzi folder (PAPARAZZI_HOME or assume local path by default)
+ char* PprzFolder = getenv("PAPARAZZI_HOME");
+ if (PprzFolder == NULL) PprzFolder = defaultPprzFolder;
+
+ // Parse options
+ int i;
+ for (i = 1; i < argc; ++i) {
+ if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
+ print_help();
+ exit(0);
+ }
+ else if (strcmp(argv[i], "-t") == 0) {
+ tcp_port = atoi(argv[++i]);
+ }
+ else if (strcmp(argv[i], "-u") == 0) {
+ udp_port = atoi(argv[++i]);
+ }
+ else if (strcmp(argv[i], "-b") == 0) {
+ IvyBus = argv[++i];
+ }
+ else if (strcmp(argv[i], "-p") == 0) {
+ AppPass = argv[++i];
+ }
+ else if (strcmp(argv[i], "-v") == 0) {
+ verbose = 1;
+ }
+ else {
+ printf("App Server: Unknown option\n");
+ print_help();
+ exit(0);
+ }
+ }
+
+ if (verbose) {
+ printf("### Paparazzi App Server ###\n");
+ printf("Using Paparazzi Folder : %s\n", PprzFolder);
+ printf("Server listen port (TCP) : %d\n", tcp_port);
+ printf("Server broadcast port (UDP) : %d\n", udp_port);
+ printf("Control Pass : %s\n", AppPass);
+ printf("Ivy Bus : %s\n", IvyBus);
+ fflush(stdout);
+ }
+
+ //Parse conf.xml
+ parse_ac_data(PprzFolder);
+
+ //Create tcp listener
+#if !GLIB_CHECK_VERSION (2, 35, 1)
+ // init GLib type system (only for older version)
+ g_type_init();
+#endif
+ GSocketService *service = g_socket_service_new();
+
+ GInetAddress *address = g_inet_address_new_any(G_SOCKET_FAMILY_IPV6); //G_SOCKET_FAMILY_IPV4 could be used
+ GSocketAddress *socket_address = g_inet_socket_address_new(address, tcp_port);
+ //Add listener
+ g_socket_listener_add_address(G_SOCKET_LISTENER(service), socket_address, G_SOCKET_TYPE_STREAM,
+ G_SOCKET_PROTOCOL_TCP, NULL, NULL, NULL);
+
+ g_object_unref(socket_address);
+ g_object_unref(address);
+ g_socket_service_start(service);
+
+ //Connect listening signal
+ g_signal_connect(service, "incoming", G_CALLBACK(new_connection), NULL);
+
+ //Here comes the ivy bindings
+ IvyInit ("PPRZ_App_Server", "Papparazzi App Server Ready", NULL, NULL, NULL, NULL);
+
+ IvyBindMsg(Ivy_All_Msgs, NULL, "(^ground .*)");
+ IvyBindMsg(Ivy_All_Msgs, NULL, "(^\\S* AIRSPEED (\\S*) (\\S*) (\\S*) (\\S*))");
+ IvyStart(IvyBus);
+
+ GMainLoop *loop = g_main_loop_new(NULL, FALSE);
+
+ if (verbose) {
+ printf("Starting App Server\n");
+ fflush(stdout);
+ }
+
+ g_main_loop_run(loop);
+
+ if (verbose) {
+ printf("Stoping App Server\n");
+ fflush(stdout);
+ }
+ return 0;
+}
+
diff --git a/sw/ground_segment/tmtc/boa b/sw/ground_segment/tmtc/boa
deleted file mode 100755
index 75446c3443..0000000000
--- a/sw/ground_segment/tmtc/boa
+++ /dev/null
@@ -1,6 +0,0 @@
-#! /bin/sh
-if test -z "$PAPARAZZI_SRC"; then
- PAPARAZZI_SRC=/usr/share/paparazzi
-fi
-mkdir -p $PAPARAZZI_HOME/var/logs
-/usr/sbin/boa -d -f $PAPARAZZI_HOME/var/boa.conf
diff --git a/sw/ground_segment/tmtc/server.ml b/sw/ground_segment/tmtc/server.ml
index 4a637d3fc3..2de1e85ef8 100644
--- a/sw/ground_segment/tmtc/server.ml
+++ b/sw/ground_segment/tmtc/server.ml
@@ -201,7 +201,7 @@ let send_dl_values = fun a ->
for i = 0 to a.nb_dl_setting_values - 1 do
csv := sprintf "%s%f," !csv a.dl_setting_values.(i)
done;
- let vs = ["ac_id", Pprz.String a.id; "values", Pprz.String !csv] in
+ let vs = ["ac_id", Pprz.String a.id; "values", Pprz.String ("|"^ !csv ^"|")] in
Ground_Pprz.message_send my_id "DL_VALUES" vs
let send_svsinfo = fun a ->
@@ -223,7 +223,7 @@ let send_svsinfo = fun a ->
concat azim a.svinfo.(i).azim;
concat age a.svinfo.(i).age
done;
- let f = fun s r -> (s, Pprz.String !r) in
+ let f = fun s r -> (s, Pprz.String ("|"^ !r ^"|")) in
let vs = ["ac_id", Pprz.String a.id;
"pacc", Pprz.Int a.gps_Pacc;
f "svid" svid; f "flags" flags; f "qi" qi; f "msg_age" age;
diff --git a/sw/lib/ocaml/Makefile b/sw/lib/ocaml/Makefile
index d0872d3788..9b0f9e53c1 100644
--- a/sw/lib/ocaml/Makefile
+++ b/sw/lib/ocaml/Makefile
@@ -55,7 +55,7 @@ PKGCOMMON=xml-light,netclient,glibivy,lablgtk2
XINCLUDES=
XPKGCOMMON=xml-light,glibivy,$(LABLGTK2GNOMECANVAS),lablgtk2.glade
-SRC = fig.ml debug.ml base64.ml serial.ml ocaml_tools.ml expr_syntax.ml expr_parser.ml expr_lexer.ml extXml.ml env.ml xml2h.ml latlong.ml egm96.ml srtm.ml http.ml maps_support.ml gm.ml iGN.ml geometry_2d.ml cserial.o convert.o ubx.ml pprz.ml xbee.ml logpprz.ml xmlCom.ml os_calls.ml editAirframe.ml defivybus.ml
+SRC = fig.ml debug.ml base64.ml serial.ml ocaml_tools.ml expr_syntax.ml expr_parser.ml expr_lexer.ml extXml.ml env.ml xml2h.ml latlong.ml egm96.ml srtm.ml http.ml maps_support.ml gm.ml iGN.ml geometry_2d.ml cserial.o convert.o ubx.ml pprz.ml xbee.ml logpprz.ml xmlCom.ml os_calls.ml editAirframe.ml defivybus.ml fp_proc.ml
CMO = $(SRC:.ml=.cmo)
CMX = $(SRC:.ml=.cmx)
@@ -187,7 +187,8 @@ clean :
#
.depend: Makefile $(GEN_DEP)
- $(OCAMLDEP) *.ml* > .depend
+ @echo DEPEND $@
+ $(Q)$(OCAMLDEP) *.ml* > .depend
ifneq ($(MAKECMDGOALS),clean)
-include .depend
diff --git a/sw/lib/ocaml/env.ml b/sw/lib/ocaml/env.ml
index cf98beaed2..1aeeacadf0 100644
--- a/sw/lib/ocaml/env.ml
+++ b/sw/lib/ocaml/env.ml
@@ -51,7 +51,7 @@ let gconf_file = paparazzi_home // "conf" // "%gconf.xml"
let gcs_icons_path = paparazzi_home // "data" // "pictures" // "gcs_icons"
-let dump_fp = paparazzi_src // "sw" // "tools" // "gen_flight_plan.out -dump"
+let dump_fp = paparazzi_src // "sw" // "tools" // "generators" // "gen_flight_plan.out -dump"
let expand_ac_xml = fun ?(raise_exception = true) ac_conf ->
let prefix = fun s -> sprintf "%s/conf/%s" paparazzi_home s in
@@ -80,6 +80,7 @@ let expand_ac_xml = fun ?(raise_exception = true) ac_conf ->
try
(* get full path file name *)
let fp = prefix (ExtXml.attrib ac_conf a) in
+ if Sys.is_directory fp then raise Not_found;
(* create a temporary dump file *)
let dump = Filename.temp_file "fp_dump" ".xml" in
(* set command then call it *)
diff --git a/sw/tools/fp_proc.ml b/sw/lib/ocaml/fp_proc.ml
similarity index 100%
rename from sw/tools/fp_proc.ml
rename to sw/lib/ocaml/fp_proc.ml
diff --git a/sw/tools/fp_proc.mli b/sw/lib/ocaml/fp_proc.mli
similarity index 100%
rename from sw/tools/fp_proc.mli
rename to sw/lib/ocaml/fp_proc.mli
diff --git a/sw/lib/ocaml/geometry_2d.ml b/sw/lib/ocaml/geometry_2d.ml
index eb0513cfcb..3ae3e65fa1 100644
--- a/sw/lib/ocaml/geometry_2d.ml
+++ b/sw/lib/ocaml/geometry_2d.ml
@@ -298,7 +298,7 @@ let test_on_hl t = (test_in_segment t)||(t=T_OUT_SEG_PT4)||(t=T_OUT_SEG_PT2)
let crossing_seg_seg a b c d =
match crossing_point a (vect_make a b) c (vect_make c d) with
None -> false
- | Some (type1, type2, _pt) -> (test_in_segment type1)&&(test_in_segment type2)
+ | Some (type1, type2, _pt) -> (test_in_segment type1) && (test_in_segment type2)
(* ============================================================================= *)
(* = Teste l'intersection d'un segment (a,b) et d'une demi-droite (c,v) = *)
@@ -346,7 +346,7 @@ let poly_is_closed poly =
(* = Ferme un polygone [A; B; C; D] -> [A; B; C; D; A] = *)
(* ============================================================================= *)
let poly_close poly =
- if poly = [] or poly_is_closed poly then poly else poly@[List.hd poly]
+ if poly = [] || poly_is_closed poly then poly else poly@[List.hd poly]
(* ============================================================================= *)
(* = Ferme un polygone [A; B; C; D] -> [|A; B; C; D; A; B|] = *)
@@ -393,10 +393,10 @@ let convex_hull poly =
in
let plus_proche a b c d =
- (d=a) or ((not(c=a)) &
- ((du_meme_cote b c d a) or (
+ (d=a) || ((not(c=a)) &&
+ ((du_meme_cote b c d a) || (
let u = vect_make b c and v = vect_make b d in
- (det u v)=0.0 & (abs_float(u.x2D)+.abs_float(u.y2D)>
+ (det u v)=0.0 && (abs_float(u.x2D)+.abs_float(u.y2D)>
abs_float(v.x2D)+.abs_float(v.y2D)))))
in
@@ -412,7 +412,7 @@ let convex_hull poly =
| [] -> raise Exit
in
- let p a b = a.x2Db.y2D) in
+ let p a b = a.x2Db.y2D) in
let l2=poly in
let debut,_=extract_mini p l2 in
let rec itere a o liste sol =
@@ -640,7 +640,7 @@ let in_tesselation poly =
let a = vertices.(n1) and b = vertices.(n2) in
(* AAA if is_in_cone a b && is_in_cone b a then begin *)
- if is_in_cone a b or is_in_cone b a then begin
+ if is_in_cone a b || is_in_cone b a then begin
let rec f l =
match l with
c::reste ->
diff --git a/sw/lib/ocaml/mapCanvas.ml b/sw/lib/ocaml/mapCanvas.ml
index eb2a4ffce3..b550e984de 100644
--- a/sw/lib/ocaml/mapCanvas.ml
+++ b/sw/lib/ocaml/mapCanvas.ml
@@ -258,6 +258,7 @@ object (self)
initializer (
spin_button#set_adjustment adj;
+ spin_button#set_value 1.; (* this should be done by set_adjustment but seems to fail on ubuntu 13.10 (at least) *)
utc_time#hide ();
diff --git a/sw/lib/ocaml/mapWaypoints.ml b/sw/lib/ocaml/mapWaypoints.ml
index adc7231e0b..bd2f8dd45e 100644
--- a/sw/lib/ocaml/mapWaypoints.ml
+++ b/sw/lib/ocaml/mapWaypoints.ml
@@ -143,8 +143,9 @@ object (self)
~value:alt ~lower:(-100.) ~upper:10000.
~step_incr:1. ~page_incr:10.0 ~page_size:0. () in
ea#set_adjustment adj;
+ ea#set_value alt; (* this should be done by set_adjustment but seems to fail on ubuntu 13.10 (at least) *)
- let agl = alt -. float (try Srtm.of_wgs84 wgs84 with _ -> 0) in
+ let agl = alt -. float (try Srtm.of_wgs84 initial_wgs84 with _ -> 0) in
let agl_lab = GMisc.label ~text:(sprintf " AGL: %4.0fm" agl) ~packing:ha#add () in
let plus10= GButton.button ~label:"+10" ~packing:ha#add () in
let change_alt = fun x ->
diff --git a/sw/lib/ocaml/ocaml_tools.ml b/sw/lib/ocaml/ocaml_tools.ml
index 6d801905c2..43579b9921 100644
--- a/sw/lib/ocaml/ocaml_tools.ml
+++ b/sw/lib/ocaml/ocaml_tools.ml
@@ -25,8 +25,8 @@
let pi = 3.14159265358979323846;;
let open_compress file =
- if Filename.check_suffix file "gz" or Filename.check_suffix file "Z" or
- Filename.check_suffix file "zip" or Filename.check_suffix file "ZIP" then
+ if Filename.check_suffix file "gz" || Filename.check_suffix file "Z" ||
+ Filename.check_suffix file "zip" || Filename.check_suffix file "ZIP" then
Unix.open_process_in ("gunzip -c "^file)
else if Filename.check_suffix file "bz2" then
Unix.open_process_in ("bunzip2 -c "^file)
diff --git a/sw/lib/ocaml/pprz.ml b/sw/lib/ocaml/pprz.ml
index f2de6e2ff8..b6af3c1fa6 100644
--- a/sw/lib/ocaml/pprz.ml
+++ b/sw/lib/ocaml/pprz.ml
@@ -160,7 +160,7 @@ let rec string_of_value = function
| Int64 x -> Int64.to_string x
| Char c -> String.make 1 c
| String s -> s
- | Array a -> String.concat separator (Array.to_list (Array.map string_of_value a))
+ | Array a -> "|"^(String.concat separator (Array.to_list (Array.map string_of_value a)))^"|"
let magic = fun x -> (Obj.magic x:('a,'b,'c) Pervasives.format)
@@ -241,6 +241,17 @@ let alt_unit_coef_of_xml = fun ?auto xml ->
in
coef
+let key_modifiers_of_string = fun key ->
+ let key_split = Str.split (Str.regexp "\\+") key in
+ let keys = List.map (fun k ->
+ match k with
+ | "Ctrl" -> ""
+ | "Alt" -> ""
+ | "Shift" -> ""
+ | "Meta" -> ""
+ | x -> x
+ ) key_split in
+ String.concat "" keys
let pipe_regexp = Str.regexp "|"
let field_of_xml = fun xml ->
@@ -650,8 +661,21 @@ module MessagesOfXml(Class:CLASS_Xml) = struct
let space = Str.regexp "[ \t]+"
+ let array_sep = Str.regexp "|"
let values_of_string = fun s ->
- match Str.split space s with
+ (* split arguments and arrays *)
+ let array_split = Str.full_split array_sep s in
+ let rec loop = fun fields ->
+ match fields with
+ | [] -> []
+ | (Str.Delim "|")::((Str.Text l)::[Str.Delim "|"]) -> [l]
+ | (Str.Delim "|")::((Str.Text l)::((Str.Delim "|")::xs)) -> [l] @ (loop xs)
+ | [Str.Text x] -> Str.split space x
+ | (Str.Text x)::xs -> (Str.split space x) @ (loop xs)
+ | (Str.Delim _)::_ -> failwith "Pprz.values_of_string: incorrect array delimiter"
+ in
+ let msg_split = loop array_split in
+ match msg_split with
msg_name::args ->
begin
try
diff --git a/sw/lib/ocaml/pprz.mli b/sw/lib/ocaml/pprz.mli
index 4181035fb0..0f47a307d2 100644
--- a/sw/lib/ocaml/pprz.mli
+++ b/sw/lib/ocaml/pprz.mli
@@ -109,6 +109,12 @@ val alt_unit_coef_of_xml : ?auto:string -> Xml.xml -> string
(** Return coef for alternate unit
*)
+val key_modifiers_of_string : string -> string
+(** Convert key modifiers from Qt style (without '<' or '>', separated with '+')
+ * to GTK style.
+ * Supported modifiers are Alt, Ctrl, Shift and Meta
+ *)
+
exception Unknown_msg_name of string * string
(** [Unknown_msg_name (name, class_name)] Raised if message [name] is not
found in class [class_name]. *)
diff --git a/sw/logalizer/Makefile b/sw/logalizer/Makefile
index 2dad1b104d..36c45ed2c8 100644
--- a/sw/logalizer/Makefile
+++ b/sw/logalizer/Makefile
@@ -32,23 +32,23 @@ XLINKPKG = $(XPKG) -linkpkg -dllpath-pkg pprz.xlib
all: play plotter plot sd2log plotprofile openlog2tlm
-play : log_file.cmo play_core.cmo play.cmo
+play : log_file.cmo play_core.cmo play.cmo $(LIBPPRZCMA)
@echo OL $@
$(Q)$(OCAMLC) $(INCLUDES) -o $@ $(LINKPKG) gtkInit.cmo $^
-play-nox : play_core.cmo play-nox.cmo
+play-nox : play_core.cmo play-nox.cmo $(LIBPPRZCMA)
@echo OL $@
$(Q)$(OCAMLC) $(INCLUDES) -o $@ $(LINKPKG) $^
-plotter : plotter.cmo
+plotter : plotter.cmo $(LIBPPRZCMA) $(XLIBPPRZCMA)
@echo OL $@
$(Q)$(OCAMLC) $(INCLUDES) -o $@ $(XLINKPKG) gtkInit.cmo $^
-plot : log_file.cmo gtk_export.cmo export.cmo plot.cmo
+plot : log_file.cmo gtk_export.cmo export.cmo plot.cmo $(LIBPPRZCMA) $(XLIBPPRZCMA)
@echo OL $@
$(Q)$(OCAMLC) $(INCLUDES) -o $@ $(XLINKPKG) gtkInit.cmo $^
-sd2log : sd2log.cmo
+sd2log : sd2log.cmo $(LIBPPRZCMA)
@echo OL $@
$(Q)$(OCAMLC) $(INCLUDES) -o $@ $(LINKPKG) $^
@@ -200,7 +200,8 @@ clean:
#
.depend: Makefile
- $(OCAMLDEP) -I $(LIBPPRZDIR) *.ml* > .depend
+ @echo DEPEND $@
+ $(Q)$(OCAMLDEP) -I $(LIBPPRZDIR) *.ml* > .depend
ifneq ($(MAKECMDGOALS),clean)
-include .depend
diff --git a/sw/logalizer/export.ml b/sw/logalizer/export.ml
index ae3e95be1d..1ff7431e41 100644
--- a/sw/logalizer/export.ml
+++ b/sw/logalizer/export.ml
@@ -274,8 +274,18 @@ let popup = fun ?(no_gui = false) xml log_filename data ->
(** Render the columns *)
display_columns w#treeview_messages model;
+ (** Build list of message name *)
+ let msg_names = Hashtbl.create 30 in
+ List.iter (fun (_, name, _) -> if not (Hashtbl.mem msg_names name) then Hashtbl.add msg_names name ()) data;
(** Fill the colums *)
let xml_class = ExtXml.child ~select:(fun c -> ExtXml.attrib c "name" = class_name) xml "class" in
+ (** Filter xml message *)
+ let xml_class = Xml.Element (
+ class_name, [],
+ List.filter (fun xml ->
+ let name = Xml.attrib xml "name" in
+ Hashtbl.mem msg_names name) (Xml.children xml_class)
+ ) in
let prefs = read_preferences () in
fill_data w#treeview_messages model xml_class prefs;
diff --git a/sw/logalizer/play_core.ml b/sw/logalizer/play_core.ml
index c6268c50ed..8a9d891d34 100644
--- a/sw/logalizer/play_core.ml
+++ b/sw/logalizer/play_core.ml
@@ -29,7 +29,7 @@ module Tm_Pprz = Pprz.Messages(struct let name = "telemetry" end)
let (//) = Filename.concat
let replay_dir = Env.paparazzi_home // "var" // "replay"
-let dump_fp = Env.paparazzi_src // "sw" // "tools" // "gen_flight_plan.out -dump"
+let dump_fp = Env.paparazzi_src // "sw" // "tools" // "generators" // "gen_flight_plan.out -dump"
let log = ref [||]
diff --git a/sw/simulator/Makefile b/sw/simulator/Makefile
index dc1f876449..37198beead 100644
--- a/sw/simulator/Makefile
+++ b/sw/simulator/Makefile
@@ -56,19 +56,19 @@ fg.so : fg.o
@echo BUILD $@
$(Q)$(CC) -shared -o $@ $^
-simhitl : fg.so $(SIMHCMO) simhitl.cmo
+simhitl : fg.so $(SIMHCMO) simhitl.cmo $(LIBPPRZCMA)
@echo OL $@
$(Q)$(OCAMLC) $(INCLUDES) -o $@ $(LINKPKG) gtkInit.cmo $<
-sitl.cma : fg.o $(SIMSCMO)
+sitl.cma : fg.o $(SIMSCMO) $(LIBPPRZCMA)
@echo OL $@
$(Q)$(OCAMLMKLIB) -o sitl $^
-sitl.cmxa : $(SIMSCMX)
+sitl.cmxa : $(SIMSCMX) $(LIBPPRZCMXA)
@echo OC $@
$(Q)$(OCAMLOPT) -o $@ -a $^
-gaia : gaia.cmo
+gaia : gaia.cmo $(LIBPPRZCMA)
@echo OL $@
$(Q)$(OCAMLC) $(INCLUDES) -o $@ $(LINKPKG) gtkInit.cmo $<
@@ -103,7 +103,8 @@ clean :
#
.depend: Makefile
- $(OCAMLDEP) -I $(LIBPPRZDIR) *.ml* > .depend
+ @echo DEPEND $@
+ $(Q)$(OCAMLDEP) -I $(LIBPPRZDIR) *.ml* > .depend
ifneq ($(MAKECMDGOALS),clean)
-include .depend
diff --git a/sw/simulator/nps/nps_fdm_jsbsim.c b/sw/simulator/nps/nps_fdm_jsbsim.c
index 1e20c5c376..b831f18a2f 100644
--- a/sw/simulator/nps/nps_fdm_jsbsim.c
+++ b/sw/simulator/nps/nps_fdm_jsbsim.c
@@ -94,6 +94,9 @@ static FGFDMExec* FDMExec;
static struct LtpDef_d ltpdef;
+// Offset between ecef in geodetic and geocentric coordinates
+static struct EcefCoor_d offset;
+
/// The largest distance between vehicle CG and contact point
double vehicle_radius_max;
@@ -110,6 +113,8 @@ void nps_fdm_init(double dt) {
fdm.nan_count = 0;
+ VECT3_ASSIGN(offset, 0., 0., 0.);
+
init_jsbsim(dt);
FDMExec->RunIC();
@@ -391,6 +396,7 @@ static void init_jsbsim(double dt) {
IC->SetLatitudeDegIC(DegOfRad(gc_lat));
IC->SetLongitudeDegIC(NAV_LON0 / 1e7);
+
IC->SetAltitudeASLFtIC(FeetOfMeters(GROUND_ALT + 2.0));
IC->SetTerrainElevationFtIC(FeetOfMeters(GROUND_ALT));
IC->SetPsiDegIC(QFU);
@@ -402,6 +408,16 @@ static void init_jsbsim(double dt) {
cerr << "Initialization from flight plan unsuccessful" << endl;
exit(-1);
}
+
+ // compute offset between geocentric and geodetic ecef
+ struct LlaCoor_d lla0 = { RadOfDeg(NAV_LON0 / 1e7), gd_lat, (double)(NAV_ALT0+NAV_MSL0)/1000. };
+ ecef_of_lla_d(&offset, &lla0);
+ struct EcefCoor_d ecef0 = {
+ MetersOfFeet(FDMExec->GetPropagate()->GetLocation().Entry(1)),
+ MetersOfFeet(FDMExec->GetPropagate()->GetLocation().Entry(2)),
+ MetersOfFeet(FDMExec->GetPropagate()->GetLocation().Entry(3))
+ };
+ VECT3_DIFF(offset, offset, ecef0);
}
// calculate vehicle max radius in m
@@ -465,6 +481,7 @@ static void jsbsimloc_to_loc(EcefCoor_d* fdm_location, const FGLocation* jsb_loc
fdm_location->y = MetersOfFeet(jsb_location->Entry(2));
fdm_location->z = MetersOfFeet(jsb_location->Entry(3));
+ VECT3_ADD(*fdm_location, offset);
}
/**
diff --git a/sw/supervision/Makefile b/sw/supervision/Makefile
index 374c645e19..49634ee0e4 100644
--- a/sw/supervision/Makefile
+++ b/sw/supervision/Makefile
@@ -85,7 +85,8 @@ clean:
#
.depend: Makefile
- $(OCAMLDEP) -I $(LIBPPRZDIR) *.ml* > .depend
+ @echo DEPEND $@
+ $(Q)$(OCAMLDEP) -I $(LIBPPRZDIR) *.ml* > .depend
ifneq ($(MAKECMDGOALS),clean)
-include .depend
diff --git a/sw/tools/Makefile b/sw/tools/Makefile
index b3ed28bbe7..1565800749 100644
--- a/sw/tools/Makefile
+++ b/sw/tools/Makefile
@@ -22,28 +22,20 @@
# Quiet compilation
Q=@
+CC = gcc
+
include ../Makefile.ocaml
INCLUDES =
PKG = -package pprz
LINKPKG = $(PKG) -linkpkg -dllpath-pkg pprz
-all: gen_common.cmo gen_aircraft.out gen_airframe.out gen_messages2.out gen_messages.out gen_ubx.out gen_mtk.out gen_flight_plan.out gen_radio.out gen_periodic.out gen_settings.out gen_xsens.out gen_modules.out gen_autopilot.out gen_abi.out find_free_msg_id.out gen_srtm.out mergelogs
+all: find_free_msg_id.out mergelogs
-FP_CMO = fp_proc.cmo gen_flight_plan.cmo
-ABS_FP = $(FP_CMO:%=$$PAPARAZZI_SRC/sw/tools/%)
-gen_flight_plan.out : $(FP_CMO) $(LIBPPRZCMA)
- @echo OL $@
- $(Q)$(OCAMLC) $(INCLUDES) -o $@ $(LINKPKG) $^
-
-gen_srtm.out : gen_srtm.ml $(LIBPPRZCMA)
- @echo OL $@
- $(Q)$(OCAMLC) $(INCLUDES) -o $@ $(LINKPKG) $<
-
-%.out : %.ml gen_common.cmo $(LIBPPRZCMA)
+%.out : %.ml $(LIBPPRZCMA)
@echo OL $<
- $(Q)$(OCAMLC) $(INCLUDES) -o $@ $(LINKPKG) gen_common.cmo $<
+ $(Q)$(OCAMLC) $(INCLUDES) -o $@ $(LINKPKG) $<
%.cmo : %.ml
@echo OC $<
@@ -54,10 +46,11 @@ gen_srtm.out : gen_srtm.ml $(LIBPPRZCMA)
$(Q)$(OCAMLC) $(INCLUDES) $(PKG) -c $<
mergelogs: mergelogs.c
- gcc mergelogs.c -o mergelogs
+ @echo LD $@
+ $(Q)$(CC) mergelogs.c -o mergelogs
clean:
- $(Q)rm -f *.cm* *.out *~ .depend fp_parser.ml fp_parser.mli mergelogs
+ $(Q)rm -f *.cm* *.out *~ .depend mergelogs
.PHONY: all clean
@@ -66,7 +59,8 @@ clean:
#
.depend: Makefile
- $(OCAMLDEP) -I $(LIBPPRZDIR) *.ml *.mli > .depend
+ @echo DEPEND $@
+ $(Q)$(OCAMLDEP) -I $(LIBPPRZDIR) *.ml *.mli > .depend
ifneq ($(MAKECMDGOALS),clean)
-include .depend
diff --git a/sw/tools/generators/Makefile b/sw/tools/generators/Makefile
new file mode 100644
index 0000000000..dcc5a43ff8
--- /dev/null
+++ b/sw/tools/generators/Makefile
@@ -0,0 +1,68 @@
+# Hey Emacs, this is a -*- makefile -*-
+#
+# Copyright (C) 2003-2014 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.
+
+# Quiet compilation
+Q=@
+
+include ../../Makefile.ocaml
+
+INCLUDES =
+PKG = -package pprz
+LINKPKG = $(PKG) -linkpkg -dllpath-pkg pprz
+
+all: gen_common.cmo gen_aircraft.out gen_airframe.out gen_messages2.out gen_messages.out gen_ubx.out gen_mtk.out gen_flight_plan.out gen_radio.out gen_periodic.out gen_settings.out gen_xsens.out gen_modules.out gen_autopilot.out gen_abi.out gen_srtm.out
+
+gen_flight_plan.out : gen_flight_plan.cmo $(LIBPPRZCMA)
+ @echo OL $@
+ $(Q)$(OCAMLC) $(INCLUDES) -o $@ $(LINKPKG) $^
+
+gen_srtm.out : gen_srtm.ml $(LIBPPRZCMA)
+ @echo OL $@
+ $(Q)$(OCAMLC) $(INCLUDES) -o $@ $(LINKPKG) $<
+
+%.out : %.ml gen_common.cmo $(LIBPPRZCMA)
+ @echo OL $<
+ $(Q)$(OCAMLC) $(INCLUDES) -o $@ $(LINKPKG) gen_common.cmo $<
+
+%.cmo : %.ml
+ @echo OC $<
+ $(Q)$(OCAMLC) $(INCLUDES) $(PKG) -c $<
+
+%.cmi : %.mli
+ @echo OC $<
+ $(Q)$(OCAMLC) $(INCLUDES) $(PKG) -c $<
+
+clean:
+ $(Q)rm -f *.cm* *.out *~ .depend
+
+.PHONY: all clean
+
+#
+# Dependencies
+#
+
+.depend: Makefile
+ @echo DEPEND $@
+ $(Q)$(OCAMLDEP) -I $(LIBPPRZDIR) *.ml *.mli > .depend
+
+ifneq ($(MAKECMDGOALS),clean)
+-include .depend
+endif
diff --git a/sw/tools/gen_abi.ml b/sw/tools/generators/gen_abi.ml
similarity index 100%
rename from sw/tools/gen_abi.ml
rename to sw/tools/generators/gen_abi.ml
diff --git a/sw/tools/gen_aircraft.ml b/sw/tools/generators/gen_aircraft.ml
similarity index 100%
rename from sw/tools/gen_aircraft.ml
rename to sw/tools/generators/gen_aircraft.ml
diff --git a/sw/tools/gen_airframe.ml b/sw/tools/generators/gen_airframe.ml
similarity index 100%
rename from sw/tools/gen_airframe.ml
rename to sw/tools/generators/gen_airframe.ml
diff --git a/sw/tools/gen_autopilot.ml b/sw/tools/generators/gen_autopilot.ml
similarity index 100%
rename from sw/tools/gen_autopilot.ml
rename to sw/tools/generators/gen_autopilot.ml
diff --git a/sw/tools/gen_common.ml b/sw/tools/generators/gen_common.ml
similarity index 100%
rename from sw/tools/gen_common.ml
rename to sw/tools/generators/gen_common.ml
diff --git a/sw/tools/gen_common.mli b/sw/tools/generators/gen_common.mli
similarity index 100%
rename from sw/tools/gen_common.mli
rename to sw/tools/generators/gen_common.mli
diff --git a/sw/tools/gen_flight_plan.ml b/sw/tools/generators/gen_flight_plan.ml
similarity index 98%
rename from sw/tools/gen_flight_plan.ml
rename to sw/tools/generators/gen_flight_plan.ml
index d0f466edf2..3cd7146a82 100644
--- a/sw/tools/gen_flight_plan.ml
+++ b/sw/tools/generators/gen_flight_plan.ml
@@ -363,7 +363,14 @@ let rec print_stage = fun index_of_waypoints x ->
lprintf "waypoints[0].y = %s;\n" (parsed_attrib x "y");
"0"
in
- let at = try ExtXml.attrib x "approaching_time" with _ -> "CARROT" in
+ let at = try Some (ExtXml.attrib x "approaching_time") with _ -> None in
+ let et = try Some (ExtXml.attrib x "exceeding_time") with _ -> None in
+ let at = match at, et with
+ | Some a, None -> a
+ | None, Some e -> "-"^e
+ | None, None -> "CARROT"
+ | _, _ -> failwith "Error: 'approaching_time' and 'exceeding_time' attributes are not compatible"
+ in
let last_wp =
try
get_index_waypoint (ExtXml.attrib x "from") index_of_waypoints
diff --git a/sw/tools/gen_messages.ml b/sw/tools/generators/gen_messages.ml
similarity index 100%
rename from sw/tools/gen_messages.ml
rename to sw/tools/generators/gen_messages.ml
diff --git a/sw/tools/gen_messages2.ml b/sw/tools/generators/gen_messages2.ml
similarity index 100%
rename from sw/tools/gen_messages2.ml
rename to sw/tools/generators/gen_messages2.ml
diff --git a/sw/tools/gen_modules.ml b/sw/tools/generators/gen_modules.ml
similarity index 100%
rename from sw/tools/gen_modules.ml
rename to sw/tools/generators/gen_modules.ml
diff --git a/sw/tools/gen_mtk.ml b/sw/tools/generators/gen_mtk.ml
similarity index 100%
rename from sw/tools/gen_mtk.ml
rename to sw/tools/generators/gen_mtk.ml
diff --git a/sw/tools/gen_periodic.ml b/sw/tools/generators/gen_periodic.ml
similarity index 100%
rename from sw/tools/gen_periodic.ml
rename to sw/tools/generators/gen_periodic.ml
diff --git a/sw/tools/gen_radio.ml b/sw/tools/generators/gen_radio.ml
similarity index 100%
rename from sw/tools/gen_radio.ml
rename to sw/tools/generators/gen_radio.ml
diff --git a/sw/tools/gen_settings.ml b/sw/tools/generators/gen_settings.ml
similarity index 100%
rename from sw/tools/gen_settings.ml
rename to sw/tools/generators/gen_settings.ml
diff --git a/sw/tools/gen_srtm.ml b/sw/tools/generators/gen_srtm.ml
similarity index 100%
rename from sw/tools/gen_srtm.ml
rename to sw/tools/generators/gen_srtm.ml
diff --git a/sw/tools/gen_ubx.ml b/sw/tools/generators/gen_ubx.ml
similarity index 100%
rename from sw/tools/gen_ubx.ml
rename to sw/tools/generators/gen_ubx.ml
diff --git a/sw/tools/gen_xsens.ml b/sw/tools/generators/gen_xsens.ml
similarity index 100%
rename from sw/tools/gen_xsens.ml
rename to sw/tools/generators/gen_xsens.ml