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
searchpattern Namespace Reference

Namespace containing algorithms related to calculating drive powers, odometry, trajectories, kinematics, etc of search pattern. More...

Functions

std::vector< geoops::Waypoint > CalculateSpiralPatternWaypoints (const geoops::Waypoint &stStartingPoint, const double dAngularStepDegrees=57, const double dMaxRadius=25, const double dStartingHeadingDegrees=0, const double dStartSpacing=1)
 Perform a spiral search pattern starting from a given point.
 
std::vector< geoops::Waypoint > CalculateZigZagPatternWaypoints (const geoops::Waypoint &stCenterPoint, const double dWidth=20.0, const double dHeight=20.0, const double dSpacing=1.0, const bool bVertical=true)
 Calculate waypoints for a zigzag pattern. This function generates waypoints for a zigzag pattern starting from a given point with configurable width, height, and spacing. The direction of the zigzag pattern (vertical or horizontal) can be specified.
 
std::vector< geoops::Waypoint > CalculateSnakeSearchPattern (const geoops::Waypoint &stStartCoord, const double dWidth=20.0, const double dHeight=20.0, const double dSpacing=1.0, const int nNumberOfSlithers=1.0, const bool bVertical=true)
 Calculate waypoints for a snake search pattern.
 

Detailed Description

Namespace containing algorithms related to calculating drive powers, odometry, trajectories, kinematics, etc of search pattern.

Author
Jacob V (jpvf2.nosp@m.d@um.nosp@m.syste.nosp@m.m.ed.nosp@m.u)
Date
2024-02-04

Function Documentation

◆ CalculateSpiralPatternWaypoints()

std::vector< geoops::Waypoint > searchpattern::CalculateSpiralPatternWaypoints ( const geoops::Waypoint &  stStartingPoint,
const double  dAngularStepDegrees = 57,
const double  dMaxRadius = 25,
const double  dStartingHeadingDegrees = 0,
const double  dStartSpacing = 1 
)
inline

Perform a spiral search pattern starting from a given point.

Parameters
stStartingPoint- The coordinate of the starting point of the search.
dAngularStepDegrees- The amount the angle is incremented in each iteration of the loop (degrees).
dMaxRadius- The maximum radius to cover in the search (meters).
dStartingHeadingDegrees- The angle the rover is facing at the start of the search (degrees).
dStartSpacing- The spacing between successive points in the spiral (meters). This will become larger as the spiral grows.
Returns
vWaypoints - A vector representing the waypoints forming the spiral search pattern.
Author
Jacob V (jpvf2.nosp@m.d@um.nosp@m.syste.nosp@m.m.ed.nosp@m.u)
Date
2024-02-04
54 {
55 // Define variables.
56 std::vector<geoops::Waypoint> vWaypoints;
57 double dAngularStepRadians = dAngularStepDegrees * M_PI / 180;
58 double dAngleRadians = (-dStartingHeadingDegrees) * M_PI / 180.0;
59 double dCurrentSpacingWindUp = 0.0;
60 double dStartingX = stStartingPoint.GetUTMCoordinate().dEasting;
61 double dStartingY = stStartingPoint.GetUTMCoordinate().dNorthing;
62 double dCurrentRadius = 0.0;
63
64 // Check if the MaxRadius is less than 1 meter. If so return an empty vector.
65 if (dMaxRadius < 1)
66 {
67 // Submit logger message.
68 LOG_WARNING(logging::g_qSharedLogger, "MaxRadius is less than 1 meter. Cannot create spiral pattern.");
69 return vWaypoints;
70 }
71
72 // Calculate each waypoint. Stop when the radius exceeds the maximum.
73 while (dCurrentRadius <= dMaxRadius)
74 {
75 // Get X and Y positions for the current point.
76 double dCurrentX = dStartingX + dCurrentSpacingWindUp * cos(dAngleRadians);
77 double dCurrentY = dStartingY + dCurrentSpacingWindUp * sin(dAngleRadians);
78
79 // Add the current waypoint to the final vector.
80 geoops::UTMCoordinate stCurrentCoordinate = stStartingPoint.GetUTMCoordinate();
81 stCurrentCoordinate.dEasting = dCurrentX;
82 stCurrentCoordinate.dNorthing = dCurrentY;
83 vWaypoints.emplace_back(stCurrentCoordinate, geoops::WaypointType::eNavigationWaypoint);
84
85 // Increment angle and radius for the next waypoint.
86 dAngleRadians += dAngularStepRadians;
87 dCurrentSpacingWindUp += dStartSpacing;
88
89 // Calculate the current distance from the starting point. This is our radius.
90 dCurrentRadius = geoops::CalculateGeoMeasurement(stStartingPoint.GetUTMCoordinate(), stCurrentCoordinate).dDistanceMeters;
91 }
92 // Same but going back in.
93 while (dCurrentRadius >= 0.5 && dCurrentSpacingWindUp > 0.0)
94 {
95 // Get X and Y positions for the current point.
96 double dCurrentX = dStartingX + dCurrentSpacingWindUp * cos(dAngleRadians);
97 double dCurrentY = dStartingY + dCurrentSpacingWindUp * sin(dAngleRadians);
98
99 // Add the current waypoint to the final vector.
100 geoops::UTMCoordinate stCurrentCoordinate = stStartingPoint.GetUTMCoordinate();
101 stCurrentCoordinate.dEasting = dCurrentX;
102 stCurrentCoordinate.dNorthing = dCurrentY;
103 vWaypoints.emplace_back(stCurrentCoordinate, geoops::WaypointType::eNavigationWaypoint);
104
105 // Increment angle and radius for the next waypoint.
106 dAngleRadians += dAngularStepRadians;
107 dCurrentSpacingWindUp -= dStartSpacing;
108
109 // Calculate the current distance from the starting point. This is our radius.
110 dCurrentRadius = geoops::CalculateGeoMeasurement(stStartingPoint.GetUTMCoordinate(), stCurrentCoordinate).dDistanceMeters;
111 }
112
113 // Write the search pattern points to the logger, just store the GPS lat/long.
114 std::string szSearchPatternPoints = "Search Pattern Points (Spiral): ";
115 for (geoops::Waypoint& stWaypoint : vWaypoints)
116 {
117 szSearchPatternPoints +=
118 "(" + std::to_string(stWaypoint.GetGPSCoordinate().dLatitude) + ", " + std::to_string(stWaypoint.GetGPSCoordinate().dLongitude) + "), ";
119 }
120 // Submit logger message.
121 LOG_DEBUG(logging::g_qSharedLogger, "{}", szSearchPatternPoints);
122
123 return vWaypoints;
124 }
__device__ __forceinline__ float1 cos(const uchar1 &a)
__device__ __forceinline__ float4 sin(const uchar4 &a)
GeoMeasurement CalculateGeoMeasurement(const GPSCoordinate &stCoord1, const GPSCoordinate &stCoord2)
The shortest path between two points on an ellipsoid at (lat1, lon1) and (lat2, lon2) is called the g...
Definition GeospatialOperations.hpp:553
This struct stores/contains information about a UTM coordinate.
Definition GeospatialOperations.hpp:211
This struct is used by the WaypointHandler class to store location, size, and type information about ...
Definition GeospatialOperations.hpp:423
const geoops::UTMCoordinate & GetUTMCoordinate() const
Accessor for the geoops::UTMCoordinate member variable.
Definition GeospatialOperations.hpp:508
Here is the call graph for this function:
Here is the caller graph for this function:

◆ CalculateZigZagPatternWaypoints()

std::vector< geoops::Waypoint > searchpattern::CalculateZigZagPatternWaypoints ( const geoops::Waypoint &  stCenterPoint,
const double  dWidth = 20.0,
const double  dHeight = 20.0,
const double  dSpacing = 1.0,
const bool  bVertical = true 
)
inline

Calculate waypoints for a zigzag pattern. This function generates waypoints for a zigzag pattern starting from a given point with configurable width, height, and spacing. The direction of the zigzag pattern (vertical or horizontal) can be specified.

Parameters
stCenterPoint- The center point of the zigzag pattern.
dWidth- The width of the zigzag pattern in meters.
dHeight- The height of the zigzag pattern in meters.
dSpacing- The spacing between successive points in the zigzag pattern in meters.
bVertical- Indicates whether or not the zigzag pattern is vertical or horizontal.
Returns
std::vector<geoops::Waypoint> - A vector representing the waypoints forming the zigzag search pattern.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-04-01
148 {
149 // Create instance variables.
150 std::vector<geoops::Waypoint> vWaypoints;
151 double dStartingX = stCenterPoint.GetUTMCoordinate().dEasting - (dWidth / 2);
152 double dStartingY = stCenterPoint.GetUTMCoordinate().dNorthing - (dHeight / 2);
153 double dCurrentX = dStartingX;
154 double dCurrentY = dStartingY;
155 bool bZigNotZag = true;
156 double bCalcSpacing = dSpacing;
157
158 // Check if the width or height is less than 1 meter. If so return an empty vector.
159 if (dWidth < 1 || dHeight < 1 || dSpacing < 1)
160 {
161 // Submit logger message.
162 LOG_WARNING(logging::g_qSharedLogger, "Width or height or spacing is less than 1 meter. Cannot create zigzag pattern.");
163 return vWaypoints;
164 }
165
166 // Limit spacing to the width or height.
167 if (bCalcSpacing > dWidth / 2.0)
168 {
169 // Submit logger message.
170 LOG_WARNING(logging::g_qSharedLogger, "Spacing is greater than width. Setting spacing to width / 2.");
171 // Set spacing to half the width.
172 bCalcSpacing = dWidth / 2.0 - 1.0;
173 }
174 if (bCalcSpacing > dHeight / 2.0)
175 {
176 // Submit logger message.
177 LOG_WARNING(logging::g_qSharedLogger, "Spacing is greater than height. Setting spacing to height / 2.");
178 // Set spacing to half the height.
179 bCalcSpacing = dHeight / 2.0 - 1.0;
180 }
181
182 // Loop until covered entire space of width and height.
183 while ((bVertical && dCurrentY <= dStartingY + dHeight) || (!bVertical && dCurrentX <= dStartingX + dWidth))
184 {
185 // Check if pattern should be vertical or horizontal.
186 if (bVertical)
187 {
188 // Check step direction.
189 if (bZigNotZag)
190 {
191 // Zig.
192 dCurrentX = dStartingX + bCalcSpacing;
193 }
194 else
195 {
196 // Zag.
197 dCurrentX = dStartingX - bCalcSpacing;
198 }
199 }
200 else
201 {
202 // Check step direction.
203 if (bZigNotZag)
204 {
205 // Zig.
206 dCurrentY = dStartingY + bCalcSpacing;
207 }
208 else
209 {
210 // Zag.
211 dCurrentY = dStartingY - bCalcSpacing;
212 }
213 }
214
215 // Loop and add points along line until we reached the limit or width or height.
216 while ((bZigNotZag && bVertical && dCurrentX <= dStartingX + dWidth) || (!bZigNotZag && bVertical && dCurrentX >= dStartingX) ||
217 (bZigNotZag && !bVertical && dCurrentY <= dStartingY + dHeight) || (!bZigNotZag && !bVertical && dCurrentY >= dStartingY))
218 {
219 // Construct UTMCoordinate.
220 geoops::UTMCoordinate stCurrentCoordinate = stCenterPoint.GetUTMCoordinate();
221 stCurrentCoordinate.dEasting = dCurrentX;
222 stCurrentCoordinate.dNorthing = dCurrentY;
223 geoops::Waypoint stCurrentWaypoint(stCurrentCoordinate, geoops::WaypointType::eNavigationWaypoint);
224 // Add current waypoint to final path.
225 vWaypoints.push_back(stCurrentWaypoint);
226
227 // Move to the next point based on spacing and direction.
228 if (bVertical)
229 {
230 // Increment current position.
231 dCurrentX += bZigNotZag ? bCalcSpacing : -bCalcSpacing;
232 }
233 else
234 {
235 // Increment current position.
236 dCurrentY += bZigNotZag ? bCalcSpacing : -bCalcSpacing;
237 }
238 }
239
240 // Now shift the opposite coordinate forward.
241 if (bVertical)
242 {
243 dCurrentY += bCalcSpacing;
244 }
245 else
246 {
247 dCurrentX += bCalcSpacing;
248 }
249
250 // Toggle zigzag direction.
251 bZigNotZag = !bZigNotZag;
252 }
253
254 // The path now contains the zigzag pattern with points spaced at the specified distance. This means that there
255 // are many points potentially very close to each other. This is not ideal for navigation, so we will filter out
256 // points that are too close to each other, by calculating their GeoMeasurement and testing if the distance is greater
257 // then the CalcSpacing. If the CalcSpacing is greater a certain threshold, we will remove the point since it jumps to the other side.
258 // This will reduce the number of points in the zigzag pattern, making it more efficient for navigation.
259
260 // Create a vector to store the filtered waypoints.
261 std::vector<geoops::Waypoint> vFilterWaypoints;
262 // Always store the first point.
263 vFilterWaypoints.push_back(vWaypoints[0]);
264 // Loop through the waypoints and remove any that are too close to each other.
265 for (size_t i = 0; i < vWaypoints.size() - 1; ++i)
266 {
267 // Calculate the GeoMeasurement between the current waypoint and the next waypoint.
268 geoops::GeoMeasurement stGeoMeasurement = geoops::CalculateGeoMeasurement(vWaypoints[i].GetGPSCoordinate(), vWaypoints[i + 1].GetGPSCoordinate());
269 if (stGeoMeasurement.dDistanceMeters > bCalcSpacing * 1.5)
270 {
271 // Add the points to the filtered waypoints.
272 vFilterWaypoints.push_back(vWaypoints[i]);
273 vFilterWaypoints.push_back(vWaypoints[i + 1]);
274 }
275 }
276
277 // Write the search pattern points to the logger, just store the GPS lat/long.
278 std::string szSearchPatternPoints = "Search Pattern Points (Spiral): ";
279 for (geoops::Waypoint& stWaypoint : vWaypoints)
280 {
281 szSearchPatternPoints +=
282 "(" + std::to_string(stWaypoint.GetGPSCoordinate().dLatitude) + ", " + std::to_string(stWaypoint.GetGPSCoordinate().dLongitude) + "), ";
283 }
284 // Submit logger message.
285 LOG_DEBUG(logging::g_qSharedLogger, "{}", szSearchPatternPoints);
286
287 // Return the final path.
288 return vFilterWaypoints;
289 }
This struct is used to store the distance, arc length, and relative bearing for a calculated geodesic...
Definition GeospatialOperations.hpp:83
Here is the call graph for this function:
Here is the caller graph for this function:

◆ CalculateSnakeSearchPattern()

std::vector< geoops::Waypoint > searchpattern::CalculateSnakeSearchPattern ( const geoops::Waypoint &  stStartCoord,
const double  dWidth = 20.0,
const double  dHeight = 20.0,
const double  dSpacing = 1.0,
const int  nNumberOfSlithers = 1.0,
const bool  bVertical = true 
)
inline

Calculate waypoints for a snake search pattern.

Parameters
stStartCoord- The starting coordinate of the search pattern.
dWidth- The width of the search pattern in meters.
dHeight- The height of the search pattern in meters.
dSpacing- The spacing between successive points in the search pattern in meters.
nNumberOfSlithers- The number of slithers in the snake pattern.
bVertical- Indicates whether the search pattern is vertical or horizontal.
Returns
std::vector<geoops::Waypoint> - A vector representing the waypoints forming the snake
Author
Vexas5266 (wd.gr.nosp@m.ove2.nosp@m.@gmai.nosp@m.l.co.nosp@m.m)
Date
2025-04-09
311 {
312 // Create instance variables.
313 std::vector<geoops::Waypoint> vWaypoints;
314 geoops::UTMCoordinate stStartUTM = stStartCoord.GetUTMCoordinate();
315 double dStartingX = (bVertical) ? stStartUTM.dEasting : stStartUTM.dEasting - (dWidth / 2);
316 double dStartingY = (bVertical) ? stStartUTM.dNorthing - (dHeight / 2) : stStartUTM.dNorthing;
317
318 // Check if the dimensions are valid.
319 if (dWidth < 1.0 || dHeight < 1.0 || dSpacing < 0.1 || nNumberOfSlithers < 1)
320 {
321 // Submit logger message.
322 LOG_WARNING(logging::g_qSharedLogger,
323 "Invalid parameters for snake pattern: width={}, height={}, spacing={}, number of slithers={}",
324 dWidth,
325 dHeight,
326 dSpacing,
327 nNumberOfSlithers);
328 return vWaypoints;
329 }
330
331 // Calculate the number of points based on path length and spacing and the number of slithers.
332 // For a sine wave, we need enough points to make it smooth.
333 int nPoints = static_cast<int>(dWidth + dHeight / dSpacing);
334
335 // Generate the sine wave pattern.
336 for (int nIter = 0; nIter < nPoints; ++nIter)
337 {
338 double dTime = static_cast<double>(nIter) / (nPoints - 1);
339 double dCurrentX, dCurrentY;
340
341 if (bVertical)
342 {
343 // Vertical primary movement: sinusoidal variation in x.
344 dCurrentY = dStartingY + dTime * dWidth;
345 // Sine wave with multiple periods.
346 dCurrentX = dStartingX + (dHeight / 2.0) * std::cos(2.0 * nNumberOfSlithers * M_PI * dTime);
347 }
348 else
349 {
350 // Horizontal primary movement: sinusoidal variation in y.
351 dCurrentX = dStartingX + dTime * dWidth;
352 // Sine wave with multiple periods.
353 dCurrentY = dStartingY + (dHeight / 2.0) * std::cos(2.0 * nNumberOfSlithers * M_PI * dTime);
354 }
355
356 // Create waypoint at current position.
357 geoops::UTMCoordinate stCurrentUTM = stStartUTM;
358 stCurrentUTM.dEasting = dCurrentX;
359 stCurrentUTM.dNorthing = dCurrentY;
360 geoops::Waypoint stCurrentWaypoint(stCurrentUTM, geoops::WaypointType::eNavigationWaypoint);
361 vWaypoints.push_back(stCurrentWaypoint);
362 }
363
364 // Log the waypoints.
365 std::string szSearchPatternPoints = "Search Pattern Points (Snake): ";
366 for (const geoops::Waypoint& stWaypoint : vWaypoints)
367 {
368 szSearchPatternPoints +=
369 "(" + std::to_string(stWaypoint.GetGPSCoordinate().dLatitude) + ", " + std::to_string(stWaypoint.GetGPSCoordinate().dLongitude) + "), ";
370 }
371 LOG_DEBUG(logging::g_qSharedLogger, "{}", szSearchPatternPoints);
372
373 return vWaypoints;
374 }
Here is the call graph for this function:
Here is the caller graph for this function: