smooth
A C++ library for Lie theory
Loading...
Searching...
No Matches
so3.hpp
1// Copyright (C) 2021-2022 Petter Nilsson. MIT License.
2
3#pragma once
4
5#include <Eigen/Core>
6#include <Eigen/Geometry>
7
8#include "detail/macro.hpp"
9#include "detail/so3.hpp"
10#include "lie_group_base.hpp"
11
12SMOOTH_BEGIN_NAMESPACE
13
14// \cond
15template<typename Scalar>
16class SO2;
17// \endcond
18
53template<typename _Derived>
54class SO3Base : public LieGroupBase<_Derived>
55{
57
58protected:
59 SO3Base() = default;
60
61public:
62 SMOOTH_INHERIT_TYPEDEFS;
63
67 Eigen::Map<Eigen::Quaternion<Scalar>> quat()
68 requires is_mutable
69 {
70 return Eigen::Map<Eigen::Quaternion<Scalar>>(static_cast<_Derived &>(*this).data());
71 }
72
76 Eigen::Map<const Eigen::Quaternion<Scalar>> quat() const
77 {
78 return Eigen::Map<const Eigen::Quaternion<Scalar>>(static_cast<const _Derived &>(*this).data());
79 }
80
91 Eigen::Vector3<Scalar> eulerAngles(Eigen::Index i1 = 2, Eigen::Index i2 = 1, Eigen::Index i3 = 0) const
92 {
93 return quat().toRotationMatrix().eulerAngles(i1, i2, i3);
94 }
95
99 template<typename EigenDerived>
100 Eigen::Vector3<Scalar> operator*(const Eigen::MatrixBase<EigenDerived> & v) const
101 {
102 return quat() * v;
103 }
104
112 template<typename EigenDerived>
113 Eigen::Matrix3<Scalar> dr_action(const Eigen::MatrixBase<EigenDerived> & v) const
114 {
115 return -Base::matrix() * Base::hat(v);
116 }
117
126 {
127 using std::atan2;
128
129 const auto q = quat();
130 Scalar yaw =
131 atan2(Scalar(2) * (q.w() * q.z() + q.x() * q.y()), Scalar(1) - Scalar(2) * (q.y() * q.y() + q.z() * q.z()));
132 return SO2<Scalar>(yaw);
133 }
134};
135
136// STORAGE TYPE TRAITS
137
138// \cond
139template<typename _Scalar>
140class SO3;
141// \endcond
142
143// \cond
144template<typename _Scalar>
145struct liebase_info<SO3<_Scalar>>
146{
147 static constexpr bool is_mutable = true;
148
149 using Impl = SO3Impl<_Scalar>;
150 using Scalar = _Scalar;
151
152 template<typename NewScalar>
154};
155// \endcond
156
162template<typename _Scalar>
163class SO3 : public SO3Base<SO3<_Scalar>>
164{
165 using Base = SO3Base<SO3<_Scalar>>;
166
167 SMOOTH_GROUP_API(SO3);
168
169public:
177 template<typename Derived>
178 explicit SO3(const Eigen::QuaternionBase<Derived> & quat) : m_coeffs(quat.normalized().coeffs())
179 {
180 if (m_coeffs(3) < 0) { m_coeffs *= Scalar(-1); }
181 }
182
187 static SO3 rot_x(const Scalar & angle)
188 {
189 using std::cos, std::sin;
190
191 SO3 ret;
192 ret.coeffs() << sin(angle / 2), Scalar(0), Scalar(0), cos(angle / 2);
193 if (ret.coeffs()(3) < 0) { ret.coeffs() *= Scalar(-1); }
194 return ret;
195 }
196
201 static SO3 rot_y(const Scalar & angle)
202 {
203 using std::cos, std::sin;
204
205 SO3 ret;
206 ret.coeffs() << Scalar(0), sin(angle / 2), Scalar(0), cos(angle / 2);
207 if (ret.coeffs()(3) < 0) { ret.coeffs() *= Scalar(-1); }
208 return ret;
209 }
210
215 static SO3 rot_z(const Scalar & angle)
216 {
217 using std::cos, std::sin;
218
219 SO3 ret;
220 ret.coeffs() << Scalar(0), Scalar(0), sin(angle / 2), cos(angle / 2);
221 if (ret.coeffs()(3) < 0) { ret.coeffs() *= Scalar(-1); }
222 return ret;
223 }
224};
225
226// \cond
227template<typename _Scalar>
228struct liebase_info<Map<SO3<_Scalar>>> : public liebase_info<SO3<_Scalar>>
229{};
230// \endcond
231
237template<typename _Scalar>
238class Map<SO3<_Scalar>> : public SO3Base<Map<SO3<_Scalar>>>
239{
241
242 SMOOTH_MAP_API();
243};
244
245// \cond
246template<typename _Scalar>
247struct liebase_info<Map<const SO3<_Scalar>>> : public liebase_info<SO3<_Scalar>>
248{
249 static constexpr bool is_mutable = false;
250};
251// \endcond
252
258template<typename _Scalar>
259class Map<const SO3<_Scalar>> : public SO3Base<Map<const SO3<_Scalar>>>
260{
262
263 SMOOTH_CONST_MAP_API();
264};
265
266using SO3f = SO3<float>;
267using SO3d = SO3<double>;
268
269SMOOTH_END_NAMESPACE
270
271// Std format
272#if __has_include(<format>)
273#include <format>
274#include <string>
275
276template<class Scalar>
277struct std::formatter<smooth::SO3<Scalar>>
278{
279 std::string m_format;
280
281 constexpr auto parse(std::format_parse_context & ctx)
282 {
283 m_format = "{:";
284 for (auto it = ctx.begin(); it != ctx.end(); ++it) {
285 char c = *it;
286 m_format += c;
287 if (c == '}') return it;
288 }
289 return ctx.end();
290 }
291
292 auto format(const smooth::SO3<Scalar> & obj, std::format_context & ctx) const
293 {
294 const auto fmtSting = std::format("[{0}, {0}, {0}, {0}]", m_format);
295 return std::vformat_to(
296 ctx.out(), fmtSting, std::make_format_args(obj.quat().w(), obj.quat().x(), obj.quat().y(), obj.quat().z()));
297 }
298};
299
300#endif
Base class for Lie group types.
typename traits::Scalar Scalar
Scalar type.
auto & coeffs() const
Access underlying storages.
static constexpr bool is_mutable
True if underlying storage supports modification.
static Matrix hat(const Eigen::MatrixBase< TangentDerived > &a) noexcept
Lie algebra hat map.
Matrix matrix() const noexcept
Return as matrix Lie group element in .
Eigen::Matrix< Scalar, Dim, Dim > Matrix
Lie group matrix type.
Memory mapping of internal Lie group types.
Storage implementation of SO2 Lie group.
Definition so2.hpp:190
Base class for SO3 Lie group types.
Definition so3.hpp:55
Eigen::Vector3< Scalar > operator*(const Eigen::MatrixBase< EigenDerived > &v) const
Rotation action on 3D vector.
Definition so3.hpp:100
Eigen::Map< Eigen::Quaternion< Scalar > > quat()
Access quaterion.
Definition so3.hpp:67
SO2< Scalar > project_so2() const
Project to SO2.
Definition so3.hpp:125
Eigen::Vector3< Scalar > eulerAngles(Eigen::Index i1=2, Eigen::Index i2=1, Eigen::Index i3=0) const
Return euler angles.
Definition so3.hpp:91
Eigen::Matrix3< Scalar > dr_action(const Eigen::MatrixBase< EigenDerived > &v) const
Jacobian of rotation action w.r.t. group.
Definition so3.hpp:113
Eigen::Map< const Eigen::Quaternion< Scalar > > quat() const
Access const quaterion.
Definition so3.hpp:76
Storage implementation of SO3 Lie group.
Definition so3.hpp:164
static SO3 rot_z(const Scalar &angle)
SO3 representing rotation around the z axis.
Definition so3.hpp:215
static SO3 rot_x(const Scalar &angle)
SO3 representing rotation around the x axis.
Definition so3.hpp:187
static SO3 rot_y(const Scalar &angle)
SO3 representing rotation around the y axis.
Definition so3.hpp:201
SO3(const Eigen::QuaternionBase< Derived > &quat)
Construct from quaternion.
Definition so3.hpp:178
typename traits::man< M >::Scalar Scalar
Manifold scalar type.
Definition manifold.hpp:88
typename traits::man< M >::PlainObject PlainObject
Manifold default type.
Definition manifold.hpp:94
Type trait that maps a type to Lie group operations.