RIT VEXU Core API
Loading...
Searching...
No Matches
pose2d.h
1#pragma once
2
3#include <vector>
4
5#include "cevalm.hpp"
6#include "core/math/geometry/rotation2d.h"
7#include "core/math/geometry/transform2d.h"
8#include "core/math/geometry/translation2d.h"
9#include "core/math/geometry/twist2d.h"
10#include "core/math/units.h"
11
21class Pose2d {
22 private:
23 Translation2d translation_;
24 Rotation2d rotation_;
25
26 public:
28 constexpr Pose2d() : translation_{Translation2d()}, rotation_{Rotation2d()} {}
29
36 constexpr Pose2d(Translation2d translation, Rotation2d rotation)
37 : translation_{translation}, rotation_{rotation} {}
38
46 constexpr Pose2d(units::Length x, units::Length y, Rotation2d rotation)
47 : translation_{x, y}, rotation_{rotation} {}
48
56 constexpr Pose2d(units::Length x, units::Length y, double radians)
57 : translation_{x, y}, rotation_{radians} {}
58
67 constexpr Pose2d(
68 const Eigen::Vector3d& pose_vector, units::Length length_unit,
69 units::Angle angle_unit = units::radians
70 )
71 : translation_{
72 units::Length(pose_vector[0], length_unit),
73 units::Length(pose_vector[1], length_unit)
74 },
75 rotation_{units::Angle(pose_vector[2], angle_unit)} {}
76
78 constexpr units::Length x() const { return translation_.x(); }
79
81 constexpr double x(units::Length unit) const { return translation_.x(unit); }
82
84 constexpr void set_x(units::Length val) { translation_.set_x(val); }
85
87 constexpr units::Length y() const { return translation_.y(); }
88
90 constexpr double y(units::Length unit) const { return translation_.y(unit); }
91
93 constexpr void set_y(units::Length val) { translation_.set_y(val); }
94
96 constexpr Translation2d translation() const { return translation_; }
97
99 constexpr void set_translation(Translation2d val) { translation_ = val; }
100
102 constexpr Rotation2d rotation() const { return rotation_; }
103
105 constexpr void set_rotation(Rotation2d val) { rotation_ = val; }
106
108 constexpr units::Angle angle() const { return rotation_.angle(); }
109
111 constexpr double angle(units::Angle unit) const { return rotation_.angle(unit); }
112
114 constexpr void set_angle(units::Angle val) { rotation_ = Rotation2d(val); }
115
117 EVec<3> as_vector(units::Length length_unit, units::Angle angle_unit = units::radians) const {
118 return {translation_.x().to(length_unit), translation_.y().to(length_unit),
119 rotation_.angle().to(angle_unit)};
120 }
121
123 constexpr units::Length distance(Translation2d point) const {
124 return translation_.distance(point);
125 }
126
128 constexpr units::Length distance(const Pose2d& other) const {
129 return distance(other.translation_);
130 }
131
133 constexpr Rotation2d bearing_to(Translation2d point) const {
134 const auto delta = point - translation_;
135 if (delta.x().internal() == 0 && delta.y().internal() == 0) {
136 return rotation_;
137 }
138 return delta.theta();
139 }
140
142 constexpr units::Angle angle_to(Translation2d point) const {
143 return (bearing_to(point) - rotation_).angle();
144 }
145
147 constexpr Translation2d local_to_world(Translation2d point) const {
148 return translation_ + point.rotate_by(rotation_);
149 }
150
152 constexpr Translation2d world_to_local(Translation2d point) const {
153 return (point - translation_).rotate_by(-rotation_);
154 }
155
162 constexpr Pose2d relative_to(const Pose2d& other) const {
163 Transform2d transform = *this - other;
164 return Pose2d{transform.translation(), transform.rotation()};
165 }
166
175 constexpr Pose2d transform_by(const Transform2d& transform) const {
176 return Pose2d{
177 translation_ + (transform.translation().rotate_by(rotation_)),
178 rotation_ + transform.rotation()
179 };
180 }
181
188 constexpr Pose2d interpolate(const Pose2d& end, double fraction) const {
189 if (fraction <= 0) {
190 return *this;
191 }
192 if (fraction >= 1) {
193 return end;
194 }
195 return {translation_ + (end.translation_ - translation_) * fraction,
196 rotation_ + (end.rotation_ - rotation_) * fraction};
197 }
198
218 constexpr Pose2d exp(const Twist2d& twist) const {
219 const units::Length dx = twist.dx();
220 const units::Length dy = twist.dy();
221 const double dtheta = twist.dtheta().to(units::radians);
222
223 const double sin_theta = cevalm::sin(dtheta);
224 const double cos_theta = cevalm::cos(dtheta);
225
226 double s, c;
227 if (cevalm::abs(dtheta) < 1e-9) {
228 s = 1.0 - 1.0 / 6.0 * dtheta * dtheta;
229 c = 0.5 * dtheta;
230 } else {
231 s = sin_theta / dtheta;
232 c = (1 - cos_theta) / dtheta;
233 }
234
235 const Transform2d transform{
236 Translation2d{dx * s - dy * c, dx * c + dy * s}, Rotation2d{cos_theta, sin_theta}
237 };
238
239 return *this + transform;
240 }
241
250 constexpr Twist2d log(const Transform2d& transform) const {
251 const double dtheta = transform.rotation().radians();
252 const double half_dtheta = dtheta / 2.0;
253
254 const double cos_minus_one = transform.rotation().f_cos() - 1;
255
256 double half_theta_by_tan_of_half_dtheta;
257
258 if (cevalm::abs(cos_minus_one) < 1e-9) {
259 half_theta_by_tan_of_half_dtheta = 1.0 - 1.0 / 12.0 * dtheta * dtheta;
260 } else {
261 half_theta_by_tan_of_half_dtheta =
262 -(half_dtheta * transform.rotation().f_sin()) / cos_minus_one;
263 }
264
265 const Translation2d translation_part =
266 transform.translation().rotate_by(
267 {half_theta_by_tan_of_half_dtheta, -half_dtheta}
268 ) *
269 cevalm::hypot(half_theta_by_tan_of_half_dtheta, half_dtheta);
270
271 return Twist2d{
272 translation_part.x(), translation_part.y(), units::Angle(dtheta, units::radians)
273 };
274 }
275
282 static Pose2d wrapped_mean(const std::vector<Pose2d>& list) {
283 if (list.size() == 0) {
284 return Pose2d{};
285 }
286
287 units::Length sumx;
288 units::Length sumy;
289
290 double sum_sin = 0;
291 double sum_cos = 0;
292
293 for (Pose2d pose : list) {
294 sumx += pose.x();
295 sumy += pose.y();
296
297 sum_sin += pose.rotation_.f_sin();
298 sum_cos += pose.rotation_.f_cos();
299 }
300
301 return Pose2d{
302 Translation2d{sumx / list.size(), sumy / list.size()},
303 Rotation2d{sum_cos / list.size(), sum_sin / list.size()}
304 };
305 }
306
308 constexpr Pose2d operator+(const Transform2d& transform) const {
309 return Pose2d{
310 translation_ + (transform.translation().rotate_by(rotation_)),
311 transform.rotation() + rotation_
312 };
313 }
314
316 constexpr Pose2d& operator+=(const Transform2d& transform) { return *this = *this + transform; }
317
319 constexpr Transform2d operator-(const Pose2d& other) const {
320 return Transform2d{
321 (translation_ - other.translation_).rotate_by(-other.rotation_),
322 rotation_ - other.rotation_
323 };
324 }
325
327 constexpr bool operator==(const Pose2d& other) const {
328 return (translation_ == other.translation_) && (rotation_ == other.rotation_);
329 }
330
335 constexpr bool is_near(
336 const Pose2d& other, units::Length distance_tolerance = units::Length(1e-6),
337 units::Angle angle_tolerance = units::Angle(1e-6)
338 ) const {
339 return translation_.is_near(other.translation_, distance_tolerance) &&
340 rotation_.is_near(other.rotation_, angle_tolerance);
341 }
342};
constexpr Rotation2d theta() const
Gets the angle of the vector from the x axis.
Definition translation2d.h:83
constexpr Q x() const
Gets the x component.
Definition translation2d.h:65
constexpr LinearVector2d rotate_by(Rotation2d rotation) const
Definition translation2d.h:140
constexpr Q y() const
Gets the y component.
Definition translation2d.h:74
constexpr Pose2d & operator+=(const Transform2d &transform)
Adds a transform to this pose by rotating it into the pose frame then adding.
Definition pose2d.h:316
constexpr void set_angle(units::Angle val)
Sets the rotation as an angle.
Definition pose2d.h:114
constexpr Rotation2d rotation() const
Gets the rotation.
Definition pose2d.h:102
constexpr Pose2d exp(const Twist2d &twist) const
Definition pose2d.h:218
constexpr void set_rotation(Rotation2d val)
Sets the rotation.
Definition pose2d.h:105
constexpr units::Length distance(Translation2d point) const
Calculates the distance from the pose to another point.
Definition pose2d.h:123
constexpr Pose2d(units::Length x, units::Length y, Rotation2d rotation)
Definition pose2d.h:46
constexpr Pose2d transform_by(const Transform2d &transform) const
Definition pose2d.h:175
constexpr void set_y(units::Length val)
Sets the y value of the translation.
Definition pose2d.h:93
constexpr units::Angle angle() const
Gets the heading as an angle.
Definition pose2d.h:108
constexpr void set_x(units::Length val)
Sets the x value of the translation.
Definition pose2d.h:84
constexpr Rotation2d bearing_to(Translation2d point) const
Calculates the bearing from this to another point in the world frame.
Definition pose2d.h:133
EVec< 3 > as_vector(units::Length length_unit, units::Angle angle_unit=units::radians) const
Gets [x, y, theta] in the supplied units. Angles default to radians.
Definition pose2d.h:117
constexpr units::Length y() const
Gets the y value of the translation.
Definition pose2d.h:87
constexpr void set_translation(Translation2d val)
Sets the translation.
Definition pose2d.h:99
constexpr Pose2d(Translation2d translation, Rotation2d rotation)
Definition pose2d.h:36
constexpr Twist2d log(const Transform2d &transform) const
Definition pose2d.h:250
static Pose2d wrapped_mean(const std::vector< Pose2d > &list)
Definition pose2d.h:282
constexpr Pose2d(const Eigen::Vector3d &pose_vector, units::Length length_unit, units::Angle angle_unit=units::radians)
Definition pose2d.h:67
constexpr Pose2d interpolate(const Pose2d &end, double fraction) const
Definition pose2d.h:188
constexpr Translation2d world_to_local(Translation2d point) const
Converts a point from the world frame to this pose's local frame.
Definition pose2d.h:152
constexpr units::Length distance(const Pose2d &other) const
Calculates the distance from this to another pose, ignoring rotation.
Definition pose2d.h:128
constexpr Translation2d translation() const
Gets the translation.
Definition pose2d.h:96
constexpr Translation2d local_to_world(Translation2d point) const
Converts a point from this pose's local frame to the world frame.
Definition pose2d.h:147
constexpr double angle(units::Angle unit) const
Gets the angle in the supplied unit.
Definition pose2d.h:111
constexpr double y(units::Length unit) const
Gets y in the supplied length unit.
Definition pose2d.h:90
constexpr units::Angle angle_to(Translation2d point) const
Calculates the smallest angle to another point in the local frame.
Definition pose2d.h:142
constexpr double x(units::Length unit) const
Gets x in the supplied length unit.
Definition pose2d.h:81
constexpr Pose2d operator+(const Transform2d &transform) const
Adds a transform to this pose by rotating it into the pose frame then adding.
Definition pose2d.h:308
constexpr bool operator==(const Pose2d &other) const
Checks exact equality between this and another pose.
Definition pose2d.h:327
constexpr units::Length x() const
Gets the x value of the translation.
Definition pose2d.h:78
constexpr Transform2d operator-(const Pose2d &other) const
Subtracts another pose from this to find the transform between them.
Definition pose2d.h:319
constexpr Pose2d relative_to(const Pose2d &other) const
Definition pose2d.h:162
constexpr bool is_near(const Pose2d &other, units::Length distance_tolerance=units::Length(1e-6), units::Angle angle_tolerance=units::Angle(1e-6)) const
Definition pose2d.h:335
constexpr Pose2d()
Default Constructor for Pose2d.
Definition pose2d.h:28
constexpr Pose2d(units::Length x, units::Length y, double radians)
Definition pose2d.h:56
Definition rotation2d.h:16
constexpr double radians() const
Gets the rotation in radians.
Definition rotation2d.h:72
constexpr Rotation2d()=default
Default Constructor for Rotation2d.
constexpr double f_cos() const
Gets the cosine of the rotation.
Definition rotation2d.h:84
Definition transform2d.h:17
constexpr Translation2d translation() const
Gets the translation.
Definition transform2d.h:98
constexpr Rotation2d rotation() const
Gets the rotation.
Definition transform2d.h:104
Definition twist2d.h:20
constexpr units::Length dx() const
Gets the x displacement.
Definition twist2d.h:56
constexpr units::Length dy() const
Gets the y displacement.
Definition twist2d.h:65
constexpr units::Angle dtheta() const
Gets the Angle displacement.
Definition twist2d.h:74