Mercurial > public > hwos_code
diff src/Tests/compass_trigo_test.cpp @ 282:7d9edd3b8c86
Make a more compact COMPASS calibration code (<7KB), and add more tests.
author | jDG |
---|---|
date | Fri, 22 May 2015 14:50:40 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Tests/compass_trigo_test.cpp Fri May 22 14:50:40 2015 +0200 @@ -0,0 +1,140 @@ +////////////////////////////////////////////////////////////////////////////// +/// compass_trigo_test.cpp +/// Unit test for compass various operations. +/// Copyright (c) 2012-2015, JD Gascuel, HeinrichsWeikamp, all right reserved. +////////////////////////////////////////////////////////////////////////////// +// HISTORY +// 2015-05-23 jDG: Rewrite compass testing, to allow reducing code size. + +extern "C" { +# include "compass.h" +} + +#include <gtest/gtest.h> + +////////////////////////////////////////////////////////////////////////////// +// Fake assembleur fixed point multiplies. +extern "C" Int16 compass_umul(void); +extern "C" Int16 compass_imul(void); +extern "C" Int16 compass_a, compass_b; + +// The (filtered) components of the magnetometer sensor: +Int16 compass_DX_f; +Int16 compass_DY_f; +Int16 compass_DZ_f; + +// Found soft-iron calibration values, deduced from already filtered values. +Int16 compass_CX_f; +Int16 compass_CY_f; +Int16 compass_CZ_f; + +// The (filtered) components of the accelerometer sensor: +Int16 accel_DX_f; +Int16 accel_DY_f; +Int16 accel_DZ_f; + +// The compass result value. +Int16 compass_heading; +Int16 compass_roll; +Int16 compass_pitch; + +Int16 compass_a, compass_b; +Int16 compass_umul() +{ + unsigned int a = compass_a; + unsigned int b = compass_b; + a *= b; + a >>= 15; + return (Int16)a; +} + +Int16 compass_imul() +{ + int a = compass_a; + int b = compass_b; + a *= b; + a >>= 15; + return (Int16)a; +} + +////////////////////////////////////////////////////////////////////////////// + +TEST(ops, multiply) { + // Check basic sign handling: + EXPECT_EQ(umul( 8000, 4000), (Int16)0x03D0); // 8000/2**15 * 4000/2**15 = 0x3D0 + EXPECT_EQ(imul(-8000, 4000), (Int16)0xFC2F); // -976 = 0xFC2F + EXPECT_EQ(imul( 8000, -4000), (Int16)0xFC2F); // -976 = 0xFC2F + EXPECT_EQ(imul(-8000, -4000), (Int16)0x03D0); // +976 = 0x3D0 +} + +TEST(ops, divide) { + // Check basic divides: + EXPECT_EQ(udiv(32000, 32001), (Int16)32766); // 0.99997 ~ 32766 + EXPECT_EQ(udiv( 4000, 8000), (Int16)16384); + EXPECT_EQ(udiv( 2000, 8000), (Int16) 8192); + EXPECT_EQ(udiv( 1000, 8000), (Int16) 4096); + EXPECT_EQ(udiv( 500, 8000), (Int16) 2048); +} + +TEST(trigo, atan) { + // Check angles returned by the SINGLE QUADRANT atan() function: + EXPECT_EQ(utan(100, 100), (Int16)4501); // +1 + EXPECT_EQ(utan( 90, 100), (Int16)4195); // -4 + EXPECT_EQ(utan( 80, 100), (Int16)3864); // -2 + EXPECT_EQ(utan( 70, 100), (Int16)3500); // +1 + EXPECT_EQ(utan( 60, 100), (Int16)3099); // +3 + EXPECT_EQ(utan( 50, 100), (Int16)2658); // +1 + EXPECT_EQ(utan( 40, 100), (Int16)2179); // -1 + EXPECT_EQ(utan( 30, 100), (Int16)1667); // -3 + EXPECT_EQ(utan( 20, 100), (Int16)1127); // -4 + EXPECT_EQ(utan( 10, 100), (Int16) 569); // -2 + EXPECT_EQ(utan( 0, 100), (Int16) 0); +} + +TEST(trigo, cosx2h2) { + // Check ONE-OCTANT pseudo-cosinus function + // Note: cosxh(x**2, x**2+y**2) is computing cos(atan(y/x)) + EXPECT_EQ(cosxh(12769, 13169), (Int16)32268); // 113, 20 --> 10.0369° --> 32267 +1 + EXPECT_EQ(cosxh(10000, 12500), (Int16)29310); // 100, 50 --> 26.5650° --> 29309 +1 + EXPECT_EQ(cosxh(10000, 20000), (Int16)23171); // 100, 100 --> 45.0000° --> 23170 +1 + EXPECT_EQ(cosxh( 2500, 12500), (Int16)14658); // 50, 100 --> 63.4349° --> 14654 +4 + EXPECT_EQ(cosxh( 400, 13169), (Int16) 5718); // 20, 113 --> 79.9631° --> 5711 +7 +} + +TEST(trigo, sinCos) { + Int16 sin, cos; + + //---- Check sincos() FIRST QUADRANT --------------------------------- + sincos( 20, 113, &sin, &cos); // 80° + EXPECT_EQ(sin, (Int16)32269); // +2 + EXPECT_EQ(cos, (Int16) 5727); // +16 + + sincos( 50, 100, &sin, &cos); // 63° + EXPECT_EQ(sin, (Int16)29311); // +2 + EXPECT_EQ(cos, (Int16)14660); // +6 + + sincos(100, 100, &sin, &cos); // 45° + EXPECT_EQ(sin, (Int16)23173); // +3 + EXPECT_EQ(cos, (Int16)23173); // +3 + + sincos(100, 50, &sin, &cos); // 27° + EXPECT_EQ(sin, (Int16)14660); // +6 + EXPECT_EQ(cos, (Int16)29311); // +2 + + sincos(113, 20, &sin, &cos); // 10° + EXPECT_EQ(sin, (Int16) 5727); // +16 + EXPECT_EQ(cos, (Int16)32269); // +2 + + //---- Check sincos() OTHER QUADRANTS -------------------------------- + sincos(-20, 113, &sin, &cos); // 90+80° + EXPECT_EQ(sin, (Int16) 32269); // +2 + EXPECT_EQ(cos, (Int16) -5727); // +16 + + sincos(-20,-113, &sin, &cos); // 180+80° + EXPECT_EQ(sin, (Int16)-32269); // +2 + EXPECT_EQ(cos, (Int16) -5727); // +16 + + sincos( 20,-113, &sin, &cos); // 270+80° + EXPECT_EQ(sin, (Int16)-32269); // +2 + EXPECT_EQ(cos, (Int16) 5727); // +16 +}