2 * This file is part of Cleanflight.
4 * Cleanflight is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * Cleanflight is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
23 #include "common/axis.h"
24 #include "drivers/sensor.h"
25 #include "sensors/boardalignment.h"
26 #include "sensors/sensors.h"
29 #include "gtest/gtest.h"
32 * This test file contains an independent method of rotating a vector.
33 * The output of applySensorAlignment() is compared to the output of the test
36 * For each alignment condition (CW0, CW90, etc) the source vector under
37 * test is set to a unit vector along each axis (x-axis, y-axis, z-axis)
38 * plus one additional random vector is tested.
41 #define DEG2RAD 0.01745329251
43 static void rotateVector(float mat[3][3], float vec[3], float *out)
47 for(int i=0; i<3; i++) {
49 for(int j=0; j<3; j++) {
50 tmp[i] += mat[j][i] * vec[j];
60 //static void initXAxisRotation(int32_t mat[][3], int32_t angle)
66 // mat[1][1] = cos(angle*DEG2RAD);
67 // mat[1][2] = -sin(angle*DEG2RAD);
69 // mat[2][1] = sin(angle*DEG2RAD);
70 // mat[2][2] = cos(angle*DEG2RAD);
73 static void initYAxisRotation(float mat[][3], int32_t angle)
75 mat[0][0] = cos(angle*DEG2RAD);
77 mat[0][2] = sin(angle*DEG2RAD);
81 mat[2][0] = -sin(angle*DEG2RAD);
83 mat[2][2] = cos(angle*DEG2RAD);
86 static void initZAxisRotation(float mat[][3], int32_t angle)
88 mat[0][0] = cos(angle*DEG2RAD);
89 mat[0][1] = -sin(angle*DEG2RAD);
91 mat[1][0] = sin(angle*DEG2RAD);
92 mat[1][1] = cos(angle*DEG2RAD);
99 static void testCW(sensor_align_e rotation, int32_t angle)
101 float src[XYZ_AXIS_COUNT];
102 float test[XYZ_AXIS_COUNT];
104 // unit vector along x-axis
110 initZAxisRotation(matrix, angle);
111 rotateVector(matrix, src, test);
113 applySensorAlignment(src, src, rotation);
114 EXPECT_EQ(test[X], src[X]) << "X-Unit alignment does not match in X-Axis. " << test[X] << " " << src[X];
115 EXPECT_EQ(test[Y], src[Y]) << "X-Unit alignment does not match in Y-Axis. " << test[Y] << " " << src[Y];
116 EXPECT_EQ(test[Z], src[Z]) << "X-Unit alignment does not match in Z-Axis. " << test[Z] << " " << src[Z];
118 // unit vector along y-axis
123 rotateVector(matrix, src, test);
124 applySensorAlignment(src, src, rotation);
125 EXPECT_EQ(test[X], src[X]) << "Y-Unit alignment does not match in X-Axis. " << test[X] << " " << src[X];
126 EXPECT_EQ(test[Y], src[Y]) << "Y-Unit alignment does not match in Y-Axis. " << test[Y] << " " << src[Y];
127 EXPECT_EQ(test[Z], src[Z]) << "Y-Unit alignment does not match in Z-Axis. " << test[Z] << " " << src[Z];
129 // unit vector along z-axis
134 rotateVector(matrix, src, test);
135 applySensorAlignment(src, src, rotation);
136 EXPECT_EQ(test[X], src[X]) << "Z-Unit alignment does not match in X-Axis. " << test[X] << " " << src[X];
137 EXPECT_EQ(test[Y], src[Y]) << "Z-Unit alignment does not match in Y-Axis. " << test[Y] << " " << src[Y];
138 EXPECT_EQ(test[Z], src[Z]) << "Z-Unit alignment does not match in Z-Axis. " << test[Z] << " " << src[Z];
140 // random vector to test
145 rotateVector(matrix, src, test);
146 applySensorAlignment(src, src, rotation);
147 EXPECT_EQ(test[X], src[X]) << "Random alignment does not match in X-Axis. " << test[X] << " " << src[X];
148 EXPECT_EQ(test[Y], src[Y]) << "Random alignment does not match in Y-Axis. " << test[Y] << " " << src[Y];
149 EXPECT_EQ(test[Z], src[Z]) << "Random alignment does not match in Z-Axis. " << test[Z] << " " << src[Z];
153 * Since the order of flip and rotation matters, these tests make the
154 * assumption that the 'flip' occurs first, followed by clockwise rotation
156 static void testCWFlip(sensor_align_e rotation, int32_t angle)
158 float src[XYZ_AXIS_COUNT];
159 float test[XYZ_AXIS_COUNT];
161 // unit vector along x-axis
167 initYAxisRotation(matrix, 180);
168 rotateVector(matrix, src, test);
169 initZAxisRotation(matrix, angle);
170 rotateVector(matrix, test, test);
172 applySensorAlignment(src, src, rotation);
174 EXPECT_EQ(test[X], src[X]) << "X-Unit alignment does not match in X-Axis. " << test[X] << " " << src[X];
175 EXPECT_EQ(test[Y], src[Y]) << "X-Unit alignment does not match in Y-Axis. " << test[Y] << " " << src[Y];
176 EXPECT_EQ(test[Z], src[Z]) << "X-Unit alignment does not match in Z-Axis. " << test[Z] << " " << src[Z];
178 // unit vector along y-axis
183 initYAxisRotation(matrix, 180);
184 rotateVector(matrix, src, test);
185 initZAxisRotation(matrix, angle);
186 rotateVector(matrix, test, test);
188 applySensorAlignment(src, src, rotation);
190 EXPECT_EQ(test[X], src[X]) << "Y-Unit alignment does not match in X-Axis. " << test[X] << " " << src[X];
191 EXPECT_EQ(test[Y], src[Y]) << "Y-Unit alignment does not match in Y-Axis. " << test[Y] << " " << src[Y];
192 EXPECT_EQ(test[Z], src[Z]) << "Y-Unit alignment does not match in Z-Axis. " << test[Z] << " " << src[Z];
194 // unit vector along z-axis
199 initYAxisRotation(matrix, 180);
200 rotateVector(matrix, src, test);
201 initZAxisRotation(matrix, angle);
202 rotateVector(matrix, test, test);
204 applySensorAlignment(src, src, rotation);
206 EXPECT_EQ(test[X], src[X]) << "Z-Unit alignment does not match in X-Axis. " << test[X] << " " << src[X];
207 EXPECT_EQ(test[Y], src[Y]) << "Z-Unit alignment does not match in Y-Axis. " << test[Y] << " " << src[Y];
208 EXPECT_EQ(test[Z], src[Z]) << "Z-Unit alignment does not match in Z-Axis. " << test[Z] << " " << src[Z];
210 // random vector to test
215 initYAxisRotation(matrix, 180);
216 rotateVector(matrix, src, test);
217 initZAxisRotation(matrix, angle);
218 rotateVector(matrix, test, test);
220 applySensorAlignment(src, src, rotation);
222 EXPECT_EQ(test[X], src[X]) << "Random alignment does not match in X-Axis. " << test[X] << " " << src[X];
223 EXPECT_EQ(test[Y], src[Y]) << "Random alignment does not match in Y-Axis. " << test[Y] << " " << src[Y];
224 EXPECT_EQ(test[Z], src[Z]) << "Random alignment does not match in Z-Axis. " << test[Z] << " " << src[Z];
228 TEST(AlignSensorTest, ClockwiseZeroDegrees)
234 TEST(AlignSensorTest, ClockwiseNinetyDegrees)
236 testCW(CW90_DEG, 90);
239 TEST(AlignSensorTest, ClockwiseOneEightyDegrees)
241 testCW(CW180_DEG, 180);
244 TEST(AlignSensorTest, ClockwiseTwoSeventyDegrees)
246 testCW(CW270_DEG, 270);
249 TEST(AlignSensorTest, ClockwiseZeroDegreesFlip)
251 testCWFlip(CW0_DEG_FLIP, 0);
254 TEST(AlignSensorTest, ClockwiseNinetyDegreesFlip)
256 testCWFlip(CW90_DEG_FLIP, 90);
259 TEST(AlignSensorTest, ClockwiseOneEightyDegreesFlip)
261 testCWFlip(CW180_DEG_FLIP, 180);
264 TEST(AlignSensorTest, ClockwiseTwoSeventyDegreesFlip)
266 testCWFlip(CW270_DEG_FLIP, 270);