SpatialAlgebraOperators.h
Go to the documentation of this file.
1 /*
2  * Original Copyright (c) 2011-2016 Martin Felis <martin.felis@iwr.uni-heidelberg.de>
3  *
4  *
5  * RDL - Robot Dynamics Library
6  * Modifications Copyright (c) 2017 Jordan Lack <jlack1987@gmail.com>
7  *
8  * Licensed under the zlib license. See LICENSE for more details.
9  */
10 
15 #ifndef __RDL_SPATIALALGEBRAOPERATORS_H__
16 #define __RDL_SPATIALALGEBRAOPERATORS_H__
17 
18 #include <iostream>
19 #include <cmath>
22 
23 namespace RobotDynamics
24 {
25 namespace Math
26 {
34 static inline Vector3d toIntrinsicZYXAngles(const Quaternion& q, double yaw_at_pitch_singularity = 0.)
35 {
38  double sqw = q.w() * q.w();
39  double sqx = q.x() * q.x();
40  double sqy = q.y() * q.y();
41  double sqz = q.z() * q.z();
42  double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
43  double test = q.w() * q.y() - q.z() * q.x();
44  if (test > 0.499 * unit)
45  { // singularity at north pole
46  return Vector3d(yaw_at_pitch_singularity, M_PI_2, 2. * atan2(q.x(), q.y()) + yaw_at_pitch_singularity);
47  }
48  if (test < -0.499 * unit)
49  { // singularity at south pole
50  return Vector3d(yaw_at_pitch_singularity, -M_PI_2, 2. * atan2(q.x(), q.w()) - yaw_at_pitch_singularity);
51  }
52 
53  return Vector3d(atan2(2. * (q.w() * q.z() + q.x() * q.y()), 1. - 2. * (sqy + sqz)), asin(2. * test / unit),
54  atan2(2. * (q.w() * q.x() + q.y() * q.z()), 1. - 2. * (sqx + sqy)));
55 }
56 
63 static inline Quaternion toQuaternion(const Vector3d& axis, double angle_rad)
64 {
65  double d = axis.norm();
66  double s2 = std::sin(angle_rad * 0.5) / d;
67 
68  return Quaternion(axis[0] * s2, axis[1] * s2, axis[2] * s2, std::cos(angle_rad * 0.5));
69 }
70 
74 static inline Quaternion toQuaternion(const AxisAngle& axisAngle)
75 {
76  return toQuaternion(axisAngle.axis(), axisAngle.angle());
77 }
78 
82 static inline Quaternion intrinsicZYXAnglesToQuaternion(double yaw, double pitch, double roll)
83 {
84  return toQuaternion(Vector3d(0., 0., 1.), yaw) * toQuaternion(Vector3d(0., 1., 0.), pitch) * toQuaternion(Vector3d(1., 0., 0.), roll);
85 }
86 
90 static inline Quaternion intrinsicZYXAnglesToQuaternion(const Vector3d& zyx_angles)
91 {
92  return intrinsicZYXAnglesToQuaternion(zyx_angles[0], zyx_angles[1], zyx_angles[2]);
93 }
94 
98 static inline Quaternion intrinsicYXZAnglesToQuaternion(double pitch, double roll, double yaw)
99 {
100  return toQuaternion(Vector3d(0., 1., 0.), pitch) * toQuaternion(Vector3d(1., 0., 0.), roll) * toQuaternion(Vector3d(0., 0., 1.), yaw);
101 }
102 
106 static inline Quaternion intrinsicYXZAnglesToQuaternion(const Vector3d& yxz_angles)
107 {
108  return intrinsicYXZAnglesToQuaternion(yxz_angles[0], yxz_angles[1], yxz_angles[2]);
109 }
110 
114 static inline Quaternion intrinsicXYZAnglesToQuaternion(double roll, double pitch, double yaw)
115 {
116  return toQuaternion(Vector3d(1., 0., 0.), roll) * toQuaternion(Vector3d(0., 1., 0.), pitch) * toQuaternion(Vector3d(0., 0., 1.), yaw);
117 }
118 
122 static inline Quaternion intrinsicXYZAnglesToQuaternion(const Vector3d& xyz_angles)
123 {
124  return intrinsicXYZAnglesToQuaternion(xyz_angles[0], xyz_angles[1], xyz_angles[2]);
125 }
126 
133 {
134  double n = q.vec().norm();
135  if (n < std::numeric_limits<double>::epsilon())
136  {
137  n = q.vec().stableNorm();
138  }
139 
140  AxisAngle axisAngle;
141  if (n > 0.0)
142  {
143  axisAngle.angle() = 2.0 * atan2(n, q.w());
144  axisAngle.axis() = q.vec() / n;
145  }
146  else
147  {
148  axisAngle.angle() = 0.0;
149  axisAngle.axis() << 1.0, 0.0, 0.0;
150  }
151 
152  return axisAngle;
153 }
154 
158 static inline Quaternion toQuaternion(const Matrix3d& mat)
159 {
160  double trace = mat.trace();
161 
162  if (trace > 0.)
163  {
164  double s = 2. * std::sqrt(trace + 1.);
165  return Quaternion((mat(1, 2) - mat(2, 1)) / s, (mat(2, 0) - mat(0, 2)) / s, (mat(0, 1) - mat(1, 0)) / s, 0.25 * s);
166  }
167  else if ((mat(0, 0) > mat(1, 1)) && (mat(0, 0) > mat(2, 2)))
168  {
169  double s = 2. * std::sqrt(1. + mat(0, 0) - mat(1, 1) - mat(2, 2));
170  return Quaternion(-0.25 * s, (-mat(0, 1) - mat(1, 0)) / s, (-mat(0, 2) - mat(2, 0)) / s, (mat(2, 1) - mat(1, 2)) / s);
171  }
172  else if (mat(1, 1) > mat(2, 2))
173  {
174  double s = 2. * std::sqrt(1. + mat(1, 1) - mat(0, 0) - mat(2, 2));
175  return Quaternion((-mat(0, 1) - mat(1, 0)) / s, -0.25 * s, (-mat(1, 2) - mat(2, 1)) / s, (mat(0, 2) - mat(2, 0)) / s);
176  }
177  else
178  {
179  double s = 2. * std::sqrt(1. + mat(2, 2) - mat(0, 0) - mat(1, 1));
180  return Quaternion((-mat(0, 2) - mat(2, 0)) / s, (-mat(1, 2) - mat(2, 1)) / s, -0.25 * s, (mat(1, 0) - mat(0, 1)) / s);
181  }
182 }
183 
187 static inline Matrix3d toMatrix(const Quaternion& q)
188 {
189  double x = q.x();
190  double y = q.y();
191  double z = q.z();
192  double w = q.w();
193 
194  return Matrix3d(1. - 2. * (y * y + z * z), 2. * x * y + 2. * w * z, 2. * x * z - 2. * w * y, 2. * x * y - 2. * w * z, 1. - 2. * (x * x + z * z),
195  2. * y * z + 2. * w * x, 2. * x * z + 2. * w * y, 2. * y * z - 2. * w * x, 1. - 2. * (x * x + y * y));
196 }
197 
205 static inline Vector3d toIntrinsicZYXAngles(const Matrix3d& m, double yaw_at_pitch_singularity = 0.)
206 {
207  // // Assuming the angles are in radians.
208  if (m(0, 2) < -0.999)
209  { // singularity at north pole
210  return Vector3d(yaw_at_pitch_singularity, M_PI_2, yaw_at_pitch_singularity + atan2(m(1, 0), m(1, 1)));
211  }
212  if (m(0, 2) > 0.999)
213  { // singularity at south pole
214  return Vector3d(yaw_at_pitch_singularity, -M_PI_2, -yaw_at_pitch_singularity + atan2(-m(1, 0), m(1, 1)));
215  }
216 
217  return Vector3d(atan2(m(0, 1), m(0, 0)), asin(-m(0, 2)), atan2(m(1, 2), m(2, 2)));
218 }
219 
227 static inline Matrix3d toTildeForm(const Vector3d& vector)
228 {
229  return Matrix3d(0., -vector[2], vector[1], vector[2], 0., -vector[0], -vector[1], vector[0], 0.);
230 }
231 
232 static inline Matrix3d toTildeForm(const double x, const double y, const double z)
233 {
234  return Matrix3d(0., -z, y, z, 0., -x, -y, z, 0.);
235 }
236 
237 inline std::ostream& operator<<(std::ostream& output, const SpatialTransform& X)
238 {
239  output << "X.E = " << std::endl << X.E << std::endl;
240  output << "X.r = " << X.r.transpose();
241  return output;
242 }
243 
250 inline SpatialTransform Xrot(double angle_rad, const Vector3d& axis)
251 {
252  double s, c;
253 
254  s = sin(angle_rad);
255  c = cos(angle_rad);
256 
257  return SpatialTransform(Matrix3d(axis[0] * axis[0] * (1.0f - c) + c, axis[1] * axis[0] * (1.0f - c) + axis[2] * s, axis[0] * axis[2] * (1.0f - c) - axis[1] * s,
258 
259  axis[0] * axis[1] * (1.0f - c) - axis[2] * s, axis[1] * axis[1] * (1.0f - c) + c, axis[1] * axis[2] * (1.0f - c) + axis[0] * s,
260 
261  axis[0] * axis[2] * (1.0f - c) + axis[1] * s, axis[1] * axis[2] * (1.0f - c) - axis[0] * s, axis[2] * axis[2] * (1.0f - c) + c
262 
263  ),
264  Vector3d(0., 0., 0.));
265 }
266 
272 inline SpatialTransform Xrotx(const double& xrot)
273 {
274  double s, c;
275 
276  s = sin(xrot);
277  c = cos(xrot);
278  return SpatialTransform(Matrix3d(1., 0., 0., 0., c, s, 0., -s, c), Vector3d(0., 0., 0.));
279 }
280 
286 inline SpatialTransform Xroty(const double& yrot)
287 {
288  double s, c;
289 
290  s = sin(yrot);
291  c = cos(yrot);
292  return SpatialTransform(Matrix3d(c, 0., -s, 0., 1., 0., s, 0., c), Vector3d(0., 0., 0.));
293 }
294 
300 inline SpatialTransform Xrotz(const double& zrot)
301 {
302  double s, c;
303 
304  s = sin(zrot);
305  c = cos(zrot);
306  return SpatialTransform(Matrix3d(c, s, 0., -s, c, 0., 0., 0., 1.), Vector3d(0., 0., 0.));
307 }
308 
316 inline SpatialTransform XeulerZYX(double yaw, double pitch, double roll)
317 {
318  return Xrotx(roll) * Xroty(pitch) * Xrotz(yaw);
319 }
320 
328 {
329  return XeulerZYX(ypr[0], ypr[1], ypr[2]);
330 }
331 
339 inline SpatialTransform XeulerXYZ(double roll, double pitch, double yaw)
340 {
341  return Xrotz(yaw) * Xroty(pitch) * Xrotx(roll);
342 }
343 
349 inline SpatialTransform XeulerXYZ(const Vector3d& xyz_angles)
350 {
351  return XeulerXYZ(xyz_angles[0], xyz_angles[1], xyz_angles[2]);
352 }
353 
354 inline SpatialTransform XrotQuat(double x, double y, double z, double w)
355 {
356  return SpatialTransform(toMatrix(Quaternion(x, y, z, w)));
357 }
358 
359 inline SpatialTransform XrotQuat(const Quaternion& orientation)
360 {
361  return SpatialTransform(toMatrix(orientation));
362 }
363 
370 {
371  return SpatialTransform(Matrix3d::Identity(3, 3), r);
372 }
373 
380 {
381  return SpatialMatrix(0, -v[2], v[1], 0, 0, 0, v[2], 0, -v[0], 0, 0, 0, -v[1], v[0], 0, 0, 0, 0, 0, -v[5], v[4], 0, -v[2], v[1], v[5], 0, -v[3], v[2], 0, -v[0], -v[4],
382  v[3], 0, -v[1], v[0], 0);
383 }
384 
391 inline SpatialVector crossm(const SpatialVector& v1, const SpatialVector& v2)
392 {
393  return SpatialVector(-v1[2] * v2[1] + v1[1] * v2[2], v1[2] * v2[0] - v1[0] * v2[2], -v1[1] * v2[0] + v1[0] * v2[1],
394  -v1[5] * v2[1] + v1[4] * v2[2] - v1[2] * v2[4] + v1[1] * v2[5], v1[5] * v2[0] - v1[3] * v2[2] + v1[2] * v2[3] - v1[0] * v2[5],
395  -v1[4] * v2[0] + v1[3] * v2[1] - v1[1] * v2[3] + v1[0] * v2[4]);
396 }
397 
404 {
405  return SpatialMatrix(0, -v[2], v[1], 0, -v[5], v[4], v[2], 0, -v[0], v[5], 0, -v[3], -v[1], v[0], 0, -v[4], v[3], 0, 0, 0, 0, 0, -v[2], v[1], 0, 0, 0, v[2], 0, -v[0],
406  0, 0, 0, -v[1], v[0], 0);
407 }
408 
415 inline SpatialVector crossf(const SpatialVector& v1, const SpatialVector& v2)
416 {
417  return SpatialVector(-v1[2] * v2[1] + v1[1] * v2[2] - v1[5] * v2[4] + v1[4] * v2[5], v1[2] * v2[0] - v1[0] * v2[2] + v1[5] * v2[3] - v1[3] * v2[5],
418  -v1[1] * v2[0] + v1[0] * v2[1] - v1[4] * v2[3] + v1[3] * v2[4], -v1[2] * v2[4] + v1[1] * v2[5], +v1[2] * v2[3] - v1[0] * v2[5],
419  -v1[1] * v2[3] + v1[0] * v2[4]);
420 }
421 
429 {
430  double v_rxw_x = v[3] - X.r[1] * v[2] + X.r[2] * v[1];
431  double v_rxw_y = v[4] - X.r[2] * v[0] + X.r[0] * v[2];
432  double v_rxw_z = v[5] - X.r[0] * v[1] + X.r[1] * v[0];
433 
434  return Vector3d(X.E(0, 0) * v_rxw_x + X.E(0, 1) * v_rxw_y + X.E(0, 2) * v_rxw_z, X.E(1, 0) * v_rxw_x + X.E(1, 1) * v_rxw_y + X.E(1, 2) * v_rxw_z,
435  X.E(2, 0) * v_rxw_x + X.E(2, 1) * v_rxw_y + X.E(2, 2) * v_rxw_z);
436 }
437 } // namespace Math
438 } // namespace RobotDynamics
439 
441 
442 /* __RDL_SPATIALALGEBRAOPERATORS_H__*/
443 #endif // ifndef __RDL_SPATIALALGEBRAOPERATORS_H__
static Vector3d toIntrinsicZYXAngles(const Quaternion &q, double yaw_at_pitch_singularity=0.)
Converte quaternion to intrinsic ZYX euler angles.
EIGEN_STRONG_INLINE double & w()
Definition: Quaternion.h:106
SpatialTransform XrotQuat(double x, double y, double z, double w)
EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(RobotDynamics::Joint)
static Quaternion intrinsicXYZAnglesToQuaternion(double roll, double pitch, double yaw)
Convert RPY angles to quaternion.
SpatialTransform Xroty(const double &yrot)
Get transform with zero translation and pure rotation about y axis.
SpatialMatrix crossf(const SpatialVector &v)
Get the spatial force cross matrix.
SpatialTransform Xtrans(const Vector3d &r)
Get pure translation transform.
EIGEN_STRONG_INLINE Vector3d vec() const
Get vector part.
Definition: Quaternion.h:128
static Quaternion toQuaternion(const Vector3d &axis, double angle_rad)
Get quaternion representation of axis and angle.
static Matrix3d toTildeForm(const Point3d &p)
Definition: Point3.hpp:370
static Quaternion intrinsicYXZAnglesToQuaternion(double pitch, double roll, double yaw)
Convert PRY angles to quaternion.
Vector3d getLinearPartTransformed(const SpatialVector &v, const SpatialTransform &X)
Get the rotated linear portion of the spatial vector.
SpatialTransform Xrotz(const double &zrot)
Get transform with zero translation and pure rotation about z axis.
Compact representation of spatial transformations.
EIGEN_STRONG_INLINE double & y()
Definition: Quaternion.h:86
Quaternion that are used for singularity free joints.
Definition: Quaternion.h:25
std::ostream & operator<<(std::ostream &output, const FramePoint &framePoint)
Definition: FramePoint.hpp:375
SpatialTransform Xrotx(const double &xrot)
Get transform with zero translation and pure rotation about x axis.
EIGEN_STRONG_INLINE double & x()
Definition: Quaternion.h:76
SpatialTransform XeulerZYX(double yaw, double pitch, double roll)
Get transform with zero translation and intrinsic euler z/y/x rotation.
SpatialTransform XeulerXYZ(double roll, double pitch, double yaw)
Get transform with zero translation and intrinsic euler x/y/z rotation.
EIGEN_STRONG_INLINE double & z()
Definition: Quaternion.h:96
SpatialMatrix crossm(const SpatialVector &v)
Get the spatial motion cross matrix.
Eigen::AngleAxisd AxisAngle
Definition: rdl_eigenmath.h:27
static Quaternion intrinsicZYXAnglesToQuaternion(double yaw, double pitch, double roll)
Convert YPR angles to quaternion.
static Matrix3d toMatrix(const Quaternion &q)
Convert quaternion to rotation matrix.
Namespace for all structures of the RobotDynamics library.
Definition: Body.h:21
SpatialTransform Xrot(double angle_rad, const Vector3d &axis)
Get spatial transform from angle and axis.
static AxisAngle toAxisAngle(Quaternion q)
Get axis angle representation of a quaternion.


rdl_dynamics
Author(s):
autogenerated on Tue Apr 20 2021 02:25:28