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
ArucoGenerateTags.hpp
Go to the documentation of this file.
1
12#include "../../src/interfaces/AutonomyThread.hpp"
13#include "../../src/util/ExampleChecker.h"
14#include "../opencv/TagGenerator.hpp"
15
17#include <chrono>
18#include <filesystem>
19#include <iostream>
20
22
23
33{
34 private:
35 // Declare and define private member variables.
36 int m_nNumTagsToGenerate = 0;
37 std::vector<cv::aruco::PredefinedDictionaryType> m_vDictionaries;
38 std::mutex m_muDictMutex; // This mutex is used for locking write access to the dictionary in threads.
39
40
47 void ThreadedContinuousCode() override
48 {
49 // Start thread pool. Run detached since the threads aren't returning anything.
50 // This is much faster than the normal RunPool function.
51 this->RunDetachedPool(m_vDictionaries.size(), m_vDictionaries.size());
52
53 // Wait for pool tasks to finish.
54 this->JoinPool();
55
56 // Stop threaded code.
57 this->RequestStop();
58 }
59
60
70 void PooledLinearCode() override
71 {
72 // Acquire resource lock for dictionary vector.
73 std::unique_lock<std::mutex> lock(m_muDictMutex);
74 // Get dictionary enum from back of dictionary vector.
75 cv::aruco::PredefinedDictionaryType cvDictType = m_vDictionaries.back();
76 m_vDictionaries.pop_back();
77 // Release resource lock.
78 lock.unlock();
79
81 // Change this bool to test the two different
82 // blocks of code!
84 bool bUseParallelLoop = false;
85 if (bUseParallelLoop)
86 {
88 // This code splits the loop into parts and
89 // completes it in different threads.
91 this->ParallelizeLoop(50,
92 m_nNumTagsToGenerate,
93 [&cvDictType](const int a, const int b)
94 {
95 // Loop through and generate each of the tags.
96 for (int i = a; i < b; ++i)
97 GenerateOpenCVArucoMarker(cvDictType, i);
98 });
99 }
100 else
101 {
103 // This code linearly runs through every tag.
105 for (int i = 0; i < m_nNumTagsToGenerate; ++i)
106 {
107 GenerateOpenCVArucoMarker(cvDictType, i);
108 }
109 }
110 }
111
112 public:
113 // Declare and define public methods and variables.
114 ArucoGenerateTagsThreaded() = default;
115
116
125 void SetNumTagsToGenerate(const int nNumTags) { m_nNumTagsToGenerate = nNumTags; }
126
127
135 void AddTagDictionaryType(const cv::aruco::PredefinedDictionaryType eDictionary) { m_vDictionaries.emplace_back(eDictionary); }
136};
137
138
146{
147 private:
148 // Declare and define private member variables.
149 int m_nNumTagsToGenerate = 0;
150 std::vector<cv::aruco::PredefinedDictionaryType> m_vDictionaries;
151
152 public:
153 // Declare and define public methods and variables.
154 ArucoGenerateTagsLinear() = default;
155
156
163 void Start()
164 {
165 while (m_vDictionaries.size() > 0)
166 {
167 // Get dictionary enum from back of dictionary vector.
168 cv::aruco::PredefinedDictionaryType cvDictType = m_vDictionaries.back();
169 m_vDictionaries.pop_back();
170
171 // Loop through and generate each of the tags.
172 for (int i = 0; i < m_nNumTagsToGenerate; ++i)
173 GenerateOpenCVArucoMarker(cvDictType, i);
174 }
175 }
176
177
186 void SetNumTagsToGenerate(const int nNumTags) { m_nNumTagsToGenerate = nNumTags; }
187
188
196 void AddTagDictionaryType(const cv::aruco::PredefinedDictionaryType eDictionary) { m_vDictionaries.emplace_back(eDictionary); }
197};
198
199
208{
212 // Start the timer
213 std::chrono::time_point tmStartTime = std::chrono::high_resolution_clock::now();
214
215 // Create generator.
216 ArucoGenerateTagsLinear LinearTagGenerator;
217
218 // Configure tag generator for first run.
223 LinearTagGenerator.SetNumTagsToGenerate(50);
224 // Start first run.
225 LinearTagGenerator.Start();
226
227 // Add new dictionary to generator.
232 LinearTagGenerator.SetNumTagsToGenerate(100);
233 // Start second run.
234 LinearTagGenerator.Start();
235
236 // Add new dictionary to generator.
241 LinearTagGenerator.SetNumTagsToGenerate(250);
242 // Start third run.
243 LinearTagGenerator.Start();
244
245 // Add new dictionary to generator.
250 LinearTagGenerator.SetNumTagsToGenerate(1000);
251 // Start fourth run.
252 LinearTagGenerator.Start();
253
254 // End the timer
255 std::chrono::time_point tmEndTime = std::chrono::high_resolution_clock::now();
256 // Calculate the elapsed time
257 int nSingledThreadedDuration = std::chrono::duration_cast<std::chrono::milliseconds>(tmEndTime - tmStartTime).count();
258 // Print the result
259 std::cout << "Time taken for single threaded generator: " << nSingledThreadedDuration << " milliseconds." << std::endl;
260
261 // Remove all png files in the current directory.
262 for (const std::filesystem::directory_entry& stdEntry : std::filesystem::directory_iterator("."))
263 {
264 // Loop all *.png files.
265 if (std::filesystem::is_regular_file(stdEntry) && stdEntry.path().extension() == ".png")
266 {
267 // Delete.
268 std::filesystem::remove(stdEntry.path());
269 }
270 }
271
275 // Start the timer
276 tmStartTime = std::chrono::high_resolution_clock::now();
277
278 // Create Aruco generator threads.
279 ArucoGenerateTagsThreaded ThreadedTagGenerator1;
280 ArucoGenerateTagsThreaded ThreadedTagGenerator2;
281 ArucoGenerateTagsThreaded ThreadedTagGenerator3;
282 ArucoGenerateTagsThreaded ThreadedTagGenerator4;
283
284 // Configure tag generator for first run.
285 ThreadedTagGenerator1.AddTagDictionaryType(cv::aruco::DICT_4X4_50);
286 ThreadedTagGenerator1.AddTagDictionaryType(cv::aruco::DICT_5X5_50);
287 ThreadedTagGenerator1.AddTagDictionaryType(cv::aruco::DICT_6X6_50);
288 ThreadedTagGenerator1.AddTagDictionaryType(cv::aruco::DICT_7X7_50);
289 ThreadedTagGenerator1.SetNumTagsToGenerate(50);
290 // Start first run.
291 ThreadedTagGenerator1.Start();
292
293 // Add new dictionary to generator.
294 ThreadedTagGenerator2.AddTagDictionaryType(cv::aruco::DICT_4X4_100);
295 ThreadedTagGenerator2.AddTagDictionaryType(cv::aruco::DICT_5X5_100);
296 ThreadedTagGenerator2.AddTagDictionaryType(cv::aruco::DICT_6X6_100);
297 ThreadedTagGenerator2.AddTagDictionaryType(cv::aruco::DICT_7X7_100);
298 ThreadedTagGenerator2.SetNumTagsToGenerate(100);
299 // Start second run.
300 ThreadedTagGenerator2.Start();
301
302 // Add new dictionary to generator.
303 ThreadedTagGenerator3.AddTagDictionaryType(cv::aruco::DICT_4X4_250);
304 ThreadedTagGenerator3.AddTagDictionaryType(cv::aruco::DICT_5X5_250);
305 ThreadedTagGenerator3.AddTagDictionaryType(cv::aruco::DICT_6X6_250);
306 ThreadedTagGenerator3.AddTagDictionaryType(cv::aruco::DICT_7X7_250);
307 ThreadedTagGenerator3.SetNumTagsToGenerate(250);
308 // Start third run.
309 ThreadedTagGenerator3.Start();
310
311 // Add new dictionary to generator.
312 ThreadedTagGenerator4.AddTagDictionaryType(cv::aruco::DICT_4X4_1000);
313 ThreadedTagGenerator4.AddTagDictionaryType(cv::aruco::DICT_5X5_1000);
314 ThreadedTagGenerator4.AddTagDictionaryType(cv::aruco::DICT_6X6_1000);
315 ThreadedTagGenerator4.AddTagDictionaryType(cv::aruco::DICT_7X7_1000);
316 ThreadedTagGenerator4.SetNumTagsToGenerate(1000);
317 // Start fourth run.
318 ThreadedTagGenerator4.Start();
319
320 // Join all.
321 ThreadedTagGenerator1.Join();
322 ThreadedTagGenerator2.Join();
323 ThreadedTagGenerator3.Join();
324 ThreadedTagGenerator4.Join();
325
326 // End the timer
327 tmEndTime = std::chrono::high_resolution_clock::now();
328 // Calculate the elapsed time
329 int nMultiThreadedDuration = std::chrono::duration_cast<std::chrono::milliseconds>(tmEndTime - tmStartTime).count();
330 // Print the result
331 std::cout << "Time taken for multithreaded generator: " << nMultiThreadedDuration << " milliseconds." << std::endl;
332 std::cout << "\n\nCheck your build directory for all aruco tags!" << std::endl;
333}
void RunExample()
Main example method.
Definition ArucoGenerateTags.hpp:207
void GenerateOpenCVArucoMarker(cv::aruco::PredefinedDictionaryType eDictionary, unsigned short sMarker)
Generate an ArUco Tag.
Definition TagGenerator.hpp:25
This class is non threaded.
Definition ArucoGenerateTags.hpp:146
void Start()
Single threaded, runs in main loop.
Definition ArucoGenerateTags.hpp:163
void AddTagDictionaryType(const cv::aruco::PredefinedDictionaryType eDictionary)
Mutator for the Tag Dictionary Type private member.
Definition ArucoGenerateTags.hpp:196
void SetNumTagsToGenerate(const int nNumTags)
Mutator for the Num Tags To Generate private member. Given number must not exceed the dictionary type...
Definition ArucoGenerateTags.hpp:186
This class inherits the AutonomyThread interface and implements the threaded container methods....
Definition ArucoGenerateTags.hpp:33
void AddTagDictionaryType(const cv::aruco::PredefinedDictionaryType eDictionary)
Mutator for the Tag Dictionary Type private member.
Definition ArucoGenerateTags.hpp:135
void PooledLinearCode() override
Any highly parallelizable code that can be used in the main thread goes here.
Definition ArucoGenerateTags.hpp:70
void SetNumTagsToGenerate(const int nNumTags)
Mutator for the Num Tags To Generate private member. Given number must not exceed the dictionary type...
Definition ArucoGenerateTags.hpp:125
void ThreadedContinuousCode() override
This code will run in a separate thread. This is the main code.
Definition ArucoGenerateTags.hpp:47
Interface class used to easily multithread a child class.
Definition AutonomyThread.hpp:38
void Join()
Waits for thread to finish executing and then closes thread. This method will block the calling code ...
Definition AutonomyThread.hpp:180
void ParallelizeLoop(const int nNumThreads, const N tTotalIterations, F &&tLoopFunction)
Given a ref-qualified looping function and an arbitrary number of iterations, this method will divide...
Definition AutonomyThread.hpp:404
void RequestStop()
Signals threads to stop executing user code, terminate. DOES NOT JOIN. This method will not force the...
Definition AutonomyThread.hpp:164
void Start()
When this method is called, it starts a new thread that runs the code within the ThreadedContinuousCo...
Definition AutonomyThread.hpp:117
void RunDetachedPool(const unsigned int nNumTasksToQueue, const unsigned int nNumThreads=2, const bool bForceStopCurrentThreads=false)
When this method is called, it starts a thread pool full of threads that don't return std::futures (l...
Definition AutonomyThread.hpp:336
void JoinPool()
Waits for pool to finish executing tasks. This method will block the calling code until thread is fin...
Definition AutonomyThread.hpp:439
PredefinedDictionaryType