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)
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 VisualizationHandler* pVisualizationHandler = new VisualizationHandler(constants::VISUALIZER_WEBSERVER_PORT);
221
222 // Initialize GeoPlanner.
223 globals::g_pGeoPlanner = new pathplanners::GeoPlanner(constants::GEOPLANNER_TILE_SIZE);
224
225 // Open the LiDAR database.
226 if (!globals::g_pLiDARHandler->OpenDB(constants::LIDAR_HANDLER_DB_PATH))
227 {
228 // Submit logger message.
229 LOG_ERROR(logging::g_qSharedLogger, "Failed to open LiDAR database.");
230 // Stop main loop.
231 bMainStop = true;
232 }
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 IPS IterPerSecond = IPS();
256
257 // Create a vector of ints to store the FPS values for each thread.
258 std::vector<uint32_t> vThreadFPSValues;
259
260 /*
261 This while loop is the main periodic loop for the Autonomy_Software program.
262 Loop until user sends sigkill or sigterm.
263 */
264 while (!bMainStop)
265 {
266 // Add each threads FPS value to the vector.
267 vThreadFPSValues.clear();
268 vThreadFPSValues.push_back(static_cast<uint32_t>(IterPerSecond.GetExactIPS()));
269 vThreadFPSValues.push_back(static_cast<uint32_t>(pMainCam->GetIPS().GetExactIPS()));
270 vThreadFPSValues.push_back(static_cast<uint32_t>(pMainTagDetector->GetIPS().GetExactIPS()));
271 vThreadFPSValues.push_back(static_cast<uint32_t>(pMainObjectDetector->GetIPS().GetExactIPS()));
272 vThreadFPSValues.push_back(static_cast<uint32_t>(globals::g_pStateMachineHandler->GetIPS().GetExactIPS()));
273 vThreadFPSValues.push_back(static_cast<uint32_t>(network::g_pRoveCommUDPNode->GetIPS().GetExactIPS()));
274 vThreadFPSValues.push_back(static_cast<uint32_t>(network::g_pRoveCommTCPNode->GetIPS().GetExactIPS()));
275
276 // Create a string to append FPS values to.
277 std::string szMainInfo = "";
278 // Get FPS of all cameras and detectors and construct the info into a string.
279 szMainInfo += "\n--------[ Threads FPS ]--------\n";
280 szMainInfo += "Main Process FPS: " + std::to_string(IterPerSecond.GetExactIPS()) + "\n";
281 szMainInfo += "MainCam FPS: " + std::to_string(pMainCam->GetIPS().GetExactIPS()) + "\n";
282 szMainInfo += "MainTagDetector FPS: " + std::to_string(pMainTagDetector->GetIPS().GetExactIPS()) + "\n";
283 szMainInfo += "MainObjectDetector FPS: " + std::to_string(pMainObjectDetector->GetIPS().GetExactIPS()) + "\n";
284 szMainInfo += "\nStateMachine FPS: " + std::to_string(globals::g_pStateMachineHandler->GetIPS().GetExactIPS()) + "\n";
285 szMainInfo += "\nVisualizer FPS: " + std::to_string(pVisualizationHandler->GetIPS().GetExactIPS()) + "\n";
286 szMainInfo += "\nRoveCommUDP FPS: " + std::to_string(network::g_pRoveCommTCPNode->GetIPS().GetExactIPS()) + "\n";
287 szMainInfo += "RoveCommTCP FPS: " + std::to_string(network::g_pRoveCommTCPNode->GetIPS().GetExactIPS()) + "\n";
288 szMainInfo += "\n--------[ State Machine Info ]--------\n";
289 szMainInfo += "Current State: " + statemachine::StateToString(globals::g_pStateMachineHandler->GetCurrentState()) + "\n";
290 // Submit logger message.
291 LOG_DEBUG(logging::g_qSharedLogger, "{}", szMainInfo);
292
293 // Print out the FPS stats to the console if the user presses 'f' or 'F'.
294 if (CheckKeyPress() > 0)
295 {
296 char chTerminalInput = 0;
297 ssize_t nBytesRead = read(STDIN_FILENO, &chTerminalInput, 1);
298 if (nBytesRead <= 0)
299 {
300 LOG_WARNING(logging::g_qSharedLogger, "Failed to read from terminal input.");
301 }
302 else
303 {
304 if (chTerminalInput == 'h' || chTerminalInput == 'H')
305 {
306 // Print help message to console.
307 LOG_NOTICE(logging::g_qSharedLogger,
308 "\n--------[ Autonomy Software Help ]--------\n"
309 "Press 'f' or 'F' to print FPS stats to the log file.\n"
310 "Press 'p' or 'P' to print rover pose info to the log file.\n"
311 "Press 's' or 'S' to print sensor data to the log file.\n"
312 "Press 'd' or 'D' to print current drive powers.\n"
313 "Press 't' or 'T' to print tag detection info to the log file.\n"
314 "Press 'm' or 'M' to print object detection info to the log file.\n"
315 "Press 'q' or 'Q' to quit the program.\n"
316 "-------------------------------------------\n");
317 }
318 else if (chTerminalInput == 'f' || chTerminalInput == 'F')
319 {
320 LOG_NOTICE(logging::g_qSharedLogger, "{}", szMainInfo);
321 }
322 else if (chTerminalInput == 'p' || chTerminalInput == 'P')
323 {
324 // Get the rover pose from the waypoint handler.
325 geoops::RoverPose stCurrentRoverPose = globals::g_pStateMachineHandler->SmartRetrieveRoverPose();
326 // Assemble a string to print containing data about the rover pose.
327 std::string szRoverPoseInfo = "\n--------[ Rover Pose Info ]--------\n";
328 szRoverPoseInfo += "Easting: " + std::to_string(stCurrentRoverPose.GetUTMCoordinate().dEasting) + "\n";
329 szRoverPoseInfo += "Northing: " + std::to_string(stCurrentRoverPose.GetUTMCoordinate().dNorthing) + "\n";
330 szRoverPoseInfo += "Altitude: " + std::to_string(stCurrentRoverPose.GetUTMCoordinate().dAltitude) + "\n";
331 szRoverPoseInfo += "Compass: " + std::to_string(stCurrentRoverPose.GetCompassHeading()) + "\n";
332 // Submit logger message.
333 LOG_NOTICE(logging::g_qSharedLogger, "{}", szRoverPoseInfo);
334 }
335 else if (chTerminalInput == 's' || chTerminalInput == 'S')
336 {
337 // Get the sensor data from the navigation board.
338 sl::SensorsData slSensorData;
339 std::future<bool> fuResult = pMainCam->RequestSensorsCopy(slSensorData);
340
341 // Wait for the data to be copied.
342 if (fuResult.get())
343 {
344 // Assemble a string to print containing data about the sensor data.
345 std::string szSensorDataInfo = "\n--------[ Sensor Data Info ]--------\n";
346 szSensorDataInfo += "IMU Accel X: " + std::to_string(slSensorData.imu.linear_acceleration.x) + "\n";
347 szSensorDataInfo += "IMU Accel Y: " + std::to_string(slSensorData.imu.linear_acceleration.y) + "\n";
348 szSensorDataInfo += "IMU Accel Z: " + std::to_string(slSensorData.imu.linear_acceleration.z) + "\n";
349 szSensorDataInfo += "IMU AngVel X: " + std::to_string(slSensorData.imu.angular_velocity.x) + "\n";
350 szSensorDataInfo += "IMU AngVel Y: " + std::to_string(slSensorData.imu.angular_velocity.y) + "\n";
351 szSensorDataInfo += "IMU AngVel Z: " + std::to_string(slSensorData.imu.angular_velocity.z) + "\n";
352 szSensorDataInfo += "IMU Gyro X:" + std::to_string(slSensorData.imu.pose.getEulerAngles(false).x) + "\n";
353 szSensorDataInfo += "IMU Gyro Y: " + std::to_string(slSensorData.imu.pose.getEulerAngles(false).y) + "\n";
354 szSensorDataInfo += "IMU Gyro Z: " + std::to_string(slSensorData.imu.pose.getEulerAngles(false).z) + "\n";
355 // Submit logger message.
356 LOG_NOTICE(logging::g_qSharedLogger, "{}", szSensorDataInfo);
357 }
358 }
359 else if (chTerminalInput == 'd' || chTerminalInput == 'D')
360 {
361 // Get the current drive powers from the drive board.
362 diffdrive::DrivePowers stCurrentDrivePowers = globals::g_pDriveBoard->GetDrivePowers();
363 // Assemble a string to print containing data about the drive powers.
364 std::string szDrivePowersInfo = "\n--------[ Drive Powers Info ]--------\n";
365 szDrivePowersInfo += "Left Power: " + std::to_string(stCurrentDrivePowers.dLeftDrivePower) + "\n";
366 szDrivePowersInfo += "Right Power: " + std::to_string(stCurrentDrivePowers.dRightDrivePower) + "\n";
367 // Submit logger message.
368 LOG_NOTICE(logging::g_qSharedLogger, "{}", szDrivePowersInfo);
369 }
370 else if (chTerminalInput == 't' || chTerminalInput == 'T')
371 {
372 // Get the tags from the tag detectors.
373 if (pMainTagDetector->GetIsReady())
374 {
375 // Create instance variables.
376 tagdetectutils::ArucoTag stBestOpenCVTag, stBestTorchTag;
377 int nTagCount = 0;
378
379 // Get the best/valid tags from the tag detectors.
380 std::vector<std::shared_ptr<TagDetector>> vTagDetectors = {pMainTagDetector};
381 // Check if the next waypoint in the waypoint handler exists and had a tag ID.
382 if (globals::g_pWaypointHandler->GetWaypointCount() > 0)
383 {
384 // Get the best tags from the tag detectors.
385 nTagCount = statemachine::IdentifyTargetMarker(vTagDetectors,
386 stBestOpenCVTag,
387 stBestTorchTag,
388 globals::g_pWaypointHandler->PeekNextWaypoint().nID);
389 }
390 else
391 {
392 // Get the best tags from the tag detectors.
393 nTagCount = statemachine::IdentifyTargetMarker(vTagDetectors, stBestOpenCVTag, stBestTorchTag);
394 }
395
396 // Submit logger message.
397 std::ostringstream ossTagsInfo;
398 ossTagsInfo << "\n--------[ All Detections ]--------\n"
399 << "Detected Tags Info:\n"
400 << "Total Tags: " << nTagCount << "\n";
401
402 ossTagsInfo << "\n--------[ Valid/Best Tags ]--------\n";
403 if (stBestOpenCVTag.nID != -1)
404 {
405 ossTagsInfo << "Best OpenCV Tag ID: " << stBestOpenCVTag.nID << "\n";
406 ossTagsInfo << "Best OpenCV Tag Distance: " << stBestOpenCVTag.dStraightLineDistance << "\n";
407 ossTagsInfo << "Best OpenCV Tag Yaw Angle: " << stBestOpenCVTag.dYawAngle << "\n";
408 }
409 else
410 {
411 ossTagsInfo << "No valid OpenCV tags detected.\n";
412 }
413 if (stBestTorchTag.dConfidence != 0.0)
414 {
415 ossTagsInfo << "Best Torch Tag ID: " << stBestTorchTag.nID << "\n";
416 ossTagsInfo << "Best Torch Tag Distance: " << stBestTorchTag.dStraightLineDistance << "\n";
417 ossTagsInfo << "Best Torch Tag Yaw Angle: " << stBestTorchTag.dYawAngle << "\n";
418 }
419 else
420 {
421 ossTagsInfo << "No valid Torch tags detected.\n";
422 }
423
424 LOG_NOTICE(logging::g_qSharedLogger, "{}", ossTagsInfo.str());
425 }
426 else
427 {
428 // Submit logger message.
429 LOG_WARNING(logging::g_qSharedLogger, "Tag Detector is not ready yet. Cannot get tags.");
430 }
431 }
432 else if (chTerminalInput == 'm' || chTerminalInput == 'M')
433 {
434 // Get the tags from the tag detectors.
435 if (pMainObjectDetector->GetIsReady())
436 {
437 // Create instance variables.
438 objectdetectutils::Object stBestTorchObject;
439 int nObjectCount = 0;
440
441 // Get the best/valid tags from the tag detectors.
442 std::vector<std::shared_ptr<ObjectDetector>> vTagDetectors = {pMainObjectDetector};
443 // Get the best tags from the tag detectors.
444 nObjectCount = statemachine::IdentifyTargetObject(vTagDetectors, stBestTorchObject);
445
446 // Submit logger message.
447 std::ostringstream ossTagsInfo;
448 ossTagsInfo << "\n--------[ All Detections ]--------\n"
449 << "Detected Object Info:\n"
450 << "Total Object: " << nObjectCount << "\n";
451
452 ossTagsInfo << "\n--------[ Valid/Best Objects ]--------\n";
453 if (stBestTorchObject.dConfidence != 0.0)
454 {
455 ossTagsInfo << "Best Torch Object Distance: " << stBestTorchObject.dStraightLineDistance << "\n";
456 ossTagsInfo << "Best Torch Object Yaw Angle: " << stBestTorchObject.dYawAngle << "\n";
457 }
458 else
459 {
460 ossTagsInfo << "No valid Torch objects detected.\n";
461 }
462
463 LOG_NOTICE(logging::g_qSharedLogger, "{}", ossTagsInfo.str());
464 }
465 else
466 {
467 // Submit logger message.
468 LOG_WARNING(logging::g_qSharedLogger, "Object Detector is not ready yet. Cannot get objects.");
469 }
470 }
471 else if (chTerminalInput == 'q' || chTerminalInput == 'Q')
472 {
473 LOG_INFO(logging::g_qSharedLogger, "'Q' key pressed. Initiating shutdown...");
474 bMainStop = true;
475 }
476 }
477 }
478
480 // Send thread stats over RoveComm.
482 // Check if rovecomm is initialized and running.
483 if (network::g_pRoveCommUDPNode)
484 {
485 // Construct a RoveComm packet with the drive data.
486 rovecomm::RoveCommPacket<uint32_t> stPacket;
487 stPacket.unDataId = manifest::Autonomy::TELEMETRY.find("THREADFPS")->second.DATA_ID;
488 stPacket.unDataCount = manifest::Autonomy::TELEMETRY.find("THREADFPS")->second.DATA_COUNT;
489 stPacket.eDataType = manifest::Autonomy::TELEMETRY.find("THREADFPS")->second.DATA_TYPE;
490 // Create a static variable to act a counter/iterator for the FPS value to use.
491 static uint32_t nThreadFPSIndex = 0;
492 // Check if the index is within bounds of the vector.
493 if (nThreadFPSIndex < static_cast<uint32_t>(vThreadFPSValues.size()))
494 {
495 // First push back the thread enum identifier cast to an int.
496 stPacket.vData.push_back(nThreadFPSIndex + 1);
497 // Add the current FPS value to the packet data.
498 stPacket.vData.push_back(static_cast<float>(vThreadFPSValues[nThreadFPSIndex]));
499 // Increment the index for the next iteration.
500 nThreadFPSIndex++;
501 }
502 else
503 {
504 // Reset the index if it exceeds the vector size.
505 nThreadFPSIndex = 0;
506 }
507 // Send the packet over RoveComm UDP.
508 network::g_pRoveCommUDPNode->SendUDPPacket(stPacket, "0.0.0.0", constants::ROVECOMM_OUTGOING_UDP_PORT);
509 }
510
511 // Update IPS tick.
512 IterPerSecond.Tick();
513
514 // No need to loop as fast as possible. Sleep...
515 std::this_thread::sleep_for(std::chrono::microseconds(66666));
516 }
517
519 // Cleanup.
521
522 // Export visualization data.
523 pVisualizationHandler->SaveVisualization(constants::LOGGING_OUTPUT_PATH_ABSOLUTE + logging::g_szProgramStartTimeString + "/visualization.html");
524
525 // Check if ZED spatial map was enabled.
526 if (pMainCam->GetSpatialMappingState() == sl::SPATIAL_MAPPING_STATE::OK)
527 {
528 // Submit logger message.
529 LOG_INFO(logging::g_qSharedLogger, "Exporting ZED spatial map...");
530 // Extract and save spatial map.
531 std::future<sl::Mesh> fuSpatialMap;
532 pMainCam->ExtractSpatialMapAsync(fuSpatialMap);
533 sl::Mesh slSpatialMap = fuSpatialMap.get();
534 std::string szFilePath = constants::LOGGING_OUTPUT_PATH_ABSOLUTE + logging::g_szProgramStartTimeString + "/spatial_map";
535 slSpatialMap.save(szFilePath.c_str(), sl::MESH_FILE_FORMAT::PLY);
536 }
537
538 // Stop handlers.
539 globals::g_pStateMachineHandler->StopStateMachine();
540 globals::g_pObjectDetectionHandler->StopAllDetectors();
541 globals::g_pTagDetectionHandler->StopAllDetectors();
542 globals::g_pCameraHandler->StopAllCameras();
543 // Stop the visualization handler.
544 pVisualizationHandler->RequestStop();
545 pVisualizationHandler->Join();
546
547 // Close the LiDAR database.
548 globals::g_pLiDARHandler->CloseDB();
549
550 // Cleanup GeoPlanner.
551 delete globals::g_pGeoPlanner;
552 // Cleanup handlers.
553 delete pVisualizationHandler;
554 delete globals::g_pStateMachineHandler;
555 delete globals::g_pObjectDetectionHandler;
556 delete globals::g_pTagDetectionHandler;
557 delete globals::g_pCameraHandler;
558 delete globals::g_pWaypointHandler;
559 delete globals::g_pLiDARHandler;
560 // Set all pointers to nullptr to prevent dangling pointers.
561 globals::g_pGeoPlanner = nullptr;
562 pVisualizationHandler = nullptr;
563 globals::g_pStateMachineHandler = nullptr;
564 globals::g_pObjectDetectionHandler = nullptr;
565 globals::g_pTagDetectionHandler = nullptr;
566 globals::g_pCameraHandler = nullptr;
567 globals::g_pWaypointHandler = nullptr;
568 globals::g_pLiDARHandler = nullptr;
569 }
570
571 // Stop RoveComm quill logging or quill will segfault if trying to output logs to RoveComm.
572 network::g_bRoveCommUDPStatus = false;
573 network::g_bRoveCommTCPStatus = false;
574
575 // Cleanup driver objects.
576 delete globals::g_pDriveBoard;
577 delete globals::g_pMultimediaBoard;
578 delete globals::g_pNavigationBoard;
579
580 // Finally, stop RoveComm.
581 LOG_INFO(logging::g_qSharedLogger, "Stopping RoveComm...");
582 network::g_pRoveCommUDPNode->CloseUDPSocket();
583 network::g_pRoveCommTCPNode->CloseTCPSocket();
584 delete network::g_pRoveCommUDPNode;
585 delete network::g_pRoveCommTCPNode;
586
587 // Set all pointers to nullptr to prevent dangling pointers.
588 globals::g_pDriveBoard = nullptr;
589 globals::g_pMultimediaBoard = nullptr;
590 globals::g_pNavigationBoard = nullptr;
591 network::g_pRoveCommUDPNode = nullptr;
592 network::g_pRoveCommTCPNode = nullptr;
593
594 // Submit logger message that program is done cleaning up and is now exiting.
595 LOG_INFO(logging::g_qSharedLogger, "Clean up finished. Exiting...");
596
597 // Successful exit.
598 return 0;
599}
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:180
void RequestStop()
Signals threads to stop executing user code, terminate. DOES NOT JOIN. This method will not force the...
Definition AutonomyThread.hpp:164
IPS & GetIPS()
Accessor for the Frame I P S private member.
Definition AutonomyThread.hpp:224
void Start()
When this method is called, it starts a new thread that runs the code within the ThreadedContinuousCo...
Definition AutonomyThread.hpp:117
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:132
void StartAllCameras()
Signals all cameras to start their threads.
Definition CameraHandler.cpp:103
void StartRecording()
Signal the RecordingHandler to start recording video feeds from the CameraHandler.
Definition CameraHandler.cpp:119
std::shared_ptr< ZEDCamera > GetZED(ZEDCamName eCameraName)
Accessor for ZED cameras.
Definition CameraHandler.cpp:170
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:295
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:39
bool CloseDB()
Closes the currently open LiDAR database.
Definition LiDARHandler.cpp:104
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:67
void StartRecording()
Signal the RecordingHandler to start recording feeds from the detectors.
Definition ObjectDetectionHandler.cpp:80
std::shared_ptr< ObjectDetector > GetObjectDetector(ObjectDetectors eDetectorName)
Accessor for ObjectDetector detectors.
Definition ObjectDetectionHandler.cpp:127
void StopAllDetectors()
Signals all detectors to stop their threads.
Definition ObjectDetectionHandler.cpp:93
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:187
void StopStateMachine()
This method will stop the state machine. It will signal whatever state is currently running to abort ...
Definition StateMachineHandler.cpp:212
geoops::RoverPose SmartRetrieveRoverPose(bool bVIOHeading=true, bool bVIOTracking=false)
Retrieve the rover's current position and heading. Automatically picks between getting the position/h...
Definition StateMachineHandler.cpp:445
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:98
void StartAllDetectors()
Signals all detectors to start their threads.
Definition TagDetectionHandler.cpp:72
void StartRecording()
Signal the RecordingHandler to start recording video feeds from the TagDetectionHandler.
Definition TagDetectionHandler.cpp:85
std::shared_ptr< TagDetector > GetTagDetector(TagDetectors eDetectorName)
Accessor for TagDetector detectors.
Definition TagDetectionHandler.cpp:132
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:137
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 AStar's algorithm with a bias towards trave...
Definition GeoPlanner.h:86
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:59
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:91
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:90
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. Combines attributes from TorchObject and TensorflowObject struct...
Definition ObjectDetectionUtility.hpp:74
Represents a single ArUco tag. Combines attributes from TorchTag, TensorflowTag, and the original Aru...
Definition TagDetectionUtilty.hpp:59
Here is the call graph for this function: