Cheetah Software  1.0
test_orientation_tools.cpp
Go to the documentation of this file.
1 
9 #include "gmock/gmock.h"
10 #include "gtest/gtest.h"
11 
12 using namespace ori;
13 
17 TEST(Orientation, rad2deg) {
18  EXPECT_EQ(M_PI / 4., deg2rad(45.));
19  EXPECT_EQ(45, rad2deg(M_PI / 4.));
20 }
21 
25 TEST(Orientation, almostEqual) {
26  // check matrix "almostEqual" function
27  Mat3<double> a, b;
28  a << 1, 2, 3, 4, 5, 6, 7, 8, 9.2;
29  b << 1, 2, 3, 4, 5, 6, 7, 8, 9.1;
30  EXPECT_EQ(true, almostEqual(a, b, .3));
31  EXPECT_EQ(false, almostEqual(a, b, .01));
32 
33  DVec<double> qdd(4);
34  qdd << 1, 2, 3, 4;
35 
36  DVec<double> qdd2 = qdd;
37 
38  EXPECT_TRUE(almostEqual(qdd, qdd2, 1e-6));
39  qdd2(1) += .2;
40  EXPECT_FALSE(almostEqual(qdd, qdd2, 1e-6));
41 
42  DMat<double> testDynamicMat(3, 3);
43  DMat<double> testDynamicMat2(3, 3);
44  testDynamicMat << 1, 2, 3, 4, 5, 6, 7, 8, 9.2;
45  testDynamicMat2 << 1, 2, 3, 4, 5, 6, 7, 8, 9.1;
46  EXPECT_EQ(true, almostEqual(testDynamicMat, testDynamicMat2, .3));
47  EXPECT_EQ(false, almostEqual(testDynamicMat, testDynamicMat2, .01));
48 }
49 
54 TEST(Orientation, coordinateRotation) {
55  // check rotation matrices
56  double s = std::sin(.2);
57  double c = std::cos(.2);
58  Mat3<double> R_ref_x, R_ref_y, R_ref_z;
59  R_ref_x << 1, 0, 0, 0, c, s, 0, -s, c;
60  R_ref_y << c, 0, -s, 0, 1, 0, s, 0, c;
61  R_ref_z << c, s, 0, -s, c, 0, 0, 0, 1;
62  EXPECT_EQ(R_ref_x, coordinateRotation(CoordinateAxis::X, .2));
63  EXPECT_EQ(R_ref_y, coordinateRotation(CoordinateAxis::Y, .2));
64  EXPECT_EQ(R_ref_z, coordinateRotation(CoordinateAxis::Z, .2));
65 }
66 
71 TEST(Orientation, skew) {
72  // check skew vec->mat and mat->vec
73  Mat3<double> A, B;
74  A << 8, 1, 6, 3, 5, 7, 4, 9, 2;
75  B << 0, -3, 2, 3, 0, -1, -2, 1, 0;
76  Vec3<double> v(1, 1, 1);
77  Vec3<double> w(1, 2, 3);
78 
79  EXPECT_EQ(matToSkewVec(A), v);
80  EXPECT_EQ(B, vectorToSkewMat(w));
81  EXPECT_EQ(w, matToSkewVec(vectorToSkewMat(w)));
82  EXPECT_EQ(v, matToSkewVec(vectorToSkewMat(v)));
83 }
84 
89 TEST(Orientation, quatToRotm) {
90  // check R -> q and q -> R
91  Quat<double> q(.9672, -0.0672, -0.1653, -0.1808);
92  Mat3<double> R;
93  R << .8799, .3720, -.2955, -.3276, .9256, .1898, .3441, -.0702, .9363;
94  Quat<double> q2 = rotationMatrixToQuaternion(R.transpose());
95  Mat3<double> R2 = quaternionToRotationMatrix(q).transpose();
96  EXPECT_TRUE(almostEqual(q2, q, .0001));
97  EXPECT_TRUE(almostEqual(R2, R, .0001));
98 }
99 
103 TEST(Orientation, quatToRpy) {
104  // check q -> rpy
105  Quat<double> q(0.9672, -0.0672, -0.1653, -0.1808);
106  Vec3<double> rpy1(-0.0748, -0.3513, -0.3564);
107  EXPECT_TRUE(almostEqual(rpy1, quatToRPY(q), .1));
108 }
109 
113 TEST(Orientation, quatToRpy2) {
114  // check q -> rpy
117  Vec3<double> rpy = quatToRPY(q);
118  Vec3<double> rpy_ref(0, .5, 0);
119  EXPECT_TRUE(almostEqual(rpy, rpy_ref, .00001));
120 }
121 
125 TEST(Orientation, quatToRpy3) {
126  // check q -> rpy
129  Vec3<double> rpy = quatToRPY(q);
130  Vec3<double> rpy_ref(0, 0, 0.5);
131  EXPECT_TRUE(almostEqual(rpy, rpy_ref, .00001));
132 }
133 
138 TEST(Orienation, quaternionDerivative) {
139  Quat<double> ref(-10.8376, -0.6752, -2.5128, -1.3504);
140  Quat<double> q =
141  quatDerivative(Quat<double>(1, 2, 3, 4), Vec3<double>(1, 2, 3));
142  EXPECT_TRUE(almostEqual(q, ref, .0005));
143 }
144 
148 TEST(Orientation, quaternionProduct) {
149  Quat<double> q1(1, 2, 3, 4);
150  Quat<double> q2(5, 6, 7, 8);
151  Quat<double> ref(-60, 12, 30, 24);
152  EXPECT_TRUE(almostEqual(ref, quatProduct(q1, q2), .0001));
153 }
154 
155 TEST(Orientation, quaternionProductDirection) {
159 
163 
164  RotMat<double> R12_ref = R2 * R1;
165 
168  Quat<double> Q12 = quatProduct(Q1, Q2);
169 
171 
172  EXPECT_TRUE(almostEqual(R12, R12_ref, .0001));
173 }
174 
178 TEST(Orientation, quaternionIntegration) {
180 
181  Vec3<double> omegaX(1, 0, 0);
182  Vec3<double> omegaY(0, -1, 0);
183  Vec3<double> omegaZ(0, 0, 1);
184 
188 
190 
191  Quat<double> rot_x_quat = integrateQuat(eyeQ, omegaX, .1);
192  Quat<double> rot_y_quat = integrateQuat(eyeQ, omegaY, .1);
193  Quat<double> rot_z_quat = integrateQuat(eyeQ, omegaZ, .1);
194 
195  EXPECT_TRUE(
196  almostEqual(quaternionToRotationMatrix(rot_x_quat), rot_x_ref, .0001));
197  EXPECT_TRUE(
198  almostEqual(quaternionToRotationMatrix(rot_y_quat), rot_y_ref, .0001));
199  EXPECT_TRUE(
200  almostEqual(quaternionToRotationMatrix(rot_z_quat), rot_z_ref, .0001));
201 }
202 
206 TEST(Orientation, rpyToRotMat) {
207  Vec3<double> rpy(deg2rad(20.), deg2rad(34.), deg2rad(160.));
208  Mat3<double> R = rpyToRotMat(rpy);
210  Vec3<double> rpyAgain = quatToRPY(q);
211  EXPECT_TRUE(almostEqual(rpyAgain, rpy, .001));
212  std::cout << "1: " << rpy.transpose() << "\n2: " << rpyAgain.transpose()
213  << "\n";
214 }
215 
219 TEST(Orientation, allOrientationConversions) {
220  Vec3<double> refRPY(deg2rad(20.), deg2rad(34.), deg2rad(160.));
221  // do all rpy -> conversions
222  Quat<double> quatFromRPY = rpyToQuat(refRPY);
223  Mat3<double> rFromRPY = rpyToRotMat(refRPY);
224 
225  // do all quat -> conversions
226  Mat3<double> rFromQuat = quaternionToRotationMatrix(quatFromRPY);
227  Vec3<double> rpyFromQuat = quatToRPY(quatFromRPY);
228 
229  // do all r -> conversions
230  Vec3<double> rpyFromR = rotationMatrixToRPY(rFromRPY);
231  Quat<double> quatFromR = rotationMatrixToQuaternion(rFromQuat);
232 
233  EXPECT_TRUE(almostEqual(refRPY, rpyFromQuat, .0001));
234  EXPECT_TRUE(almostEqual(refRPY, rpyFromR, .0001));
235 
236  EXPECT_TRUE(almostEqual(rFromQuat, rFromRPY, .0001));
237 
238  EXPECT_TRUE(almostEqual(quatFromR, quatFromRPY, .0001));
239 }
T rad2deg(T rad)
Mat3< T > coordinateRotation(CoordinateAxis axis, T theta)
Mat3< typename T::Scalar > rpyToRotMat(const Eigen::MatrixBase< T > &v)
typename Eigen::Matrix< T, 3, 3 > Mat3
Definition: cppTypes.h:54
typename Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > DMat
Definition: cppTypes.h:106
typename Eigen::Matrix< T, 4, 1 > Quat
Definition: cppTypes.h:58
typename Eigen::Matrix< T, 3, 1 > Vec3
Definition: cppTypes.h:26
Quat< typename T::Scalar > integrateQuat(const Eigen::MatrixBase< T > &quat, const Eigen::MatrixBase< T2 > &omega, T3 dt)
Vec3< typename T::Scalar > quatToRPY(const Eigen::MatrixBase< T > &q)
TEST(Orientation, rad2deg)
Quat< typename T::Scalar > rotationMatrixToQuaternion(const Eigen::MatrixBase< T > &r1)
Quat< typename T::Scalar > quatProduct(const Eigen::MatrixBase< T > &q1, const Eigen::MatrixBase< T > &q2)
bool almostEqual(const Eigen::MatrixBase< T > &a, const Eigen::MatrixBase< T > &b, T2 tol)
Definition: MathUtilities.h:23
Quat< typename T::Scalar > rpyToQuat(const Eigen::MatrixBase< T > &rpy)
T deg2rad(T deg)
Mat3< typename T::Scalar > vectorToSkewMat(const Eigen::MatrixBase< T > &v)
Utility functions for 3D rotations.
typename Eigen::Matrix< T, Eigen::Dynamic, 1 > DVec
Definition: cppTypes.h:102
Vec3< typename T::Scalar > matToSkewVec(const Eigen::MatrixBase< T > &m)
Vec3< typename T::Scalar > rotationMatrixToRPY(const Eigen::MatrixBase< T > &R)
Mat3< typename T::Scalar > quaternionToRotationMatrix(const Eigen::MatrixBase< T > &q)
Quat< typename T::Scalar > quatDerivative(const Eigen::MatrixBase< T > &q, const Eigen::MatrixBase< T2 > &omega)
typename Eigen::Matrix< T, 3, 3 > RotMat
Definition: cppTypes.h:18