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
TagDetectionChecker.hpp
Go to the documentation of this file.
1
12#ifndef TAG_DETECTION_CHECKER_HPP
13#define TAG_DETECTION_CHECKER_HPP
14
15#include "../../AutonomyGlobals.h"
16#include "../../vision/aruco/TagDetector.h"
17
19
21
22
29namespace statemachine
30{
31
40 inline void LoadDetectedTags(std::vector<tagdetectutils::ArucoTag>& vDetectedArucoTags, const std::vector<std::shared_ptr<TagDetector>>& vTagDetectors)
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 }
85
86
100 inline int IdentifyTargetMarker(const std::vector<std::shared_ptr<TagDetector>>& vTagDetectors,
101 tagdetectutils::ArucoTag& stArucoTarget,
102 tagdetectutils::ArucoTag& stTorchTarget,
103 const int nTargetTagID = static_cast<int>(manifest::Autonomy::AUTONOMYWAYPOINTTYPES::ANY))
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 }
187} // namespace statemachine
188#endif
Namespace containing all state machine related classes.
Definition State.hpp:23
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.
Definition TagDetectionChecker.hpp:100
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
Represents a single ArUco tag.
Definition TagDetectionUtilty.hpp:57