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 "sensors/boardalignment.h"
25 #include "sensors/sensors.h"
28 #include "gtest/gtest.h"
31 * This test file contains an independent method of rotating a vector.
32 * The output of alignSensor() is compared to the output of the test
35 * For each alignment condition (CW0, CW90, etc) the source vector under
36 * test is set to a unit vector along each axis (x-axis, y-axis, z-axis)
37 * plus one additional random vector is tested.
40 #define DEG2RAD 0.01745329251
42 static void rotateVector(int16_t mat
[3][3], int16_t vec
[3], int16_t *out
)
46 for(int i
=0; i
<3; i
++) {
48 for(int j
=0; j
<3; j
++) {
49 tmp
[i
] += mat
[j
][i
] * vec
[j
];
59 //static void initXAxisRotation(int16_t mat[][3], int16_t angle)
65 // mat[1][1] = cos(angle*DEG2RAD);
66 // mat[1][2] = -sin(angle*DEG2RAD);
68 // mat[2][1] = sin(angle*DEG2RAD);
69 // mat[2][2] = cos(angle*DEG2RAD);
72 static void initYAxisRotation(int16_t mat
[][3], int16_t angle
)
74 mat
[0][0] = cos(angle
*DEG2RAD
);
76 mat
[0][2] = sin(angle
*DEG2RAD
);
80 mat
[2][0] = -sin(angle
*DEG2RAD
);
82 mat
[2][2] = cos(angle
*DEG2RAD
);
85 static void initZAxisRotation(int16_t mat
[][3], int16_t angle
)
87 mat
[0][0] = cos(angle
*DEG2RAD
);
88 mat
[0][1] = -sin(angle
*DEG2RAD
);
90 mat
[1][0] = sin(angle
*DEG2RAD
);
91 mat
[1][1] = cos(angle
*DEG2RAD
);
98 static void testCW(sensor_align_e rotation
, int16_t angle
)
100 int16_t src
[XYZ_AXIS_COUNT
];
101 int16_t dest
[XYZ_AXIS_COUNT
];
102 int16_t test
[XYZ_AXIS_COUNT
];
104 // unit vector along x-axis
109 int16_t matrix
[3][3];
110 initZAxisRotation(matrix
, angle
);
111 rotateVector(matrix
, src
, test
);
113 alignSensors(src
, dest
, rotation
);
114 EXPECT_EQ(test
[X
], dest
[X
]) << "X-Unit alignment does not match in X-Axis. " << test
[X
] << " " << dest
[X
];
115 EXPECT_EQ(test
[Y
], dest
[Y
]) << "X-Unit alignment does not match in Y-Axis. " << test
[Y
] << " " << dest
[Y
];
116 EXPECT_EQ(test
[Z
], dest
[Z
]) << "X-Unit alignment does not match in Z-Axis. " << test
[Z
] << " " << dest
[Z
];
118 // unit vector along y-axis
123 rotateVector(matrix
, src
, test
);
124 alignSensors(src
, dest
, rotation
);
125 EXPECT_EQ(test
[X
], dest
[X
]) << "Y-Unit alignment does not match in X-Axis. " << test
[X
] << " " << dest
[X
];
126 EXPECT_EQ(test
[Y
], dest
[Y
]) << "Y-Unit alignment does not match in Y-Axis. " << test
[Y
] << " " << dest
[Y
];
127 EXPECT_EQ(test
[Z
], dest
[Z
]) << "Y-Unit alignment does not match in Z-Axis. " << test
[Z
] << " " << dest
[Z
];
129 // unit vector along z-axis
134 rotateVector(matrix
, src
, test
);
135 alignSensors(src
, dest
, rotation
);
136 EXPECT_EQ(test
[X
], dest
[X
]) << "Z-Unit alignment does not match in X-Axis. " << test
[X
] << " " << dest
[X
];
137 EXPECT_EQ(test
[Y
], dest
[Y
]) << "Z-Unit alignment does not match in Y-Axis. " << test
[Y
] << " " << dest
[Y
];
138 EXPECT_EQ(test
[Z
], dest
[Z
]) << "Z-Unit alignment does not match in Z-Axis. " << test
[Z
] << " " << dest
[Z
];
140 // random vector to test
145 rotateVector(matrix
, src
, test
);
146 alignSensors(src
, dest
, rotation
);
147 EXPECT_EQ(test
[X
], dest
[X
]) << "Random alignment does not match in X-Axis. " << test
[X
] << " " << dest
[X
];
148 EXPECT_EQ(test
[Y
], dest
[Y
]) << "Random alignment does not match in Y-Axis. " << test
[Y
] << " " << dest
[Y
];
149 EXPECT_EQ(test
[Z
], dest
[Z
]) << "Random alignment does not match in Z-Axis. " << test
[Z
] << " " << dest
[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
, int16_t angle
)
158 int16_t src
[XYZ_AXIS_COUNT
];
159 int16_t dest
[XYZ_AXIS_COUNT
];
160 int16_t test
[XYZ_AXIS_COUNT
];
162 // unit vector along x-axis
167 int16_t matrix
[3][3];
168 initYAxisRotation(matrix
, 180);
169 rotateVector(matrix
, src
, test
);
170 initZAxisRotation(matrix
, angle
);
171 rotateVector(matrix
, test
, test
);
173 alignSensors(src
, dest
, rotation
);
175 EXPECT_EQ(test
[X
], dest
[X
]) << "X-Unit alignment does not match in X-Axis. " << test
[X
] << " " << dest
[X
];
176 EXPECT_EQ(test
[Y
], dest
[Y
]) << "X-Unit alignment does not match in Y-Axis. " << test
[Y
] << " " << dest
[Y
];
177 EXPECT_EQ(test
[Z
], dest
[Z
]) << "X-Unit alignment does not match in Z-Axis. " << test
[Z
] << " " << dest
[Z
];
179 // unit vector along y-axis
184 initYAxisRotation(matrix
, 180);
185 rotateVector(matrix
, src
, test
);
186 initZAxisRotation(matrix
, angle
);
187 rotateVector(matrix
, test
, test
);
189 alignSensors(src
, dest
, rotation
);
191 EXPECT_EQ(test
[X
], dest
[X
]) << "Y-Unit alignment does not match in X-Axis. " << test
[X
] << " " << dest
[X
];
192 EXPECT_EQ(test
[Y
], dest
[Y
]) << "Y-Unit alignment does not match in Y-Axis. " << test
[Y
] << " " << dest
[Y
];
193 EXPECT_EQ(test
[Z
], dest
[Z
]) << "Y-Unit alignment does not match in Z-Axis. " << test
[Z
] << " " << dest
[Z
];
195 // unit vector along z-axis
200 initYAxisRotation(matrix
, 180);
201 rotateVector(matrix
, src
, test
);
202 initZAxisRotation(matrix
, angle
);
203 rotateVector(matrix
, test
, test
);
205 alignSensors(src
, dest
, rotation
);
207 EXPECT_EQ(test
[X
], dest
[X
]) << "Z-Unit alignment does not match in X-Axis. " << test
[X
] << " " << dest
[X
];
208 EXPECT_EQ(test
[Y
], dest
[Y
]) << "Z-Unit alignment does not match in Y-Axis. " << test
[Y
] << " " << dest
[Y
];
209 EXPECT_EQ(test
[Z
], dest
[Z
]) << "Z-Unit alignment does not match in Z-Axis. " << test
[Z
] << " " << dest
[Z
];
211 // random vector to test
216 initYAxisRotation(matrix
, 180);
217 rotateVector(matrix
, src
, test
);
218 initZAxisRotation(matrix
, angle
);
219 rotateVector(matrix
, test
, test
);
221 alignSensors(src
, dest
, rotation
);
223 EXPECT_EQ(test
[X
], dest
[X
]) << "Random alignment does not match in X-Axis. " << test
[X
] << " " << dest
[X
];
224 EXPECT_EQ(test
[Y
], dest
[Y
]) << "Random alignment does not match in Y-Axis. " << test
[Y
] << " " << dest
[Y
];
225 EXPECT_EQ(test
[Z
], dest
[Z
]) << "Random alignment does not match in Z-Axis. " << test
[Z
] << " " << dest
[Z
];
229 TEST(AlignSensorTest
, ClockwiseZeroDegrees
)
235 TEST(AlignSensorTest
, ClockwiseNinetyDegrees
)
237 testCW(CW90_DEG
, 90);
240 TEST(AlignSensorTest
, ClockwiseOneEightyDegrees
)
242 testCW(CW180_DEG
, 180);
245 TEST(AlignSensorTest
, ClockwiseTwoSeventyDegrees
)
247 testCW(CW270_DEG
, 270);
250 TEST(AlignSensorTest
, ClockwiseZeroDegreesFlip
)
252 testCWFlip(CW0_DEG_FLIP
, 0);
255 TEST(AlignSensorTest
, ClockwiseNinetyDegreesFlip
)
257 testCWFlip(CW90_DEG_FLIP
, 90);
260 TEST(AlignSensorTest
, ClockwiseOneEightyDegreesFlip
)
262 testCWFlip(CW180_DEG_FLIP
, 180);
265 TEST(AlignSensorTest
, ClockwiseTwoSeventyDegreesFlip
)
267 testCWFlip(CW270_DEG_FLIP
, 270);