51 virtual bool run_tests();
57 bool integrationTests();
59 bool matrixAssignmentTests();
60 bool matrixMultTests();
61 bool matrixScalarMultTests();
62 bool setIdentityTests();
64 bool squareMatrixTests();
65 bool transposeTests();
69 bool vectorAssignmentTests();
70 bool dcmRenormTests();
71 bool pseudoInverseTests();
95 return (_tests_failed == 0);
109 Quatf q_check(0.98334744
f, 0.0342708
f, 0.10602051
f, .14357218
f);
111 0.93629336f, -0.27509585f, 0.21835066f,
112 0.28962948f, 0.95642509f, -0.03695701f,
113 -0.19866933f, 0.0978434f, 0.97517033f
115 Dcmf dcm_check(dcm_data);
123 Eulerf e_zero = zeros<float, 3, 1>();
136 Quatf q0(1, 2, 3, 4);
146 0.54772256
f, 0.73029674
f)));
154 q =
Quatf(euler_check);
158 Dcmf dcm(euler_check);
183 double deg2rad =
M_PI / 180.0;
184 double rad2deg = 180.0 /
M_PI;
187 for (
int roll = -90; roll <= 90; roll += 90) {
188 for (
int pitch = -90; pitch <= 90; pitch += 90) {
189 for (
int yaw = -179; yaw <= 180; yaw += 90) {
191 int roll_expected = roll;
192 int yaw_expected = yaw;
196 yaw_expected = yaw - roll;
198 }
else if (pitch == -90) {
200 yaw_expected = yaw + roll;
203 if (yaw_expected < -180) { yaw_expected += 360; }
205 if (yaw_expected > 180) { yaw_expected -= 360; }
209 deg2rad *
double(roll_expected),
210 deg2rad *
double(pitch),
211 deg2rad *
double(yaw_expected));
213 deg2rad *
double(roll),
214 deg2rad *
double(pitch),
215 deg2rad *
double(yaw));
222 float(deg2rad)*
float(roll_expected),
223 float(deg2rad)*
float(pitch),
224 float(deg2rad)*
float(yaw_expected));
225 Eulerf eulerf(
float(deg2rad)*
float(roll),
226 float(deg2rad)*
float(pitch),
227 float(deg2rad)*
float(yaw));
231 float(rad2deg)*euler_outf));
237 float data_v4[] = {1, 2, 3, 4};
251 Quatf q_prod_check(0.93394439
f, 0.0674002
f, 0.20851
f, 0.28236266
f);
258 Quatf q_scalar_mul(1.0
f, 2.0
f, 3.0
f, 4.0
f);
259 Quatf q_scalar_mul_check(1.0
f * scalar, 2.0
f * scalar,
260 3.0
f * scalar, 4.0
f * scalar);
261 Quatf q_scalar_mul_res = scalar * q_scalar_mul;
263 Quatf q_scalar_mul_res2 = q_scalar_mul * scalar;
265 Quatf q_scalar_mul_res3(q_scalar_mul);
266 q_scalar_mul_res3 *= scalar;
271 ut_test(fabs(q_check(0) - q(0)) < eps);
272 ut_test(fabs(q_check(1) + q(1)) < eps);
273 ut_test(fabs(q_check(2) + q(2)) < eps);
274 ut_test(fabs(q_check(3) + q(3)) < eps);
278 ut_test(fabs(q_check(0) - q(0)) < eps);
279 ut_test(fabs(q_check(1) + q(1)) < eps);
280 ut_test(fabs(q_check(2) + q(2)) < eps);
281 ut_test(fabs(q_check(3) + q(3)) < eps);
287 rot(1) = rot(2) = 0.0f;
289 Quatf q_true(cosf(1.0
f / 2), sinf(1.0
f / 2), 0.0
f, 0.0
f);
290 ut_test(fabs(qI(0) - q_true(0)) < eps);
291 ut_test(fabs(qI(1) - q_true(1)) < eps);
292 ut_test(fabs(qI(2) - q_true(2)) < eps);
293 ut_test(fabs(qI(3) - q_true(3)) < eps);
298 rot(1) = rot(2) = 0.0f;
300 q_true =
Quatf(cosf(0.0
f), sinf(0.0
f), 0.0
f, 0.0
f);
301 ut_test(fabs(qI(0) - q_true(0)) < eps);
302 ut_test(fabs(qI(1) - q_true(1)) < eps);
303 ut_test(fabs(qI(2) - q_true(2)) < eps);
304 ut_test(fabs(qI(3) - q_true(3)) < eps);
307 q =
Quatf(cosf(1.0
f / 2), 0.0
f, sinf(1.0
f / 2), 0.0
f);
321 rot(0) = rot(1) = rot(2) = 0.0f;
324 ut_test(fabs(q(0) - q_true(0)) < eps);
325 ut_test(fabs(q(1) - q_true(1)) < eps);
326 ut_test(fabs(q(2) - q_true(2)) < eps);
327 ut_test(fabs(q(3) - q_true(3)) < eps);
334 const size_t n_x = 6;
335 const size_t n_y = 5;
340 float data[] = {1, 2, 3, 4, 5};
346 kalman_correct<float, 6, 5>(
P, C, R, r, dx, dP, beta);
348 float data_check[] = {0.5, 1, 1.5, 2, 2.5, 0};
375 return v * ones<float, 6, 1>();
386 float v = 1 + cosf(tf) - cosf(t0);
394 float data[9] = {0, 2, 3,
398 float data_check[9] = {-0.4f, -0.8f, 0.6f,
431 float data[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
436 for (
size_t i = 0; i < 3; i++) {
437 for (
size_t j = 0; j < 3; j++) {
438 ut_test(fabs(data[i * 3 + j] - m2(i, j)) < eps);
442 float data_times_2[9] = {2, 4, 6, 8, 10, 12, 14, 16, 18};
453 float data_minus_1[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
463 float data_row_02_swap[9] = {
469 float data_col_02_swap[9] = {
490 ut_test(fabs(m5(0, 0) - s) < 1e-5);
501 float data[9] = {1, 0, 0, 0, 1, 0, 1, 0, 1};
503 float data_check[9] = {1, 0, 0, 0, 1, 0, -1, 0, 1};
517 Matrix3f B_check = eye<float, 3>() * 4;
525 float data[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
528 float data_check[9] = {2, 4, 6, 8, 10, 12, 14, 16, 18};
543 for (
int i = 0; i < 3; i++) {
544 for (
int j = 0; j < 3; j++) {
546 ut_test(fabs(A(i, j) - 1) < 1e-7);
549 ut_test(fabs(A(i, j) - 0) < 1e-7);
559 float data[9] = {0, 2, 3,
563 float data_check[6] = {
578 A.
slice<2, 2>(1, 1) = C;
580 float data_2_check[9] = {
594 float data[9] = {1, 2, 3,
603 float data_check[9] = {
604 1.01158503f, 0.02190432f, 0.03238144f,
605 0.04349195f, 1.05428524f, 0.06539627f,
606 0.07576783f, 0.08708946f, 1.10894048f
621 float data[6] = {1, 2, 3, 4, 5, 6};
624 float data_check[6] = {1, 4, 2, 5, 3, 6};
633 float data1[] = {1, 2, 3, 4, 5};
634 float data2[] = {6, 7, 8, 9, 10};
636 ut_test(fabs(v1.
norm() - 7.416198487095663f) < 1e-5);
642 float data1_sq[] = {1, 4, 9, 16, 25};
653 ut_test(fabs(a % b - 1.0f) < 1e-5);
656 ut_test(fabs(c(0) - 0) < 1e-5);
657 ut_test(fabs(c(1) - 0) < 1e-5);
662 ut_test(fabs(d(0, 0) - 1) < 1e-5);
663 ut_test(fabs(d(1, 0) - 0) < 1e-5);
666 ut_test(fabs(e(0) - 1) < 1e-5);
667 ut_test(fabs(e(1) - 0) < 1e-5);
669 float data[] = {4, 5};
687 float data[] = {4, 5, 6};
700 static const float eps = 1e-7
f;
702 ut_test(fabsf(v(0) - 1) < eps);
703 ut_test(fabsf(v(1) - 2) < eps);
704 ut_test(fabsf(v(2) - 3) < eps);
708 ut_test(fabsf(v2(0) - 4) < eps);
709 ut_test(fabsf(v2(1) - 5) < eps);
710 ut_test(fabsf(v2(2) - 6) < eps);
713 ut_test(fabsf(m(0, 0) - 1) < eps);
714 ut_test(fabsf(m(1, 1) - 2) < eps);
715 ut_test(fabsf(m(2, 2) - 3) < eps);
729 for (
int i = 0; i < 1000; i++) {
736 for (
int row = 0; row < 3; row++) {
738 err += fabsf(1.0f - rvec.
length());
741 printf(
"error: %e\n", (
double)err);
748 for (
int row = 0; row < 3; row++) {
750 err += fabsf(1.0f - rvec.
length());
754 printf(
"renorm error: %e\n", (
double)err);
757 static const float eps = 1e-6
f;
772 float data0_check[12] = {
773 -0.3375f, -0.1f, 0.1375f,
774 -0.13333333f, -0.03333333f, 0.06666667f,
775 0.07083333f, 0.03333333f, -0.00416667f,
776 0.275f, 0.1f, -0.075f
793 float data1_check[12] = {
794 -0.3375f, -0.13333333f, 0.07083333f, 0.275f,
795 -0.1f, -0.03333333f, 0.03333333f, 0.1f,
796 0.1375f, 0.06666667f, -0.00416667f, -0.075f
811 float data2_check[9] = {
823 const float B_quad_w[6][16] = {
824 {-0.5717536f, 0.43756646f, 0.5717536f, -0.43756646f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
825 { 0.35355328f, -0.35355328f, 0.35355328f, -0.35355328f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
826 { 0.28323701f, 0.28323701f, -0.28323701f, -0.28323701f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
827 { 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
828 { 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
829 {-0.25f, -0.25f, -0.25f, -0.25f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}
832 const float A_quad_w[16][6] = {
833 { -0.495383f, 0.707107f, 0.765306f, 0.0f, 0.0f, -1.000000f },
834 { 0.495383f, -0.707107f, 1.000000f, 0.0f, 0.0f, -1.000000f },
835 { 0.495383f, 0.707107f, -0.765306f, 0.0f, 0.0f, -1.000000f },
836 { -0.495383f, -0.707107f, -1.000000f, 0.0f, 0.0f, -1.000000f },
837 { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f},
838 { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f},
839 { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f},
840 { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f},
841 { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f},
842 { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f},
843 { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f},
844 { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f},
845 { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f},
846 { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f},
847 { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f},
848 { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}
Vector3 cross(const Matrix31 &b) const
#define ut_declare_test_c(test_function, test_class)
SquareMatrix< float, 3 > Matrix3f
void invert()
Invert quaternion in place.
Base class to be used for unit tests.
Matrix< Type, N, M > transpose() const
bool pseudoInverseTests()
int test_matrix(int argc, char *argv[])
#define ut_test(test)
Used to assert a value within a unit test.
bool matrixScalarMultTests()
void swapRows(size_t a, size_t b)
int integrate_rk4(Vector< Type, M >(*f)(Type, const Matrix< Type, M, 1 > &x, const Matrix< Type, N, 1 > &u), const Matrix< Type, M, 1 > &y0, const Matrix< Type, N, 1 > &u, Type t0, Type tf, Type h0, Matrix< Type, M, 1 > &y1)
const Slice< Type, M, 1, M, N > col(size_t j) const
Vector< Type, 3 > to_axis_angle() const
Rotation vector from quaternion XXX DEPRECATED, use AxisAngle class.
void rotate(const AxisAngle< Type > &vec)
Rotate quaternion from rotation vector.
const Slice< Type, P, Q, M, N > slice(size_t x0, size_t y0) const
void from_axis_angle(Vector< Type, 3 > vec)
Rotation quaternion from vector.
Matrix41 derivative1(const Matrix31 &w) const
Computes the derivative of q_21 when rotated with angular velocity expressed in frame 1 v_2 = q_21 * ...
bool isEqual(const Matrix< Type, M, N > &x, const Matrix< Type, M, N > &y, const Type eps=1e-4f)
Type dot(const MatrixM1 &b) const
Vector2< float > Vector2f
bool inv(const SquareMatrix< Type, M > &A, SquareMatrix< Type, M > &inv)
inverse based on LU factorization with partial pivotting
Vector< Type, M > diag() const
Type wrap_pi(Type x)
Wrap value in range [-π, π)
SquareMatrix< Type, M > diag(Vector< Type, M > d)
Vector3< float > Vector3f
Quaternion inversed() const
Invert quaternion.
Quaternion< float > Quatf
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &y, const Matrix< float, 3, 1 > &u)
const Slice< Type, 1, N, M, N > row(size_t i) const
bool matrixAssignmentTests()
Dual< Scalar, N > max(const Dual< Scalar, N > &a, const Dual< Scalar, N > &b)
bool vectorAssignmentTests()
#define ut_run_test(test)
Runs a single unit test.
virtual bool run_tests()
Override to run your unit tests.
SquareMatrix< Type, M > expm(const Matrix< Type, M, M > &A, size_t order=5)
Dual< Scalar, N > abs(const Dual< Scalar, N > &a)
All rotations and axis systems follow the right-hand rule.
void swapCols(size_t a, size_t b)
Matrix< Type, M, N > emult(const Matrix< Type, M, N > &other) const
Matrix< Type, N, M > geninv(const Matrix< Type, M, N > &G)
Geninv Fast pseudoinverse based on full rank cholesky factorisation.