MoveG 1.0.0
A modern C++ library for Robotics
Loading...
Searching...
No Matches
pose_lib.cpp
Go to the documentation of this file.
1
9#include "pose_lib.h"
10
11namespace MoveG
12{
13// Default Constructor
14Pose::Pose() noexcept
15 : position_(Eigen::Vector3d::Zero()), orientation_(Eigen::Quaterniond::Identity())
16{
17}
18
19// Constructor with position and quaternion orientation
20Pose::Pose(const Eigen::Vector3d &position, const Eigen::Quaterniond &orientation)
21 : position_(position),
22 orientation_(orientation.normalized()) // Ensure the quaternion is normalized
23{
24}
25
26// Constructor with position and rotation matrix
27Pose::Pose(const Eigen::Vector3d &position, const Eigen::Matrix3d &rotation_matrix)
28 : position_(position), orientation_(Eigen::Quaterniond(rotation_matrix))
29{
30 orientation_.normalize(); // Ensure the quaternion is normalized
31}
32
33// Constructor with Affine3d transformation
34Pose::Pose(const Eigen::Affine3d &transformation)
35 : position_(transformation.translation()),
36 orientation_(Eigen::Quaterniond(transformation.rotation()))
37{
38 orientation_.normalize(); // Ensure the quaternion is normalized
39}
40
41// Constructor with position and custom Rotation class
42Pose::Pose(const Eigen::Vector3d &position, const Rotation &orientation)
43 : position_(position), orientation_(orientation.toQuaternion())
44{
45 orientation_.normalize(); // Ensure the quaternion is normalized
46}
47
48// Constructor with Homogeneous Transformation Matrix
49Pose::Pose(const Eigen::Matrix4d &homogeneousT)
50{
51 validateHomogeneousMatrix(homogeneousT);
52
53 // Extract position
54 position_ = homogeneousT.block<3, 1>(0, 3);
55
56 // Extract rotation matrix
57 const Eigen::Matrix3d rotation_matrix = homogeneousT.block<3, 3>(0, 0);
58 orientation_ = Eigen::Quaterniond(rotation_matrix).normalized(); // Ensure normalization
59}
60
61// Destructor
63{
64 // No dynamic memory to clean up
65}
66
67// Copy Constructor
68Pose::Pose(const Pose &other) : position_(other.position_), orientation_(other.orientation_)
69{
70}
71
72// Move Constructor
73Pose::Pose(Pose &&other) noexcept
74 : position_(std::move(other.position_)), orientation_(std::move(other.orientation_))
75{
76}
77
78// Copy Assignment Operator
80{
81 if (this != &other)
82 {
83 position_ = other.position_;
85 }
86 return *this;
87}
88
89// Move Assignment Operator
90Pose &Pose::operator=(Pose &&other) noexcept
91{
92 if (this != &other)
93 {
94 position_ = std::move(other.position_);
95 orientation_ = std::move(other.orientation_);
96 }
97 return *this;
98}
99
100// Getters
101
102Eigen::Vector3d Pose::getPosition() const
103{
104 return position_;
105}
106
107Eigen::Quaterniond Pose::getQuaternion() const
108{
109 return orientation_;
110}
111
112Eigen::Matrix3d Pose::getRotationMatrix() const
113{
114 return orientation_.toRotationMatrix();
115}
116
117Eigen::Affine3d Pose::getAffineTransformation() const
118{
119 Eigen::Affine3d transformation = Eigen::Affine3d::Identity();
120 transformation.translation() = position_;
121 transformation.linear() = orientation_.toRotationMatrix();
122 return transformation;
123}
124
125Eigen::Matrix4d Pose::getHomogeneousT() const
126{
127 Eigen::Matrix4d homogeneous = Eigen::Matrix4d::Identity();
128 homogeneous.block<3, 3>(0, 0) = orientation_.toRotationMatrix();
129 homogeneous.block<3, 1>(0, 3) = position_;
130 return homogeneous;
131}
132
133// Additional Getters for individual components
134
135double Pose::getX() const
136{
137 return position_.x();
138}
139
140double Pose::getY() const
141{
142 return position_.y();
143}
144
145double Pose::getZ() const
146{
147 return position_.z();
148}
149
150double Pose::getQx() const
151{
152 return orientation_.x();
153}
154
155double Pose::getQy() const
156{
157 return orientation_.y();
158}
159
160double Pose::getQz() const
161{
162 return orientation_.z();
163}
164
165double Pose::getQw() const
166{
167 return orientation_.w();
168}
169
170// Setters
171
172void Pose::setPosition(const Eigen::Vector3d &position)
173{
174 position_ = position;
175}
176
177void Pose::setOrientation(const Eigen::Quaterniond &orientation)
178{
179 orientation_ = orientation.normalized(); // Ensure the quaternion is normalized
180}
181
182void Pose::setRotationMatrix(const Eigen::Matrix3d &rotation_matrix)
183{
184 orientation_ = Eigen::Quaterniond(rotation_matrix).normalized(); // Ensure normalization
185}
186
187void Pose::setAffineTransformation(const Eigen::Affine3d &transformation)
188{
189 position_ = transformation.translation();
190 orientation_ = Eigen::Quaterniond(transformation.rotation()).normalized();
191}
192
193void Pose::setHomogeneousT(const Eigen::Matrix4d &homogeneousT)
194{
195 validateHomogeneousMatrix(homogeneousT);
196
197 // Extract position
198 position_ = homogeneousT.block<3, 1>(0, 3);
199
200 // Extract rotation matrix
201 const Eigen::Matrix3d rotation_matrix = homogeneousT.block<3, 3>(0, 0);
202 orientation_ = Eigen::Quaterniond(rotation_matrix).normalized();
203}
204
205// Distance metrics
206double Pose::positionDistance(const Pose &other) const
207{
208 return (position_ - other.position_).norm();
209}
210
211double Pose::orientationDistance(const Pose &other) const
212{
213 // Compute the angle between quaternions
214 double dot = std::abs(orientation_.dot(other.orientation_));
215 // Clamp dot to [-1, 1] to avoid numerical issues
216 dot = std::max(-1.0, std::min(1.0, dot));
217 return 2.0 * std::acos(dot);
218}
219
220// Compose two poses
221Pose Pose::operator*(const Pose &other) const
222{
223 const Eigen::Quaterniond combined_orientation = orientation_ * other.orientation_;
224 const Eigen::Vector3d combined_position = position_ + orientation_ * other.position_;
225 return Pose(combined_position, combined_orientation);
226}
227
228// Inverse of the pose
230{
231 const Eigen::Quaterniond inv_orientation = orientation_.conjugate();
232 const Eigen::Vector3d inv_position = -(inv_orientation * position_);
233 return Pose(inv_position, inv_orientation);
234}
235
236// Validate homogeneous transformation matrix
237void Pose::validateHomogeneousMatrix(const Eigen::Matrix4d &homogeneousT)
238{
239 // Check the last row
240 Eigen::RowVector4d expected_last_row(0, 0, 0, 1);
241 Eigen::RowVector4d actual_last_row = homogeneousT.block<1, 4>(3, 0);
242
243 if (!actual_last_row.isApprox(expected_last_row, 1e-6))
244 {
245 std::stringstream error_msg;
246 error_msg << "Invalid homogeneous transformation matrix. The last row must be [0, 0, 0, "
247 "1], but got ["
248 << actual_last_row(0) << ", " << actual_last_row(1) << ", " << actual_last_row(2)
249 << ", " << actual_last_row(3) << "].";
250 throw std::invalid_argument(error_msg.str());
251 }
252
253 // Extract the rotation matrix part
254 const Eigen::Matrix3d rotation_part = homogeneousT.block<3, 3>(0, 0);
255
256 // Check if the rotation matrix is orthogonal
257 // A rotation matrix multiplied by its transpose should give the identity matrix
258 Eigen::Matrix3d orthogonality_check = rotation_part * rotation_part.transpose();
259 Eigen::Matrix3d identity = Eigen::Matrix3d::Identity();
260
261 if (!orthogonality_check.isApprox(identity, 1e-6))
262 {
263 std::stringstream error_msg;
264 error_msg
265 << "Invalid homogeneous transformation matrix. The rotation part is not orthogonal.";
266 throw std::invalid_argument(error_msg.str());
267 }
268
269 // Additionally, check the determinant is approximately 1 (proper rotation)
270 double det = rotation_part.determinant();
271 if (std::abs(det - 1.0) > 1e-6)
272 {
273 std::stringstream error_msg;
274 error_msg << "Invalid homogeneous transformation matrix. The rotation part has determinant "
275 << det << ", which differs from 1.0 (expected for a proper rotation).";
276 throw std::invalid_argument(error_msg.str());
277 }
278}
279
280// Overload the output stream operator
281std::ostream &operator<<(std::ostream &os, const Pose &pose)
282{
283 os << "Position: [" << pose.position_.x() << ", " << pose.position_.y() << ", "
284 << pose.position_.z() << "]\n";
285 os << "Orientation (quaternion): [" << pose.orientation_.x() << ", " << pose.orientation_.y()
286 << ", " << pose.orientation_.z() << ", " << pose.orientation_.w() << "]";
287 return os;
288}
289
290// Implementation of coordinate transformation methods
291Pose Pose::transformPose(const Pose &transform) const
292{
293 // This method transforms this pose by the given transformation
294 // This is useful for changing coordinate frames
295 return transform * (*this);
296}
297
298Eigen::Vector3d Pose::localToGlobal(const Eigen::Vector3d &local_point) const
299{
300 // Transform a point from the local coordinate frame to the global frame
301 // This applies the rotation and then the translation
302 return position_ + orientation_ * local_point;
303}
304
305Eigen::Vector3d Pose::globalToLocal(const Eigen::Vector3d &global_point) const
306{
307 // Transform a point from the global coordinate frame to the local frame
308 // This applies the inverse transformation (first translate, then rotate)
309 return orientation_.conjugate() * (global_point - position_);
310}
311} // namespace MoveG
Class representing a pose in 3D space.
Definition pose_lib.h:35
Eigen::Vector3d globalToLocal(const Eigen::Vector3d &global_point) const
Transforms a point from the global frame to the pose's local frame.
Definition pose_lib.cpp:305
double getQw() const
Gets the W component of the quaternion.
Definition pose_lib.cpp:165
double getQz() const
Gets the Z component of the quaternion.
Definition pose_lib.cpp:160
double getY() const
Gets the Y coordinate of the position.
Definition pose_lib.cpp:140
double getQy() const
Gets the Y component of the quaternion.
Definition pose_lib.cpp:155
Eigen::Quaterniond orientation_
Orientation represented as quaternion.
Definition pose_lib.h:314
double positionDistance(const Pose &other) const
Calculates the Euclidean distance between the positions of two poses.
Definition pose_lib.cpp:206
void setOrientation(const Eigen::Quaterniond &orientation)
Sets the orientation via quaternion.
Definition pose_lib.cpp:177
double getX() const
Gets the X coordinate of the position.
Definition pose_lib.cpp:135
Pose transformPose(const Pose &transform) const
Transforms this pose from one coordinate frame to another.
Definition pose_lib.cpp:291
Eigen::Vector3d getPosition() const
Gets the position.
Definition pose_lib.cpp:102
void setAffineTransformation(const Eigen::Affine3d &transformation)
Sets the affine transformation.
Definition pose_lib.cpp:187
Eigen::Vector3d position_
Position in 3D space.
Definition pose_lib.h:313
Pose() noexcept
Default constructor.
Definition pose_lib.cpp:14
void setRotationMatrix(const Eigen::Matrix3d &rotation_matrix)
Sets the rotation matrix.
Definition pose_lib.cpp:182
Eigen::Affine3d getAffineTransformation() const
Gets the affine transformation.
Definition pose_lib.cpp:117
Eigen::Vector3d localToGlobal(const Eigen::Vector3d &local_point) const
Transforms a point from the pose's local frame to the global frame.
Definition pose_lib.cpp:298
Pose & operator=(const Pose &other)
Copy assignment operator.
Definition pose_lib.cpp:79
void setPosition(const Eigen::Vector3d &position)
Sets the position.
Definition pose_lib.cpp:172
static void validateHomogeneousMatrix(const Eigen::Matrix4d &homogeneousT)
Validates a homogeneous transformation matrix.
Definition pose_lib.cpp:237
double getQx() const
Gets the X component of the quaternion.
Definition pose_lib.cpp:150
void setHomogeneousT(const Eigen::Matrix4d &homogeneousT)
Sets the homogeneous transformation matrix.
Definition pose_lib.cpp:193
~Pose()
Destructor.
Definition pose_lib.cpp:62
Pose inverse() const
Calculates the inverse of the pose.
Definition pose_lib.cpp:229
Eigen::Quaterniond getQuaternion() const
Gets the orientation quaternion.
Definition pose_lib.cpp:107
double getZ() const
Gets the Z coordinate of the position.
Definition pose_lib.cpp:145
double orientationDistance(const Pose &other) const
Calculates the angular distance between the orientations of two poses.
Definition pose_lib.cpp:211
Pose operator*(const Pose &other) const
Composition of two poses.
Definition pose_lib.cpp:221
Eigen::Matrix3d getRotationMatrix() const
Gets the rotation matrix.
Definition pose_lib.cpp:112
Eigen::Matrix4d getHomogeneousT() const
Gets the homogeneous transformation matrix.
Definition pose_lib.cpp:125
Class for representing and managing rotations in three-dimensional space.
Namespace for movement and manipulation of poses.
Definition pose_lib.cpp:12
std::ostream & operator<<(std::ostream &os, const Pose &pose)
Definition pose_lib.cpp:281
Class for representing Poses.