diff --git a/sw/airborne/math/Makefile b/sw/airborne/math/Makefile index 11cba79adb..3d7873a2c7 100644 --- a/sw/airborne/math/Makefile +++ b/sw/airborne/math/Makefile @@ -31,7 +31,8 @@ all: @cat README shared_lib: $(OBJ) - $(CC) -shared -o $(BUILDDIR)/$(LIBNAME).so $(OBJ) -lm + @echo CREATE shared $(LIBNAME) + $(Q)$(CC) -shared -o $(BUILDDIR)/$(LIBNAME).so $(OBJ) -lm install_shared_lib: shared_lib test -d $(LIB_INSTALLDIR) || mkdir -p $(LIB_INSTALLDIR) @@ -43,8 +44,8 @@ install_shared_lib: shared_lib sed -e 's#PREFIX#$(PREFIX)#g' $(PKGCONFIG_FILE).in > $(PKGCONFIG_INSTALLDIR)/$(PKGCONFIG_FILE) $(BUILDDIR)/%.o: %.c - test -d $(BUILDDIR) || mkdir -p $(BUILDDIR) - $(CC) -c $< $(CFLAGS) $(INCLUDES) -o $@ + $(Q)test -d $(BUILDDIR) || mkdir -p $(BUILDDIR) + $(Q)$(CC) -c $< $(CFLAGS) $(INCLUDES) -o $@ clean: $(Q)rm -f $(BUILDDIR)/*.o $(BUILDDIR)/$(LIBNAME).so diff --git a/tests/math/.gitignore b/tests/math/.gitignore index c2120bd679..abad43aa66 100644 --- a/tests/math/.gitignore +++ b/tests/math/.gitignore @@ -1,2 +1,3 @@ test_pprz_math.run test_pprz_geodetic.run +test_state_interface.run diff --git a/tests/math/Makefile b/tests/math/Makefile index f5edbc0526..26d0fdc3a7 100644 --- a/tests/math/Makefile +++ b/tests/math/Makefile @@ -36,11 +36,16 @@ MATHLIB_PATH=$(PAPARAZZI_SRC)/var/build/math ##################################################### # If you add more test files you add their names here -TESTS = test_pprz_math.run test_pprz_geodetic.run +TESTS = test_pprz_math.run test_pprz_geodetic.run test_state_interface.run ################################################### # You should not need to touch the rest of the file +TEST_VERBOSE ?= 0 +ifneq ($(TEST_VERBOSE), 0) +VERBOSE = --verbose +endif + all: test math_shlib: @@ -49,12 +54,14 @@ math_shlib: build_tests: math_shlib $(TESTS) test: build_tests - $(Q)for i in $(TESTS); do \ - LD_LIBRARY_PATH=$(MATHLIB_PATH):$LD_LIBRARY_PATH ./$$i; \ - done + LD_LIBRARY_PATH=$(MATHLIB_PATH):$LD_LIBRARY_PATH prove $(VERBOSE) --exec '' ./*.run -%.run: %.c - $(CC) -L$(MATHLIB_PATH) -I$(PAPARAZZI_SRC)/sw/airborne -I$(PAPARAZZI_SRC)/sw/include $(USER_CFLAGS) tap.c $< -lpprzmath -o $@ +# test_state_interface also depends on state.c +test_state_interface.run: $(PAPARAZZI_SRC)/sw/airborne/state.c + +%.run: %.c | math_shlib + @echo BUILD $@ + $(Q)$(CC) -L$(MATHLIB_PATH) -I$(PAPARAZZI_SRC)/sw/airborne -I$(PAPARAZZI_SRC)/sw/include $(USER_CFLAGS) tap.c $^ -lpprzmath -o $@ clean: $(Q)rm -f $(MATHLIB_PATH)/*.o $(MATHLIB_PATH)/libpprzmath.so diff --git a/tests/math/test_state_interface.c b/tests/math/test_state_interface.c new file mode 100644 index 0000000000..833f6221f9 --- /dev/null +++ b/tests/math/test_state_interface.c @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2014 Felix Ruess + * + * This file is part of paparazzi. + * + * paparazzi is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * paparazzi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with paparazzi; see the file COPYING. If not, see + * . + */ + +/** + * @file test_state_interface.c + * @brief Tests for Paparazzi state interface. + * + * Which heavily uses the math libary. + * + * Using libtap to create a TAP (TestAnythingProtocol) producer: + * https://github.com/zorgnax/libtap + * + */ + +#include "tap.h" +#include "state.h" +#include "math/pprz_geodetic_double.h" + +static void test_pos_lla_i(void) +{ + struct LlaCoor_d lla_ref = {.lat=0.749999999392454875, + .lon=0.019999999054505127, + .alt=180.0}; + note("LLA reference: lat: %.10f deg, lon: %.10f deg, alt %.4f m", + DegOfRad(lla_ref.lat), DegOfRad(lla_ref.lon), lla_ref.alt); + + struct LlaCoor_i lla_ref_i; + LLA_BFP_OF_REAL(lla_ref_i, lla_ref); + + struct EcefCoor_d ecef_ref; + ecef_of_lla_d(&ecef_ref, &lla_ref); + note("ECEF reference: x: %.4f m, y: %.4f m, z: %.4f m", + ecef_ref.x, ecef_ref.y, ecef_ref.z); + + /* calc lla_i from ecef_f */ + struct EcefCoor_f ecef_f; + VECT3_COPY(ecef_f, ecef_ref); + stateSetPositionEcef_f(&ecef_f); + + struct LlaCoor_i *lla_result; + lla_result = stateGetPositionLla_i(); + + /* compare LLA result with reference (directly convered from double) */ + int32_t lat_err = abs(lla_result->lat - lla_ref_i.lat); + int32_t lon_err = abs(lla_result->lon - lla_ref_i.lon); + int32_t alt_err = abs(lla_result->alt - lla_ref_i.alt); + + /* max error is 1e-6 deg in lat/lon and 10cm in alt (lla_i is in 1e7deg and mm) */ + const int32_t max_err_i = 1e-6 * 1e7; // convert to 1e7 deg + if (lat_err < max_err_i && lon_err < max_err_i && alt_err < 100) { + pass("stateGetPositionLla_i() from ecef_f has max error of 1e-6deg in lat/lon and 10cm in lat"); + } + else { + note("lat is %d, should be %d", lla_result->lat, lla_ref_i.lat); + note("lon is %d, should be %d", lla_result->lon, lla_ref_i.lon); + note("alt is %d, should be %d", lla_result->alt, lla_ref_i.alt); + fail("stateGetPositionLla_i() from ecef_f exceeded error of 1e-6deg in lat/lon and 10cm in lat"); + } +} + +int main() +{ + note("\n *** running state interface tests ***"); + plan(1); + + stateInit(); + + test_pos_lla_i(); + + done_testing(); +}