Kindr
Kinematics and Dynamics for Robotics
Quaternions

This library defines an interface for quaternions to enable different implementations.

Note that these quaternions should not be used to represent rotations! Use a RotationQuaternion instead as explained on page Rotations.

Interfaces

The interfaces are declared in QuaternionBase.hpp.

Generic Quaternion

The class kindr::QuaternionBase defines the interface for a Hamiltonian generic quaternion defined as:

$\boxed{\begin{aligned}Q &= q_0 + q_1 i + q_2 j + q_3 k \in \mathbb{H}, \quad q_i \in \mathbb{R} \\ i^2 &= j^2=k^2 = ijk = -1 \\ \end{aligned}}$

The interface defines generic functions, such as:

Unit Quaternion

The class kindr::UnitQuaternionBase defines the interface for a Hamiltonian unit quaternion defined as:

$\boxed{\begin{aligned}P &= p_0 + p_1 i + p_2 j + p_3 k \in \mathbb{H}, \quad p_i \in \mathbb{R} \\ i^2 &= j^2=k^2 = ijk = -1, \quad \lVert P \rVert= \sqrt{p_0^2 + p_1^2 + p_2^2 + p_3^2} = 1 \\ \end{aligned}}$

There are two reasons why there is an extra class for unit quaternions:

  • Mathematical properties of a unit quaternion, such as the inverse is equal to the conjugate, can be exploited to increase computational speed.
  • The unit length can be guaranteed.

Implementation

Eigen provides a Eigen::Quaternion, which is used as a primitive for a quaternion.

To use the quaternions based on Eigen, include the following header:

#include <kindr/Core>

Generic Quaternion

The class kindr::Quaternion implements a Hamiltonian generic quaternion.

The coefficients are defined as

$\boxed{Q = w + x i + yj + z k}$

The following two typedefs are provided for convenience:

Example code to create a quaternion:

namespace quat = kindr::eigen_impl; // select implementation based on Eigen
quat::QuaternionD quat1; // creates a quaternion with all coefficients equal to zero
quat::QuaternionD quat2(1.0, 2.0, 3.0, 4.0); //creates a quaternion with w=1, x=2, y=3, z=4

Unit Quaternion

The class kindr::UnitQuaternion implements a Hamiltonian unit quaternion.

The following two typedefs are provided for convenience:

The class only checks if the quaternion has unit length if the code is built with debugging symbols, i.e. #define NDEBUG exists. If the unit quaternion has not unit length, an exception will be thrown.

Conversion between Generic Quaternion and Unit Quaternion

Conversion by constructor:

QuaternionD quat(uquat);
UnitQuaternionD uquat2(quat); // error (not allowed)
UnitQuaternionD uquat3(quat.toUnitQuaternion()); // normalizes the quaternion

Conversion by assignment:

quat = uquat;
uquat = quat; // error (not allowed)
uquat = quat.toUnitQuaternion(); // normalizes the quaternion