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
main.cpp File Reference

Main program file. Sets up classes and runs main program functions. More...

Include dependency graph for main.cpp:

Functions

void RunExample ()
 
void SignalHandler (int nSignal)
 Help function given to the C++ csignal standard library to run when a CONTROL^C is given from the terminal.
 
void ResetTerminalMode ()
 Reset terminal mode to original settings.
 
void SetNonCanonicalTerminalMode ()
 Mutator for the Non Canonical Terminal Mode private member.
 
int CheckKeyPress ()
 Check if a key has been pressed in the terminal.
 
int main ()
 Autonomy main function.
 

Variables

static bool bRunExampleFlag = false
 
volatile sig_atomic_t bMainStop = false
 
struct termios g_stOriginalTermSettings
 

Detailed Description

Main program file. Sets up classes and runs main program functions.

Author
Eli Byrd (edbgk.nosp@m.k@ms.nosp@m.t.edu), ClayJay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-06-20

Function Documentation

◆ RunExample()

void RunExample ( )
30{}

◆ SignalHandler()

void SignalHandler ( int  nSignal)

Help function given to the C++ csignal standard library to run when a CONTROL^C is given from the terminal.

Parameters
nSignal- Integer representing the interrupt value.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-01-08
50{
51 // Check signal type.
52 if (nSignal == SIGINT || nSignal == SIGTERM)
53 {
54 // Submit logger message.
55 LOG_INFO(logging::g_qSharedLogger, "Ctrl+C or SIGTERM received. Cleaning up...");
56
57 // Update stop signal.
58 bMainStop = true;
59 }
60 // The SIGQUIT signal can be sent to the terminal by pressing CNTL+\.
61 else if (nSignal == SIGQUIT)
62 {
63 // Submit logger message.
64 LOG_INFO(logging::g_qSharedLogger, "Quit signal key pressed. Cleaning up...");
65
66 // Update stop signal.
67 bMainStop = true;
68 }
69}
Here is the caller graph for this function:

◆ ResetTerminalMode()

void ResetTerminalMode ( )

Reset terminal mode to original settings.

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2025-04-04
79{
80 tcsetattr(STDIN_FILENO, TCSANOW, &g_stOriginalTermSettings);
81}
Here is the caller graph for this function:

◆ SetNonCanonicalTerminalMode()

void SetNonCanonicalTerminalMode ( )

Mutator for the Non Canonical Terminal Mode private member.

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2025-04-04
91{
92 struct termios stNewTermSettings;
93
94 tcgetattr(STDIN_FILENO, &g_stOriginalTermSettings);
95 std::memcpy(&stNewTermSettings, &g_stOriginalTermSettings, sizeof(struct termios));
96
97 stNewTermSettings.c_lflag &= ~(ICANON | ECHO);
98 tcsetattr(STDIN_FILENO, TCSANOW, &stNewTermSettings);
99
100 atexit(ResetTerminalMode);
101}
void ResetTerminalMode()
Reset terminal mode to original settings.
Definition main.cpp:78
Here is the call graph for this function:
Here is the caller graph for this function:

◆ CheckKeyPress()

int CheckKeyPress ( )

Check if a key has been pressed in the terminal.

Returns
int - Number of bytes waiting in the terminal buffer.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2025-04-04
112{
113 int nBytesWaiting;
114 ioctl(STDIN_FILENO, FIONREAD, &nBytesWaiting);
115 return nBytesWaiting;
116}
Here is the caller graph for this function:

◆ main()

int main ( )

Autonomy main function.

Returns
int - Exit status number.
Author
Eli Byrd (edbgk.nosp@m.k@ms.nosp@m.t.edu), ClayJay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om), Sam Hajdukiewicz (saman.nosp@m.thah.nosp@m.ajduk.nosp@m.iewi.nosp@m.cz@gm.nosp@m.ail..nosp@m.com)
Date
2023-06-20
127{
128 // Print Software Header
129 std::ifstream fHeaderText("../data/ASCII/v25.txt");
130 std::string szHeaderText;
131 if (fHeaderText.is_open())
132 {
133 std::ostringstream pHeaderText;
134 pHeaderText << fHeaderText.rdbuf();
135 szHeaderText = pHeaderText.str();
136 }
137
138 std::cout << szHeaderText << std::endl;
139 std::cout << "Copyright \u00A9 2025 - Mars Rover Design Team\n" << std::endl;
140
141 // Initialize Loggers
142 logging::InitializeLoggers(constants::LOGGING_OUTPUT_PATH_ABSOLUTE);
143
145 // Setup global objects.
147 // Initialize RoveComm.
148 network::g_pRoveCommUDPNode = new rovecomm::RoveCommUDP();
149 network::g_pRoveCommTCPNode = new rovecomm::RoveCommTCP();
150 // Start RoveComm instances bound on ports.
151 network::g_bRoveCommUDPStatus = network::g_pRoveCommUDPNode->InitUDPSocket(manifest::General::ETHERNET_UDP_PORT);
152 network::g_bRoveCommTCPStatus = network::g_pRoveCommTCPNode->InitTCPSocket(constants::ROVECOMM_TCP_INTERFACE_IP.c_str(), manifest::General::ETHERNET_TCP_PORT);
153
154 // Check if RoveComm was successfully initialized.
155 if (!network::g_bRoveCommUDPStatus || !network::g_bRoveCommTCPStatus)
156 {
157 // Submit logger message.
158 LOG_CRITICAL(logging::g_qSharedLogger,
159 "RoveComm did not initialize properly! UDPNode Status: {}, TCPNode Status: {}",
160 network::g_bRoveCommUDPStatus.load(),
161 network::g_bRoveCommTCPStatus.load());
162
163 // Since RoveComm is crucial, stop code.
164 bMainStop = true;
165 }
166 else
167 {
168 // Submit logger message.
169 LOG_INFO(logging::g_qSharedLogger, "RoveComm UDP and TCP nodes successfully initialized.");
170 }
171 // Initialize callbacks.
172 network::g_pRoveCommUDPNode->AddUDPCallback<uint8_t>(logging::SetLoggingLevelsCallback, manifest::Autonomy::COMMANDS.find("SETLOGGINGLEVELS")->second.DATA_ID);
173
174 // Initialize drivers.
175 globals::g_pDriveBoard = new DriveBoard();
176 globals::g_pMultimediaBoard = new MultimediaBoard();
177 globals::g_pNavigationBoard = new NavigationBoard();
178
179 // Check whether or not we should run example code or continue with normal operation.
180 if (bRunExampleFlag)
181 {
182 // Run example code from included file.
183 RunExample();
184 }
185 else
186 {
187 // Setup signal interrupt handler.
188 struct sigaction stSigBreak;
189 stSigBreak.sa_handler = SignalHandler;
190 stSigBreak.sa_flags = 0;
191 sigemptyset(&stSigBreak.sa_mask);
192 sigaction(SIGINT, &stSigBreak, nullptr);
193 sigaction(SIGQUIT, &stSigBreak, nullptr);
194 // Set the terminal to non-canonical mode. This allows us to read a single character from the terminal without waiting for a newline.
196
197 // Print warnings if running in SIM mode.
198 if (constants::MODE_SIM)
199 {
200 // Print 5 times to make it noticeable.
201 for (int nIter = 0; nIter < 5; ++nIter)
202 {
203 // Submit logger message.
204 LOG_WARNING(logging::g_qSharedLogger,
205 "Autonomy_Software is running in SIM mode! If you aren't currently using the Unreal RoveSoSimulator sim, disable SIM mode in CMakeLists.txt "
206 "or in your build arguments!");
207 }
208
209 // Sleep for 3 seconds to make sure it's seen.
210 std::this_thread::sleep_for(std::chrono::seconds(3));
211 }
212
213 // Initialize handlers.
214 globals::g_pWaypointHandler = new WaypointHandler();
215 globals::g_pLiDARHandler = new LiDARHandler();
216 globals::g_pCameraHandler = new CameraHandler();
217 globals::g_pTagDetectionHandler = new TagDetectionHandler();
218 globals::g_pObjectDetectionHandler = new ObjectDetectionHandler();
219 globals::g_pStateMachineHandler = new StateMachineHandler();
220
221 // // Open the LiDAR database.
222 if (!globals::g_pLiDARHandler->OpenDB(constants::LIDAR_HANDLER_DB_PATH))
223 {
224 // Submit logger message.
225 LOG_ERROR(logging::g_qSharedLogger, "Failed to open LiDAR database.");
226 // Stop main loop.
227 bMainStop = true;
228 }
229
230 // Initialize GeoPlanner and VizHandler
231 globals::g_pGeoPlanner = new pathplanners::GeoPlanner(constants::GEOPLANNER_TILE_SIZE);
232 VisualizationHandler* pVisualizationHandler = new VisualizationHandler(constants::VISUALIZER_WEBSERVER_PORT);
233
234 // Start camera and detection handlers.
235 globals::g_pCameraHandler->StartAllCameras();
236 globals::g_pTagDetectionHandler->StartAllDetectors();
237 globals::g_pObjectDetectionHandler->StartAllDetectors();
238 // Enable recording on handlers.
239 globals::g_pCameraHandler->StartRecording();
240 globals::g_pTagDetectionHandler->StartRecording();
241 globals::g_pObjectDetectionHandler->StartRecording();
242 // Now that cameras and detectors are configured start state machine.
243 globals::g_pStateMachineHandler->StartStateMachine();
244 // Start the visualization handler.
245 pVisualizationHandler->Start();
246
248 // Declare local variables used in main loop.
250 // Get Camera and Tag detector pointers .
251 std::shared_ptr<ZEDCamera> pMainCam = globals::g_pCameraHandler->GetZED(CameraHandler::ZEDCamName::eHeadMainCam);
252 std::shared_ptr<TagDetector> pMainTagDetector = globals::g_pTagDetectionHandler->GetTagDetector(TagDetectionHandler::TagDetectors::eHeadMainCam);
253 std::shared_ptr<ObjectDetector> pMainObjectDetector =
254 globals::g_pObjectDetectionHandler->GetObjectDetector(ObjectDetectionHandler::ObjectDetectors::eHeadMainCam);
255 std::shared_ptr<ZEDCamera> pRearCam = globals::g_pCameraHandler->GetZED(CameraHandler::ZEDCamName::eRearCam);
256 std::shared_ptr<TagDetector> pRearTagDetector = globals::g_pTagDetectionHandler->GetTagDetector(TagDetectionHandler::TagDetectors::eRearCam);
257 std::shared_ptr<ObjectDetector> pRearObjectDetector = globals::g_pObjectDetectionHandler->GetObjectDetector(ObjectDetectionHandler::ObjectDetectors::eRearCam);
258 IPS IterPerSecond = IPS();
259
260 // Create a vector of ints to store the FPS values for each thread.
261 std::vector<uint32_t> vThreadFPSValues;
262
263 /*
264 This while loop is the main periodic loop for the Autonomy_Software program.
265 Loop until user sends sigkill or sigterm.
266 */
267 while (!bMainStop)
268 {
269 // Add each threads FPS value to the vector.
270 vThreadFPSValues.clear();
271 vThreadFPSValues.push_back(static_cast<uint32_t>(IterPerSecond.GetExactIPS()));
272 vThreadFPSValues.push_back(static_cast<uint32_t>(pMainCam->GetIPS().GetExactIPS()));
273 vThreadFPSValues.push_back(static_cast<uint32_t>(pMainTagDetector->GetIPS().GetExactIPS()));
274 vThreadFPSValues.push_back(static_cast<uint32_t>(pMainObjectDetector->GetIPS().GetExactIPS()));
275 vThreadFPSValues.push_back(static_cast<uint32_t>(pRearCam ? pRearCam->GetIPS().GetExactIPS() : 0));
276 vThreadFPSValues.push_back(static_cast<uint32_t>(pRearTagDetector ? pRearTagDetector->GetIPS().GetExactIPS() : 0));
277 vThreadFPSValues.push_back(static_cast<uint32_t>(pRearObjectDetector ? pRearObjectDetector->GetIPS().GetExactIPS() : 0));
278 vThreadFPSValues.push_back(static_cast<uint32_t>(globals::g_pStateMachineHandler->GetIPS().GetExactIPS()));
279 vThreadFPSValues.push_back(static_cast<uint32_t>(network::g_pRoveCommUDPNode->GetIPS().GetExactIPS()));
280 vThreadFPSValues.push_back(static_cast<uint32_t>(network::g_pRoveCommTCPNode->GetIPS().GetExactIPS()));
281
282 // Create a string to append FPS values to.
283 std::string szMainInfo = "";
284 // Get FPS of all cameras and detectors and construct the info into a string.
285 szMainInfo += "\n--------[ Threads FPS ]--------\n";
286 szMainInfo += "Main Process FPS: " + std::to_string(IterPerSecond.GetExactIPS()) + "\n";
287 szMainInfo += "MainCam FPS: " + std::to_string(pMainCam->GetIPS().GetExactIPS()) + "\n";
288 szMainInfo += "MainTagDetector FPS: " + std::to_string(pMainTagDetector->GetIPS().GetExactIPS()) + "\n";
289 szMainInfo += "MainObjectDetector FPS: " + std::to_string(pMainObjectDetector->GetIPS().GetExactIPS()) + "\n";
290 szMainInfo += "RearCam FPS: " + std::to_string(pRearCam ? pRearCam->GetIPS().GetExactIPS() : 0) + "\n";
291 szMainInfo += "RearTagDetector FPS: " + std::to_string(pRearTagDetector ? pRearTagDetector->GetIPS().GetExactIPS() : 0) + "\n";
292 szMainInfo += "RearObjectDetector FPS: " + std::to_string(pRearObjectDetector ? pRearObjectDetector->GetIPS().GetExactIPS() : 0) + "\n";
293 szMainInfo += "\nStateMachine FPS: " + std::to_string(globals::g_pStateMachineHandler->GetIPS().GetExactIPS()) + "\n";
294 szMainInfo += "\nVisualizer FPS: " + std::to_string(pVisualizationHandler->GetIPS().GetExactIPS()) + "\n";
295 szMainInfo += "\nRoveCommUDP FPS: " + std::to_string(network::g_pRoveCommTCPNode->GetIPS().GetExactIPS()) + "\n";
296 szMainInfo += "RoveCommTCP FPS: " + std::to_string(network::g_pRoveCommTCPNode->GetIPS().GetExactIPS()) + "\n";
297 szMainInfo += "\n--------[ State Machine Info ]--------\n";
298 szMainInfo += "Current State: " + statemachine::StateToString(globals::g_pStateMachineHandler->GetCurrentState()) + "\n";
299 // Submit logger message.
300 LOG_DEBUG(logging::g_qSharedLogger, "{}", szMainInfo);
301
302 // Print out the FPS stats to the console if the user presses 'f' or 'F'.
303 if (CheckKeyPress() > 0)
304 {
305 char chTerminalInput = 0;
306 ssize_t nBytesRead = read(STDIN_FILENO, &chTerminalInput, 1);
307 if (nBytesRead <= 0)
308 {
309 LOG_WARNING(logging::g_qSharedLogger, "Failed to read from terminal input.");
310 }
311 else
312 {
313 if (chTerminalInput == 'h' || chTerminalInput == 'H')
314 {
315 // Print help message to console.
316 LOG_NOTICE(logging::g_qSharedLogger,
317 "\n--------[ Autonomy Software Help ]--------\n"
318 "Press 'f' or 'F' to print FPS stats to the log file.\n"
319 "Press 'p' or 'P' to print rover pose info to the log file.\n"
320 "Press 's' or 'S' to print sensor data to the log file.\n"
321 "Press 'd' or 'D' to print current drive powers.\n"
322 "Press 't' or 'T' to print tag detection info to the log file.\n"
323 "Press 'm' or 'M' to print object detection info to the log file.\n"
324 "Press 'q' or 'Q' to quit the program.\n"
325 "-------------------------------------------\n");
326 }
327 else if (chTerminalInput == 'f' || chTerminalInput == 'F')
328 {
329 LOG_NOTICE(logging::g_qSharedLogger, "{}", szMainInfo);
330 }
331 else if (chTerminalInput == 'p' || chTerminalInput == 'P')
332 {
333 // Get the rover pose from the waypoint handler.
334 geoops::RoverPose stCurrentRoverPose = globals::g_pStateMachineHandler->SmartRetrieveRoverPose();
335 // Assemble a string to print containing data about the rover pose.
336 std::string szRoverPoseInfo = "\n--------[ Rover Pose Info ]--------\n";
337 szRoverPoseInfo += "Easting: " + std::to_string(stCurrentRoverPose.GetUTMCoordinate().dEasting) + "\n";
338 szRoverPoseInfo += "Northing: " + std::to_string(stCurrentRoverPose.GetUTMCoordinate().dNorthing) + "\n";
339 szRoverPoseInfo += "Altitude: " + std::to_string(stCurrentRoverPose.GetUTMCoordinate().dAltitude) + "\n";
340 szRoverPoseInfo += "Compass: " + std::to_string(stCurrentRoverPose.GetCompassHeading()) + "\n";
341 // Submit logger message.
342 LOG_NOTICE(logging::g_qSharedLogger, "{}", szRoverPoseInfo);
343 }
344 else if (chTerminalInput == 's' || chTerminalInput == 'S')
345 {
346 // Get the sensor data from the navigation board.
347 sl::SensorsData slSensorData;
348 std::future<bool> fuResult = pMainCam->RequestSensorsCopy(slSensorData);
349
350 // Wait for the data to be copied.
351 if (fuResult.get())
352 {
353 // Assemble a string to print containing data about the sensor data.
354 std::string szSensorDataInfo = "\n--------[ Sensor Data Info ]--------\n";
355 szSensorDataInfo += "IMU Accel X: " + std::to_string(slSensorData.imu.linear_acceleration.x) + "\n";
356 szSensorDataInfo += "IMU Accel Y: " + std::to_string(slSensorData.imu.linear_acceleration.y) + "\n";
357 szSensorDataInfo += "IMU Accel Z: " + std::to_string(slSensorData.imu.linear_acceleration.z) + "\n";
358 szSensorDataInfo += "IMU AngVel X: " + std::to_string(slSensorData.imu.angular_velocity.x) + "\n";
359 szSensorDataInfo += "IMU AngVel Y: " + std::to_string(slSensorData.imu.angular_velocity.y) + "\n";
360 szSensorDataInfo += "IMU AngVel Z: " + std::to_string(slSensorData.imu.angular_velocity.z) + "\n";
361 szSensorDataInfo += "IMU Gyro X:" + std::to_string(slSensorData.imu.pose.getEulerAngles(false).x) + "\n";
362 szSensorDataInfo += "IMU Gyro Y: " + std::to_string(slSensorData.imu.pose.getEulerAngles(false).y) + "\n";
363 szSensorDataInfo += "IMU Gyro Z: " + std::to_string(slSensorData.imu.pose.getEulerAngles(false).z) + "\n";
364 // Submit logger message.
365 LOG_NOTICE(logging::g_qSharedLogger, "{}", szSensorDataInfo);
366 }
367 }
368 else if (chTerminalInput == 'd' || chTerminalInput == 'D')
369 {
370 // Get the current drive powers from the drive board.
371 diffdrive::DrivePowers stCurrentDrivePowers = globals::g_pDriveBoard->GetDrivePowers();
372 // Assemble a string to print containing data about the drive powers.
373 std::string szDrivePowersInfo = "\n--------[ Drive Powers Info ]--------\n";
374 szDrivePowersInfo += "Left Power: " + std::to_string(stCurrentDrivePowers.dLeftDrivePower) + "\n";
375 szDrivePowersInfo += "Right Power: " + std::to_string(stCurrentDrivePowers.dRightDrivePower) + "\n";
376 // Submit logger message.
377 LOG_NOTICE(logging::g_qSharedLogger, "{}", szDrivePowersInfo);
378 }
379 else if (chTerminalInput == 't' || chTerminalInput == 'T')
380 {
381 // Get the tags from the tag detectors.
382 if (pMainTagDetector->GetIsReady())
383 {
384 // Create instance variables.
385 tagdetectutils::ArucoTag stBestOpenCVTag, stBestTorchTag;
386 int nTagCount = 0;
387
388 // Get the best/valid tags from the tag detectors.
389 std::vector<std::shared_ptr<TagDetector>> vTagDetectors = {pMainTagDetector};
390 // Check if the next waypoint in the waypoint handler exists and had a tag ID.
391 if (globals::g_pWaypointHandler->GetWaypointCount() > 0)
392 {
393 // Get the best tags from the tag detectors.
394 nTagCount = statemachine::IdentifyTargetMarker(vTagDetectors,
395 stBestOpenCVTag,
396 stBestTorchTag,
397 globals::g_pWaypointHandler->PeekNextWaypoint().nID);
398 }
399 else
400 {
401 // Get the best tags from the tag detectors.
402 nTagCount = statemachine::IdentifyTargetMarker(vTagDetectors, stBestOpenCVTag, stBestTorchTag);
403 }
404
405 // Submit logger message.
406 std::ostringstream ossTagsInfo;
407 ossTagsInfo << "\n--------[ All Detections ]--------\n"
408 << "Detected Tags Info:\n"
409 << "Total Tags: " << nTagCount << "\n";
410
411 ossTagsInfo << "\n--------[ Valid/Best Tags ]--------\n";
412 if (stBestOpenCVTag.nID != -1)
413 {
414 ossTagsInfo << "Best OpenCV Tag ID: " << stBestOpenCVTag.nID << "\n";
415 ossTagsInfo << "Best OpenCV Tag Distance: " << stBestOpenCVTag.dStraightLineDistance << "\n";
416 ossTagsInfo << "Best OpenCV Tag Yaw Angle: " << stBestOpenCVTag.dYawAngle << "\n";
417 }
418 else
419 {
420 ossTagsInfo << "No valid OpenCV tags detected.\n";
421 }
422 if (stBestTorchTag.dConfidence != 0.0)
423 {
424 ossTagsInfo << "Best Torch Tag ID: " << stBestTorchTag.nID << "\n";
425 ossTagsInfo << "Best Torch Tag Distance: " << stBestTorchTag.dStraightLineDistance << "\n";
426 ossTagsInfo << "Best Torch Tag Yaw Angle: " << stBestTorchTag.dYawAngle << "\n";
427 }
428 else
429 {
430 ossTagsInfo << "No valid Torch tags detected.\n";
431 }
432
433 LOG_NOTICE(logging::g_qSharedLogger, "{}", ossTagsInfo.str());
434 }
435 else
436 {
437 // Submit logger message.
438 LOG_WARNING(logging::g_qSharedLogger, "Tag Detector is not ready yet. Cannot get tags.");
439 }
440 }
441 else if (chTerminalInput == 'm' || chTerminalInput == 'M')
442 {
443 // Get the tags from the tag detectors.
444 if (pMainObjectDetector->GetIsReady())
445 {
446 // Create instance variables.
447 objectdetectutils::Object stBestTorchObject;
448 int nObjectCount = 0;
449
450 // Get the best/valid tags from the tag detectors.
451 std::vector<std::shared_ptr<ObjectDetector>> vTagDetectors = {pMainObjectDetector, pRearObjectDetector};
452 // Get the best tags from the tag detectors.
453 nObjectCount = statemachine::IdentifyTargetObject(vTagDetectors, stBestTorchObject);
454
455 // Submit logger message.
456 std::ostringstream ossTagsInfo;
457 ossTagsInfo << "\n--------[ All Detections ]--------\n"
458 << "Detected Object Info:\n"
459 << "Total Object: " << nObjectCount << "\n";
460
461 ossTagsInfo << "\n--------[ Valid/Best Objects ]--------\n";
462 if (stBestTorchObject.dConfidence != 0.0)
463 {
464 ossTagsInfo << "Best Torch Object Distance: " << stBestTorchObject.dStraightLineDistance << "\n";
465 ossTagsInfo << "Best Torch Object Yaw Angle: " << stBestTorchObject.dYawAngle << "\n";
466 }
467 else
468 {
469 ossTagsInfo << "No valid Torch objects detected.\n";
470 }
471
472 LOG_NOTICE(logging::g_qSharedLogger, "{}", ossTagsInfo.str());
473 }
474 else
475 {
476 // Submit logger message.
477 LOG_WARNING(logging::g_qSharedLogger, "Object Detector is not ready yet. Cannot get objects.");
478 }
479 }
480 else if (chTerminalInput == 'q' || chTerminalInput == 'Q')
481 {
482 LOG_INFO(logging::g_qSharedLogger, "'Q' key pressed. Initiating shutdown...");
483 bMainStop = true;
484 }
485 }
486 }
487
489 // Send thread stats over RoveComm.
491 // Check if rovecomm is initialized and running.
492 if (network::g_pRoveCommUDPNode)
493 {
494 // Construct a RoveComm packet with the drive data.
495 rovecomm::RoveCommPacket<uint32_t> stPacket;
496 stPacket.unDataId = manifest::Autonomy::TELEMETRY.find("THREADFPS")->second.DATA_ID;
497 stPacket.unDataCount = manifest::Autonomy::TELEMETRY.find("THREADFPS")->second.DATA_COUNT;
498 stPacket.eDataType = manifest::Autonomy::TELEMETRY.find("THREADFPS")->second.DATA_TYPE;
499 // Create a static variable to act a counter/iterator for the FPS value to use.
500 static uint32_t nThreadFPSIndex = 0;
501 // Check if the index is within bounds of the vector.
502 if (nThreadFPSIndex < static_cast<uint32_t>(vThreadFPSValues.size()))
503 {
504 // First push back the thread enum identifier cast to an int.
505 stPacket.vData.push_back(nThreadFPSIndex + 1);
506 // Add the current FPS value to the packet data.
507 stPacket.vData.push_back(static_cast<float>(vThreadFPSValues[nThreadFPSIndex]));
508 // Increment the index for the next iteration.
509 nThreadFPSIndex++;
510 }
511 else
512 {
513 // Reset the index if it exceeds the vector size.
514 nThreadFPSIndex = 0;
515 }
516 // Send the packet over RoveComm UDP.
517 network::g_pRoveCommUDPNode->SendUDPPacket(stPacket, "0.0.0.0", constants::ROVECOMM_OUTGOING_UDP_PORT);
518 }
519
520 // Update IPS tick.
521 IterPerSecond.Tick();
522
523 // No need to loop as fast as possible. Sleep...
524 std::this_thread::sleep_for(std::chrono::microseconds(66666));
525 }
526
528 // Cleanup.
530
531 // Stop handlers.
532 globals::g_pStateMachineHandler->StopStateMachine();
533
534 // Stop the visualization handler.
535 pVisualizationHandler->RequestStop();
536 pVisualizationHandler->Join();
537
538 // Export visualization data.
539 pVisualizationHandler->SaveVisualization(constants::LOGGING_OUTPUT_PATH_ABSOLUTE + logging::g_szProgramStartTimeString + "/visualization.html");
540
541 // Stop detectors.
542 globals::g_pObjectDetectionHandler->StopAllDetectors();
543 globals::g_pTagDetectionHandler->StopAllDetectors();
544
545 // Check if ZED spatial map was enabled.
546 if (pMainCam->GetSpatialMappingState() == sl::SPATIAL_MAPPING_STATE::OK)
547 {
548 // Submit logger message.
549 LOG_INFO(logging::g_qSharedLogger, "Exporting ZED spatial map...");
550 // Extract and save spatial map.
551 std::future<sl::Mesh> fuSpatialMap;
552 pMainCam->ExtractSpatialMapAsync(fuSpatialMap);
553 sl::Mesh slSpatialMap = fuSpatialMap.get();
554 std::string szFilePath = constants::LOGGING_OUTPUT_PATH_ABSOLUTE + logging::g_szProgramStartTimeString + "/spatial_map";
555 slSpatialMap.save(szFilePath.c_str(), sl::MESH_FILE_FORMAT::PLY);
556 }
557
558 // Stop the camera handler.
559 globals::g_pCameraHandler->StopAllCameras();
560
561 // Close the LiDAR database.
562 globals::g_pLiDARHandler->CloseDB();
563
564 // Cleanup handlers.
565 delete pVisualizationHandler;
566 delete globals::g_pGeoPlanner;
567 delete globals::g_pStateMachineHandler;
568 delete globals::g_pObjectDetectionHandler;
569 delete globals::g_pTagDetectionHandler;
570 delete globals::g_pCameraHandler;
571 delete globals::g_pWaypointHandler;
572 delete globals::g_pLiDARHandler;
573 // Set all pointers to nullptr to prevent dangling pointers.
574 pVisualizationHandler = nullptr;
575 globals::g_pGeoPlanner = nullptr;
576 globals::g_pStateMachineHandler = nullptr;
577 globals::g_pObjectDetectionHandler = nullptr;
578 globals::g_pTagDetectionHandler = nullptr;
579 globals::g_pCameraHandler = nullptr;
580 globals::g_pWaypointHandler = nullptr;
581 globals::g_pLiDARHandler = nullptr;
582 }
583
584 // Stop RoveComm quill logging or quill will segfault if trying to output logs to RoveComm.
585 network::g_bRoveCommUDPStatus = false;
586 network::g_bRoveCommTCPStatus = false;
587 // Cleanup driver objects.
588 delete globals::g_pDriveBoard;
589 delete globals::g_pMultimediaBoard;
590 delete globals::g_pNavigationBoard;
591
592 // Finally, stop RoveComm.
593 LOG_INFO(logging::g_qSharedLogger, "Stopping RoveComm...");
594 network::g_pRoveCommUDPNode->CloseUDPSocket();
595 network::g_pRoveCommTCPNode->CloseTCPSocket();
596 delete network::g_pRoveCommUDPNode;
597 delete network::g_pRoveCommTCPNode;
598
599 // Set all pointers to nullptr to prevent dangling pointers.
600 globals::g_pDriveBoard = nullptr;
601 globals::g_pMultimediaBoard = nullptr;
602 globals::g_pNavigationBoard = nullptr;
603 network::g_pRoveCommUDPNode = nullptr;
604 network::g_pRoveCommTCPNode = nullptr;
605
606 // Submit logger message that program is done cleaning up and is now exiting.
607 LOG_INFO(logging::g_qSharedLogger, "Clean up finished. Exiting...");
608
609 // Successful exit.
610 return 0;
611}
void RunExample()
Example function to demonstrate the usage of LiDARHandler.
Definition GeoPlanner.hpp:25
void Join()
Waits for thread to finish executing and then closes thread. This method will block the calling code ...
Definition AutonomyThread.hpp:203
void RequestStop()
Signals threads to stop executing user code, terminate. DOES NOT JOIN. This method will not force the...
Definition AutonomyThread.hpp:187
IPS & GetIPS()
Accessor for the Frame I P S private member.
Definition AutonomyThread.hpp:257
void Start()
When this method is called, it starts a new thread that runs the code within the ThreadedContinuousCo...
Definition AutonomyThread.hpp:134
The CameraHandler class is responsible for managing all of the camera feeds that Autonomy_Software us...
Definition CameraHandler.h:34
void StopAllCameras()
Signals all cameras to stop their threads.
Definition CameraHandler.cpp:173
void StartAllCameras()
Signals all cameras to start their threads.
Definition CameraHandler.cpp:146
void StartRecording()
Signal the RecordingHandler to start recording video feeds from the CameraHandler.
Definition CameraHandler.cpp:160
std::shared_ptr< ZEDCamera > GetZED(ZEDCamName eCameraName)
Accessor for ZED cameras.
Definition CameraHandler.cpp:215
This class handles communication with the drive board on the rover by sending RoveComm packets over t...
Definition DriveBoard.h:35
diffdrive::DrivePowers GetDrivePowers() const
Accessor for the current drive powers of the robot.
Definition DriveBoard.cpp:346
This util class provides an easy way to keep track of iterations per second for any body of code.
Definition IPS.hpp:30
double GetExactIPS() const
Accessor for the Current I P S private member. This method will return the immediate IPS since the la...
Definition IPS.hpp:165
void Tick()
This method is used to update the iterations per second counter and recalculate all of the IPS metric...
Definition IPS.hpp:138
The LiDARHandler class manages runtime queries against a LiDAR point cloud database for autonomy navi...
Definition LiDARHandler.h:40
bool CloseDB()
Closes the currently open LiDAR DuckDB connection.
Definition LiDARHandler.cpp:112
This class handles communication with the multimedia board on the rover by sending RoveComm packets o...
Definition MultimediaBoard.h:23
This class handles communication with the navigation board on the rover by sending RoveComm packets o...
Definition NavigationBoard.h:33
The ObjectDetectionHandler class is responsible for managing all of the different detectors that Auto...
Definition ObjectDetectionHandler.h:28
void StartAllDetectors()
Signals all detectors to start their threads.
Definition ObjectDetectionHandler.cpp:86
void StartRecording()
Signal the RecordingHandler to start recording feeds from the detectors.
Definition ObjectDetectionHandler.cpp:102
std::shared_ptr< ObjectDetector > GetObjectDetector(ObjectDetectors eDetectorName)
Accessor for ObjectDetector detectors.
Definition ObjectDetectionHandler.cpp:153
void StopAllDetectors()
Signals all detectors to stop their threads.
Definition ObjectDetectionHandler.cpp:115
The StateMachineHandler class serves as the main state machine for Autonomy Software....
Definition StateMachineHandler.h:44
void StartStateMachine()
This method will start the state machine. It will set the first state to Idle and start the thread po...
Definition StateMachineHandler.cpp:192
void StopStateMachine()
This method will stop the state machine. It will signal whatever state is currently running to abort ...
Definition StateMachineHandler.cpp:217
geoops::RoverPose SmartRetrieveRoverPose(bool bIMUHeading=true)
This method is used to retrieve the rover's current position and heading. It uses the GPS data from t...
Definition StateMachineHandler.cpp:375
The TagDetectionHandler class is responsible for managing all of the different detectors that Autonom...
Definition TagDetectionHandler.h:28
void StopAllDetectors()
Signals all detectors to stop their threads.
Definition TagDetectionHandler.cpp:125
void StartAllDetectors()
Signals all detectors to start their threads.
Definition TagDetectionHandler.cpp:96
void StartRecording()
Signal the RecordingHandler to start recording video feeds from the TagDetectionHandler.
Definition TagDetectionHandler.cpp:112
std::shared_ptr< TagDetector > GetTagDetector(TagDetectors eDetectorName)
Accessor for TagDetector detectors.
Definition TagDetectionHandler.cpp:163
The VisualizationHandler class manages persistent world state and hosts a 3D web server for interacti...
Definition VisualizationHandler.h:35
void SaveVisualization(const std::string &szFilename)
Save the current visualization to a single HTML file with embedded assets.
Definition VisualizationHandler.cpp:143
The WaypointHandler class is used throughout the entire project (mainly by the state machine) to glob...
Definition WaypointHandler.h:33
This class implements a geospatial path planner that uses a discrete 2.5D Costmap and a fast Weighted...
Definition GeoPlanner.h:49
void SetNonCanonicalTerminalMode()
Mutator for the Non Canonical Terminal Mode private member.
Definition main.cpp:90
int CheckKeyPress()
Check if a key has been pressed in the terminal.
Definition main.cpp:111
void SignalHandler(int nSignal)
Help function given to the C++ csignal standard library to run when a CONTROL^C is given from the ter...
Definition main.cpp:49
::uint32_t uint32_t
::uint8_t uint8_t
void read(const FileNode &fn, optflow::GPCTree::Node &node, optflow::GPCTree::Node)
void InitializeLoggers(std::string szLoggingOutputPath, std::string szProgramTimeLogsDir)
Logger Initializer - Sets Up all the logging handlers required for having the above loggers.
Definition AutonomyLogging.cpp:57
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
std::string StateToString(States eState)
Converts a state object to a string.
Definition State.hpp:85
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
This struct is used to store the left and right drive powers for the robot. Storing these values in a...
Definition DifferentialDrive.hpp:73
This struct is used by the WaypointHandler to provide an easy way to store all pose data about the ro...
Definition GeospatialOperations.hpp:708
double GetCompassHeading() const
Accessor for the Compass Heading private member.
Definition GeospatialOperations.hpp:787
const geoops::UTMCoordinate & GetUTMCoordinate() const
Accessor for the geoops::UTMCoordinate member variable.
Definition GeospatialOperations.hpp:767
Represents a single detected object.
Definition ObjectDetectionUtility.hpp:73
Represents a single ArUco tag.
Definition TagDetectionUtilty.hpp:57
Here is the call graph for this function: