77 std::abs(
normSqr() - 1.0) < 1e-3,
79 "Initialization data for quaternion is not normalized: %f %f " 80 "%f %f -> sqrNorm=%f",
88 inline T
r()
const {
return (*
this)[0]; }
90 inline T
x()
const {
return (*
this)[1]; }
92 inline T
y()
const {
return (*
this)[2]; }
94 inline T
z()
const {
return (*
this)[3]; }
96 inline void r(
const T
r) { (*this)[0] =
r; }
98 inline void x(
const T
x) { (*this)[1] =
x; }
100 inline void y(
const T
y) { (*this)[2] =
y; }
102 inline void z(
const T
z) { (*this)[3] =
z; }
117 template <
class ARRAYLIKE3>
125 const T angle = std::sqrt(
x *
x +
y *
y +
z *
z);
129 (*this)[1] =
static_cast<T
>(0.5) *
x;
130 (*this)[2] =
static_cast<T
>(0.5) *
y;
131 (*this)[3] =
static_cast<T
>(0.5) *
z;
135 const T
s = (::sin(angle / 2)) / angle;
136 const T
c = ::cos(angle / 2);
154 template <
class ARRAYLIKE3>
155 inline void ln(ARRAYLIKE3& out_ln)
const 157 if (out_ln.size() != 3) out_ln.resize(3);
161 template <
class ARRAYLIKE3>
162 inline ARRAYLIKE3
ln()
const 169 template <
class ARRAYLIKE3>
174 const T K = (xyz_norm < 1e-7) ? 2 : 2 * ::acos(
r()) / xyz_norm;
182 template <
class ARRAYLIKE3>
186 q.fromRodriguesVector(
v);
190 template <
class ARRAYLIKE3>
207 const T new_r = q1.
r() * q2.
r() - q1.
x() * q2.
x() - q1.
y() * q2.
y() -
209 const T new_x = q1.
r() * q2.
x() + q2.
r() * q1.
x() + q1.
y() * q2.
z() -
211 const T new_y = q1.
r() * q2.
y() + q2.
r() * q1.
y() + q1.
z() * q2.
x() -
213 const T new_z = q1.
r() * q2.
z() + q2.
r() * q1.
z() + q1.
x() * q2.
y() -
226 const double lx,
const double ly,
const double lz,
double& gx,
227 double& gy,
double& gz)
const 229 const double t2 =
r() *
x();
230 const double t3 =
r() *
y();
231 const double t4 =
r() *
z();
232 const double t5 = -
x() *
x();
233 const double t6 =
x() *
y();
234 const double t7 =
x() *
z();
235 const double t8 = -
y() *
y();
236 const double t9 =
y() *
z();
237 const double t10 = -
z() *
z();
238 gx = 2 * ((t8 + t10) * lx + (t6 - t4) * ly + (t3 + t7) * lz) + lx;
239 gy = 2 * ((t4 + t6) * lx + (t5 + t10) * ly + (t9 - t2) * lz) + ly;
240 gz = 2 * ((t7 - t3) * lx + (t2 + t9) * ly + (t5 + t8) * lz) + lz;
247 const double lx,
const double ly,
const double lz,
double& gx,
248 double& gy,
double& gz)
const 250 const double t2 = -
r() *
x();
251 const double t3 = -
r() *
y();
252 const double t4 = -
r() *
z();
253 const double t5 = -
x() *
x();
254 const double t6 =
x() *
y();
255 const double t7 =
x() *
z();
256 const double t8 = -
y() *
y();
257 const double t9 =
y() *
z();
258 const double t10 = -
z() *
z();
259 gx = 2 * ((t8 + t10) * lx + (t6 - t4) * ly + (t3 + t7) * lz) + lx;
260 gy = 2 * ((t4 + t6) * lx + (t5 + t10) * ly + (t9 - t2) * lz) + ly;
261 gz = 2 * ((t7 - t3) * lx + (t2 + t9) * ly + (t5 + t8) * lz) + lz;
275 const T qq = 1.0 / std::sqrt(
normSqr());
276 for (
unsigned int i = 0; i < 4; i++) (*
this)[i] *= qq;
283 template <
class MATRIXLIKE>
286 const T
n = 1.0 / std::pow(
normSqr(), T(1.5));
288 J.get_unsafe(0, 0) =
x() *
x() +
y() *
y() +
z() *
z();
289 J.get_unsafe(0, 1) = -
r() *
x();
290 J.get_unsafe(0, 2) = -
r() *
y();
291 J.get_unsafe(0, 3) = -
r() *
z();
293 J.get_unsafe(1, 0) = -
x() *
r();
294 J.get_unsafe(1, 1) =
r() *
r() +
y() *
y() +
z() *
z();
295 J.get_unsafe(1, 2) = -
x() *
y();
296 J.get_unsafe(1, 3) = -
x() *
z();
298 J.get_unsafe(2, 0) = -
y() *
r();
299 J.get_unsafe(2, 1) = -
y() *
x();
300 J.get_unsafe(2, 2) =
r() *
r() +
x() *
x() +
z() *
z();
301 J.get_unsafe(2, 3) = -
y() *
z();
303 J.get_unsafe(3, 0) = -
z() *
r();
304 J.get_unsafe(3, 1) = -
z() *
x();
305 J.get_unsafe(3, 2) = -
z() *
y();
306 J.get_unsafe(3, 3) =
r() *
r() +
x() *
x() +
y() *
y();
315 template <
class MATRIXLIKE>
319 J.get_unsafe(0, 0) =
r();
320 J.get_unsafe(0, 1) = -
x();
321 J.get_unsafe(0, 2) = -
y();
322 J.get_unsafe(0, 3) = -
z();
323 J.get_unsafe(1, 0) =
x();
324 J.get_unsafe(1, 1) =
r();
325 J.get_unsafe(1, 2) = -
z();
326 J.get_unsafe(1, 3) =
y();
327 J.get_unsafe(2, 0) =
y();
328 J.get_unsafe(2, 1) =
z();
329 J.get_unsafe(2, 2) =
r();
330 J.get_unsafe(2, 3) = -
x();
331 J.get_unsafe(3, 0) =
z();
332 J.get_unsafe(3, 1) = -
y();
333 J.get_unsafe(3, 2) =
x();
334 J.get_unsafe(3, 3) =
r();
350 template <
class MATRIXLIKE>
360 template <
class MATRIXLIKE>
363 M.get_unsafe(0, 0) =
r() *
r() +
x() *
x() -
y() *
y() -
z() *
z();
364 M.get_unsafe(0, 1) = 2 * (
x() *
y() -
r() *
z());
365 M.get_unsafe(0, 2) = 2 * (
z() *
x() +
r() *
y());
366 M.get_unsafe(1, 0) = 2 * (
x() *
y() +
r() *
z());
367 M.get_unsafe(1, 1) =
r() *
r() -
x() *
x() +
y() *
y() -
z() *
z();
368 M.get_unsafe(1, 2) = 2 * (
y() *
z() -
r() *
x());
369 M.get_unsafe(2, 0) = 2 * (
z() *
x() -
r() *
y());
370 M.get_unsafe(2, 1) = 2 * (
y() *
z() +
r() *
x());
371 M.get_unsafe(2, 2) =
r() *
r() -
x() *
x() -
y() *
y() +
z() *
z();
399 roll,
pitch, yaw, static_cast<mrpt::math::CMatrixDouble*>(
nullptr));
411 template <
class MATRIXLIKE>
413 T&
roll, T&
pitch, T& yaw, MATRIXLIKE* out_dr_dq =
nullptr,
414 bool resize_out_dr_dq_to3x4 =
true)
const 419 if (out_dr_dq && resize_out_dr_dq_to3x4) out_dr_dq->setSize(3, 4);
420 const T discr =
r() *
y() -
x() *
z();
421 if (fabs(discr) > 0.49999)
424 yaw = -2 * atan2(
x(),
r());
429 out_dr_dq->get_unsafe(0, 0) = +2 /
x();
430 out_dr_dq->get_unsafe(0, 2) = -2 *
r() / (
x() *
x());
433 else if (discr < -0.49999)
436 yaw = 2 * atan2(
x(),
r());
441 out_dr_dq->get_unsafe(0, 0) = -2 /
x();
442 out_dr_dq->get_unsafe(0, 2) = +2 *
r() / (
x() *
x());
448 2 * (
r() *
z() +
x() *
y()), 1 - 2 * (
y() *
y() +
z() *
z()));
449 pitch = ::asin(2 * discr);
451 2 * (
r() *
x() +
y() *
z()), 1 - 2 * (
x() *
x() +
y() *
y()));
455 const double val1 = (2 *
x() *
x() + 2 *
y() *
y() - 1);
456 const double val12 =
square(val1);
457 const double val2 = (2 *
r() *
x() + 2 *
y() *
z());
458 const double val22 =
square(val2);
459 const double xy2 = 2 *
x() *
y();
460 const double rz2 = 2 *
r() *
z();
461 const double ry2 = 2 *
r() *
y();
462 const double val3 = (2 *
y() *
y() + 2 *
z() *
z() - 1);
465 const double val5 = (4 * (rz2 + xy2)) /
square(val3);
468 const double val7 = 2.0 / sqrt(1 -
square(ry2 - 2 *
x() *
z()));
469 const double val8 = (val22 / val12 + 1);
470 const double val9 = -2.0 / val8;
472 out_dr_dq->get_unsafe(0, 0) = -2 *
z() / val4;
473 out_dr_dq->get_unsafe(0, 1) = -2 *
y() / val4;
474 out_dr_dq->get_unsafe(0, 2) =
475 -(2 *
x() / val3 -
y() * val5) * val6;
476 out_dr_dq->get_unsafe(0, 3) =
477 -(2 *
r() / val3 -
z() * val5) * val6;
479 out_dr_dq->get_unsafe(1, 0) =
y() * val7;
480 out_dr_dq->get_unsafe(1, 1) = -
z() * val7;
481 out_dr_dq->get_unsafe(1, 2) =
r() * val7;
482 out_dr_dq->get_unsafe(1, 3) = -
x() * val7;
484 out_dr_dq->get_unsafe(2, 0) = val9 *
x() / val1;
485 out_dr_dq->get_unsafe(2, 1) =
486 val9 * (
r() / val1 - (2 *
x() * val2) / val12);
487 out_dr_dq->get_unsafe(2, 2) =
488 val9 * (
z() / val1 - (2 *
y() * val2) / val12);
489 out_dr_dq->get_unsafe(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: .
void normalize()
Normalize this quaternion, so its norm becomes the unitity.
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
TConstructorFlags_Quaternions
T y() const
Return y coordinate of the quaternion.
#define THROW_EXCEPTION(msg)
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...
CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...
CQuaternion< double > CQuaternionDouble
A quaternion of data type "double".
T square(const T x)
Inline function for the square of a number.
double normSqr() const
Return the squared norm of the quaternion.
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 ...
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.
CArrayNumeric< T, 4 > Base
ARRAYLIKE3 ln() const
overload that returns by value
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
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.
T square(const T x)
Inline function for the square of a number.
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.
#define ASSERTMSG_(f, __ERROR_MSG)
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...
CQuaternion< float > CQuaternionFloat
A quaternion of data type "float".
void fromRodriguesVector(const ARRAYLIKE3 &v)
Set this quaternion to the rotation described by a 3D (Rodrigues) rotation vector : If ...