You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

216 lines
6.3 KiB

9 years ago
#include <cstdio>
#include <stdexcept>
9 years ago
#include <matrix/math.hpp>
#include "test_macros.hpp"
9 years ago
using namespace matrix;
template class Quaternion<float>;
template class Euler<float>;
template class Dcm<float>;
int main()
{
double eps = 1e-6;
// check data
Eulerf euler_check(0.1f, 0.2f, 0.3f);
Quatf q_check(0.98334744f, 0.0342708f, 0.10602051f, .14357218f);
9 years ago
float dcm_data[] = {
0.93629336f, -0.27509585f, 0.21835066f,
0.28962948f, 0.95642509f, -0.03695701f,
-0.19866933f, 0.0978434f, 0.97517033f
9 years ago
};
9 years ago
Dcmf dcm_check(dcm_data);
// euler ctor
TEST(isEqual(euler_check, Vector3f(0.1f, 0.2f, 0.3f)));
// euler default ctor
Eulerf e;
Eulerf e_zero = zeros<float, 3, 1>();
TEST(isEqual(e, e_zero));
TEST(isEqual(e, e));
9 years ago
// euler vector ctor
Vector<float, 3> v;
v(0) = 0.1f;
v(1) = 0.2f;
v(2) = 0.3f;
Eulerf euler_copy(v);
TEST(isEqual(euler_copy, euler_check));
9 years ago
// quaternion ctor
Quatf q(1, 2, 3, 4);
TEST(fabs(q(0) - 1) < eps);
TEST(fabs(q(1) - 2) < eps);
TEST(fabs(q(2) - 3) < eps);
TEST(fabs(q(3) - 4) < eps);
9 years ago
// quat normalization
9 years ago
q.normalize();
TEST(isEqual(q, Quatf(0.18257419f, 0.36514837f,
0.54772256f, 0.73029674f)));
// quat default ctor
q = Quatf();
TEST(isEqual(q, Quatf(1, 0, 0, 0)));
9 years ago
// euler to quaternion
q = Quatf(euler_check);
TEST(isEqual(q, q_check));
9 years ago
// euler to dcm
Dcmf dcm(euler_check);
TEST(isEqual(dcm, dcm_check));
9 years ago
// quaternion to euler
Eulerf e1(q_check);
TEST(isEqual(e1, euler_check));
9 years ago
// quaternion to dcm
Dcmf dcm1(q_check);
TEST(isEqual(dcm1, dcm_check));
// dcm default ctor
Dcmf dcm2;
SquareMatrix<float, 3> I = eye<float, 3>();
TEST(isEqual(dcm2, I));
9 years ago
// dcm to euler
Eulerf e2(dcm_check);
TEST(isEqual(e2, euler_check));
9 years ago
// dcm to quaterion
Quatf q2(dcm_check);
TEST(isEqual(q2, q_check));
9 years ago
// constants
double deg2rad = M_PI/180.0;
double rad2deg = 180.0/M_PI;
// euler dcm round trip check
for (int roll=-90; roll<90; roll+=1) {
for (int pitch=-90; pitch<90; pitch+=1) {
for (int yaw=0; yaw<360; yaw+=1) {
// note if theta = pi/2, then roll is set to zero
if (pitch == 90 || pitch == -90) {
roll = 0;
}
printf("roll:%d pitch:%d yaw:%d\n", roll, pitch, yaw);
Euler<double> euler(deg2rad*double(roll),
deg2rad*double(pitch),
deg2rad*double(yaw));
Dcm<double> dcm_from_euler(euler);
Euler<double> euler_out(dcm_from_euler);
TEST(isEqual(rad2deg*euler, rad2deg*euler_out));
Eulerf eulerf(float(deg2rad)*float(roll),
float(deg2rad)*float(pitch),
float(deg2rad)*float(yaw));
Dcm<float> dcm_from_eulerf(eulerf);
Euler<float> euler_outf(dcm_from_eulerf);
TEST(isEqual(float(rad2deg)*eulerf,
float(rad2deg)*euler_outf));
}
}
}
// quaterion copy ctors
float data_v4[] = {1, 2, 3, 4};
Vector<float, 4> v4(data_v4);
Quatf q_from_v(v4);
TEST(isEqual(q_from_v, v4));
Matrix<float, 4, 1> m4(data_v4);
Quatf q_from_m(m4);
TEST(isEqual(q_from_m, m4));
// quaternion derivate
Vector<float, 4> q_dot = q.derivative(Vector3f(1, 2, 3));
// quaternion product
Quatf q_prod_check(
9 years ago
0.93394439f, 0.0674002f, 0.20851f, 0.28236266f);
TEST(isEqual(q_prod_check, q_check*q_check));
9 years ago
q_check *= q_check;
TEST(isEqual(q_prod_check, q_check));
// Quaternion scalar multiplication
float scalar = 0.5;
Quatf q_scalar_mul(1.0f, 2.0f, 3.0f, 4.0f);
Quatf q_scalar_mul_check(1.0f * scalar, 2.0f * scalar,
9 years ago
3.0f * scalar, 4.0f * scalar);
Quatf q_scalar_mul_res = scalar * q_scalar_mul;
TEST(isEqual(q_scalar_mul_check, q_scalar_mul_res));
Quatf q_scalar_mul_res2 = q_scalar_mul * scalar;
TEST(isEqual(q_scalar_mul_check, q_scalar_mul_res2));
Quatf q_scalar_mul_res3(q_scalar_mul);
q_scalar_mul_res3 *= scalar;
TEST(isEqual(q_scalar_mul_check, q_scalar_mul_res3));
// quaternion inverse
q = q_check.inversed();
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();
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);
Vector<float, 3> rot;
rot(0) = 1.0f;
rot(1) = rot(2) = 0.0f;
qI.rotate(rot);
Quatf q_true(cosf(1.0f / 2), sinf(1.0f / 2), 0.0f, 0.0f);
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);
rot(0) = 0.0f;
rot(1) = rot(2) = 0.0f;
qI.rotate(rot);
q_true = Quatf(cosf(0.0f), sinf(0.0f), 0.0f, 0.0f);
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();
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();
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);
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);
};
9 years ago
/* vim: set et fenc=utf-8 ff=unix sts=0 sw=4 ts=4 : */