TinyRobotics
Loading...
Searching...
No Matches
Angle.h
1#pragma once
2#include <cmath>
3
4namespace tinyrobotics {
5
6/**
7 * @enum AngleUnit
8 * @ingroup units
9 * @brief Supported angle units for conversion and representation.
10 */
11enum class AngleUnit { DEG, RAD };
12
13/**
14 * @class Angle
15 * @ingroup units
16 * @brief Represents an angle with unit conversion and wrap-around support.
17 *
18 * The Angle class encapsulates an angle value and its unit, supporting degrees
19 * (DEG) and radians (RAD). It provides methods to set and retrieve the angle in
20 * any supported unit, automatically handling conversions and wrap-around
21 * (0-360° or 0-2π rad).
22 *
23 * - Internal state is always consistent with the last set value and unit.
24 * - Designed for embedded and robotics applications where unit flexibility and
25 * efficiency are required.
26 * - Supports addition and subtraction with automatic wrap-around.
27 * - Use getValue() to retrieve the angle in any unit; use setValue() to update
28 * the value and unit.
29 *
30 * Example:
31 * @code
32 * Angle a(90.0, AngleUnit::DEG);
33 * float rad = a.getValue(AngleUnit::RAD); // Convert to radians
34 * a.add(Angle(45.0, AngleUnit::DEG)); // Add 45 degrees
35 * Angle b = a - Angle(180.0, AngleUnit::DEG); // Subtract 180 degrees
36 * @endcode
37 *
38 * @note Invalid conversions return -1.0f.
39 *
40 * @see AngleUnit
41 */
42class Angle {
43 public:
44 Angle() = default;
45 Angle(float angle, AngleUnit unit) { setValue(angle, unit); }
46
47 void setValue(float newAngle, AngleUnit newUnit) {
48 angle = newAngle;
49 unit = newUnit;
50 normalize();
51 }
52
53 float getValue(AngleUnit desiredUnit) const {
54 if (unit == desiredUnit) return angle;
55 switch (unit) {
56 case AngleUnit::DEG:
57 if (desiredUnit == AngleUnit::RAD) return angle * (float)M_PI / 180.0f;
58 break;
59 case AngleUnit::RAD:
60 if (desiredUnit == AngleUnit::DEG) return angle * 180.0f / (float)M_PI;
61 break;
62 }
63 return -1; // Invalid conversion
64 }
65
66 Angle operator*(float scalar) const { return Angle(angle * scalar, unit); }
67
68 Angle operator/(float scalar) const {
69 if (scalar == 0) return Angle(0, unit);
70 return Angle(angle / scalar, unit);
71 }
72
73 bool operator==(const Angle& other) const {
74 return angle == other.getValue(unit);
75 }
76
77 bool operator!=(const Angle& other) const { return !(*this == other); }
78
79 bool operator<(const Angle& other) const {
80 return angle < other.getValue(unit);
81 }
82
83 bool operator<=(const Angle& other) const {
84 return angle <= other.getValue(unit);
85 }
86
87 bool operator>(const Angle& other) const {
88 return angle > other.getValue(unit);
89 }
90
91 bool operator>=(const Angle& other) const {
92 return angle >= other.getValue(unit);
93 }
94
95 Angle& operator*=(float scalar) {
96 angle *= scalar;
97 normalize();
98 return *this;
99 }
100
101 Angle& operator/=(float scalar) {
102 if (scalar == 0) {
103 angle = 0;
104 } else {
105 angle /= scalar;
106 }
107 normalize();
108 return *this;
109 }
110
111 protected:
112 float angle = 0.0f;
113 AngleUnit unit = AngleUnit::DEG;
114
115 inline void normalize() {
116 switch (unit) {
117 case AngleUnit::DEG:
118 angle = normalizeAngleDeg(angle);
119 break;
120 case AngleUnit::RAD:
121 angle = normalizeAngleRad(angle);
122 break;
123 }
124 }
125
126 void add(Angle other) {
127 float otherAngle = other.getValue(unit);
128 angle += otherAngle;
129 normalize();
130 }
131
132 void subtract(Angle other) {
133 float otherAngle = other.getValue(unit);
134 angle -= otherAngle;
135 normalize();
136 }
137};
138
139} // namespace tinyrobotics
Represents an angle with unit conversion and wrap-around support.
Definition: Angle.h:42
AngleUnit
Supported angle units for conversion and representation.
Definition: Angle.h:11