Cheetah Software  1.0
spatial.h
Go to the documentation of this file.
1 
8 #ifndef LIBBIOMIMETICS_SPATIAL_H
9 #define LIBBIOMIMETICS_SPATIAL_H
10 
11 #include "Math/orientation_tools.h"
12 
13 #include <eigen3/Eigen/Dense>
14 
15 #include <cmath>
16 #include <iostream>
17 #include <type_traits>
18 
19 namespace spatial {
20 using namespace ori;
22 
27 template <typename T>
29  static_assert(std::is_floating_point<T>::value,
30  "must use floating point value");
31  RotMat<T> R = coordinateRotation(axis, theta);
33  X.template topLeftCorner<3, 3>() = R;
34  X.template bottomRightCorner<3, 3>() = R;
35  return X;
36 }
37 
42 template <typename T>
43 auto motionCrossMatrix(const Eigen::MatrixBase<T>& v) {
44  static_assert(T::ColsAtCompileTime == 1 && T::RowsAtCompileTime == 6,
45  "Must have 6x1 vector");
47  m << 0, -v(2), v(1), 0, 0, 0, v(2), 0, -v(0), 0, 0, 0, -v(1), v(0), 0, 0, 0,
48  0,
49 
50  0, -v(5), v(4), 0, -v(2), v(1), v(5), 0, -v(3), v(2), 0, -v(0), -v(4),
51  v(3), 0, -v(1), v(0), 0;
52  return m;
53 }
54 
59 template <typename T>
60 auto forceCrossMatrix(const Eigen::MatrixBase<T>& v) {
62  f << 0, -v(2), v(1), 0, -v(5), v(4), v(2), 0, -v(0), v(5), 0, -v(3), -v(1),
63  v(0), 0, -v(4), v(3), 0, 0, 0, 0, 0, -v(2), v(1), 0, 0, 0, v(2), 0, -v(0),
64  0, 0, 0, -v(1), v(0), 0;
65  return f;
66 }
67 
72 template <typename T>
73 auto motionCrossProduct(const Eigen::MatrixBase<T>& a,
74  const Eigen::MatrixBase<T>& b) {
75  static_assert(T::ColsAtCompileTime == 1 && T::RowsAtCompileTime == 6,
76  "Must have 6x1 vector");
78  mv << a(1) * b(2) - a(2) * b(1), a(2) * b(0) - a(0) * b(2),
79  a(0) * b(1) - a(1) * b(0),
80  a(1) * b(5) - a(2) * b(4) + a(4) * b(2) - a(5) * b(1),
81  a(2) * b(3) - a(0) * b(5) - a(3) * b(2) + a(5) * b(0),
82  a(0) * b(4) - a(1) * b(3) + a(3) * b(1) - a(4) * b(0);
83  return mv;
84 }
85 
90 template <typename T>
91 auto forceCrossProduct(const Eigen::MatrixBase<T>& a,
92  const Eigen::MatrixBase<T>& b) {
93  static_assert(T::ColsAtCompileTime == 1 && T::RowsAtCompileTime == 6,
94  "Must have 6x1 vector");
96  mv << b(2) * a(1) - b(1) * a(2) - b(4) * a(5) + b(5) * a(4),
97  b(0) * a(2) - b(2) * a(0) + b(3) * a(5) - b(5) * a(3),
98  b(1) * a(0) - b(0) * a(1) - b(3) * a(4) + b(4) * a(3),
99  b(5) * a(1) - b(4) * a(2), b(3) * a(2) - b(5) * a(0),
100  b(4) * a(0) - b(3) * a(1);
101  return mv;
102 }
103 
107 template <typename T>
108 auto sxformToHomogeneous(const Eigen::MatrixBase<T>& X) {
109  static_assert(T::ColsAtCompileTime == 6 && T::RowsAtCompileTime == 6,
110  "Must have 6x6 matrix");
112  RotMat<typename T::Scalar> R = X.template topLeftCorner<3, 3>();
113  Mat3<typename T::Scalar> skewR = X.template bottomLeftCorner<3, 3>();
114  H.template topLeftCorner<3, 3>() = R;
115  H.template topRightCorner<3, 1>() = matToSkewVec(skewR * R.transpose());
116  H(3, 3) = 1;
117  return H;
118 }
119 
123 template <typename T>
124 auto homogeneousToSXform(const Eigen::MatrixBase<T>& H) {
125  static_assert(T::ColsAtCompileTime == 4 && T::RowsAtCompileTime == 4,
126  "Must have 4x4 matrix");
127  Mat3<typename T::Scalar> R = H.template topLeftCorner<3, 3>();
128  Vec3<typename T::Scalar> translate = H.template topRightCorner<3, 1>();
130  X.template topLeftCorner<3, 3>() = R;
131  X.template bottomLeftCorner<3, 3>() = vectorToSkewMat(translate) * R;
132  X.template bottomRightCorner<3, 3>() = R;
133  return X;
134 }
135 
139 template <typename T, typename T2>
140 auto createSXform(const Eigen::MatrixBase<T>& R,
141  const Eigen::MatrixBase<T2>& r) {
142  static_assert(T::ColsAtCompileTime == 3 && T::RowsAtCompileTime == 3,
143  "Must have 3x3 matrix");
144  static_assert(T2::ColsAtCompileTime == 1 && T2::RowsAtCompileTime == 3,
145  "Must have 3x1 matrix");
147  X.template topLeftCorner<3, 3>() = R;
148  X.template bottomRightCorner<3, 3>() = R;
149  X.template bottomLeftCorner<3, 3>() = -R * vectorToSkewMat(r);
150  return X;
151 }
152 
156 template <typename T>
157 auto rotationFromSXform(const Eigen::MatrixBase<T>& X) {
158  static_assert(T::ColsAtCompileTime == 6 && T::RowsAtCompileTime == 6,
159  "Must have 6x6 matrix");
160  RotMat<typename T::Scalar> R = X.template topLeftCorner<3, 3>();
161  return R;
162 }
163 
167 template <typename T>
168 auto translationFromSXform(const Eigen::MatrixBase<T>& X) {
169  static_assert(T::ColsAtCompileTime == 6 && T::RowsAtCompileTime == 6,
170  "Must have 6x6 matrix");
173  -matToSkewVec(R.transpose() * X.template bottomLeftCorner<3, 3>());
174  return r;
175 }
176 
180 template <typename T>
181 auto invertSXform(const Eigen::MatrixBase<T>& X) {
182  static_assert(T::ColsAtCompileTime == 6 && T::RowsAtCompileTime == 6,
183  "Must have 6x6 matrix");
186  -matToSkewVec(R.transpose() * X.template bottomLeftCorner<3, 3>());
187  SXform<typename T::Scalar> Xinv = createSXform(R.transpose(), -R * r);
188  return Xinv;
189 }
190 
194 template <typename T>
196  Vec3<T> v(0, 0, 0);
197  SVec<T> phi = SVec<T>::Zero();
198  if (axis == CoordinateAxis::X)
199  v(0) = 1;
200  else if (axis == CoordinateAxis::Y)
201  v(1) = 1;
202  else
203  v(2) = 1;
204 
205  if (joint == JointType::Prismatic)
206  phi.template bottomLeftCorner<3, 1>() = v;
207  else if (joint == JointType::Revolute)
208  phi.template topLeftCorner<3, 1>() = v;
209  else
210  throw std::runtime_error("Unknown motion subspace");
211 
212  return phi;
213 }
214 
218 template <typename T>
220  Mat6<T> X = Mat6<T>::Zero();
221  if (joint == JointType::Revolute) {
222  X = spatialRotation(axis, q);
223  } else if (joint == JointType::Prismatic) {
224  Vec3<T> v(0, 0, 0);
225  if (axis == CoordinateAxis::X)
226  v(0) = q;
227  else if (axis == CoordinateAxis::Y)
228  v(1) = q;
229  else if (axis == CoordinateAxis::Z)
230  v(2) = q;
231 
233  } else {
234  throw std::runtime_error("Unknown joint xform\n");
235  }
236  return X;
237 }
238 
244 template <typename T>
246  const Eigen::MatrixBase<T>& dims) {
247  static_assert(T::ColsAtCompileTime == 1 && T::RowsAtCompileTime == 3,
248  "Must have 3x1 vector");
250  Mat3<typename T::Scalar>::Identity() * dims.norm() * dims.norm();
251  for (int i = 0; i < 3; i++) I(i, i) -= dims(i) * dims(i);
252  I = I * mass / 12;
253  return I;
254 }
255 
260 template <typename T, typename T2>
261 auto spatialToLinearVelocity(const Eigen::MatrixBase<T>& v,
262  const Eigen::MatrixBase<T2>& x) {
263  static_assert(T::ColsAtCompileTime == 1 && T::RowsAtCompileTime == 6,
264  "Must have 6x1 vector");
265  static_assert(T2::ColsAtCompileTime == 1 && T2::RowsAtCompileTime == 3,
266  "Must have 3x1 vector");
267  Vec3<typename T::Scalar> vsAng = v.template topLeftCorner<3, 1>();
268  Vec3<typename T::Scalar> vsLin = v.template bottomLeftCorner<3, 1>();
269  Vec3<typename T::Scalar> vLinear = vsLin + vsAng.cross(x);
270  return vLinear;
271 }
272 
276 template <typename T>
277 auto spatialToAngularVelocity(const Eigen::MatrixBase<T>& v) {
278  static_assert(T::ColsAtCompileTime == 1 && T::RowsAtCompileTime == 6,
279  "Must have 6x1 vector");
280  Vec3<typename T::Scalar> vsAng = v.template topLeftCorner<3, 1>();
281  return vsAng;
282 }
283 
288 template <typename T, typename T2>
289 auto spatialToLinearAcceleration(const Eigen::MatrixBase<T>& a,
290  const Eigen::MatrixBase<T2>& v) {
291  static_assert(T::ColsAtCompileTime == 1 && T::RowsAtCompileTime == 6,
292  "Must have 6x1 vector");
293  static_assert(T2::ColsAtCompileTime == 1 && T2::RowsAtCompileTime == 6,
294  "Must have 6x1 vector");
295 
297  // classical accleration = spatial linear acc + omega x v
298  acc = a.template tail<3>() + v.template head<3>().cross(v.template tail<3>());
299  return acc;
300 }
301 
306 template <typename T, typename T2, typename T3>
307 auto spatialToLinearAcceleration(const Eigen::MatrixBase<T>& a,
308  const Eigen::MatrixBase<T2>& v,
309  const Eigen::MatrixBase<T3>& x) {
310  static_assert(T::ColsAtCompileTime == 1 && T::RowsAtCompileTime == 6,
311  "Must have 6x1 vector");
312  static_assert(T2::ColsAtCompileTime == 1 && T2::RowsAtCompileTime == 6,
313  "Must have 6x1 vector");
314  static_assert(T3::ColsAtCompileTime == 1 && T3::RowsAtCompileTime == 3,
315  "Must have 3x1 vector");
316 
319 
320  // classical accleration = spatial linear acc + omega x v
321  Vec3<typename T::Scalar> acc = alin_x + v.template head<3>().cross(vlin_x);
322  return acc;
323 }
324 
328 template <typename T, typename T2>
329 auto sXFormPoint(const Eigen::MatrixBase<T>& X,
330  const Eigen::MatrixBase<T2>& p) {
331  static_assert(T::ColsAtCompileTime == 6 && T::RowsAtCompileTime == 6,
332  "Must have 6x6 vector");
333  static_assert(T2::ColsAtCompileTime == 1 && T2::RowsAtCompileTime == 3,
334  "Must have 3x1 vector");
335 
338  Vec3<typename T::Scalar> Xp = R * (p - r);
339  return Xp;
340 }
341 
347 template <typename T, typename T2>
348 auto forceToSpatialForce(const Eigen::MatrixBase<T>& f,
349  const Eigen::MatrixBase<T2>& p) {
350  static_assert(T::ColsAtCompileTime == 1 && T::RowsAtCompileTime == 3,
351  "Must have 3x1 vector");
352  static_assert(T2::ColsAtCompileTime == 1 && T2::RowsAtCompileTime == 3,
353  "Must have 3x1 vector");
355  fs.template topLeftCorner<3, 1>() = p.cross(f);
356  fs.template bottomLeftCorner<3, 1>() = f;
357  return fs;
358 }
359 
360 } // namespace spatial
361 
362 #endif // LIBBIOMIMETICS_SPATIAL_H
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
typename Eigen::Matrix< T, 4, 4 > Mat4
Definition: cppTypes.h:94
typename Eigen::Matrix< T, 3, 1 > Vec3
Definition: cppTypes.h:26
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
auto createSXform(const Eigen::MatrixBase< T > &R, const Eigen::MatrixBase< T2 > &r)
Definition: spatial.h:140
auto sxformToHomogeneous(const Eigen::MatrixBase< T > &X)
Definition: spatial.h:108
auto motionCrossProduct(const Eigen::MatrixBase< T > &a, const Eigen::MatrixBase< T > &b)
Definition: spatial.h:73
JointType
Definition: spatial.h:21
auto homogeneousToSXform(const Eigen::MatrixBase< T > &H)
Definition: spatial.h:124
Mat3< typename T::Scalar > vectorToSkewMat(const Eigen::MatrixBase< T > &v)
Utility functions for 3D rotations.
Vec3< typename T::Scalar > matToSkewVec(const Eigen::MatrixBase< T > &m)
SVec< T > jointMotionSubspace(JointType joint, CoordinateAxis axis)
Definition: spatial.h:195
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
auto spatialToAngularVelocity(const Eigen::MatrixBase< T > &v)
Definition: spatial.h:277
MX f(const MX &x, const MX &u)
auto invertSXform(const Eigen::MatrixBase< T > &X)
Definition: spatial.h:181