27#include <AH/Arduino-Wrapper.h>
30#include <AH/STL/cmath>
31#include <AH/STL/limits>
69 Quaternion(
float w,
float x,
float y,
float z) : w(w), x(x), y(y), z(z) {}
74 return *
this = hamiltonianProduct(*
this, rhs);
79 return hamiltonianProduct(*
this, rhs);
131 float normSquared()
const {
return w * w + x * x + y * y + z * z; }
133 float norm()
const {
return std::sqrt(normSquared()); }
161 float M11 = 1 - 2 * q.
y * q.
y - 2 * q.
z * q.
z;
162 float M12 = 2 * (q.
x * q.
y - q.
w * q.
z);
163 float M13 = 2 * (q.
x * q.
z + q.
w * q.
y);
164 float M21 = 2 * (q.
x * q.
y + q.
w * q.
z);
165 float M22 = 1 - 2 * q.
x * q.
x - 2 * q.
z * q.
z;
166 float M23 = 2 * (q.
y * q.
z - q.
w * q.
x);
167 float M31 = 2 * (q.
x * q.
z - q.
w * q.
y);
168 float M32 = 2 * (q.
y * q.
z + q.
w * q.
x);
169 float M33 = 1 - 2 * q.
x * q.
x - 2 * q.
y * q.
y;
172 M11 * v.
x + M12 * v.
y + M13 * v.
z,
173 M21 * v.
x + M22 * v.
y + M23 * v.
z,
174 M31 * v.
x + M32 * v.
y + M33 * v.
z,
180 return this->w == rhs.
w && this->x == rhs.
x && this->y == rhs.
y &&
208 float eps = std::numeric_limits<float>::epsilon();
211 float v_norm = v.
norm();
216 float x = v.
x / v_norm;
217 float y = v.
y / v_norm;
220 if (std::abs(x) <= eps && std::abs(y) <= eps)
225 Vec2f cross = {-y, x};
226 float crossNorm =
min(cross.
norm(), 1);
230 float angle = std::asin(crossNorm);
232 angle = float(180_deg) - angle;
237 std::sin(angle / 2) * cross.
x,
238 std::sin(angle / 2) * cross.
y,
262 return Quaternion::fromDirection(v);
268 r.
w * q.
w - r.
x * q.
x - r.
y * q.
y - r.
z * q.
z,
269 r.
w * q.
x + r.
x * q.
w - r.
y * q.
z + r.
z * q.
y,
270 r.
w * q.
y + r.
x * q.
z + r.
y * q.
w - r.
z * q.
x,
271 r.
w * q.
z - r.
x * q.
y + r.
y * q.
x + r.
z * q.
w,
279 return {lhs * rhs.
w, lhs * rhs.
x, lhs * rhs.
y, lhs * rhs.
z};
300 : yaw(yaw), pitch(pitch), roll(roll) {}
309 return this->yaw == rhs.
yaw && this->pitch == rhs.
pitch &&
310 this->roll == rhs.
roll;
322 float phi = std::atan2(2 * (q.
w * q.
x + q.
y * q.
z),
323 1 - 2 * (q.
x * q.
x + q.
y * q.
y));
324 float theta = std::asin(2 * (q.
w * q.
y - q.
z * q.
x));
325 float psi = std::atan2(2 * (q.
w * q.
z + q.
x * q.
y),
326 1 - 2 * (q.
y * q.
y + q.
z * q.
z));
327 return {psi, theta, phi};
334 float cy = std::cos(eulerAngles.
yaw / 2);
335 float sy = std::sin(eulerAngles.
yaw / 2);
336 float cp = std::cos(eulerAngles.
pitch / 2);
337 float sp = std::sin(eulerAngles.
pitch / 2);
338 float cr = std::cos(eulerAngles.
roll / 2);
339 float sr = std::sin(eulerAngles.
roll / 2);
342 cy * cp * cr + sy * sp * sr,
343 cy * cp * sr - sy * sp * cr,
344 sy * cp * sr + cy * sp * cr,
345 sy * cp * cr - cy * sp * sr,
354std::ostream &
operator<<(std::ostream &os, Quaternion q);
358std::ostream &
operator<<(std::ostream &os, EulerAngles e);
#define BEGIN_AH_NAMESPACE
Conversions between radians and degrees.
Definition of Vec2f and Vec3f.
#define AH_DIAGNOSTIC_POP()
#define AH_DIAGNOSTIC_WERROR()
constexpr auto min(const T &a, const U &b) -> decltype(b< a ? b :a)
Return the smaller of two numbers/objects.
Print & operator<<(Print &os, Quaternion e)
Printing.
Quaternion operator*(float lhs, Quaternion rhs)
Scalar multiplication.
Struct for Euler angles of floating point numbers.
bool operator==(EulerAngles rhs) const
Equality check.
EulerAngles(Quaternion q)
Create Euler angles from the given quaternion.
float roll
X": drone X = world +Y.
float pitch
Y': drone Y = world -X.
static EulerAngles quat2eul(Quaternion q)
Convert the given quaternion to Euler angles.
bool operator!=(EulerAngles rhs) const
Inequality check.
float yaw
Z : drone Z = world +Z.
EulerAngles(float yaw, float pitch, float roll)
Create Euler angles with the given values for yaw, pitch and roll.
EulerAngles()=default
Create Euler angles that are initialized to (0 0 0), or upright.
static Quaternion eul2quat(EulerAngles eulerAngles)
Convert the given Euler angles to a quaternion.
Type for quaternions of floating point numbers.
Quaternion & operator+=(Quaternion rhs)
Sum of two quaterions uses quaternion multiplication.
static Quaternion fromDirection(Vec3f v)
Calculate the quaternion that satisfies the following: result.rotate(Vec3f{0, 0, 1}) == v....
Quaternion & operator/=(float rhs)
Scalar division.
Quaternion operator-() const
Negated quaternion is its conjugate.
float w
Scalar (real) component.
static Quaternion hamiltonianProduct(Quaternion q, Quaternion r)
Quaternion multiplication.
float normSquared() const
Norm squared.
bool operator==(Quaternion rhs) const
Equality check.
Quaternion(float w, float x, float y, float z)
Create a quaterion with the given values for w, x, y and z.
bool operator!=(Quaternion rhs) const
Inequality check.
Quaternion operator/(float rhs) const
Scalar division.
float y
Second vector (imaginary) component .
Quaternion()=default
Create a quaternion that is initialized to the identity quaternion.
Quaternion operator+(Quaternion rhs) const
Sum of two quaternions uses quaternion multiplication.
Quaternion & operator-=(Quaternion rhs)
Difference of two quaternions a and b is the quaternion multiplication of a and the conjugate of b.
Quaternion operator*(float rhs) const
Scalar multiplication.
static Quaternion fromXYAngle(float xAngle, float yAngle)
Calculate the quaternion from a vector that makes a given angle with the XZ plane and a given angle w...
Vec3f rotate(Vec3f v) const
Rotate vector by this quaternion.
Quaternion normalized() const
Normalize a copy of this quaternion (doesn't change the original quaternion).
Quaternion & normalize()
Normalize this quaternion.
float x
First vector (imaginary) component .
static Quaternion identity()
Identity quaternion (1,0,0,0).
Quaternion operator-(Quaternion rhs) const
Difference of two quaternions a and b is the quaternion multiplication of a and the conjugate of b.
Quaternion & operator*=(float rhs)
Scalar multiplication.
float z
Third vector (imaginary) component .
Quaternion conjugated() const
Complex conjugate (doesn't change the original quaternion).
Type for 2D vectors of floating point numbers.
float y
The y component of the vector.
float x
The x component of the vector.
Type for 3D vectors of floating point numbers.
float y
The y component of the vector.
float x
The x component of the vector.
float z
The z component of the vector.