75 std::abs(
normSqr() - 1.0) < 1e-3,
77 "Initialization data for quaternion is not normalized: %f %f " 78 "%f %f -> sqrNorm=%f",
86 inline T
r()
const {
return (*
this)[0]; }
88 inline T
x()
const {
return (*
this)[1]; }
90 inline T
y()
const {
return (*
this)[2]; }
92 inline T
z()
const {
return (*
this)[3]; }
94 inline void r(
const T
r) { (*this)[0] =
r; }
96 inline void x(
const T
x) { (*this)[1] =
x; }
98 inline void y(
const T
y) { (*this)[2] =
y; }
100 inline void z(
const T
z) { (*this)[3] =
z; }
115 template <
class ARRAYLIKE3>
120 const T
x =
v[0],
y =
v[1],
z =
v[2];
121 const T theta_sq =
x *
x +
y *
y +
z *
z, theta = std::sqrt(theta_sq);
126 const T theta_po4 = theta_sq * theta_sq;
127 i = T(0.5) - T(1.0 / 48.0) * theta_sq + T(1.0 / 3840.0) * theta_po4;
128 r = T(1.0) - T(0.5) * theta_sq + T(1.0 / 384.0) * theta_po4;
132 i = (std::sin(theta / 2)) / theta;
133 r = std::cos(theta / 2);
142 "fromRodriguesVector() failed, tangent_vector=[%g %g %g]",
v[0],
157 template <
class ARRAYLIKE3>
158 inline void ln(ARRAYLIKE3& out_ln)
const 160 if (out_ln.size() != 3) out_ln.resize(3);
164 template <
class ARRAYLIKE3>
165 inline ARRAYLIKE3
ln()
const 172 template <
class ARRAYLIKE3>
177 const T K = (xyz_norm < 1e-7) ? 2 : 2 * ::acos(
r()) / xyz_norm;
185 template <
class ARRAYLIKE3>
189 q.fromRodriguesVector(
v);
193 template <
class ARRAYLIKE3>
210 const T new_r = q1.
r() * q2.
r() - q1.
x() * q2.
x() - q1.
y() * q2.
y() -
212 const T new_x = q1.
r() * q2.
x() + q2.
r() * q1.
x() + q1.
y() * q2.
z() -
214 const T new_y = q1.
r() * q2.
y() + q2.
r() * q1.
y() + q1.
z() * q2.
x() -
216 const T new_z = q1.
r() * q2.
z() + q2.
r() * q1.
z() + q1.
x() * q2.
y() -
229 const double lx,
const double ly,
const double lz,
double& gx,
230 double& gy,
double& gz)
const 232 const double t2 =
r() *
x();
233 const double t3 =
r() *
y();
234 const double t4 =
r() *
z();
235 const double t5 = -
x() *
x();
236 const double t6 =
x() *
y();
237 const double t7 =
x() *
z();
238 const double t8 = -
y() *
y();
239 const double t9 =
y() *
z();
240 const double t10 = -
z() *
z();
241 gx = 2 * ((t8 + t10) * lx + (t6 - t4) * ly + (t3 + t7) * lz) + lx;
242 gy = 2 * ((t4 + t6) * lx + (t5 + t10) * ly + (t9 - t2) * lz) + ly;
243 gz = 2 * ((t7 - t3) * lx + (t2 + t9) * ly + (t5 + t8) * lz) + lz;
250 const double lx,
const double ly,
const double lz,
double& gx,
251 double& gy,
double& gz)
const 253 const double t2 = -
r() *
x();
254 const double t3 = -
r() *
y();
255 const double t4 = -
r() *
z();
256 const double t5 = -
x() *
x();
257 const double t6 =
x() *
y();
258 const double t7 =
x() *
z();
259 const double t8 = -
y() *
y();
260 const double t9 =
y() *
z();
261 const double t10 = -
z() *
z();
262 gx = 2 * ((t8 + t10) * lx + (t6 - t4) * ly + (t3 + t7) * lz) + lx;
263 gy = 2 * ((t4 + t6) * lx + (t5 + t10) * ly + (t9 - t2) * lz) + ly;
264 gz = 2 * ((t7 - t3) * lx + (t2 + t9) * ly + (t5 + t8) * lz) + lz;
278 const T qq = 1.0 / std::sqrt(
normSqr());
279 for (
unsigned int i = 0; i < 4; i++) (*
this)[i] *= qq;
286 template <
class MATRIXLIKE>
289 const T
n = 1.0 / std::pow(
normSqr(), T(1.5));
291 J(0, 0) =
x() *
x() +
y() *
y() +
z() *
z();
292 J(0, 1) = -
r() *
x();
293 J(0, 2) = -
r() *
y();
294 J(0, 3) = -
r() *
z();
296 J(1, 0) = -
x() *
r();
297 J(1, 1) =
r() *
r() +
y() *
y() +
z() *
z();
298 J(1, 2) = -
x() *
y();
299 J(1, 3) = -
x() *
z();
301 J(2, 0) = -
y() *
r();
302 J(2, 1) = -
y() *
x();
303 J(2, 2) =
r() *
r() +
x() *
x() +
z() *
z();
304 J(2, 3) = -
y() *
z();
306 J(3, 0) = -
z() *
r();
307 J(3, 1) = -
z() *
x();
308 J(3, 2) = -
z() *
y();
309 J(3, 3) =
r() *
r() +
x() *
x() +
y() *
y();
318 template <
class MATRIXLIKE>
353 template <
class MATRIXLIKE>
363 template <
class MATRIXLIKE>
366 M(0, 0) =
r() *
r() +
x() *
x() -
y() *
y() -
z() *
z();
367 M(0, 1) = 2 * (
x() *
y() -
r() *
z());
368 M(0, 2) = 2 * (
z() *
x() +
r() *
y());
369 M(1, 0) = 2 * (
x() *
y() +
r() *
z());
370 M(1, 1) =
r() *
r() -
x() *
x() +
y() *
y() -
z() *
z();
371 M(1, 2) = 2 * (
y() *
z() -
r() *
x());
372 M(2, 0) = 2 * (
z() *
x() -
r() *
y());
373 M(2, 1) = 2 * (
y() *
z() +
r() *
x());
374 M(2, 2) =
r() *
r() -
x() *
x() -
y() *
y() +
z() *
z();
402 roll,
pitch, yaw, static_cast<mrpt::math::CMatrixDouble*>(
nullptr));
414 template <
class MATRIXLIKE>
416 T&
roll, T&
pitch, T& yaw, MATRIXLIKE* out_dr_dq =
nullptr,
417 bool resize_out_dr_dq_to3x4 =
true)
const 422 if (out_dr_dq && resize_out_dr_dq_to3x4) out_dr_dq->setSize(3, 4);
423 const T discr =
r() *
y() -
x() *
z();
424 if (fabs(discr) > 0.49999)
427 yaw = -2 * atan2(
x(),
r());
431 out_dr_dq->setZero();
432 (*out_dr_dq)(0, 0) = +2 /
x();
433 (*out_dr_dq)(0, 2) = -2 *
r() / (
x() *
x());
436 else if (discr < -0.49999)
439 yaw = 2 * atan2(
x(),
r());
443 out_dr_dq->setZero();
444 (*out_dr_dq)(0, 0) = -2 /
x();
445 (*out_dr_dq)(0, 2) = +2 *
r() / (
x() *
x());
451 2 * (
r() *
z() +
x() *
y()), 1 - 2 * (
y() *
y() +
z() *
z()));
452 pitch = ::asin(2 * discr);
454 2 * (
r() *
x() +
y() *
z()), 1 - 2 * (
x() *
x() +
y() *
y()));
458 const double val1 = (2 *
x() *
x() + 2 *
y() *
y() - 1);
459 const double val12 =
square(val1);
460 const double val2 = (2 *
r() *
x() + 2 *
y() *
z());
461 const double val22 =
square(val2);
462 const double xy2 = 2 *
x() *
y();
463 const double rz2 = 2 *
r() *
z();
464 const double ry2 = 2 *
r() *
y();
465 const double val3 = (2 *
y() *
y() + 2 *
z() *
z() - 1);
468 const double val5 = (4 * (rz2 + xy2)) /
square(val3);
471 const double val7 = 2.0 / sqrt(1 -
square(ry2 - 2 *
x() *
z()));
472 const double val8 = (val22 / val12 + 1);
473 const double val9 = -2.0 / val8;
475 (*out_dr_dq)(0, 0) = -2 *
z() / val4;
476 (*out_dr_dq)(0, 1) = -2 *
y() / val4;
477 (*out_dr_dq)(0, 2) = -(2 *
x() / val3 -
y() * val5) * val6;
478 (*out_dr_dq)(0, 3) = -(2 *
r() / val3 -
z() * val5) * val6;
480 (*out_dr_dq)(1, 0) =
y() * val7;
481 (*out_dr_dq)(1, 1) = -
z() * val7;
482 (*out_dr_dq)(1, 2) =
r() * val7;
483 (*out_dr_dq)(1, 3) = -
x() * val7;
485 (*out_dr_dq)(2, 0) = val9 *
x() / val1;
487 val9 * (
r() / val1 - (2 *
x() * val2) / val12);
489 val9 * (
z() / val1 - (2 *
y() * val2) / val12);
490 (*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.
void rotationMatrix(MATRIXLIKE &M) const
Calculate the 3x3 rotation matrix associated to this quaternion: .
A compile-time fixed-size numeric matrix container.
void normalize()
Normalize this quaternion, so its norm becomes the unitity.
TConstructorFlags_Quaternions
T y() const
Return y coordinate of the quaternion.
GLdouble GLdouble GLdouble GLdouble q
void rotationMatrixNoResize(MATRIXLIKE &M) const
Fill out the top-left 3x3 block of the given matrix with the rotation matrix associated to this quate...
T square(const T x)
Inline function for the square of a number.
#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 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.
ARRAYLIKE3 ln() const
overload that returns by value
T x() const
Return x coordinate of the quaternion.
GLdouble GLdouble GLdouble r
void normalizationJacobian(MATRIXLIKE &J) const
Calculate the 4x4 Jacobian of the normalization operation of this quaternion.
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
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...
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.
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.
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 ...