Autonomy main function.
126{
127
128 std::ifstream fHeaderText("../data/ASCII/v25.txt");
129 std::string szHeaderText;
130 if (fHeaderText.is_open())
131 {
132 std::ostringstream pHeaderText;
133 pHeaderText << fHeaderText.rdbuf();
134 szHeaderText = pHeaderText.str();
135 }
136
137 std::cout << szHeaderText << std::endl;
138 std::cout << "Copyright \u00A9 2025 - Mars Rover Design Team\n" << std::endl;
139
140
142
144
146
147 network::g_pRoveCommUDPNode = new rovecomm::RoveCommUDP();
148 network::g_pRoveCommTCPNode = new rovecomm::RoveCommTCP();
149
150 network::g_bRoveCommUDPStatus = network::g_pRoveCommUDPNode->InitUDPSocket(manifest::General::ETHERNET_UDP_PORT);
151 network::g_bRoveCommTCPStatus = network::g_pRoveCommTCPNode->InitTCPSocket(constants::ROVECOMM_TCP_INTERFACE_IP.c_str(), manifest::General::ETHERNET_TCP_PORT);
152
153
154 if (!network::g_bRoveCommUDPStatus || !network::g_bRoveCommTCPStatus)
155 {
156
157 LOG_CRITICAL(logging::g_qSharedLogger,
158 "RoveComm did not initialize properly! UDPNode Status: {}, TCPNode Status: {}",
159 network::g_bRoveCommUDPStatus.load(),
160 network::g_bRoveCommTCPStatus.load());
161
162
163 bMainStop = true;
164 }
165 else
166 {
167
168 LOG_INFO(logging::g_qSharedLogger, "RoveComm UDP and TCP nodes successfully initialized.");
169 }
170
171 network::g_pRoveCommUDPNode->AddUDPCallback<
uint8_t>(logging::SetLoggingLevelsCallback, manifest::Autonomy::COMMANDS.find(
"SETLOGGINGLEVELS")->second.DATA_ID);
172
173
177
178
179 if (bRunExampleFlag)
180 {
181
183 }
184 else
185 {
186
187 struct sigaction stSigBreak;
189 stSigBreak.sa_flags = 0;
190 sigemptyset(&stSigBreak.sa_mask);
191 sigaction(SIGINT, &stSigBreak, nullptr);
192 sigaction(SIGQUIT, &stSigBreak, nullptr);
193
195
196
197 if (constants::MODE_SIM)
198 {
199
200 for (int nIter = 0; nIter < 5; ++nIter)
201 {
202
203 LOG_WARNING(logging::g_qSharedLogger,
204 "Autonomy_Software is running in SIM mode! If you aren't currently using the Unreal RoveSoSimulator sim, disable SIM mode in CMakeLists.txt "
205 "or in your build arguments!");
206 }
207
208
209 std::this_thread::sleep_for(std::chrono::seconds(3));
210 }
211
212
218
219
223
227
229
231
232 std::shared_ptr<ZEDCamera> pMainCam = globals::g_pCameraHandler->
GetZED(CameraHandler::ZEDCamName::eHeadMainCam);
233 std::shared_ptr<TagDetector> pMainTagDetector = globals::g_pTagDetectionHandler->
GetTagDetector(TagDetectionHandler::TagDetectors::eHeadMainCam);
234 std::shared_ptr<ObjectDetector> pMainObjectDetector =
235 globals::g_pObjectDetectionHandler->
GetObjectDetector(ObjectDetectionHandler::ObjectDetectors::eHeadMainCam);
236 IPS IterPerSecond =
IPS();
237
238
240
241
242 std::vector<uint32_t> vThreadFPSValues;
243
244
245
246
247
248 while (!bMainStop)
249 {
250
251 vThreadFPSValues.clear();
253 vThreadFPSValues.push_back(
static_cast<uint32_t>(pMainCam->GetIPS().GetExactIPS()));
254 vThreadFPSValues.push_back(
static_cast<uint32_t>(pMainTagDetector->GetIPS().GetExactIPS()));
255 vThreadFPSValues.push_back(
static_cast<uint32_t>(pMainObjectDetector->GetIPS().GetExactIPS()));
256 vThreadFPSValues.push_back(
static_cast<uint32_t>(globals::g_pStateMachineHandler->GetIPS().GetExactIPS()));
257 vThreadFPSValues.push_back(
static_cast<uint32_t>(network::g_pRoveCommUDPNode->GetIPS().GetExactIPS()));
258 vThreadFPSValues.push_back(
static_cast<uint32_t>(network::g_pRoveCommTCPNode->GetIPS().GetExactIPS()));
259
260
261 std::string szMainInfo = "";
262
263 szMainInfo += "\n--------[ Threads FPS ]--------\n";
264 szMainInfo +=
"Main Process FPS: " + std::to_string(IterPerSecond.
GetExactIPS()) +
"\n";
265 szMainInfo += "MainCam FPS: " + std::to_string(pMainCam->GetIPS().GetExactIPS()) + "\n";
266 szMainInfo += "MainTagDetector FPS: " + std::to_string(pMainTagDetector->GetIPS().GetExactIPS()) + "\n";
267 szMainInfo += "MainObjectDetector FPS: " + std::to_string(pMainObjectDetector->GetIPS().GetExactIPS()) + "\n";
268 szMainInfo += "\nStateMachine FPS: " + std::to_string(globals::g_pStateMachineHandler->GetIPS().GetExactIPS()) + "\n";
269 szMainInfo += "\nRoveCommUDP FPS: " + std::to_string(network::g_pRoveCommTCPNode->GetIPS().GetExactIPS()) + "\n";
270 szMainInfo += "RoveCommTCP FPS: " + std::to_string(network::g_pRoveCommTCPNode->GetIPS().GetExactIPS()) + "\n";
271 szMainInfo += "\n--------[ State Machine Info ]--------\n";
273
274 LOG_DEBUG(logging::g_qSharedLogger, "{}", szMainInfo);
275
276
278 {
279 char chTerminalInput = 0;
280 ssize_t nBytesRead =
read(STDIN_FILENO, &chTerminalInput, 1);
281 if (nBytesRead <= 0)
282 {
283 LOG_WARNING(logging::g_qSharedLogger, "Failed to read from terminal input.");
284 }
285 else
286 {
287 if (chTerminalInput == 'h' || chTerminalInput == 'H')
288 {
289
290 LOG_NOTICE(logging::g_qSharedLogger,
291 "\n--------[ Autonomy Software Help ]--------\n"
292 "Press 'f' or 'F' to print FPS stats to the log file.\n"
293 "Press 'p' or 'P' to print rover pose info to the log file.\n"
294 "Press 't' or 'T' to print tag detection info to the log file.\n"
295 "Press 'm' or 'M' to print object detection info to the log file.\n"
296 "Press 'q' or 'Q' to quit the program.\n"
297 "-------------------------------------------\n");
298 }
299 else if (chTerminalInput == 'f' || chTerminalInput == 'F')
300 {
301 LOG_NOTICE(logging::g_qSharedLogger, "{}", szMainInfo);
302 }
303 else if (chTerminalInput == 'p' || chTerminalInput == 'P')
304 {
305
307
308 std::string szRoverPoseInfo = "\n--------[ Rover Pose Info ]--------\n";
309 szRoverPoseInfo +=
"Easting: " + std::to_string(stCurrentRoverPose.
GetUTMCoordinate().dEasting) +
"\n";
310 szRoverPoseInfo +=
"Northing: " + std::to_string(stCurrentRoverPose.
GetUTMCoordinate().dNorthing) +
"\n";
311 szRoverPoseInfo +=
"Altitude: " + std::to_string(stCurrentRoverPose.
GetUTMCoordinate().dAltitude) +
"\n";
312 szRoverPoseInfo +=
"Compass: " + std::to_string(stCurrentRoverPose.
GetCompassHeading()) +
"\n";
313
314 LOG_NOTICE(logging::g_qSharedLogger, "{}", szRoverPoseInfo);
315 }
316 else if (chTerminalInput == 't' || chTerminalInput == 'T')
317 {
318
319 if (pMainTagDetector->GetIsReady())
320 {
321
323 int nTagCount = 0;
324
325
326 std::vector<std::shared_ptr<TagDetector>> vTagDetectors = {pMainTagDetector};
327
328 if (globals::g_pWaypointHandler->GetWaypointCount() > 0)
329 {
330
332 stBestOpenCVTag,
333 stBestTorchTag,
334 globals::g_pWaypointHandler->PeekNextWaypoint().nID);
335 }
336 else
337 {
338
340 }
341
342
343 std::ostringstream ossTagsInfo;
344 ossTagsInfo << "\n--------[ All Detections ]--------\n"
345 << "Detected Tags Info:\n"
346 << "Total Tags: " << nTagCount << "\n";
347
348 ossTagsInfo << "\n--------[ Valid/Best Tags ]--------\n";
349 if (stBestOpenCVTag.nID != -1)
350 {
351 ossTagsInfo << "Best OpenCV Tag ID: " << stBestOpenCVTag.nID << "\n";
352 ossTagsInfo << "Best OpenCV Tag Distance: " << stBestOpenCVTag.dStraightLineDistance << "\n";
353 ossTagsInfo << "Best OpenCV Tag Yaw Angle: " << stBestOpenCVTag.dYawAngle << "\n";
354 }
355 else
356 {
357 ossTagsInfo << "No valid OpenCV tags detected.\n";
358 }
359 if (stBestTorchTag.dConfidence != 0.0)
360 {
361 ossTagsInfo << "Best Torch Tag ID: " << stBestTorchTag.nID << "\n";
362 ossTagsInfo << "Best Torch Tag Distance: " << stBestTorchTag.dStraightLineDistance << "\n";
363 ossTagsInfo << "Best Torch Tag Yaw Angle: " << stBestTorchTag.dYawAngle << "\n";
364 }
365 else
366 {
367 ossTagsInfo << "No valid Torch tags detected.\n";
368 }
369
370 LOG_NOTICE(logging::g_qSharedLogger, "{}", ossTagsInfo.str());
371 }
372 else
373 {
374
375 LOG_WARNING(logging::g_qSharedLogger, "Tag Detector is not ready yet. Cannot get tags.");
376 }
377 }
378 else if (chTerminalInput == 'm' || chTerminalInput == 'M')
379 {
380
381 if (pMainObjectDetector->GetIsReady())
382 {
383
385 int nObjectCount = 0;
386
387
388 std::vector<std::shared_ptr<ObjectDetector>> vTagDetectors = {pMainObjectDetector};
389
391
392
393 std::ostringstream ossTagsInfo;
394 ossTagsInfo << "\n--------[ All Detections ]--------\n"
395 << "Detected Object Info:\n"
396 << "Total Object: " << nObjectCount << "\n";
397
398 ossTagsInfo << "\n--------[ Valid/Best Objects ]--------\n";
399 if (stBestTorchObject.dConfidence != 0.0)
400 {
401 ossTagsInfo << "Best Torch Object Distance: " << stBestTorchObject.dStraightLineDistance << "\n";
402 ossTagsInfo << "Best Torch Object Yaw Angle: " << stBestTorchObject.dYawAngle << "\n";
403 }
404 else
405 {
406 ossTagsInfo << "No valid Torch objects detected.\n";
407 }
408
409 LOG_NOTICE(logging::g_qSharedLogger, "{}", ossTagsInfo.str());
410 }
411 else
412 {
413
414 LOG_WARNING(logging::g_qSharedLogger, "Object Detector is not ready yet. Cannot get objects.");
415 }
416 }
417 else if (chTerminalInput == 'q' || chTerminalInput == 'Q')
418 {
419 LOG_INFO(logging::g_qSharedLogger, "'Q' key pressed. Initiating shutdown...");
420 bMainStop = true;
421 }
422 }
423 }
424
426
428
429 if (network::g_pRoveCommUDPNode)
430 {
431
432 rovecomm::RoveCommPacket<uint32_t> stPacket;
433 stPacket.unDataId = manifest::Autonomy::TELEMETRY.find("THREADFPS")->second.DATA_ID;
434 stPacket.unDataCount = manifest::Autonomy::TELEMETRY.find("THREADFPS")->second.DATA_COUNT;
435 stPacket.eDataType = manifest::Autonomy::TELEMETRY.find("THREADFPS")->second.DATA_TYPE;
436
437 static uint32_t nThreadFPSIndex = 0;
438
439 if (nThreadFPSIndex <
static_cast<uint32_t>(vThreadFPSValues.size()))
440 {
441
442 stPacket.vData.push_back(nThreadFPSIndex + 1);
443
444 stPacket.vData.push_back(static_cast<float>(vThreadFPSValues[nThreadFPSIndex]));
445
446 nThreadFPSIndex++;
447 }
448 else
449 {
450
451 nThreadFPSIndex = 0;
452 }
453
454 network::g_pRoveCommUDPNode->SendUDPPacket(stPacket, "0.0.0.0", constants::ROVECOMM_OUTGOING_UDP_PORT);
455 }
456
457
458 IterPerSecond.
Tick();
459
460
461 std::this_thread::sleep_for(std::chrono::microseconds(66666));
462 }
463
465
467
468
469 if (pMainCam->GetSpatialMappingState() == sl::SPATIAL_MAPPING_STATE::OK)
470 {
471
472 LOG_INFO(logging::g_qSharedLogger, "Exporting ZED spatial map...");
473
474 std::future<sl::Mesh> fuSpatialMap;
475 pMainCam->ExtractSpatialMapAsync(fuSpatialMap);
476 sl::Mesh slSpatialMap = fuSpatialMap.get();
477 std::string szFilePath = constants::LOGGING_OUTPUT_PATH_ABSOLUTE + logging::g_szProgramStartTimeString + "/spatial_map";
478 slSpatialMap.save(szFilePath.c_str(), sl::MESH_FILE_FORMAT::PLY);
479 }
480
481
486
487
488 delete globals::g_pStateMachineHandler;
489 delete globals::g_pObjectDetectionHandler;
490 delete globals::g_pTagDetectionHandler;
491 delete globals::g_pCameraHandler;
492 delete globals::g_pWaypointHandler;
493
494 globals::g_pStateMachineHandler = nullptr;
495 globals::g_pObjectDetectionHandler = nullptr;
496 globals::g_pTagDetectionHandler = nullptr;
497 globals::g_pCameraHandler = nullptr;
498 globals::g_pWaypointHandler = nullptr;
499 }
500
501
502 network::g_bRoveCommUDPStatus = false;
503 network::g_bRoveCommTCPStatus = false;
504
505
506 delete globals::g_pDriveBoard;
507 delete globals::g_pMultimediaBoard;
508 delete globals::g_pNavigationBoard;
509
510
511 LOG_INFO(logging::g_qSharedLogger, "Stopping RoveComm...");
512 network::g_pRoveCommUDPNode->CloseUDPSocket();
513 network::g_pRoveCommTCPNode->CloseTCPSocket();
514 delete network::g_pRoveCommUDPNode;
515 delete network::g_pRoveCommTCPNode;
516
517
518 globals::g_pDriveBoard = nullptr;
519 globals::g_pMultimediaBoard = nullptr;
520 globals::g_pNavigationBoard = nullptr;
521 network::g_pRoveCommUDPNode = nullptr;
522 network::g_pRoveCommTCPNode = nullptr;
523
524
525 LOG_INFO(logging::g_qSharedLogger, "Clean up finished. Exiting...");
526
527
528 return 0;
529}
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:34
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
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:46
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:209
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 WaypointHandler class is used throughout the entire project (mainly by the state machine) to glob...
Definition WaypointHandler.h:33
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 WaypointHandler.cpp:742
void SetNonCanonicalTerminalMode()
Mutator for the Non Canonical Terminal Mode private member.
Definition main.cpp:89
int CheckKeyPress()
Check if a key has been pressed in the terminal.
Definition main.cpp:110
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:48
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:60
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:89
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 by the WaypointHandler to provide an easy way to store all pose data about the ro...
Definition GeospatialOperations.hpp:677
double GetCompassHeading() const
Accessor for the Compass Heading private member.
Definition GeospatialOperations.hpp:756
const geoops::UTMCoordinate & GetUTMCoordinate() const
Accessor for the geoops::UTMCoordinate member variable.
Definition GeospatialOperations.hpp:736
Represents a single detected object. Combines attributes from TorchObject and TensorflowObject struct...
Definition ObjectDetectionUtility.hpp:73
Represents a single ArUco tag. Combines attributes from TorchTag, TensorflowTag, and the original Aru...
Definition TagDetectionUtilty.hpp:59