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
statemachine::NavigatingState Class Reference

The NavigatingState class implements the Navigating state for the Autonomy State Machine. More...

#include <NavigatingState.h>

Inheritance diagram for statemachine::NavigatingState:
Collaboration diagram for statemachine::NavigatingState:

Public Member Functions

 NavigatingState ()
 Construct a new State object.
 
void Run () override
 Run the state machine. Returns the next state.
 
States TriggerEvent (Event eEvent) override
 Trigger an event in the state machine. Returns the next state.
 
- Public Member Functions inherited from statemachine::State
 State (States eState)
 Construct a new State object.
 
virtual ~State ()=default
 Destroy the State object.
 
States GetState () const
 Accessor for the State private member.
 
virtual std::string ToString () const
 Accessor for the State private member. Returns the state as a string.
 
virtual bool operator== (const State &other) const
 Checks to see if the current state is equal to the passed state.
 
virtual bool operator!= (const State &other) const
 Checks to see if the current state is not equal to the passed state.
 

Protected Member Functions

void Start () override
 This method is called when the state is first started. It is used to initialize the state.
 
void Exit () override
 This method is called when the state is exited. It is used to clean up the state.
 

Private Attributes

bool m_bWasStuck
 
bool m_bWithinWaypointRadius
 
bool m_bFetchNewWaypoint
 
geoops::Waypoint m_stGoalWaypoint
 
bool m_bInitialized
 
std::vector< std::shared_ptr< TagDetector > > m_vTagDetectors
 
std::vector< std::shared_ptr< ObjectDetector > > m_vObjectDetectors
 
statemachine::TimeIntervalBasedStuckDetector m_StuckDetector
 
std::unique_ptr< controllers::PredictiveStanleyController > m_pStanleyController
 
std::vector< geoops::Waypoint > m_vPathCoordinates
 

Detailed Description

The NavigatingState class implements the Navigating state for the Autonomy State Machine.

Author
Eli Byrd (edbgk.nosp@m.k@ms.nosp@m.t.edu)
Date
2024-01-17

Constructor & Destructor Documentation

◆ NavigatingState()

statemachine::NavigatingState::NavigatingState ( )

Construct a new State object.

Author
Eli Byrd (edbgk.nosp@m.k@ms.nosp@m.t.edu), Sam Hajdukiewicz (saman.nosp@m.thah.nosp@m.ajduk.nosp@m.iewi.nosp@m.cz@gm.nosp@m.ail..nosp@m.com)
Date
2024-01-17
69 : State(States::eNavigating)
70 {
71 // Submit logger message.
72 LOG_INFO(logging::g_qConsoleLogger, "Entering State: {}", ToString());
73
74 // Initialize member variables.
75 m_bInitialized = false;
76 m_StuckDetector = statemachine::TimeIntervalBasedStuckDetector(constants::NAVIGATING_STUCK_CHECK_ATTEMPTS, constants::NAVIGATING_STUCK_CHECK_INTERVAL);
77 m_pStanleyController = std::make_unique<controllers::PredictiveStanleyController>(constants::STANLEY_CROSSTRACK_CONTROL_GAIN,
78 constants::STANLEY_ANGULAR_VELOCITY_LIMIT,
79 constants::STANLEY_PREDICTION_HORIZON,
80 constants::STANLEY_PREDICTION_TIME_STEP);
81
82 // Start state.
83 if (!m_bInitialized)
84 {
85 Start();
86 m_bInitialized = true;
87 }
88 }
void Start() override
This method is called when the state is first started. It is used to initialize the state.
Definition NavigatingState.cpp:33
virtual std::string ToString() const
Accessor for the State private member. Returns the state as a string.
Definition State.hpp:202
State(States eState)
Construct a new State object.
Definition State.hpp:145
This class should be instantiated within another state to be used for detection of if the rover is st...
Definition StuckDetection.hpp:43
Here is the call graph for this function:

Member Function Documentation

◆ Start()

void statemachine::NavigatingState::Start ( )
overrideprotectedvirtual

This method is called when the state is first started. It is used to initialize the state.

Author
Eli Byrd (edbgk.nosp@m.k@ms.nosp@m.t.edu), Sam Hajdukiewicz (saman.nosp@m.thah.nosp@m.ajduk.nosp@m.iewi.nosp@m.cz@gm.nosp@m.ail..nosp@m.com)
Date
2024-01-17

Reimplemented from statemachine::State.

34 {
35 // Schedule the next run of the state's logic
36 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Scheduling next run of state logic.");
37
38 // Initialize member variables.
39 m_bWasStuck = false;
40 m_bWithinWaypointRadius = false;
41 m_bFetchNewWaypoint = true;
42 m_vTagDetectors = {globals::g_pTagDetectionHandler->GetTagDetector(TagDetectionHandler::TagDetectors::eHeadMainCam),
43 globals::g_pTagDetectionHandler->GetTagDetector(TagDetectionHandler::TagDetectors::eRearCam)};
44 m_vObjectDetectors = {globals::g_pObjectDetectionHandler->GetObjectDetector(ObjectDetectionHandler::ObjectDetectors::eHeadMainCam),
45 globals::g_pObjectDetectionHandler->GetObjectDetector(ObjectDetectionHandler::ObjectDetectors::eRearCam)};
46 }
std::shared_ptr< ObjectDetector > GetObjectDetector(ObjectDetectors eDetectorName)
Accessor for ObjectDetector detectors.
Definition ObjectDetectionHandler.cpp:153
std::shared_ptr< TagDetector > GetTagDetector(TagDetectors eDetectorName)
Accessor for TagDetector detectors.
Definition TagDetectionHandler.cpp:163
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Exit()

void statemachine::NavigatingState::Exit ( )
overrideprotectedvirtual

This method is called when the state is exited. It is used to clean up the state.

Author
Eli Byrd (edbgk.nosp@m.k@ms.nosp@m.t.edu)
Date
2024-01-17

Reimplemented from statemachine::State.

57 {
58 // Clean up the state before exiting
59 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Exiting state.");
60 }
Here is the caller graph for this function:

◆ Run()

void statemachine::NavigatingState::Run ( )
overridevirtual

Run the state machine. Returns the next state.

Author
Eli Byrd (edbgk.nosp@m.k@ms.nosp@m.t.edu)
Date
2024-01-17

Implements statemachine::State.

97 {
98 // Submit logger message.
99 LOG_DEBUG(logging::g_qSharedLogger, "NavigatingState: Running state-specific behavior.");
100
101 // If navigating was previously stuck, then re-path plan stuck area
102 if (m_bWasStuck)
103 {
104 // Retrieve modified path from stuck
105 m_vPathCoordinates = globals::g_pWaypointHandler->RetrievePath("GeoPlannerPath");
106
107 // Update visualizer and stanley
108 m_pStanleyController->SetReferencePath(m_vPathCoordinates);
109
110 m_bWasStuck = false;
111 }
112
113 // Check if we should get a new goal waypoint and that the waypoint handler has one for us.
114 if (m_bFetchNewWaypoint && globals::g_pWaypointHandler->GetWaypointCount() > 0)
115 {
116 // Trigger new waypoint event.
117 globals::g_pStateMachineHandler->HandleEvent(Event::eNewWaypoint);
118 return;
119 }
120
121 // Get Current rover pose.
122 geoops::RoverPose stCurrentRoverPose = globals::g_pStateMachineHandler->SmartRetrieveRoverPose();
123
124 // Calculate distance and bearing from goal waypoint.
125 geoops::GeoMeasurement stGoalWaypointMeasurement = geoops::CalculateGeoMeasurement(stCurrentRoverPose.GetUTMCoordinate(), m_stGoalWaypoint.GetUTMCoordinate());
126
127 // Only print out every so often.
128 static bool bAlreadyPrinted = false;
129 if ((std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count() % 5) == 0 && !bAlreadyPrinted)
130 {
131 // Assemble the error metrics into a single string. We are going to include the distance and bearing to the goal waypoint and
132 // the error between the rover pose and the GPS position. The rover pose could be from VIO or GNSS fusion, or just GPS.
133 std::string szErrorMetrics =
134 "--------[ Navigating Error Report ]--------\nDistance to Goal Waypoint: " + std::to_string(stGoalWaypointMeasurement.dDistanceMeters) + " meters\n" +
135 "Bearing to Goal Waypoint: " + std::to_string(stGoalWaypointMeasurement.dStartRelativeBearing) + " degrees\n";
136 // Submit the error metrics to the logger.
137 LOG_INFO(logging::g_qSharedLogger, "{}", szErrorMetrics);
138
139 // Set toggle.
140 bAlreadyPrinted = true;
141 }
142 else if ((std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count() % 5) != 0 && bAlreadyPrinted)
143 {
144 // Reset toggle.
145 bAlreadyPrinted = false;
146 }
147
148 /*
149 The overall flow of this state is as follows.
150 1. Is there a tag -> MarkerSeen
151 2. Is there an object -> ObjectSeen
152 3. Is there an obstacle -> TBD
153 4. Navigate to goal waypoint.
154 5. Is the rover stuck -> Stuck
155 */
156
158 /* --- Detect Tags --- */
160
161 // In order to even care about any tags we see, the goal waypoint needs to be of type MARKER and we need to be within the search radius of the MARKER waypoint.
162 if (m_stGoalWaypoint.eType == geoops::WaypointType::eTagWaypoint && stGoalWaypointMeasurement.dDistanceMeters <= m_stGoalWaypoint.dRadius)
163 {
164 // Create instance variables.
165 tagdetectutils::ArucoTag stBestArucoTag, stBestTorchTag;
166 // Identify target marker.
167 statemachine::IdentifyTargetMarker(m_vTagDetectors, stBestArucoTag, stBestTorchTag, m_stGoalWaypoint.nID);
168 // Check if either tag type is seen.
169 if (stBestArucoTag.nID != -1 || stBestTorchTag.dConfidence != 0.0)
170 {
171 // Submit logger message.
172 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Rover has seen a target marker!");
173 // Handle state transition and save the current search pattern state.
174 globals::g_pStateMachineHandler->HandleEvent(Event::eMarkerSeen, true);
175 // Don't execute the rest of the state.
176 return;
177 }
178 }
179
181 /* --- Detect Objects --- */
183
184 // In order to even care about any objects we see, the goal waypoint needs to be of an object type and we need to be within the search radius of the object
185 // waypoint.
186 if ((m_stGoalWaypoint.eType == geoops::WaypointType::eObjectWaypoint || m_stGoalWaypoint.eType == geoops::WaypointType::eMalletWaypoint ||
187 m_stGoalWaypoint.eType == geoops::WaypointType::eWaterBottleWaypoint || m_stGoalWaypoint.eType == geoops::WaypointType::eRockPickWaypoint) &&
188 stGoalWaypointMeasurement.dDistanceMeters <= m_stGoalWaypoint.dRadius)
189 {
190 // Create instance variables.
191 objectdetectutils::Object stBestTorchObject;
192 // Identify target object.
193 statemachine::IdentifyTargetObject(m_vObjectDetectors, stBestTorchObject, m_stGoalWaypoint.eType);
194 // Check if either tag type is seen.
195 if (stBestTorchObject.dConfidence != 0.0)
196 {
197 // Submit logger message.
198 LOG_NOTICE(logging::g_qSharedLogger, "NavigatingState: Rover has seen a target object!");
199
200 // Handle state transition and save the current search pattern state.
201 globals::g_pStateMachineHandler->HandleEvent(Event::eObjectSeen, true);
202 // Don't execute the rest of the state.
203 return;
204 }
205 }
206
208 /* --- Detect Obstacles --- */
210
211 // TODO: Add obstacle detection to Navigating state
212
214 /* --- Navigate to goal waypoint --- */
216 // Check if we are at the goal waypoint.
217 if (stGoalWaypointMeasurement.dDistanceMeters > constants::NAVIGATING_REACHED_GOAL_RADIUS)
218 {
219 // Default to normal navigating speed.
220 double dNavigatingSpeed = constants::NAVIGATING_MOTOR_POWER;
221
222 // Check if we are at least withing the radius of the goal waypoint. If we are, slow down to search pattern speeds.
223 if (constants::NAVIGATING_SLOWDOWN_WITHIN_WAYPOINT_RADIUS && stGoalWaypointMeasurement.dDistanceMeters <= m_stGoalWaypoint.dRadius)
224 {
225 // Check if this is the first time entering the radius
226 if (!m_bWithinWaypointRadius)
227 {
228 LOG_NOTICE(logging::g_qSharedLogger,
229 "NavigatingState: Rover is now within waypoint radius of {}. Slowing down to search pattern speed...",
230 m_stGoalWaypoint.dRadius);
231 m_bWithinWaypointRadius = true;
232 }
233
234 // Update navigating power to match the search pattern power.
235 dNavigatingSpeed = constants::SEARCH_MOTOR_POWER;
236 }
237
238 // Use stanley to calculate drive move/powers.
239 controllers::PredictiveStanleyController::DriveVector stDriveVector = m_pStanleyController->Calculate(stCurrentRoverPose, dNavigatingSpeed);
240 // Calculate move from goal heading and desired speed.
241 diffdrive::DrivePowers stDriveSpeeds = globals::g_pDriveBoard->CalculateMove(stDriveVector.dVelocity,
242 stDriveVector.dThetaHeading,
243 stCurrentRoverPose.GetCompassHeading(),
244 diffdrive::DifferentialControlMethod::eArcadeDrive);
245 // Send drive powers over RoveComm.
246 globals::g_pDriveBoard->SendDrive(stDriveSpeeds);
247 }
248 else
249 {
250 // Stop drive.
251 globals::g_pDriveBoard->SendStop();
252
253 // Check waypoint type.
254 switch (m_stGoalWaypoint.eType)
255 {
256 // Goal waypoint is navigation.
257 case geoops::WaypointType::eNavigationWaypoint:
258 {
259 // Continuously navigate to the next waypoint if our current waypoint ID is set to -99.
260 if (globals::g_pWaypointHandler->GetWaypointCount() > 1 &&
261 m_stGoalWaypoint.nID == static_cast<int>(manifest::Autonomy::AUTONOMYWAYPOINTTYPES::CONTINUOUSNAVIGATE))
262 {
263 // Submit logger message.
264 LOG_NOTICE(logging::g_qSharedLogger,
265 "NavigatingState: The current waypoint ID is signalling continuous navigation ({}). Continuing to next waypoint...",
266 m_stGoalWaypoint.nID);
267 // Pop the next waypoint.
268 globals::g_pWaypointHandler->PopNextWaypoint();
269 // Trigger new waypoint event.
270 globals::g_pStateMachineHandler->HandleEvent(Event::eNewWaypoint, true);
271 }
272 else
273 {
274 // We are at the goal, signal event.
275 globals::g_pStateMachineHandler->HandleEvent(Event::eReachedGpsCoordinate, false);
276 }
277 return;
278 }
279 // Goal waypoint is marker.
280 case geoops::WaypointType::eTagWaypoint:
281 {
282 // We are at the goal, signal event.
283 globals::g_pStateMachineHandler->HandleEvent(Event::eReachedMarker, false);
284 return;
285 }
286 // Goal waypoint is object.
287 case geoops::WaypointType::eObjectWaypoint:
288 {
289 // We are at the goal, signal event.
290 globals::g_pStateMachineHandler->HandleEvent(Event::eReachedObject, false);
291 return;
292 }
293 // Goal waypoint is mallet.
294 case geoops::WaypointType::eMalletWaypoint:
295 {
296 // We are at the goal, signal event.
297 globals::g_pStateMachineHandler->HandleEvent(Event::eReachedObject, false);
298 return;
299 }
300 // Goal waypoint is water bottle.
301 case geoops::WaypointType::eWaterBottleWaypoint:
302 {
303 // We are at the goal, signal event.
304 globals::g_pStateMachineHandler->HandleEvent(Event::eReachedObject, false);
305 return;
306 }
307 // Goal waypoint is rock pick.
308 case geoops::WaypointType::eRockPickWaypoint:
309 {
310 // We are at the goal, signal event.
311 globals::g_pStateMachineHandler->HandleEvent(Event::eReachedObject, false);
312 return;
313 }
314 default:
315 {
316 // This waypoint type is not supported.
317 LOG_ERROR(logging::g_qSharedLogger, "NavigatingState: Unknown waypoint type!");
318 // Handle event.
319 globals::g_pStateMachineHandler->HandleEvent(Event::eAbort, true);
320 // Don't execute the rest of the state.
321 return;
322 }
323 }
324 }
325
327 /* --- Check if the rover is stuck --- */
329
330 // Check if stuck.
331 if (constants::NAVIGATING_ENABLE_STUCK_DETECT &&
332 m_StuckDetector.CheckIfStuck(globals::g_pStateMachineHandler->SmartRetrieveVelocity() * globals::g_pDriveBoard->GetMaxDriveEffort(),
333 globals::g_pStateMachineHandler->SmartRetrieveAngularVelocity(),
334 constants::NAVIGATING_STUCK_CHECK_VEL_THRESH * globals::g_pDriveBoard->GetMaxDriveEffort(),
335 constants::NAVIGATING_STUCK_CHECK_ROT_THRESH))
336 {
337 // Submit logger message.
338 LOG_NOTICE(logging::g_qSharedLogger, "NavigatingState: Rover has become stuck!");
339 m_bWasStuck = true;
340 // Handle state transition and save the current navigating state.
341 globals::g_pStateMachineHandler->HandleEvent(Event::eStuck, true);
342 // Don't execute the rest of the state.
343 return;
344 }
345 }
void SendDrive(const diffdrive::DrivePowers &stDrivePowers, const bool bEnableVariableDriveEffort=true)
Sets the left and right drive powers of the drive board.
Definition DriveBoard.cpp:166
diffdrive::DrivePowers CalculateMove(const double dGoalSpeed, const double dGoalHeading, const double dActualHeading, const diffdrive::DifferentialControlMethod eKinematicsMethod=diffdrive::DifferentialControlMethod::eArcadeDrive, const bool bDriveBackwards=false, const bool bAlwaysProgressForward=false, const bool bSquareControlInput=false, const bool bCurvatureDriveAllowTurningWhileStopped=true)
This method determines drive powers to make the Rover drive towards a given heading at a given speed.
Definition DriveBoard.cpp:89
void SendStop()
Stop the drivetrain of the Rover.
Definition DriveBoard.cpp:246
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
void HandleEvent(statemachine::Event eEvent, const bool bSaveCurrentState=false)
This method Handles Events that are passed to the State Machine Handler. It will check the current st...
Definition StateMachineHandler.cpp:285
geoops::Waypoint PopNextWaypoint()
Removes and returns the next waypoint at the front of the list.
Definition WaypointHandler.cpp:500
const std::vector< geoops::Waypoint > RetrievePath(const std::string &szPathName)
Retrieve an immutable reference to the path at the given path name/key.
Definition WaypointHandler.cpp:600
bool CheckIfStuck(double dCurrentVelocity, double dCurrentAngularVelocity, double dVelocityThreshold=0.1, double dAngularVelocityThreshold=0.1)
Checks if the rover meets stuck criteria based in the given parameters.
Definition StuckDetection.hpp:96
GeoMeasurement CalculateGeoMeasurement(const GPSCoordinate &stCoord1, const GPSCoordinate &stCoord2)
The shortest path between two points on an ellipsoid at (lat1, lon1) and (lat2, lon2) is called the g...
Definition GeospatialOperations.hpp:553
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
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
Definition PredictiveStanleyController.h:50
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 to store the distance, arc length, and relative bearing for a calculated geodesic...
Definition GeospatialOperations.hpp:83
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
const geoops::UTMCoordinate & GetUTMCoordinate() const
Accessor for the geoops::UTMCoordinate member variable.
Definition GeospatialOperations.hpp:508
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:

◆ TriggerEvent()

States statemachine::NavigatingState::TriggerEvent ( Event  eEvent)
overridevirtual

Trigger an event in the state machine. Returns the next state.

Parameters
eEvent- The event to trigger.
Returns
std::shared_ptr<State> - The next state.
Author
Eli Byrd (edbgk.nosp@m.k@ms.nosp@m.t.edu)
Date
2024-01-17

Implements statemachine::State.

357 {
358 // Create instance variables.
359 States eNextState = States::eNavigating;
360 bool bCompleteStateExit = true;
361
362 switch (eEvent)
363 {
364 case Event::eNoWaypoint:
365 {
366 // Submit logger message.
367 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Handling No Waypoint event.");
368 // Change state.
369 eNextState = States::eIdle;
370 break;
371 }
372 case Event::eReachedGpsCoordinate:
373 {
374 // Submit logger message.
375 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Handling Reached GPS Coordinate event.");
376 // Check constants to see if we should go into verifying position or just trigger reached marker.
377 if (constants::NAVIGATING_VERIFY_POSITION)
378 {
379 // Send multimedia command to update state display.
380 globals::g_pMultimediaBoard->SendLightingState(MultimediaBoard::MultimediaBoardLightingState::eAutonomy);
381 // Change state.
382 eNextState = States::eVerifyingPosition;
383 }
384 else
385 {
386 // Send multimedia command to update state display.
387 globals::g_pMultimediaBoard->SendLightingState(MultimediaBoard::MultimediaBoardLightingState::eReachedGoal);
388 // Pop the next waypoint.
389 globals::g_pWaypointHandler->PopNextWaypoint();
390 // Change state.
391 eNextState = States::eIdle;
392 }
393 break;
394 }
395 case Event::eReachedMarker:
396 {
397 // Submit logger message.
398 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Handling Reached Marker Waypoint event.");
399 // Send multimedia command to update state display.
400 globals::g_pMultimediaBoard->SendLightingState(MultimediaBoard::MultimediaBoardLightingState::eAutonomy);
401 // Change state.
402 eNextState = States::eSearchPattern;
403 break;
404 }
405 case Event::eReachedObject:
406 {
407 // Submit logger message.
408 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Handling Reached Object Waypoint event.");
409 // Send multimedia command to update state display.
410 globals::g_pMultimediaBoard->SendLightingState(MultimediaBoard::MultimediaBoardLightingState::eAutonomy);
411 // Change state.
412 eNextState = States::eSearchPattern;
413 break;
414 }
415 case Event::eNewWaypoint:
416 {
417 // Check if the next goal waypoint equals the current one.
418 if (m_stGoalWaypoint == globals::g_pWaypointHandler->PeekNextWaypoint())
419 {
420 // Submit logger message.
421 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Reusing current Waypoint.");
422 }
423 else
424 {
425 // Submit logger message.
426 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Handling New Waypoint event.");
427
428 // Reset radius toggle for the new waypoint
429 m_bWithinWaypointRadius = false;
430
431 // Get and store new goal waypoint.
432 m_stGoalWaypoint = globals::g_pWaypointHandler->PeekNextWaypoint();
433 // Plan a new path using the GeoPlanner.
434 m_vPathCoordinates = globals::g_pGeoPlanner->PlanPath(globals::g_pLiDARHandler,
435 globals::g_pStateMachineHandler->SmartRetrieveRoverPose().GetUTMCoordinate(),
436 m_stGoalWaypoint.GetUTMCoordinate());
437 // Add the path to the waypoint handler for reference by other states or handlers.
438 globals::g_pWaypointHandler->StorePath("GeoPlannerPath", m_vPathCoordinates);
439 // Set the path of the stanley controller.
440 m_pStanleyController->SetReferencePath(m_vPathCoordinates);
441
442 // Get all obstacles from the obstacle handler.
443 std::vector<geoops::Waypoint> vObstacles = globals::g_pWaypointHandler->GetAllObstacles();
444
445 // Check if the path is empty. If it is, go to idle state.
446 if (m_vPathCoordinates.empty())
447 {
448 LOG_WARNING(logging::g_qSharedLogger, "NavigatingState: Planned path is empty! Transitioning to Idle State.");
449 eNextState = States::eIdle;
450 }
451 }
452
453 // Send multimedia command to update state display.
454 globals::g_pMultimediaBoard->SendLightingState(MultimediaBoard::MultimediaBoardLightingState::eAutonomy);
455 // Set toggle.
456 m_bFetchNewWaypoint = false;
457 break;
458 }
459 case Event::eStart:
460 {
461 // Submit logger message.
462 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Handling Start event.");
463 // Send multimedia command to update state display.
464 globals::g_pMultimediaBoard->SendLightingState(MultimediaBoard::MultimediaBoardLightingState::eAutonomy);
465 break;
466 }
467 case Event::eAbort:
468 {
469 // Submit logger message.
470 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Handling Abort event.");
471 // Stop drive.
472 globals::g_pDriveBoard->SendStop();
473 // Send multimedia command to update state display.
474 globals::g_pMultimediaBoard->SendLightingState(MultimediaBoard::MultimediaBoardLightingState::eOff);
475 // Set toggle.
476 m_bFetchNewWaypoint = true;
477 // Change states.
478 eNextState = States::eIdle;
479 break;
480 }
481 case Event::eMarkerSeen:
482 {
483 // Submit logger message.
484 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Handling MarkerSeen event.");
485 // Change states.
486 eNextState = States::eApproachingMarker;
487 break;
488 }
489 case Event::eObjectSeen:
490 {
491 // Submit logger message.
492 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Handling ObjectSeen event.");
493 // Change states.
494 eNextState = States::eApproachingObject;
495 break;
496 }
497 case Event::eReverse:
498 {
499 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Handling Reverse event.");
500 eNextState = States::eReversing;
501 break;
502 }
503 case Event::eStuck:
504 {
505 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Handling Stuck event.");
506 eNextState = States::eStuck;
507 break;
508 }
509 default:
510 {
511 LOG_WARNING(logging::g_qSharedLogger, "NavigatingState: Handling unknown event.");
512 eNextState = States::eIdle;
513 break;
514 }
515 }
516
517 if (eNextState != States::eNavigating)
518 {
519 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Transitioning to {} State.", StateToString(eNextState));
520
521 // Exit the current state
522 if (bCompleteStateExit)
523 {
524 Exit();
525 }
526 }
527
528 return eNextState;
529 }
void SendLightingState(MultimediaBoardLightingState eState)
Sends a predetermined color pattern to board.
Definition MultimediaBoard.cpp:55
const geoops::Waypoint PeekNextWaypoint()
Returns an immutable reference to the geoops::Waypoint struct at the front of the list without removi...
Definition WaypointHandler.cpp:540
void StorePath(const std::string &szPathName, const std::vector< geoops::Waypoint > &vWaypointPath)
Store a path in the WaypointHandler.
Definition WaypointHandler.cpp:120
const std::vector< geoops::Waypoint > GetAllObstacles()
Accessor for the full list of current obstacle stored in the WaypointHandler.
Definition WaypointHandler.cpp:673
std::vector< geoops::Waypoint > PlanPath(LiDARHandler *pLiDARHandler, const geoops::UTMCoordinate &stStart, const geoops::UTMCoordinate &stEnd, double dSearchRadius=3.0, double dMaxSearchTimeSeconds=120.0, double dCorridorPadding=100.0)
Plan an optimal trajectory path from the start UTM to the end UTM coordinate utilizing a 2....
Definition GeoPlanner.cpp:116
void Exit() override
This method is called when the state is exited. It is used to clean up the state.
Definition NavigatingState.cpp:56
std::string StateToString(States eState)
Converts a state object to a string.
Definition State.hpp:85
States
The states that the state machine can be in.
Definition State.hpp:31
Here is the call graph for this function:

The documentation for this class was generated from the following files: