Autonomy Software C++ 24.5.1
Welcome to the Autonomy Software repository of the Mars Rover Design Team (MRDT) at Missouri University of Science and Technology (Missouri S&T)! API reference contains the source code and other resources for the development of the autonomy software for our Mars rover. The Autonomy Software project aims to compete in the University Rover Challenge (URC) by demonstrating advanced autonomous capabilities and robust navigation algorithms.
Loading...
Searching...
No Matches
NumberOperations.hpp
Go to the documentation of this file.
1
12#ifndef NUMBER_OPERATIONS_HPP
13#define NUMBER_OPERATIONS_HPP
14
16#include <algorithm>
17#include <cmath>
18#include <iostream>
19
21
22
30namespace numops
31{
32
40 template<typename T>
42 {
43 public:
44 // Declare public struct member variables.
45 T tX;
46 T tY;
47 T tZ;
48
49
59 CoordinatePoint(const T tX = 0.0, const T tY = 0.0, const T tZ = 0.0)
60 {
61 // Initialize member variables.
62 this->tX = tX;
63 this->tY = tY;
64 this->tZ = tZ;
65 }
66 };
67
68
80 template<typename T>
81 inline constexpr T Clamp(T tValue, T tMin, T tMax)
82
83 {
84 return std::max(std::min(tMax, tValue), tMin);
85 }
86
87
100 template<typename T>
101 inline bool Bounded(T tValue, T tMin, T tMax, const bool bInclusive = true)
102 {
103 // Check if value is inclusive or not.
104 if (bInclusive)
105 {
106 // Return true if the given value is valid.
107 return (tValue >= tMin) && (tValue <= tMax);
108 }
109 else
110 {
111 // Return true if the given value is valid.
112 return (tValue > tMin) && (tValue < tMax);
113 }
114 }
115
116
130 template<typename T>
131 inline constexpr T MapRange(const T tValue, const T tOldMinimum, const T tOldMaximum, const T tNewMinimum, const T tNewMaximum)
132 {
133 // Check if the ranges are valid.
134 if (tOldMinimum == tOldMaximum || tNewMinimum == tNewMaximum)
135 {
136 // Submit logger message.
137 std::cerr << "MAPRANGE: The old/new range is not valid." << std::endl;
138
139 // Return old, given value.
140 return tValue;
141 }
142
143 // Perform the mapping using linear interpolation.
144 T tOldValueRange = tOldMaximum - tOldMinimum;
145 T tNewValueRange = tNewMaximum - tNewMinimum;
146 T tScaledValue = (tValue - tOldMinimum) / tOldValueRange;
147
148 // Return new mapped value.
149 return tNewMinimum + tScaledValue * tNewValueRange;
150 }
151
152
164 template<typename T>
165 inline constexpr T InputAngleModulus(T tValue, T tMinValue, T tMaxValue)
166 {
167 // Determine the correct modulus number.
168 T tModulus = tMaxValue - tMinValue;
169
170 // Wrap input if it's above the maximum input.
171 int nNumMax = (tValue - tMinValue) / tModulus;
172 tValue -= nNumMax * tModulus;
173 // Wrap input if it's below the minimum input.
174 int nNumMin = (tValue - tMaxValue) / tModulus;
175 tValue -= nNumMin * tModulus;
176
177 // Check if the final value is the max value, set to min.
178 if (tValue == tMaxValue)
179 {
180 tValue = tMinValue;
181 }
182
183 // Return wrapped number.
184 return tValue;
185 }
186
187
203 template<typename T>
204 inline constexpr T AngularDifference(T tFirstValue, T tSecondValue)
205 {
206 // Check input.
207 if (!Bounded<T>(tFirstValue, 0, 360) && !Bounded<T>(tSecondValue, 0, 360))
208 {
209 // Submit logger message.
210 std::cerr << "ANGULARDIFFERENCE: An input value is not valid must be between 0-360. The result difference will not be accurate!" << std::endl;
211 }
212
213 // Find absolute difference between the two values.
214 T tDifference = std::abs(tFirstValue - tSecondValue);
215 // If greater than 180 degrees, subtract 360/
216 if (tDifference > 180)
217 {
218 // Wrap value.
219 tDifference -= 360;
220
221 // Check if first values is bigger than second value. If it is, flip sign so that clockwise is positive.
222 if (tFirstValue > tSecondValue)
223 {
224 tDifference *= -1;
225 }
226 }
227
228 // Return value.
229 return tDifference;
230 }
231
232
286 template<typename T>
287 inline constexpr void CoordinateFrameRotate3D(std::vector<CoordinatePoint<T>>& vPointCloud,
288 const double dXRotationDegrees,
289 const double dYRotationDegrees,
290 const double dZRotationDegrees)
291 {
292 // Convert input degrees to radians.
293 double dXRotationRadians = (dXRotationDegrees * M_PI) / 180.0;
294 double dYRotationRadians = (dYRotationDegrees * M_PI) / 180.0;
295 double dZRotationRadians = (dZRotationDegrees * M_PI) / 180.0;
296
297 // Find the cosine and sine for the X-axis rotation matrix.
298 double dCosA = cos(dXRotationRadians);
299 double dSinA = sin(dXRotationRadians);
300 // Find the cosine and sine for the Y-axis rotation matrix.
301 double dCosB = cos(dYRotationRadians);
302 double dSinB = sin(dYRotationRadians);
303 // Find the cosine and sine for the Z-axis rotation matrix.
304 double dCosC = cos(dZRotationRadians);
305 double dSinC = sin(dZRotationRadians);
306
307 // Calculate the 3D rotation matrix using matrix multiplication with proper Euler angles Z, Y, X. A = (Rz * Ry * Rx).
308 // First row of A matrix.
309 double dAXX = dCosC * dCosB;
310 double dAXY = dCosC * dSinB * dSinA - dSinC * dCosA;
311 double dAXZ = dCosC * dSinB * dCosA + dSinC * dSinA;
312 // Second row of A matrix.
313 double dAYX = dSinC * dCosB;
314 double dAYY = dSinC * dSinB * dSinA + dCosC * dCosA;
315 double dAYZ = dSinC * dSinB * dCosA - dCosC * dSinA;
316 // Third row of A matrix.
317 double dAZX = -dSinB;
318 double dAZY = dCosB * dSinA;
319 double dAZZ = dCosB * dCosA;
320
321 // Loop through each point in the given point cloud.
322 for (CoordinatePoint<T>& stPoint : vPointCloud)
323 {
324 // Rotate the points in X, Y, Z order using the rotation matrix A.
325 T tX = static_cast<T>((dAXX * stPoint.tX) + (dAXY * stPoint.tY) + (dAXZ * stPoint.tZ));
326 T tY = static_cast<T>((dAYX * stPoint.tX) + (dAYY * stPoint.tY) + (dAYZ * stPoint.tZ));
327 T tZ = static_cast<T>((dAZX * stPoint.tX) + (dAZY * stPoint.tY) + (dAZZ * stPoint.tZ));
328 // Update point cloud.
329 stPoint.tX = tX;
330 stPoint.tY = tY;
331 stPoint.tZ = tZ;
332 }
333 }
334} // namespace numops
335#endif
__device__ __forceinline__ float1 cos(const uchar1 &a)
__device__ __forceinline__ float4 sin(const uchar4 &a)
Namespace containing functions related to operations on numbers and other datatypes.
Definition NumberOperations.hpp:31
constexpr T Clamp(T tValue, T tMin, T tMax)
Clamps a given value from going above or below a given threshold.
Definition NumberOperations.hpp:81
constexpr T InputAngleModulus(T tValue, T tMinValue, T tMaxValue)
Calculates the modulus of an input angle.
Definition NumberOperations.hpp:165
constexpr void CoordinateFrameRotate3D(std::vector< CoordinatePoint< T > > &vPointCloud, const double dXRotationDegrees, const double dYRotationDegrees, const double dZRotationDegrees)
This method will rotate a list of 3D coordinate points a variable amount of degrees around the X,...
Definition NumberOperations.hpp:287
constexpr T AngularDifference(T tFirstValue, T tSecondValue)
Calculates the distance in degrees between two angles. This function accounts for wrap around so that...
Definition NumberOperations.hpp:204
constexpr T MapRange(const T tValue, const T tOldMinimum, const T tOldMaximum, const T tNewMinimum, const T tNewMaximum)
Maps a value to a new range given the old range.
Definition NumberOperations.hpp:131
bool Bounded(T tValue, T tMin, T tMax, const bool bInclusive=true)
Checks if a given value is between the given maximum and minimum ranges.
Definition NumberOperations.hpp:101
This struct represents a point in a 3D coordinate system.
Definition NumberOperations.hpp:42
CoordinatePoint(const T tX=0.0, const T tY=0.0, const T tZ=0.0)
Construct a new Coordinate Point object.
Definition NumberOperations.hpp:59