|
|
|
@ -1,7 +1,8 @@
@@ -1,7 +1,8 @@
|
|
|
|
|
#include <cassert> |
|
|
|
|
#include <cstdio> |
|
|
|
|
#include <stdexcept> |
|
|
|
|
|
|
|
|
|
#include <matrix/math.hpp> |
|
|
|
|
#include "test_macros.hpp" |
|
|
|
|
|
|
|
|
|
using namespace matrix; |
|
|
|
|
|
|
|
|
@ -24,14 +25,13 @@ int main()
@@ -24,14 +25,13 @@ int main()
|
|
|
|
|
Dcmf dcm_check(dcm_data); |
|
|
|
|
|
|
|
|
|
// euler ctor
|
|
|
|
|
euler_check.T().print(); |
|
|
|
|
assert(euler_check == Vector3f(0.1f, 0.2f, 0.3f)); |
|
|
|
|
TEST(isEqual(euler_check, Vector3f(0.1f, 0.2f, 0.3f))); |
|
|
|
|
|
|
|
|
|
// euler default ctor
|
|
|
|
|
Eulerf e; |
|
|
|
|
Eulerf e_zero = zeros<float, 3, 1>(); |
|
|
|
|
assert(e == e_zero); |
|
|
|
|
assert(e == e); |
|
|
|
|
TEST(isEqual(e, e_zero)); |
|
|
|
|
TEST(isEqual(e, e)); |
|
|
|
|
|
|
|
|
|
// euler vector ctor
|
|
|
|
|
Vector<float, 3> v; |
|
|
|
@ -39,99 +39,87 @@ int main()
@@ -39,99 +39,87 @@ int main()
|
|
|
|
|
v(1) = 0.2f; |
|
|
|
|
v(2) = 0.3f; |
|
|
|
|
Eulerf euler_copy(v); |
|
|
|
|
assert(euler_copy == euler_check); |
|
|
|
|
TEST(isEqual(euler_copy, euler_check)); |
|
|
|
|
|
|
|
|
|
// quaternion ctor
|
|
|
|
|
Quatf q(1, 2, 3, 4); |
|
|
|
|
assert(fabs(q(0) - 1) < eps); |
|
|
|
|
assert(fabs(q(1) - 2) < eps); |
|
|
|
|
assert(fabs(q(2) - 3) < eps); |
|
|
|
|
assert(fabs(q(3) - 4) < eps); |
|
|
|
|
TEST(fabs(q(0) - 1) < eps); |
|
|
|
|
TEST(fabs(q(1) - 2) < eps); |
|
|
|
|
TEST(fabs(q(2) - 3) < eps); |
|
|
|
|
TEST(fabs(q(3) - 4) < eps); |
|
|
|
|
|
|
|
|
|
// quat normalization
|
|
|
|
|
q.T().print(); |
|
|
|
|
q.normalize(); |
|
|
|
|
q.T().print(); |
|
|
|
|
assert(q == Quatf(0.18257419f, 0.36514837f, |
|
|
|
|
0.54772256f, 0.73029674f)); |
|
|
|
|
TEST(isEqual(q, Quatf(0.18257419f, 0.36514837f, |
|
|
|
|
0.54772256f, 0.73029674f))); |
|
|
|
|
|
|
|
|
|
// quat default ctor
|
|
|
|
|
q = Quatf(); |
|
|
|
|
assert(q == Quatf(1, 0, 0, 0)); |
|
|
|
|
TEST(isEqual(q, Quatf(1, 0, 0, 0))); |
|
|
|
|
|
|
|
|
|
// euler to quaternion
|
|
|
|
|
q = Quatf(euler_check); |
|
|
|
|
q.T().print(); |
|
|
|
|
assert(q == q_check); |
|
|
|
|
TEST(isEqual(q, q_check)); |
|
|
|
|
|
|
|
|
|
// euler to dcm
|
|
|
|
|
Dcmf dcm(euler_check); |
|
|
|
|
dcm.print(); |
|
|
|
|
assert(dcm == dcm_check); |
|
|
|
|
TEST(isEqual(dcm, dcm_check)); |
|
|
|
|
|
|
|
|
|
// quaternion to euler
|
|
|
|
|
Eulerf e1(q_check); |
|
|
|
|
assert(e1 == euler_check); |
|
|
|
|
TEST(isEqual(e1, euler_check)); |
|
|
|
|
|
|
|
|
|
// quaternion to dcm
|
|
|
|
|
Dcmf dcm1(q_check); |
|
|
|
|
dcm1.print(); |
|
|
|
|
assert(dcm1 == dcm_check); |
|
|
|
|
TEST(isEqual(dcm1, dcm_check)); |
|
|
|
|
|
|
|
|
|
// dcm default ctor
|
|
|
|
|
Dcmf dcm2; |
|
|
|
|
dcm2.print(); |
|
|
|
|
SquareMatrix<float, 3> I = eye<float, 3>(); |
|
|
|
|
assert(dcm2 == I); |
|
|
|
|
TEST(isEqual(dcm2, I)); |
|
|
|
|
|
|
|
|
|
// dcm to euler
|
|
|
|
|
Eulerf e2(dcm_check); |
|
|
|
|
assert(e2 == euler_check); |
|
|
|
|
TEST(isEqual(e2, euler_check)); |
|
|
|
|
|
|
|
|
|
// dcm to quaterion
|
|
|
|
|
Quatf q2(dcm_check); |
|
|
|
|
assert(q2 == q_check); |
|
|
|
|
TEST(isEqual(q2, q_check)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// euler gimbal lock check
|
|
|
|
|
// note if theta = pi/2, then roll is set to zero
|
|
|
|
|
float pi_2 = float(M_PI_2); |
|
|
|
|
Eulerf euler_gimbal_lock(0.1f, pi_2, 0.2f); |
|
|
|
|
Eulerf euler_gimbal_lock(0.0f, pi_2, 0.2f); |
|
|
|
|
Dcmf dcm_lock(euler_gimbal_lock); |
|
|
|
|
Eulerf euler_gimbal_lock_out(dcm_lock); |
|
|
|
|
euler_gimbal_lock_out.T().print(); |
|
|
|
|
euler_gimbal_lock.T().print(); |
|
|
|
|
assert(euler_gimbal_lock == euler_gimbal_lock_out); |
|
|
|
|
TEST(isEqual(euler_gimbal_lock, euler_gimbal_lock_out)); |
|
|
|
|
|
|
|
|
|
// note if theta = pi/2, then roll is set to zero
|
|
|
|
|
Eulerf euler_gimbal_lock2(0.1f, -pi_2, 0.2f); |
|
|
|
|
Eulerf euler_gimbal_lock2(0.0f, -pi_2, 0.2f); |
|
|
|
|
Dcmf dcm_lock2(euler_gimbal_lock2); |
|
|
|
|
Eulerf euler_gimbal_lock_out2(dcm_lock2); |
|
|
|
|
euler_gimbal_lock_out2.T().print(); |
|
|
|
|
euler_gimbal_lock2.T().print(); |
|
|
|
|
assert(euler_gimbal_lock2 == euler_gimbal_lock_out2); |
|
|
|
|
TEST(isEqual(euler_gimbal_lock2, euler_gimbal_lock_out2)); |
|
|
|
|
|
|
|
|
|
// quaterion copy ctors
|
|
|
|
|
float data_v4[] = {1, 2, 3, 4}; |
|
|
|
|
Vector<float, 4> v4(data_v4); |
|
|
|
|
Quatf q_from_v(v4); |
|
|
|
|
assert(q_from_v == v4); |
|
|
|
|
TEST(isEqual(q_from_v, v4)); |
|
|
|
|
|
|
|
|
|
Matrix<float, 4, 1> m4(data_v4); |
|
|
|
|
Quatf q_from_m(m4); |
|
|
|
|
assert(q_from_m == m4); |
|
|
|
|
TEST(isEqual(q_from_m, m4)); |
|
|
|
|
|
|
|
|
|
// quaternion derivate
|
|
|
|
|
Vector<float, 4> q_dot = q.derivative(Vector3f(1, 2, 3)); |
|
|
|
|
printf("q_dot:\n"); |
|
|
|
|
q_dot.T().print(); |
|
|
|
|
|
|
|
|
|
// quaternion product
|
|
|
|
|
Quatf q_prod_check( |
|
|
|
|
0.93394439f, 0.0674002f, 0.20851f, 0.28236266f); |
|
|
|
|
assert(q_prod_check == q_check*q_check); |
|
|
|
|
TEST(isEqual(q_prod_check, q_check*q_check)); |
|
|
|
|
q_check *= q_check; |
|
|
|
|
assert(q_prod_check == q_check); |
|
|
|
|
TEST(isEqual(q_prod_check, q_check)); |
|
|
|
|
|
|
|
|
|
// Quaternion scalar multiplication
|
|
|
|
|
float scalar = 0.5; |
|
|
|
@ -139,26 +127,26 @@ int main()
@@ -139,26 +127,26 @@ int main()
|
|
|
|
|
Quatf q_scalar_mul_check(1.0f * scalar, 2.0f * scalar, |
|
|
|
|
3.0f * scalar, 4.0f * scalar); |
|
|
|
|
Quatf q_scalar_mul_res = scalar * q_scalar_mul; |
|
|
|
|
assert(q_scalar_mul_check == q_scalar_mul_res); |
|
|
|
|
TEST(isEqual(q_scalar_mul_check, q_scalar_mul_res)); |
|
|
|
|
Quatf q_scalar_mul_res2 = q_scalar_mul * scalar; |
|
|
|
|
assert(q_scalar_mul_check == q_scalar_mul_res2); |
|
|
|
|
TEST(isEqual(q_scalar_mul_check, q_scalar_mul_res2)); |
|
|
|
|
Quatf q_scalar_mul_res3(q_scalar_mul); |
|
|
|
|
q_scalar_mul_res3 *= scalar; |
|
|
|
|
assert(q_scalar_mul_check == q_scalar_mul_res3); |
|
|
|
|
TEST(isEqual(q_scalar_mul_check, q_scalar_mul_res3)); |
|
|
|
|
|
|
|
|
|
// quaternion inverse
|
|
|
|
|
q = q_check.inversed(); |
|
|
|
|
assert(fabsf(q_check(0) - q(0)) < eps); |
|
|
|
|
assert(fabsf(q_check(1) + q(1)) < eps); |
|
|
|
|
assert(fabsf(q_check(2) + q(2)) < eps); |
|
|
|
|
assert(fabsf(q_check(3) + q(3)) < eps); |
|
|
|
|
TEST(fabsf(q_check(0) - q(0)) < eps); |
|
|
|
|
TEST(fabsf(q_check(1) + q(1)) < eps); |
|
|
|
|
TEST(fabsf(q_check(2) + q(2)) < eps); |
|
|
|
|
TEST(fabsf(q_check(3) + q(3)) < eps); |
|
|
|
|
|
|
|
|
|
q = q_check; |
|
|
|
|
q.invert(); |
|
|
|
|
assert(fabsf(q_check(0) - q(0)) < eps); |
|
|
|
|
assert(fabsf(q_check(1) + q(1)) < eps); |
|
|
|
|
assert(fabsf(q_check(2) + q(2)) < eps); |
|
|
|
|
assert(fabsf(q_check(3) + q(3)) < eps); |
|
|
|
|
TEST(fabsf(q_check(0) - q(0)) < eps); |
|
|
|
|
TEST(fabsf(q_check(1) + q(1)) < eps); |
|
|
|
|
TEST(fabsf(q_check(2) + q(2)) < eps); |
|
|
|
|
TEST(fabsf(q_check(3) + q(3)) < eps); |
|
|
|
|
|
|
|
|
|
// rotate quaternion (nonzero rotation)
|
|
|
|
|
Quatf qI(1.0f, 0.0f, 0.0f, 0.0f); |
|
|
|
@ -167,10 +155,10 @@ int main()
@@ -167,10 +155,10 @@ int main()
|
|
|
|
|
rot(1) = rot(2) = 0.0f; |
|
|
|
|
qI.rotate(rot); |
|
|
|
|
Quatf q_true(cosf(1.0f / 2), sinf(1.0f / 2), 0.0f, 0.0f); |
|
|
|
|
assert(fabsf(qI(0) - q_true(0)) < eps); |
|
|
|
|
assert(fabsf(qI(1) - q_true(1)) < eps); |
|
|
|
|
assert(fabsf(qI(2) - q_true(2)) < eps); |
|
|
|
|
assert(fabsf(qI(3) - q_true(3)) < eps); |
|
|
|
|
TEST(fabsf(qI(0) - q_true(0)) < eps); |
|
|
|
|
TEST(fabsf(qI(1) - q_true(1)) < eps); |
|
|
|
|
TEST(fabsf(qI(2) - q_true(2)) < eps); |
|
|
|
|
TEST(fabsf(qI(3) - q_true(3)) < eps); |
|
|
|
|
|
|
|
|
|
// rotate quaternion (zero rotation)
|
|
|
|
|
qI = Quatf(1.0f, 0.0f, 0.0f, 0.0f); |
|
|
|
@ -178,33 +166,33 @@ int main()
@@ -178,33 +166,33 @@ int main()
|
|
|
|
|
rot(1) = rot(2) = 0.0f; |
|
|
|
|
qI.rotate(rot); |
|
|
|
|
q_true = Quatf(cosf(0.0f), sinf(0.0f), 0.0f, 0.0f); |
|
|
|
|
assert(fabsf(qI(0) - q_true(0)) < eps); |
|
|
|
|
assert(fabsf(qI(1) - q_true(1)) < eps); |
|
|
|
|
assert(fabsf(qI(2) - q_true(2)) < eps); |
|
|
|
|
assert(fabsf(qI(3) - q_true(3)) < eps); |
|
|
|
|
TEST(fabsf(qI(0) - q_true(0)) < eps); |
|
|
|
|
TEST(fabsf(qI(1) - q_true(1)) < eps); |
|
|
|
|
TEST(fabsf(qI(2) - q_true(2)) < eps); |
|
|
|
|
TEST(fabsf(qI(3) - q_true(3)) < eps); |
|
|
|
|
|
|
|
|
|
// get rotation axis from quaternion (nonzero rotation)
|
|
|
|
|
q = Quatf(cosf(1.0f / 2), 0.0f, sinf(1.0f / 2), 0.0f); |
|
|
|
|
rot = q.to_axis_angle(); |
|
|
|
|
assert(fabsf(rot(0)) < eps); |
|
|
|
|
assert(fabsf(rot(1) -1.0f) < eps); |
|
|
|
|
assert(fabsf(rot(2)) < eps); |
|
|
|
|
TEST(fabsf(rot(0)) < eps); |
|
|
|
|
TEST(fabsf(rot(1) -1.0f) < eps); |
|
|
|
|
TEST(fabsf(rot(2)) < eps); |
|
|
|
|
|
|
|
|
|
// get rotation axis from quaternion (zero rotation)
|
|
|
|
|
q = Quatf(1.0f, 0.0f, 0.0f, 0.0f); |
|
|
|
|
rot = q.to_axis_angle(); |
|
|
|
|
assert(fabsf(rot(0)) < eps); |
|
|
|
|
assert(fabsf(rot(1)) < eps); |
|
|
|
|
assert(fabsf(rot(2)) < eps); |
|
|
|
|
TEST(fabsf(rot(0)) < eps); |
|
|
|
|
TEST(fabsf(rot(1)) < eps); |
|
|
|
|
TEST(fabsf(rot(2)) < eps); |
|
|
|
|
|
|
|
|
|
// from axis angle (zero rotation)
|
|
|
|
|
rot(0) = rot(1) = rot(2) = 0.0f; |
|
|
|
|
q.from_axis_angle(rot, 0.0f); |
|
|
|
|
q_true = Quatf(1.0f, 0.0f, 0.0f, 0.0f); |
|
|
|
|
assert(fabsf(q(0) - q_true(0)) < eps); |
|
|
|
|
assert(fabsf(q(1) - q_true(1)) < eps); |
|
|
|
|
assert(fabsf(q(2) - q_true(2)) < eps); |
|
|
|
|
assert(fabsf(q(3) - q_true(3)) < eps); |
|
|
|
|
TEST(fabsf(q(0) - q_true(0)) < eps); |
|
|
|
|
TEST(fabsf(q(1) - q_true(1)) < eps); |
|
|
|
|
TEST(fabsf(q(2) - q_true(2)) < eps); |
|
|
|
|
TEST(fabsf(q(3) - q_true(3)) < eps); |
|
|
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|