7#include <janus/math/Quaternion.hpp>
8#include <janus/math/Rotations.hpp>
92 return axes[0] == axes[2];
142template <
typename Scalar>
150 Mat3<Scalar> R1 = janus::rotation_matrix_3d(e1, axes[0]);
151 Mat3<Scalar> R2 = janus::rotation_matrix_3d(e2, axes[1]);
152 Mat3<Scalar> R3 = janus::rotation_matrix_3d(e3, axes[2]);
169template <
typename Scalar>
175 return janus::Quaternion<Scalar>::from_euler(e3, e2, e1);
180 return janus::Quaternion<Scalar>::from_rotation_matrix(R);
196template <
typename Scalar>
198 Scalar sin_e2 = -R(2, 0);
199 Scalar e2 = janus::asin(sin_e2);
201 Scalar eps = Scalar(1e-6);
202 Scalar cos_e2 = janus::cos(e2);
203 Scalar is_gimbal = janus::abs(cos_e2) < eps;
206 Scalar e1_normal = janus::atan2(R(1, 0), R(0, 0));
207 Scalar e3_normal = janus::atan2(R(2, 1), R(2, 2));
210 Scalar e3_gimbal = Scalar(0);
211 Scalar e1_gimbal = janus::atan2(-R(0, 1), R(1, 1));
214 euler(0) = janus::where(is_gimbal, e1_gimbal, e1_normal);
216 euler(2) = janus::where(is_gimbal, e3_gimbal, e3_normal);
228template <
typename Scalar>
230 Scalar sin_e2 = R(0, 2);
231 Scalar e2 = janus::asin(sin_e2);
233 Scalar eps = Scalar(1e-6);
234 Scalar cos_e2 = janus::cos(e2);
235 Scalar is_gimbal = janus::abs(cos_e2) < eps;
238 Scalar e1_normal = janus::atan2(-R(1, 2), R(2, 2));
239 Scalar e3_normal = janus::atan2(-R(0, 1), R(0, 0));
242 Scalar e3_gimbal = Scalar(0);
243 Scalar e1_gimbal = janus::atan2(R(2, 1), R(1, 1));
246 euler(0) = janus::where(is_gimbal, e1_gimbal, e1_normal);
248 euler(2) = janus::where(is_gimbal, e3_gimbal, e3_normal);
254template <
typename Scalar>
256 Scalar sin_e2 = -R(0, 1);
257 Scalar e2 = janus::asin(sin_e2);
259 Scalar eps = Scalar(1e-6);
260 Scalar cos_e2 = janus::cos(e2);
261 Scalar is_gimbal = janus::abs(cos_e2) < eps;
263 Scalar e1_normal = janus::atan2(R(2, 1), R(1, 1));
264 Scalar e3_normal = janus::atan2(R(0, 2), R(0, 0));
266 Scalar e3_gimbal = Scalar(0);
267 Scalar e1_gimbal = janus::atan2(-R(1, 2), R(2, 2));
270 euler(0) = janus::where(is_gimbal, e1_gimbal, e1_normal);
272 euler(2) = janus::where(is_gimbal, e3_gimbal, e3_normal);
278template <
typename Scalar>
280 Scalar sin_e2 = -R(1, 2);
281 Scalar e2 = janus::asin(sin_e2);
283 Scalar eps = Scalar(1e-6);
284 Scalar cos_e2 = janus::cos(e2);
285 Scalar is_gimbal = janus::abs(cos_e2) < eps;
287 Scalar e1_normal = janus::atan2(R(0, 2), R(2, 2));
288 Scalar e3_normal = janus::atan2(R(1, 0), R(1, 1));
290 Scalar e3_gimbal = Scalar(0);
291 Scalar e1_gimbal = janus::atan2(-R(2, 0), R(0, 0));
294 euler(0) = janus::where(is_gimbal, e1_gimbal, e1_normal);
296 euler(2) = janus::where(is_gimbal, e3_gimbal, e3_normal);
302template <
typename Scalar>
304 Scalar sin_e2 = R(1, 0);
305 Scalar e2 = janus::asin(sin_e2);
307 Scalar eps = Scalar(1e-6);
308 Scalar cos_e2 = janus::cos(e2);
309 Scalar is_gimbal = janus::abs(cos_e2) < eps;
311 Scalar e1_normal = janus::atan2(-R(2, 0), R(0, 0));
312 Scalar e3_normal = janus::atan2(-R(1, 2), R(1, 1));
314 Scalar e3_gimbal = Scalar(0);
315 Scalar e1_gimbal = janus::atan2(R(0, 2), R(2, 2));
318 euler(0) = janus::where(is_gimbal, e1_gimbal, e1_normal);
320 euler(2) = janus::where(is_gimbal, e3_gimbal, e3_normal);
326template <
typename Scalar>
328 Scalar sin_e2 = R(2, 1);
329 Scalar e2 = janus::asin(sin_e2);
331 Scalar eps = Scalar(1e-6);
332 Scalar cos_e2 = janus::cos(e2);
333 Scalar is_gimbal = janus::abs(cos_e2) < eps;
335 Scalar e1_normal = janus::atan2(-R(0, 1), R(1, 1));
336 Scalar e3_normal = janus::atan2(-R(2, 0), R(2, 2));
338 Scalar e3_gimbal = Scalar(0);
339 Scalar e1_gimbal = janus::atan2(R(1, 0), R(0, 0));
342 euler(0) = janus::where(is_gimbal, e1_gimbal, e1_normal);
344 euler(2) = janus::where(is_gimbal, e3_gimbal, e3_normal);
357template <
typename Scalar>
359 Scalar cos_e2 = R(2, 2);
360 Scalar e2 = janus::acos(cos_e2);
362 Scalar eps = Scalar(1e-6);
363 Scalar sin_e2 = janus::sin(e2);
364 Scalar is_gimbal = janus::abs(sin_e2) < eps;
367 Scalar e1_normal = janus::atan2(R(0, 2), -R(1, 2));
368 Scalar e3_normal = janus::atan2(R(2, 0), R(2, 1));
371 Scalar e3_gimbal = Scalar(0);
374 Scalar e1_gimbal = janus::atan2(-R(0, 1), R(0, 0));
377 euler(0) = janus::where(is_gimbal, e1_gimbal, e1_normal);
379 euler(2) = janus::where(is_gimbal, e3_gimbal, e3_normal);
385template <
typename Scalar>
387 Scalar cos_e2 = R(2, 2);
388 Scalar e2 = janus::acos(cos_e2);
390 Scalar eps = Scalar(1e-6);
391 Scalar sin_e2 = janus::sin(e2);
392 Scalar is_gimbal = janus::abs(sin_e2) < eps;
394 Scalar e1_normal = janus::atan2(R(1, 2), R(0, 2));
395 Scalar e3_normal = janus::atan2(R(2, 1), -R(2, 0));
397 Scalar e3_gimbal = Scalar(0);
398 Scalar e1_gimbal = janus::atan2(R(1, 0), R(0, 0));
401 euler(0) = janus::where(is_gimbal, e1_gimbal, e1_normal);
403 euler(2) = janus::where(is_gimbal, e3_gimbal, e3_normal);
409template <
typename Scalar>
411 Scalar cos_e2 = R(0, 0);
412 Scalar e2 = janus::acos(cos_e2);
414 Scalar eps = Scalar(1e-6);
415 Scalar sin_e2 = janus::sin(e2);
416 Scalar is_gimbal = janus::abs(sin_e2) < eps;
418 Scalar e1_normal = janus::atan2(R(1, 0), -R(2, 0));
419 Scalar e3_normal = janus::atan2(R(0, 1), R(0, 2));
421 Scalar e3_gimbal = Scalar(0);
422 Scalar e1_gimbal = janus::atan2(-R(1, 2), R(1, 1));
425 euler(0) = janus::where(is_gimbal, e1_gimbal, e1_normal);
427 euler(2) = janus::where(is_gimbal, e3_gimbal, e3_normal);
433template <
typename Scalar>
435 Scalar cos_e2 = R(0, 0);
436 Scalar e2 = janus::acos(cos_e2);
438 Scalar eps = Scalar(1e-6);
439 Scalar sin_e2 = janus::sin(e2);
440 Scalar is_gimbal = janus::abs(sin_e2) < eps;
442 Scalar e1_normal = janus::atan2(R(2, 0), R(1, 0));
443 Scalar e3_normal = janus::atan2(R(0, 2), -R(0, 1));
445 Scalar e3_gimbal = Scalar(0);
446 Scalar e1_gimbal = janus::atan2(R(2, 1), R(2, 2));
449 euler(0) = janus::where(is_gimbal, e1_gimbal, e1_normal);
451 euler(2) = janus::where(is_gimbal, e3_gimbal, e3_normal);
457template <
typename Scalar>
459 Scalar cos_e2 = R(1, 1);
460 Scalar e2 = janus::acos(cos_e2);
462 Scalar eps = Scalar(1e-6);
463 Scalar sin_e2 = janus::sin(e2);
464 Scalar is_gimbal = janus::abs(sin_e2) < eps;
466 Scalar e1_normal = janus::atan2(R(0, 1), R(2, 1));
467 Scalar e3_normal = janus::atan2(R(1, 0), -R(1, 2));
469 Scalar e3_gimbal = Scalar(0);
470 Scalar e1_gimbal = janus::atan2(R(0, 2), R(0, 0));
473 euler(0) = janus::where(is_gimbal, e1_gimbal, e1_normal);
475 euler(2) = janus::where(is_gimbal, e3_gimbal, e3_normal);
481template <
typename Scalar>
483 Scalar cos_e2 = R(1, 1);
484 Scalar e2 = janus::acos(cos_e2);
486 Scalar eps = Scalar(1e-6);
487 Scalar sin_e2 = janus::sin(e2);
488 Scalar is_gimbal = janus::abs(sin_e2) < eps;
490 Scalar e1_normal = janus::atan2(R(2, 1), -R(0, 1));
491 Scalar e3_normal = janus::atan2(R(1, 2), R(1, 0));
493 Scalar e3_gimbal = Scalar(0);
494 Scalar e1_gimbal = janus::atan2(-R(2, 0), R(2, 2));
497 euler(0) = janus::where(is_gimbal, e1_gimbal, e1_normal);
499 euler(2) = janus::where(is_gimbal, e3_gimbal, e3_normal);
519template <
typename Scalar>
557template <
typename Scalar>
562 auto euler_rpy = q.to_euler();
564 euler(0) = euler_rpy(2);
565 euler(1) = euler_rpy(1);
566 euler(2) = euler_rpy(0);
571 Mat3<Scalar> R = q.to_rotation_matrix();
Definition EulerSequences.hpp:187
Vec3< Scalar > euler_from_dcm_yzy(const Mat3< Scalar > &R)
Extract Euler angles from DCM for YZY sequence.
Definition EulerSequences.hpp:482
Vec3< Scalar > euler_from_dcm_xyx(const Mat3< Scalar > &R)
Extract Euler angles from DCM for XYX sequence.
Definition EulerSequences.hpp:410
Vec3< Scalar > euler_from_dcm_xyz(const Mat3< Scalar > &R)
Definition EulerSequences.hpp:229
Vec3< Scalar > euler_from_dcm_yzx(const Mat3< Scalar > &R)
Extract Euler angles from DCM for YZX sequence.
Definition EulerSequences.hpp:303
Vec3< Scalar > euler_from_dcm_yxy(const Mat3< Scalar > &R)
Extract Euler angles from DCM for YXY sequence.
Definition EulerSequences.hpp:458
Vec3< Scalar > euler_from_dcm_zyz(const Mat3< Scalar > &R)
Extract Euler angles from DCM for ZYZ sequence.
Definition EulerSequences.hpp:386
Vec3< Scalar > euler_from_dcm_yxz(const Mat3< Scalar > &R)
Extract Euler angles from DCM for YXZ sequence.
Definition EulerSequences.hpp:279
Vec3< Scalar > euler_from_dcm_zyx(const Mat3< Scalar > &R)
Definition EulerSequences.hpp:197
Vec3< Scalar > euler_from_dcm_xzx(const Mat3< Scalar > &R)
Extract Euler angles from DCM for XZX sequence.
Definition EulerSequences.hpp:434
Vec3< Scalar > euler_from_dcm_xzy(const Mat3< Scalar > &R)
Extract Euler angles from DCM for XZY sequence.
Definition EulerSequences.hpp:255
Vec3< Scalar > euler_from_dcm_zxy(const Mat3< Scalar > &R)
Extract Euler angles from DCM for ZXY sequence.
Definition EulerSequences.hpp:327
Vec3< Scalar > euler_from_dcm_zxz(const Mat3< Scalar > &R)
Definition EulerSequences.hpp:358
Definition Aerodynamics.hpp:11
constexpr const char * euler_sequence_name(EulerSequence seq)
Get sequence name as string (for debugging/logging).
Definition EulerSequences.hpp:96
Mat3< Scalar > dcm_from_euler(Scalar e1, Scalar e2, Scalar e3, EulerSequence seq)
Definition EulerSequences.hpp:143
Vec3< Scalar > euler_from_dcm(const Mat3< Scalar > &R, EulerSequence seq)
Definition EulerSequences.hpp:520
janus::Quaternion< Scalar > quaternion_from_euler(Scalar e1, Scalar e2, Scalar e3, EulerSequence seq)
Definition EulerSequences.hpp:170
EulerSequence
Definition EulerSequences.hpp:32
@ ZXY
Definition EulerSequences.hpp:38
@ XYX
Definition EulerSequences.hpp:42
@ ZYZ
Definition EulerSequences.hpp:47
@ YXZ
Definition EulerSequences.hpp:36
@ ZYX
Yaw-Pitch-Roll (aerospace standard).
Definition EulerSequences.hpp:39
@ XZY
Definition EulerSequences.hpp:35
@ YXY
Definition EulerSequences.hpp:44
@ ZXZ
Classical mechanics (precession-nutation-spin).
Definition EulerSequences.hpp:46
@ YZX
Definition EulerSequences.hpp:37
@ XYZ
Roll-Pitch-Yaw (robotics convention).
Definition EulerSequences.hpp:34
@ XZX
Definition EulerSequences.hpp:43
@ YZY
Definition EulerSequences.hpp:45
constexpr bool is_proper_euler(EulerSequence seq)
Check if sequence is proper Euler (symmetric: first axis == third axis).
Definition EulerSequences.hpp:90
Vec3< Scalar > euler_from_quaternion(const janus::Quaternion< Scalar > &q, EulerSequence seq)
Definition EulerSequences.hpp:558
constexpr std::array< int, 3 > euler_axes(EulerSequence seq)
Definition EulerSequences.hpp:58