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

Namespace containing all state machine related classes. More...

Classes

class  ApproachingMarkerState
 The ApproachingMarkerState class implements the Approaching Marker state for the Autonomy State Machine. More...
 
class  ApproachingObjectState
 The ApproachingObjectState class implements the Approaching Object state for the Autonomy State Machine. More...
 
class  IdleState
 The IdleState class implements the Idle state for the Autonomy State Machine. More...
 
class  NavigatingState
 The NavigatingState class implements the Navigating state for the Autonomy State Machine. More...
 
class  ReversingState
 The ReversingState class implements the Reversing state for the Autonomy State Machine. More...
 
class  SearchPatternState
 The SearchPatternState class implements the Search Pattern state for the Autonomy State Machine. More...
 
class  State
 The abstract state class. All states inherit from this class. More...
 
class  StuckState
 The StuckState class implements the Stuck state for the Autonomy State Machine. More...
 
class  TimeIntervalBasedStuckDetector
 This class should be instantiated within another state to be used for detection of if the rover is stuck. Stuck detection is solely based off of a check interval on the current velocity and rotation. If the velocity and rotation are non-moving for more then a maximum interval count, we are considered stuck. More...
 
class  VerifyingMarkerState
 The VerifyingMarkerState class implements the Verifying Marker state for the Autonomy State Machine. More...
 
class  VerifyingObjectState
 The VerifyingObjectState class implements the Verifying Object state for the Autonomy State Machine. More...
 
class  VerifyingPositionState
 The VerifyingPositionState class implements the Verifying Position state for the Autonomy State Machine. More...
 

Enumerations

enum class  States {
  eIdle , eNavigating , eSearchPattern , eApproachingMarker ,
  eApproachingObject , eVerifyingPosition , eVerifyingMarker , eVerifyingObject ,
  eReversing , eStuck , NUM_STATES
}
 The states that the state machine can be in. More...
 
enum class  Event {
  eStart , eReachedGpsCoordinate , eReachedMarker , eReachedObject ,
  eMarkerSeen , eObjectSeen , eMarkerUnseen , eObjectUnseen ,
  eVerifyingComplete , eVerifyingFailed , eAbort , eRestart ,
  eNoWaypoint , eNewWaypoint , eReverse , eReverseComplete ,
  eSearchFailed , eStuck , eUnstuck , NUM_EVENTS
}
 The events that can be triggered in the state machine. More...
 

Functions

std::string StateToString (States eState)
 Converts a state object to a string.
 
void LoadDetectedObjects (std::vector< objectdetectutils::Object > &vDetectedObjects, const std::vector< std::shared_ptr< ObjectDetector > > &vObjectDetectors)
 Aggregates all detected objects from each provided object detector.
 
int IdentifyTargetObject (const std::vector< std::shared_ptr< ObjectDetector > > &vObjectDetectors, objectdetectutils::Object &stObjectTarget, const geoops::WaypointType &eDesiredDetectionType=geoops::WaypointType::eUNKNOWN)
 Identify a target object in the rover's vision, using Torch detection.
 
void LoadDetectedTags (std::vector< tagdetectutils::ArucoTag > &vDetectedArucoTags, const std::vector< std::shared_ptr< TagDetector > > &vTagDetectors)
 Aggregates all detected tags from each provided tag detector for both OpenCV and YOLO detection.
 
int IdentifyTargetMarker (const std::vector< std::shared_ptr< TagDetector > > &vTagDetectors, tagdetectutils::ArucoTag &stArucoTarget, tagdetectutils::ArucoTag &stTorchTarget, const int nTargetTagID=static_cast< int >(manifest::Autonomy::AUTONOMYWAYPOINTTYPES::ANY))
 Identify a target marker in the rover's vision, using OpenCV detection.
 

Detailed Description

Namespace containing all state machine related classes.

Author
Eli Byrd (edbgk.nosp@m.k@ms.nosp@m.t.edu)
Date
2024-01-17
Author
Sam Hajdukiewicz (saman.nosp@m.thah.nosp@m.ajduk.nosp@m.iewi.nosp@m.cz@gm.nosp@m.ail..nosp@m.com)
Date
2024-01-17
Author
Eli Byrd (edbgk.nosp@m.k@ms.nosp@m.t.edu)
Date
2024-05-24
Author
Sam Hajdukiewicz (saman.nosp@m.thah.nosp@m.ajduk.nosp@m.iewi.nosp@m.cz@gm.nosp@m.ail..nosp@m.com)
Date
2025-05-08
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-04-23
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2025-04-04

Enumeration Type Documentation

◆ States

enum class statemachine::States
strong

The states that the state machine can be in.

Author
Eli Byrd (edbgk.nosp@m.k@ms.nosp@m.t.edu)
Date
2024-01-18
31 {
32 eIdle,
33 eNavigating,
34 eSearchPattern,
35 eApproachingMarker,
36 eApproachingObject,
37 eVerifyingPosition,
38 eVerifyingMarker,
39 eVerifyingObject,
40 eReversing,
41 eStuck,
42 NUM_STATES
43 };

◆ Event

enum class statemachine::Event
strong

The events that can be triggered in the state machine.

Author
Eli Byrd (edbgk.nosp@m.k@ms.nosp@m.t.edu)
Date
2024-01-18
52 {
53 eStart,
54 eReachedGpsCoordinate,
55 eReachedMarker,
56 eReachedObject,
57 eMarkerSeen,
58 eObjectSeen,
59 eMarkerUnseen,
60 eObjectUnseen,
61 eVerifyingComplete,
62 eVerifyingFailed,
63 eAbort,
64 eRestart,
65 eNoWaypoint,
66 eNewWaypoint,
67 eReverse,
68 eReverseComplete,
69 eSearchFailed,
70 eStuck,
71 eUnstuck,
72
73 NUM_EVENTS
74 };

Function Documentation

◆ StateToString()

std::string statemachine::StateToString ( States  eState)
inline

Converts a state object to a string.

Parameters
eState-
Returns
std::string -
Author
Eli Byrd (edbgk.nosp@m.k@ms.nosp@m.t.edu)
Date
2024-01-18
86 {
87 switch (eState)
88 {
89 case States::eIdle: return "Idle";
90 case States::eNavigating: return "Navigating";
91 case States::eSearchPattern: return "Search Pattern";
92 case States::eApproachingMarker: return "Approaching Marker";
93 case States::eApproachingObject: return "Approaching Object";
94 case States::eVerifyingPosition: return "Verifying Position";
95 case States::eVerifyingMarker: return "Verifying Marker";
96 case States::eVerifyingObject: return "Verifying Object";
97 case States::eReversing: return "Reversing";
98 case States::eStuck: return "Stuck";
99 default: return "Unknown";
100 }
101 }
Here is the caller graph for this function:

◆ LoadDetectedObjects()

void statemachine::LoadDetectedObjects ( std::vector< objectdetectutils::Object > &  vDetectedObjects,
const std::vector< std::shared_ptr< ObjectDetector > > &  vObjectDetectors 
)
inline

Aggregates all detected objects from each provided object detector.

Parameters
vDetectedObjects- Reference vector that will hold all of the aggregated detected objects.
vObjectDetectors- Vector of pointers to object detectors that will be used to request their detected objects.
Author
Sam Hajdukiewicz (saman.nosp@m.thah.nosp@m.ajduk.nosp@m.iewi.nosp@m.cz@gm.nosp@m.ail..nosp@m.com)
Date
2025-05-08
41 {
42 // Number of object detectors.
43 size_t siNumObjectDetectors = vObjectDetectors.size();
44
45 // Initialize vectors to store detected objects temporarily.
46 std::vector<std::vector<objectdetectutils::Object>> vDetectedObjectBuffers(siNumObjectDetectors);
47
48 // Initialize vectors to store detected objects futures.
49 std::vector<std::future<bool>> vDetectedObjectsFuture;
50
51 // Track exactly which cameras successfully spawned a future to prevent vector crashes.
52 std::vector<bool> vSpawnedFuture(siNumObjectDetectors, false);
53
54 // Request objects from each detector.
55 for (size_t siIdx = 0; siIdx < siNumObjectDetectors; ++siIdx)
56 {
57 // Check if this object detector is ready.
58 if (vObjectDetectors[siIdx]->GetIsReady())
59 {
60 // Request detected objects from detector.
61 vDetectedObjectsFuture.emplace_back(vObjectDetectors[siIdx]->RequestDetectedObjects(vDetectedObjectBuffers[siIdx]));
62 vSpawnedFuture[siIdx] = true;
63 }
64 }
65
66 // Ensure all requests have been fulfilled.
67 // Then transfer objects from the buffer to vDetectedObjects for the user to access.
68 int nFutureIdx = 0;
69 // Iterate through the total number of detectors to match the buffer and spawned tracking sizes.
70 for (size_t siIdx = 0; siIdx < siNumObjectDetectors; ++siIdx)
71 {
72 // Only check the buffer if the detector was ready and actually spawned a future
73 if (vSpawnedFuture[siIdx])
74 {
75 // Wait for the correct future to finish
76 vDetectedObjectsFuture[nFutureIdx].get();
77 nFutureIdx++;
78
79 // Loop through the detected objects and add them to the vDetectedObjects vector.
80 for (const objectdetectutils::Object& tObject : vDetectedObjectBuffers[siIdx])
81 {
82 vDetectedObjects.emplace_back(tObject);
83 }
84 }
85 }
86 }
Represents a single detected object.
Definition ObjectDetectionUtility.hpp:73
Here is the caller graph for this function:

◆ IdentifyTargetObject()

int statemachine::IdentifyTargetObject ( const std::vector< std::shared_ptr< ObjectDetector > > &  vObjectDetectors,
objectdetectutils::Object stObjectTarget,
const geoops::WaypointType &  eDesiredDetectionType = geoops::WaypointType::eUNKNOWN 
)
inline

Identify a target object in the rover's vision, using Torch detection.

Note
If multiple objects are detected the closest one will be chosen as the target.
Parameters
vObjectDetectors- The vector of object detectors to use for detection.
stObjectTarget- The detected object marker from Torch.
eDesiredDetectionType- The desired detection type to check for.
Returns
int - The total number of objects currently detected.
Author
Sam Hajdukiewicz (saman.nosp@m.thah.nosp@m.ajduk.nosp@m.iewi.nosp@m.cz@gm.nosp@m.ail..nosp@m.com)
Date
2025-05-09
104 {
105 // Create instance variables.
106 std::vector<objectdetectutils::Object> vDetectedObjects;
107 objectdetectutils::Object stBestObject;
108 std::string szIdentifiedObjects = "";
109
110 // Initialize best percentage to 0 so the first valid object always wins
111 double dBestAreaPercentage = 0.0;
112
113 // Get the current time
114 std::chrono::system_clock::time_point tmCurrentTime = std::chrono::system_clock::now();
115
116 // Load all detected objects in the rover's vision.
117 LoadDetectedObjects(vDetectedObjects, vObjectDetectors);
118
119 // Find the best object.
120 for (const objectdetectutils::Object& stCandidate : vDetectedObjects)
121 {
122 // Calculate the total age of the object.
123 double dObjectTotalAge = std::fabs(std::chrono::duration_cast<std::chrono::milliseconds>(tmCurrentTime - stCandidate.tmCreation).count() / 1000.0);
124
125 // Null pointer safety check for the bounding box
126 if (stCandidate.pBoundingBox == nullptr)
127 {
128 continue;
129 }
130
131 // Calculate the total object area and percentage of the screen the object takes up.
132 double dArea = stCandidate.pBoundingBox->area();
133 double dAreaPercentage = (dArea / (stCandidate.cvImageResolution.width * stCandidate.cvImageResolution.height)) * 100.0;
134
135 // Determine the desired detection type.
136 switch (eDesiredDetectionType)
137 {
138 case geoops::WaypointType::eMalletWaypoint:
139 {
140 if (stCandidate.eDetectionType != objectdetectutils::ObjectDetectionType::eMallet)
141 continue;
142 break;
143 }
144 case geoops::WaypointType::eWaterBottleWaypoint:
145 {
146 if (stCandidate.eDetectionType != objectdetectutils::ObjectDetectionType::eWaterBottle)
147 continue;
148 break;
149 }
150 case geoops::WaypointType::eRockPickWaypoint:
151 {
152 if (stCandidate.eDetectionType != objectdetectutils::ObjectDetectionType::eRockPick)
153 continue;
154 break;
155 }
156 case geoops::WaypointType::eObjectWaypoint:
157 {
158 if (stCandidate.eDetectionType != objectdetectutils::ObjectDetectionType::eMallet &&
159 stCandidate.eDetectionType != objectdetectutils::ObjectDetectionType::eWaterBottle &&
160 stCandidate.eDetectionType != objectdetectutils::ObjectDetectionType::eRockPick)
161 {
162 continue;
163 }
164 break;
165 }
166 default:
167 {
168 break;
169 }
170 }
171
172 // Check the object detection method type.
173 if (stCandidate.eDetectionMethod == objectdetectutils::ObjectDetectionMethod::eTorch)
174 {
175 // Assemble the identified objects string.
176 szIdentifiedObjects += "\tObject Class: " + stCandidate.szClassName + " Object Age: " + std::to_string(dObjectTotalAge) +
177 "s Object Screen Percentage: " + std::to_string(dAreaPercentage) + "%\n";
178
179 // Check if the object meets the threshold requirements.
180 if (dAreaPercentage < constants::BBOX_MIN_SCREEN_PERCENTAGE || dObjectTotalAge < constants::BBOX_MIN_LIFETIME_THRESHOLD)
181 {
182 continue;
183 }
184
185 // Prioritize the object that takes up the most screen area
186 if (dAreaPercentage > dBestAreaPercentage)
187 {
188 // Set the target object to the detected object.
189 stBestObject = stCandidate;
190 dBestAreaPercentage = dAreaPercentage;
191 }
192 }
193 }
194
195 // Only print the identified objects if there are any.
196 if (stBestObject.dConfidence != 0.0)
197 {
198 // Submit logger message.
199 LOG_DEBUG(logging::g_qSharedLogger, "ObjectDetectionChecker: Identified objects:\n{}", szIdentifiedObjects);
200 }
201
202 // Set the target object to the best object.
203 stObjectTarget = stBestObject;
204
205 return static_cast<int>(vDetectedObjects.size());
206 }
void LoadDetectedObjects(std::vector< objectdetectutils::Object > &vDetectedObjects, const std::vector< std::shared_ptr< ObjectDetector > > &vObjectDetectors)
Aggregates all detected objects from each provided object detector.
Definition ObjectDetectionChecker.hpp:40
Here is the call graph for this function:
Here is the caller graph for this function:

◆ LoadDetectedTags()

void statemachine::LoadDetectedTags ( std::vector< tagdetectutils::ArucoTag > &  vDetectedArucoTags,
const std::vector< std::shared_ptr< TagDetector > > &  vTagDetectors 
)
inline

Aggregates all detected tags from each provided tag detector for both OpenCV and YOLO detection.

Parameters
vDetectedArucoTags- Reference vector that will hold all of the aggregated detected Aruco tags.
vTagDetectors- Vector of pointers to tag detectors that will be used to request their detected tags.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2025-04-04
41 {
42 // Number of tag detectors.
43 size_t siNumTagDetectors = vTagDetectors.size();
44
45 // Initialize vectors to store detected tags temporarily.
46 std::vector<std::vector<tagdetectutils::ArucoTag>> vDetectedArucoTagBuffers(siNumTagDetectors);
47
48 // Initialize vectors to store detected tags futures.
49 std::vector<std::future<bool>> vDetectedArucoTagsFuture;
50
51 // Track exactly which cameras successfully spawned a future to prevent vector crashes.
52 std::vector<bool> vSpawnedFuture(siNumTagDetectors, false);
53
54 // Request tags from each detector.
55 for (size_t siIdx = 0; siIdx < siNumTagDetectors; ++siIdx)
56 {
57 // Check if this tag detector is ready.
58 if (vTagDetectors[siIdx]->GetIsReady())
59 {
60 // Request detected Aruco tags from detector.
61 vDetectedArucoTagsFuture.emplace_back(vTagDetectors[siIdx]->RequestDetectedArucoTags(vDetectedArucoTagBuffers[siIdx]));
62 vSpawnedFuture[siIdx] = true;
63 }
64 }
65
66 // Ensure all requests have been fulfilled.
67 int nFutureIdx = 0;
68 for (size_t siIdx = 0; siIdx < siNumTagDetectors; ++siIdx)
69 {
70 // Only check the buffer if the detector was ready and actually spawned a future
71 if (vSpawnedFuture[siIdx])
72 {
73 // Wait for the correct future to finish
74 vDetectedArucoTagsFuture[nFutureIdx].get();
75 nFutureIdx++;
76
77 // Loop through the detected tags using the correct buffer index (siIdx)
78 for (const tagdetectutils::ArucoTag& tTag : vDetectedArucoTagBuffers[siIdx])
79 {
80 vDetectedArucoTags.emplace_back(tTag);
81 }
82 }
83 }
84 }
Represents a single ArUco tag.
Definition TagDetectionUtilty.hpp:57
Here is the caller graph for this function:

◆ IdentifyTargetMarker()

int statemachine::IdentifyTargetMarker ( const std::vector< std::shared_ptr< TagDetector > > &  vTagDetectors,
tagdetectutils::ArucoTag stArucoTarget,
tagdetectutils::ArucoTag stTorchTarget,
const int  nTargetTagID = static_cast<int>(manifest::Autonomy::AUTONOMYWAYPOINTTYPES::ANY) 
)
inline

Identify a target marker in the rover's vision, using OpenCV detection.

Note
If multiple markers are detected the closest one will be chosen as the target.
Parameters
vTagDetectors- The vector of tag detectors to use for detection.
stArucoTarget- The detected target marker from OpenCV.
stTorchTarget- The detected target marker from Torch.
nTargetTagID- The ID of the target tag to identify. If -1, the closest tag will be chosen.
Returns
int - The total number of tags currently detected.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2025-04-04
104 {
105 // Create instance variables.
106 std::vector<tagdetectutils::ArucoTag> vDetectedArucoTags;
107 tagdetectutils::ArucoTag stArucoBestTag;
108 tagdetectutils::ArucoTag stTorchBestTag;
109 std::string szIdentifiedTags = "";
110
111 // Initialize best percentages to 0 so the first valid tag always wins
112 double dBestArucoAreaPercentage = 0.0;
113 double dBestTorchAreaPercentage = 0.0;
114
115 // Get the current time
116 std::chrono::system_clock::time_point tmCurrentTime = std::chrono::system_clock::now();
117
118 // Load all detected tags in the rover's vision.
119 LoadDetectedTags(vDetectedArucoTags, vTagDetectors);
120
121 // Find the best tag from the Aruco tags.
122 for (const tagdetectutils::ArucoTag& stCandidate : vDetectedArucoTags)
123 {
124 // Calculate the total age of the tag.
125 double dTagTotalAge = std::fabs(std::chrono::duration_cast<std::chrono::milliseconds>(tmCurrentTime - stCandidate.tmCreation).count() / 1000.0);
126
127 // Safety check for bounding box pointer
128 if (stCandidate.pBoundingBox == nullptr)
129 {
130 continue;
131 }
132
133 // Calculate what percentage of the screen the tag takes up.
134 double dArea = stCandidate.pBoundingBox->area();
135 double dAreaPercentage = (dArea / (stCandidate.cvImageResolution.width * stCandidate.cvImageResolution.height)) * 100.0;
136
137 // Check if the tag meets the minimum thresholds.
138 if (dAreaPercentage < constants::BBOX_MIN_SCREEN_PERCENTAGE || dTagTotalAge < constants::BBOX_MIN_LIFETIME_THRESHOLD)
139 {
140 continue;
141 }
142
143 // --- OpenCV Tag Logic ---
144 if (stCandidate.eDetectionMethod == tagdetectutils::TagDetectionMethod::eOpenCV)
145 {
146 szIdentifiedTags += "\tArUco ID: " + std::to_string(stCandidate.nID) + " Tag Age: " + std::to_string(dTagTotalAge) +
147 "s Tag Screen Percentage: " + std::to_string(dAreaPercentage) + "%\n";
148
149 // Ensure it matches the requested ID (or we accept ANY ID)
150 if (stCandidate.nID == nTargetTagID || nTargetTagID == static_cast<int>(manifest::Autonomy::AUTONOMYWAYPOINTTYPES::ANY))
151 {
152 // Prioritize the tag that takes up the most screen area
153 if (dAreaPercentage > dBestArucoAreaPercentage)
154 {
155 stArucoBestTag = stCandidate;
156 dBestArucoAreaPercentage = dAreaPercentage;
157 }
158 }
159 }
160 // --- Torch Tag Logic ---
161 else if (stCandidate.eDetectionMethod == tagdetectutils::TagDetectionMethod::eTorch)
162 {
163 szIdentifiedTags += "\tTorch Class: " + stCandidate.szClassName + " Tag Age: " + std::to_string(dTagTotalAge) +
164 "s Tag Screen Percentage: " + std::to_string(dAreaPercentage) + "%\n";
165
166 // Prioritize the tag that takes up the most screen area
167 if (dAreaPercentage > dBestTorchAreaPercentage)
168 {
169 stTorchBestTag = stCandidate;
170 dBestTorchAreaPercentage = dAreaPercentage;
171 }
172 }
173 }
174
175 // Only print the identified tags if there are any.
176 if (stArucoBestTag.nID != -1 || stTorchBestTag.dConfidence != 0.0)
177 {
178 LOG_DEBUG(logging::g_qSharedLogger, "TagDetectionChecker: Identified tags:\n{}", szIdentifiedTags);
179 }
180
181 // Set the target tag to the best tag.
182 stArucoTarget = stArucoBestTag;
183 stTorchTarget = stTorchBestTag;
184
185 return static_cast<int>(vDetectedArucoTags.size());
186 }
void LoadDetectedTags(std::vector< tagdetectutils::ArucoTag > &vDetectedArucoTags, const std::vector< std::shared_ptr< TagDetector > > &vTagDetectors)
Aggregates all detected tags from each provided tag detector for both OpenCV and YOLO detection.
Definition TagDetectionChecker.hpp:40
Here is the call graph for this function:
Here is the caller graph for this function: