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
ObjectDetectionChecker.hpp
Go to the documentation of this file.
1
12#ifndef OBJECT_DETECTION_CHECKER_HPP
13#define OBJECT_DETECTION_CHECKER_HPP
14
15#include "../../AutonomyGlobals.h"
16#include "../../vision/objects/ObjectDetector.h"
17
19
21
22
29namespace statemachine
30{
31
40 inline void LoadDetectedObjects(std::vector<objectdetectutils::Object>& vDetectedObjects, const std::vector<std::shared_ptr<ObjectDetector>>& vObjectDetectors)
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 }
87
88
101 inline int IdentifyTargetObject(const std::vector<std::shared_ptr<ObjectDetector>>& vObjectDetectors,
102 objectdetectutils::Object& stObjectTarget,
103 const geoops::WaypointType& eDesiredDetectionType = geoops::WaypointType::eUNKNOWN)
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 }
207} // namespace statemachine
208#endif
Namespace containing all state machine related classes.
Definition State.hpp:23
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.
Definition ObjectDetectionChecker.hpp:101
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
Represents a single detected object.
Definition ObjectDetectionUtility.hpp:73