77 std::abs(
normSqr() - 1.0) < 1e-3,
79 "Initialization data for quaternion is not normalized: %f %f " 80 "%f %f -> sqrNorm=%f",
102 inline T
r()
const {
return (*
this)[0]; }
104 inline T
w()
const {
return (*
this)[0]; }
106 inline T
x()
const {
return (*
this)[1]; }
108 inline T
y()
const {
return (*
this)[2]; }
110 inline T
z()
const {
return (*
this)[3]; }
112 inline void r(
const T
r) { (*this)[0] =
r; }
114 inline void w(
const T
w) { (*this)[0] =
w; }
116 inline void x(
const T
x) { (*this)[1] =
x; }
118 inline void y(
const T
y) { (*this)[2] =
y; }
120 inline void z(
const T
z) { (*this)[3] =
z; }
122 inline T&
r() {
return (*
this)[0]; }
123 inline T&
x() {
return (*
this)[1]; }
124 inline T&
y() {
return (*
this)[2]; }
125 inline T&
z() {
return (*
this)[3]; }
141 template <
class ARRAYLIKE3>
146 const T
x = v[0],
y = v[1],
z = v[2];
147 const T theta_sq =
x *
x +
y *
y +
z *
z, theta = std::sqrt(theta_sq);
152 const T theta_po4 = theta_sq * theta_sq;
153 i = T(0.5) - T(1.0 / 48.0) * theta_sq + T(1.0 / 3840.0) * theta_po4;
154 r = T(1.0) - T(0.5) * theta_sq + T(1.0 / 384.0) * theta_po4;
158 i = (std::sin(theta / 2)) / theta;
159 r = std::cos(theta / 2);
168 "fromRodriguesVector() failed, tangent_vector=[%g %g %g]", v[0],
183 template <
class ARRAYLIKE3>
184 inline void ln(ARRAYLIKE3& out_ln)
const 186 if (out_ln.size() != 3) out_ln.resize(3);
190 template <
class ARRAYLIKE3>
191 inline ARRAYLIKE3
ln()
const 198 template <
class ARRAYLIKE3>
203 const T K = (xyz_norm < 1e-7) ? 2 : 2 * ::acos(
r()) / xyz_norm;
211 template <
class ARRAYLIKE3>
219 template <
class ARRAYLIKE3>
236 const T new_r = q1.
r() * q2.
r() - q1.
x() * q2.
x() - q1.
y() * q2.
y() -
238 const T new_x = q1.
r() * q2.
x() + q2.
r() * q1.
x() + q1.
y() * q2.
z() -
240 const T new_y = q1.
r() * q2.
y() + q2.
r() * q1.
y() + q1.
z() * q2.
x() -
242 const T new_z = q1.
r() * q2.
z() + q2.
r() * q1.
z() + q1.
x() * q2.
y() -
255 const double lx,
const double ly,
const double lz,
double& gx,
256 double& gy,
double& gz)
const 258 const double t2 =
r() *
x();
259 const double t3 =
r() *
y();
260 const double t4 =
r() *
z();
261 const double t5 = -
x() *
x();
262 const double t6 =
x() *
y();
263 const double t7 =
x() *
z();
264 const double t8 = -
y() *
y();
265 const double t9 =
y() *
z();
266 const double t10 = -
z() *
z();
267 gx = 2 * ((t8 + t10) * lx + (t6 - t4) * ly + (t3 + t7) * lz) + lx;
268 gy = 2 * ((t4 + t6) * lx + (t5 + t10) * ly + (t9 - t2) * lz) + ly;
269 gz = 2 * ((t7 - t3) * lx + (t2 + t9) * ly + (t5 + t8) * lz) + lz;
276 const double lx,
const double ly,
const double lz,
double& gx,
277 double& gy,
double& gz)
const 279 const double t2 = -
r() *
x();
280 const double t3 = -
r() *
y();
281 const double t4 = -
r() *
z();
282 const double t5 = -
x() *
x();
283 const double t6 =
x() *
y();
284 const double t7 =
x() *
z();
285 const double t8 = -
y() *
y();
286 const double t9 =
y() *
z();
287 const double t10 = -
z() *
z();
288 gx = 2 * ((t8 + t10) * lx + (t6 - t4) * ly + (t3 + t7) * lz) + lx;
289 gy = 2 * ((t4 + t6) * lx + (t5 + t10) * ly + (t9 - t2) * lz) + ly;
290 gz = 2 * ((t7 - t3) * lx + (t2 + t9) * ly + (t5 + t8) * lz) + lz;
305 const T qq = 1.0 / std::sqrt(
normSqr());
306 for (
unsigned int i = 0; i < 4; i++) (*
this)[i] *= qq;
313 template <
class MATRIXLIKE>
316 const T n = 1.0 / std::pow(
normSqr(), T(1.5));
318 J(0, 0) =
x() *
x() +
y() *
y() +
z() *
z();
319 J(0, 1) = -
r() *
x();
320 J(0, 2) = -
r() *
y();
321 J(0, 3) = -
r() *
z();
323 J(1, 0) = -
x() *
r();
324 J(1, 1) =
r() *
r() +
y() *
y() +
z() *
z();
325 J(1, 2) = -
x() *
y();
326 J(1, 3) = -
x() *
z();
328 J(2, 0) = -
y() *
r();
329 J(2, 1) = -
y() *
x();
330 J(2, 2) =
r() *
r() +
x() *
x() +
z() *
z();
331 J(2, 3) = -
y() *
z();
333 J(3, 0) = -
z() *
r();
334 J(3, 1) = -
z() *
x();
335 J(3, 2) = -
z() *
y();
336 J(3, 3) =
r() *
r() +
x() *
x() +
y() *
y();
345 template <
class MATRIXLIKE>
380 template <
class MATRIXLIKE>
387 template <
class MATRIXLIKE>
398 template <
class MATRIXLIKE>
401 M(0, 0) =
r() *
r() +
x() *
x() -
y() *
y() -
z() *
z();
402 M(0, 1) = 2 * (
x() *
y() -
r() *
z());
403 M(0, 2) = 2 * (
z() *
x() +
r() *
y());
404 M(1, 0) = 2 * (
x() *
y() +
r() *
z());
405 M(1, 1) =
r() *
r() -
x() *
x() +
y() *
y() -
z() *
z();
406 M(1, 2) = 2 * (
y() *
z() -
r() *
x());
407 M(2, 0) = 2 * (
z() *
x() -
r() *
y());
408 M(2, 1) = 2 * (
y() *
z() +
r() *
x());
409 M(2, 2) =
r() *
r() -
x() *
x() -
y() *
y() +
z() *
z();
437 roll,
pitch, yaw, static_cast<mrpt::math::CMatrixDouble*>(
nullptr));
449 template <
class MATRIXLIKE>
451 T&
roll, T&
pitch, T& yaw, MATRIXLIKE* out_dr_dq =
nullptr,
452 bool resize_out_dr_dq_to3x4 =
true)
const 457 if (out_dr_dq && resize_out_dr_dq_to3x4) out_dr_dq->setSize(3, 4);
458 const T discr =
r() *
y() -
x() *
z();
462 yaw = -2 * atan2(
x(),
r());
466 out_dr_dq->setZero();
467 (*out_dr_dq)(0, 0) = +2 /
x();
468 (*out_dr_dq)(0, 2) = -2 *
r() / (
x() *
x());
471 else if (discr < -0.49999)
474 yaw = 2 * atan2(
x(),
r());
478 out_dr_dq->setZero();
479 (*out_dr_dq)(0, 0) = -2 /
x();
480 (*out_dr_dq)(0, 2) = +2 *
r() / (
x() *
x());
486 2 * (
r() *
z() +
x() *
y()), 1 - 2 * (
y() *
y() +
z() *
z()));
487 pitch = ::asin(2 * discr);
489 2 * (
r() *
x() +
y() *
z()), 1 - 2 * (
x() *
x() +
y() *
y()));
493 const double val1 = (2 *
x() *
x() + 2 *
y() *
y() - 1);
494 const double val12 =
square(val1);
495 const double val2 = (2 *
r() *
x() + 2 *
y() *
z());
496 const double val22 =
square(val2);
497 const double xy2 = 2 *
x() *
y();
498 const double rz2 = 2 *
r() *
z();
499 const double ry2 = 2 *
r() *
y();
500 const double val3 = (2 *
y() *
y() + 2 *
z() *
z() - 1);
503 const double val5 = (4 * (rz2 + xy2)) /
square(val3);
506 const double val7 = 2.0 / sqrt(1 -
square(ry2 - 2 *
x() *
z()));
507 const double val8 = (val22 / val12 + 1);
508 const double val9 = -2.0 / val8;
510 (*out_dr_dq)(0, 0) = -2 *
z() / val4;
511 (*out_dr_dq)(0, 1) = -2 *
y() / val4;
512 (*out_dr_dq)(0, 2) = -(2 *
x() / val3 -
y() * val5) * val6;
513 (*out_dr_dq)(0, 3) = -(2 *
r() / val3 -
z() * val5) * val6;
515 (*out_dr_dq)(1, 0) =
y() * val7;
516 (*out_dr_dq)(1, 1) = -
z() * val7;
517 (*out_dr_dq)(1, 2) =
r() * val7;
518 (*out_dr_dq)(1, 3) = -
x() * val7;
520 (*out_dr_dq)(2, 0) = val9 *
x() / val1;
522 val9 * (
r() / val1 - (2 *
x() * val2) / val12);
524 val9 * (
z() / val1 - (2 *
y() * val2) / val12);
525 (*out_dr_dq)(2, 3) = val9 *
y() / val1;
void rpy_and_jacobian(T &roll, T &pitch, T &yaw, MATRIXLIKE *out_dr_dq=nullptr, bool resize_out_dr_dq_to3x4=true) const
Return the yaw, pitch & roll angles associated to quaternion, and (optionally) the 3x4 Jacobian of th...
void inverseRotatePoint(const double lx, const double ly, const double lz, double &gx, double &gy, double &gz) const
Rotate a 3D point (lx,ly,lz) -> (gx,gy,gz) as described by the inverse (conjugate) of this quaternion...
static CQuaternion< T > exp(const ARRAYLIKE3 &v)
Exponential map from the SO(3) Lie Algebra to unit quaternions.
A compile-time fixed-size numeric matrix container.
void normalize()
Normalize this quaternion, so its norm becomes the unitity.
std::string std::string format(std::string_view fmt, ARGS &&... args)
TConstructorFlags_Quaternions
T y() const
Return y coordinate of the quaternion.
void rotationMatrixNoResize(MATRIXLIKE &M) const
Fill out the top-left 3x3 block of the given matrix with the rotation matrix associated to this quate...
CQuaternion(const T R, const T X, const T Y, const T Z)
Construct a quaternion from its parameters 'r', 'x', 'y', 'z', with q = r + ix + jy + kz...
#define ASSERT_(f)
Defines an assertion mechanism.
double normSqr() const
Return the squared norm of the quaternion.
This base provides a set of functions for maths stuff.
T r() const
Return r (real part) coordinate of the quaternion.
CQuaternion operator*(const T &factor)
void crossProduct(const CQuaternion &q1, const CQuaternion &q2)
Calculate the "cross" product (or "composed rotation") of two quaternion: this = q1 x q2 After the op...
void rotationJacobian(MATRIXLIKE &J) const
Compute the Jacobian of the rotation composition operation , that is the 4x4 matrix ...
#define ASSERTMSG_(f, __ERROR_MSG)
Defines an assertion mechanism.
void rotatePoint(const double lx, const double ly, const double lz, double &gx, double &gy, double &gz) const
Rotate a 3D point (lx,ly,lz) -> (gx,gy,gz) as described by this quaternion.
void ln_noresize(ARRAYLIKE3 &out_ln) const
Like ln() but does not try to resize the output vector.
return_t square(const num_t x)
Inline function for the square of a number.
ARRAYLIKE3 ln() const
overload that returns by value
T x() const
Return x coordinate of the quaternion.
void normalizationJacobian(MATRIXLIKE &J) const
Calculate the 4x4 Jacobian of the normalization operation of this quaternion.
A quaternion, which can represent a 3D rotation as pair , with a real part "r" and a 3D vector ...
T z() const
Return z coordinate of the quaternion.
T w() const
Return w (real part) coordinate of the quaternion.
void ensurePositiveRealPart()
Adhere to the convention of w>=0 to avoid ambiguity of quaternion double cover of SO(3) ...
void rpy(T &roll, T &pitch, T &yaw) const
Return the yaw, pitch & roll angles associated to quaternion.
CQuaternion conj() const
Return the conjugate quaternion.
CQuaternion()
Default constructor: construct a (1, (0,0,0) ) quaternion representing no rotation.
MATRIXLIKE rotationMatrix() const
CQuaternion(TConstructorFlags_Quaternions)
Can be used with UNINITIALIZED_QUATERNION as argument, does not initialize the 4 elements of the quat...
void fromRodriguesVector(const ARRAYLIKE3 &v)
Set this quaternion to the rotation described by a 3D (Rodrigues) rotation vector : If ...