PX4 ROS 2 Interface Library
Library to interface with PX4 from a companion computer using ROS 2
Loading...
Searching...
No Matches
geometry.hpp
1/****************************************************************************
2 * Copyright (c) 2024 PX4 Development Team.
3 * SPDX-License-Identifier: BSD-3-Clause
4 ****************************************************************************/
5
25#pragma once
26
27#include <Eigen/Eigen>
28
29namespace px4_ros2
30{
38template<typename Type>
39Type radToDeg(Type rad)
40{
41 return rad * static_cast<Type>(180.0 / M_PI);
42}
43
47template<typename Type>
48Type degToRad(Type deg)
49{
50 return deg * static_cast<Type>(M_PI / 180.0);
51}
52
53namespace literals
54{
55static inline constexpr float operator"" _deg(long double degrees)
56{
57 return static_cast<float>(degrees * M_PI / 180.0);
58}
59static inline constexpr float operator"" _rad(long double radians)
60{
61 return static_cast<float>(radians);
62}
63}
64
71template<typename Type>
72Type wrapPi(Type angle)
73{
74 while (angle >= M_PI) {
75 angle -= 2.0 * M_PI;
76 }
77 while (angle < -M_PI) {
78 angle += 2.0 * M_PI;
79 }
80 return angle;
81}
82
90template<typename Type>
91Eigen::Matrix<Type, 3, 1> quaternionToEulerRpy(const Eigen::Quaternion<Type> & q)
92{
93 Eigen::Matrix<Type, 3, 1> angles;
94 Eigen::Matrix<Type, 3, 3> dcm = q.toRotationMatrix();
95
96 angles.y() = asin(-dcm.coeff(2, 0));
97
98 if ((std::fabs(angles.y() - static_cast<Type>(M_PI / 2))) < static_cast<Type>(1.0e-3)) {
99 angles.x() = 0;
100 angles.z() = atan2(dcm.coeff(1, 2), dcm.coeff(0, 2));
101 } else if ((std::fabs(angles.y() + static_cast<Type>(M_PI / 2))) < static_cast<Type>(1.0e-3)) {
102 angles.x() = 0;
103 angles.z() = atan2(-dcm.coeff(1, 2), -dcm.coeff(0, 2));
104 } else {
105 angles.x() = atan2(dcm.coeff(2, 1), dcm.coeff(2, 2));
106 angles.z() = atan2(dcm.coeff(1, 0), dcm.coeff(0, 0));
107 }
108
109 return angles;
110}
111
118template<typename Type>
119Eigen::Quaternion<Type> eulerRpyToQuaternion(const Eigen::Matrix<Type, 3, 1> & euler)
120{
121 return Eigen::Quaternion<Type>(
122 Eigen::AngleAxis<Type>(euler[2], Eigen::Matrix<Type, 3, 1>::UnitZ()) *
123 Eigen::AngleAxis<Type>(euler[1], Eigen::Matrix<Type, 3, 1>::UnitY()) *
124 Eigen::AngleAxis<Type>(euler[0], Eigen::Matrix<Type, 3, 1>::UnitX()));
125}
126
135template<typename Type>
136Eigen::Quaternion<Type> eulerRpyToQuaternion(const Type roll, const Type pitch, const Type yaw)
137{
138 return eulerRpyToQuaternion(Eigen::Matrix<Type, 3, 1>{roll, pitch, yaw});
139}
140
147template<typename Type>
148Type quaternionToRoll(const Eigen::Quaternion<Type> & q)
149{
150 Type x = q.x();
151 Type y = q.y();
152 Type z = q.z();
153 Type w = q.w();
154
155 return std::atan2(2.0 * (w * x + y * z), w * w - x * x - y * y + z * z);
156}
157
164template<typename Type>
165Type quaternionToPitch(const Eigen::Quaternion<Type> & q)
166{
167 Type x = q.x();
168 Type y = q.y();
169 Type z = q.z();
170 Type w = q.w();
171
172 return std::atan2(2.0 * (w * y - z * x), 1.0 - 2.0 * (x * x + y * y));
173}
174
181template<typename Type>
182Type quaternionToYaw(const Eigen::Quaternion<Type> & q)
183{
184 Type x = q.x();
185 Type y = q.y();
186 Type z = q.z();
187 Type w = q.w();
188
189 return std::atan2(2.0 * (x * y + w * z), w * w + x * x - y * y - z * z);
190}
191
193} // namespace px4_ros2
Eigen::Quaternion< Type > eulerRpyToQuaternion(const Eigen::Matrix< Type, 3, 1 > &euler)
Converts RPY extrinsic Tait-Bryan Euler angles (YPR intrinsic) to quaternion.
Definition geometry.hpp:119
Type quaternionToRoll(const Eigen::Quaternion< Type > &q)
Convert quaternion to roll angle in extrinsic RPY order (intrinsic YPR)
Definition geometry.hpp:148
Type degToRad(Type deg)
Converts degrees to radians.
Definition geometry.hpp:48
Type wrapPi(Type angle)
Wraps an angle to the range [-pi, pi).
Definition geometry.hpp:72
Eigen::Matrix< Type, 3, 1 > quaternionToEulerRpy(const Eigen::Quaternion< Type > &q)
Converts a quaternion to RPY extrinsic Tait-Bryan Euler angles (YPR intrinsic) XYZ axes correspond to...
Definition geometry.hpp:91
Type quaternionToPitch(const Eigen::Quaternion< Type > &q)
Convert quaternion to pitch angle in extrinsic RPY order (intrinsic YPR)
Definition geometry.hpp:165
Type radToDeg(Type rad)
Converts radians to degrees.
Definition geometry.hpp:39
Type quaternionToYaw(const Eigen::Quaternion< Type > &q)
Convert quaternion to yaw angle in extrinsic RPY order (intrinsic YPR)
Definition geometry.hpp:182