Cheetah Software  1.0
test_spatial.cpp
Go to the documentation of this file.
1 
9 #include "Dynamics/spatial.h"
10 #include "Math/orientation_tools.h"
11 #include "gmock/gmock.h"
12 #include "gtest/gtest.h"
13 
14 using namespace ori;
15 using namespace spatial;
16 
21 TEST(Spatial, axisRotation) {
22  // test X which rotates around an axis
23  SXform<double> X1, X2;
24  X1 << 0.8384, 0.4580, -0.2955, 0, 0, 0, -0.4183, 0.8882, 0.1898, 0, 0, 0,
25  0.3494, -0.0355, 0.9363, 0, 0, 0, 0, 0, 0, 0.8384, 0.4580, -0.2955, 0, 0,
26  0, -0.4183, 0.8882, 0.1898, 0, 0, 0, 0.3494, -0.0355, 0.9363;
30 
31  EXPECT_TRUE(almostEqual(X1, X2, .001));
32 }
33 
37 TEST(Spatial, crm) {
38  // test motion cross product matrix
39  SVec<double> v1, v2, v3, v4, v5, v6;
40  v1 << 1, 2, 3, 4, 5, 6;
41  v2 << 6, 5, 4, 3, 2, 1;
42  v3 = motionCrossMatrix(v1) * v2;
43  v4 << -7, 14, -7, -14, 28, -14;
44  v6 = motionCrossMatrix(v1) * v1;
45  v5 << 0, 0, 0, 0, 0, 0;
46  EXPECT_TRUE(almostEqual(v3, v4, .001));
47  EXPECT_TRUE(almostEqual(v6, v5, .0001));
48 }
49 
54 TEST(Spatial, crf) {
55  // test force cross product matrix
56  SVec<double> v1, v2;
57  v1 << 1, 2, 3, 4, 5, 6;
58  v2 << 6, 5, 4, 3, 2, 1;
60  m1.transposeInPlace();
62  EXPECT_TRUE(almostEqual(m1, m2, .0001));
63 }
64 
69 TEST(Spatial, crm_prod) {
70  // test motion cross product
71  SVec<double> v1, v2, v3, v4;
72  v1 << 1, 2, 3, 4, 5, 6;
73  v2 << 6, 5, 4, 3, 2, 1;
74  v3 = motionCrossMatrix(v1) * v2;
75  v4 = motionCrossProduct(v1, v2);
76  EXPECT_TRUE(almostEqual(v3, v4, .0001));
77 }
78 
83 TEST(Spatial, crf_prod) {
84  // test force cross product
85  SVec<double> v1, v2, v3, v4;
86  v1 << 1, 2, 3, 4, 5, 6;
87  v2 << 6, 5, 4, 3, 2, 1;
88  v3 = forceCrossMatrix(v1) * v2;
89  v4 = forceCrossProduct(v1, v2);
90  EXPECT_TRUE(almostEqual(v3, v4, .0001));
91 }
92 
98 TEST(Spatial, inertia) {
99  // test spatial inertia, mcI, and Pat's PseudoInertia
100  Mat3<double> I;
101  I << 1, 2, 3, 2, 4, 5, 3, 5, 6;
102  Vec3<double> com(10, 11, 12);
103  SpatialInertia<double> IS(42, com, I);
104  Mat6<double> ref;
105  Mat4<double> pref;
106  pref << 4204.5, 4618, 5037, 420, 4618, 5083.5, 5539, 462, 5037, 5539, 6047.5,
107  504, 420, 462, 504, 42;
108 
109  ref << 11131, -4618, -5037, 0, -504, 462, -4618, 10252, -5539, 504, 0, -420,
110  -5037, -5539, 9288, -462, 420, 0, 0, 504, -462, 42, 0, 0, -504, 0, 420, 0,
111  42, 0, 462, -420, 0, 0, 0, 42;
112 
114 
115  EXPECT_TRUE(almostEqual(ref, IS.getMatrix(), .001));
116  EXPECT_EQ(42, IS.getMass());
117  EXPECT_TRUE(almostEqual(I, IS.getInertiaTensor(), .00001));
118  EXPECT_TRUE(almostEqual(com, IS.getCOM(), .00001));
119  EXPECT_TRUE(almostEqual(IS.getPseudoInertia(), pref, .1));
120  EXPECT_TRUE(almostEqual(IS.getMatrix(), IS2.getMatrix(), .00001));
121 }
122 
126 TEST(Spatial, inertia_flips) {
127  // test flipping inertias around axes
128  MassProperties<double> a, aref;
129  a << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
130  aref << 1, 2, -3, 4, 5, 6, 7, -8, 9, -10;
131  EXPECT_TRUE(almostEqual(
132  SpatialInertia<double>(aref).getMatrix(),
133  SpatialInertia<double>(a).flipAlongAxis(CoordinateAxis::Y).getMatrix(),
134  .0001));
135 }
136 
141 TEST(Spatial, pluho_and_plux) {
142  // test homogeneous transformations and spatial transformations
146  Vec3<double> r(4, 5, 6);
147  Mat6<double> X = createSXform(R, r);
148  Mat6<double> Xref, X2;
150  Mat4<double> Href;
151  X2 = homogeneousToSXform(H);
152  Xref << 0.4120, -0.0587, -0.9093, 0, 0, 0, -0.8337, -0.4269, -0.3502, 0, 0, 0,
153  -0.3676, 0.9024, -0.2248, 0, 0, 0, -4.1941, 6.1091, -2.2948, 0.4120,
154  -0.0587, -0.9093, 0.8106, -3.6017, 2.4610, -0.8337, -0.4269, -0.3502,
155  -6.5385, -1.3064, 5.4477, -0.3676, 0.9024, -0.2248;
156  Href << 0.4120, -0.0587, -0.9093, 4.1015, -0.8337, -0.4269, -0.3502, 7.5706,
157  -0.3676, 0.9024, -0.2248, -1.6923, 0, 0, 0, 1.0000;
158  EXPECT_TRUE(almostEqual(Xref, X, .001));
159  EXPECT_TRUE(almostEqual(R, rotationFromSXform(X), .001));
160  EXPECT_TRUE(almostEqual(r, translationFromSXform(X), .001));
161  EXPECT_TRUE(almostEqual(H, Href, .001));
162  EXPECT_TRUE(almostEqual(X, X2, .00001));
163 }
164 
169 TEST(Spatial, invert_sxform) {
173  Vec3<double> r(4, 5, 6);
174  Mat6<double> X = createSXform(R, r);
175  Mat6<double> Xi_ref = X.inverse();
176  Mat6<double> Xi = invertSXform(X);
177  EXPECT_TRUE(almostEqual(Xi_ref, Xi, .00001));
178 }
179 
184 TEST(Spatial, jcalc) {
185  Mat6<double> Xr, Xp, Xr_ref, Xp_ref;
186  SVec<double> phi_r, phi_p, phi_r_ref, phi_p_ref;
187 
188  Xr = jointXform(JointType::Revolute, CoordinateAxis::Y, std::asin(.707));
189  Xp = jointXform(JointType::Prismatic, CoordinateAxis::Z, .2);
190  phi_r = jointMotionSubspace<double>(JointType::Revolute, CoordinateAxis::Y);
191  phi_p = jointMotionSubspace<double>(JointType::Prismatic, CoordinateAxis::Z);
192 
193  Xr_ref << 0.7072, 0, -0.7070, 0, 0, 0, 0, 1.0000, 0, 0, 0, 0, 0.7070, 0,
194  0.7072, 0, 0, 0, 0, 0, 0, 0.7072, 0, -0.7070, 0, 0, 0, 0, 1.0000, 0, 0, 0,
195  0, 0.7070, 0, 0.7072;
196 
197  phi_r_ref << 0, 1, 0, 0, 0, 0;
198 
199  Xp_ref << 1.0000, 0, 0, 0, 0, 0, 0, 1.0000, 0, 0, 0, 0, 0, 0, 1.0000, 0, 0, 0,
200  0, 0.2000, 0, 1.0000, 0, 0, -0.2000, 0, 0, 0, 1.0000, 0, 0, 0, 0, 0, 0,
201  1.0000;
202 
203  phi_p_ref << 0, 0, 0, 0, 0, 1;
204 
205  EXPECT_TRUE(almostEqual(Xr, Xr_ref, .001));
206  EXPECT_TRUE(almostEqual(Xp, Xp_ref, .001));
207  EXPECT_TRUE(almostEqual(phi_r, phi_r_ref, .000001));
208  EXPECT_TRUE(almostEqual(phi_p, phi_p_ref, .000001));
209 }
210 
215 TEST(Spatial, mass_properties) {
217  a << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
218  Mat6<double> I, I_ref;
219  I_ref << 5, 10, 9, 0, -4, 3, 10, 6, 8, 4, 0, -2, 9, 8, 7, -3, 2, 0, 0, 4, -3,
220  1, 0, 0, -4, 0, 2, 0, 1, 0, 3, -2, 0, 0, 0, 1;
222  EXPECT_TRUE(almostEqual(I_ref, IS.getMatrix(), .001));
223  EXPECT_TRUE(almostEqual(a, IS.asMassPropertyVector(), .001));
224 }
225 
229 TEST(Spatial, box_inertia) {
230  // test inertia of uniformly distributed box
231  Mat3<double> I_ref;
232  I_ref << 2.0833, 0, 0, 0, 1.66667, 0, 0, 0, 1.083333;
233  Mat3<double> I_calc = rotInertiaOfBox(1., Vec3<double>(2, 3, 4));
234  EXPECT_TRUE(almostEqual(I_ref, I_calc, .001));
235 }
236 
241 TEST(Spatial, velocityConver) {
242  Vec3<double> vRef(-2, 17, 0);
243  SVec<double> vs;
244  vs << 1, 2, 3, 4, 5, 6;
245  Vec3<double> p(7, 8, 9);
247  EXPECT_TRUE(almostEqual(v, vRef, .00001));
248 }
249 
253 TEST(Spatial, pointTransform) {
254  Vec3<double> p0(1, 2, 3);
255  Vec3<double> pxRef(-3.0026, -1.9791, -3.7507);
259 
260  Vec3<double> r(4, 5, 6);
261  Mat6<double> X = createSXform(R, r);
262 
263  Vec3<double> px = sXFormPoint(X, p0);
264  EXPECT_TRUE(almostEqual(px, pxRef, .0005));
265 }
266 
271  Vec3<double> fLinear(1, 2, 3);
272  Vec3<double> point(7, 8, 9);
273  SVec<double> fRef;
274  fRef << 6, -12, 6, 1, 2, 3;
275  SVec<double> fSpatial = forceToSpatialForce(fLinear, point);
276  EXPECT_TRUE(almostEqual(fSpatial, fRef, .0005));
277 }
278 
284  SVec<double> vspat;
285  vspat << 1.93, 2.34, 3.345, -4.23, 5.8383, 6.921;
286  Vec3<double> vlin = vspat.tail(3);
287  Vec3<double> vang = vspat.head(3);
288  Vec3<double> point;
289  point << -23.23, 2.638, 9.324;
290 
291  Vec3<double> vpoint = vlin + vang.cross(point);
292  Vec3<double> vpoint2 = spatialToLinearVelocity(vspat, point);
293 
294  EXPECT_TRUE(almostEqual(vpoint2, vpoint, 1e-8));
295 }
296 
302  SVec<double> vspat, aspat;
303  // Top spinning with angular velocity w on a skateboard that is traveling at
304  // velocity v and is currently at point p
305  double w = 5;
306  double v = 1;
307  double p = 1;
308 
309  vspat << 0, 0, w, v, -w * p, 0;
310  aspat << 0, 0, 0, 0, -w * v, 0;
311 
312  Vec3<double> p2;
313  p2 << p, 0, 0;
314 
315  Vec3<double> a1 = spatialToLinearAcceleration(aspat, vspat);
316 
317  Vec3<double> a2 = spatialToLinearAcceleration(aspat, vspat, p2);
318 
319  Vec3<double> a1_expected, a2_expected;
320  a1_expected << w * w * p, 0, 0;
321  a2_expected << 0, 0, 0;
322 
323  EXPECT_TRUE(almostEqual(a1, a1_expected, 1e-8));
324  EXPECT_TRUE(almostEqual(a2, a2_expected, 1e-8));
325 
326  vspat << 1.93, 2.34, 3.345, -4.23, 5.8383, 6.921;
327  aspat << -5.164, 68.4, 1.56879, -98.44, 8.14, 6.324;
328  p2 << 54.797, -6.1654, 3.64587;
329 
330  Vec3<double> w1, v1, wd1, vd1;
331  Vec3<double> w2, v2, wd2, vd2;
332 
333  w1 = vspat.head(3);
334  v1 = vspat.tail(3);
335  wd1 = aspat.head(3);
336  vd1 = aspat.tail(3);
337 
338  w2 = w1;
339  wd2 = w2;
340  v2 = v1 + w1.cross(p2);
341  vd2 = vd1 + wd1.cross(p2);
342 
343  a1_expected = vd1 + w1.cross(v1);
344  a2_expected = vd2 + w2.cross(v2);
345 
346  a1 = spatialToLinearAcceleration(aspat, vspat);
347  a2 = spatialToLinearAcceleration(aspat, vspat, p2);
348 
349  EXPECT_TRUE(almostEqual(a1, a1_expected, 1e-8));
350  EXPECT_TRUE(almostEqual(a2, a2_expected, 1e-8));
351 }
auto forceToSpatialForce(const Eigen::MatrixBase< T > &f, const Eigen::MatrixBase< T2 > &p)
Definition: spatial.h:348
auto spatialToLinearVelocity(const Eigen::MatrixBase< T > &v, const Eigen::MatrixBase< T2 > &x)
Definition: spatial.h:261
auto forceCrossProduct(const Eigen::MatrixBase< T > &a, const Eigen::MatrixBase< T > &b)
Definition: spatial.h:91
Mat3< T > coordinateRotation(CoordinateAxis axis, T theta)
typename Eigen::Matrix< T, 6, 6 > Mat6
Definition: cppTypes.h:70
Mat6< T > jointXform(JointType joint, CoordinateAxis axis, T q)
Definition: spatial.h:219
typename Eigen::Matrix< T, 3, 3 > Mat3
Definition: cppTypes.h:54
const Mat6< T > & getMatrix() const
typename Eigen::Matrix< T, 4, 4 > Mat4
Definition: cppTypes.h:94
typename Eigen::Matrix< T, 3, 1 > Vec3
Definition: cppTypes.h:26
Mat3< T > getInertiaTensor()
auto translationFromSXform(const Eigen::MatrixBase< T > &X)
Definition: spatial.h:168
auto spatialToLinearAcceleration(const Eigen::MatrixBase< T > &a, const Eigen::MatrixBase< T2 > &v)
Definition: spatial.h:289
typename Eigen::Matrix< T, 6, 6 > SXform
Definition: cppTypes.h:66
auto sXFormPoint(const Eigen::MatrixBase< T > &X, const Eigen::MatrixBase< T2 > &p)
Definition: spatial.h:329
typename Eigen::Matrix< T, 6, 1 > SVec
Definition: cppTypes.h:62
SXform< T > spatialRotation(CoordinateAxis axis, T theta)
Definition: spatial.h:28
auto motionCrossMatrix(const Eigen::MatrixBase< T > &v)
Definition: spatial.h:43
MassProperties< T > asMassPropertyVector()
auto createSXform(const Eigen::MatrixBase< T > &R, const Eigen::MatrixBase< T2 > &r)
Definition: spatial.h:140
Mat4< T > getPseudoInertia()
Class representing spatial inertia tensors.
Vec3< T > getCOM()
auto sxformToHomogeneous(const Eigen::MatrixBase< T > &X)
Definition: spatial.h:108
bool almostEqual(const Eigen::MatrixBase< T > &a, const Eigen::MatrixBase< T > &b, T2 tol)
Definition: MathUtilities.h:23
TEST(Spatial, axisRotation)
auto motionCrossProduct(const Eigen::MatrixBase< T > &a, const Eigen::MatrixBase< T > &b)
Definition: spatial.h:73
auto homogeneousToSXform(const Eigen::MatrixBase< T > &H)
Definition: spatial.h:124
Utility functions for 3D rotations.
typename Eigen::Matrix< T, 10, 1 > MassProperties
Definition: cppTypes.h:98
auto forceCrossMatrix(const Eigen::MatrixBase< T > &v)
Definition: spatial.h:60
Mat3< typename T::Scalar > rotInertiaOfBox(typename T::Scalar mass, const Eigen::MatrixBase< T > &dims)
Definition: spatial.h:245
typename Eigen::Matrix< T, 3, 3 > RotMat
Definition: cppTypes.h:18
auto rotationFromSXform(const Eigen::MatrixBase< T > &X)
Definition: spatial.h:157
Utility functions for manipulating spatial quantities.
auto invertSXform(const Eigen::MatrixBase< T > &X)
Definition: spatial.h:181