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::PredictiveStanleyControllerm_pStanleyController
 
std::vector< geoops::Waypointm_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("unstuckPath");
106
107 // Update visualizer and stanley
108 globals::g_pWaypointHandler->StorePath("GeoPlannerPath", m_vPathCoordinates);
109 m_pStanleyController->SetReferencePath(m_vPathCoordinates);
110
111 m_bWasStuck = false;
112 }
113
114 // Check if we should get a new goal waypoint and that the waypoint handler has one for us.
115 if (m_bFetchNewWaypoint && globals::g_pWaypointHandler->GetWaypointCount() > 0)
116 {
117 // Trigger new waypoint event.
118 globals::g_pStateMachineHandler->HandleEvent(Event::eNewWaypoint);
119 return;
120 }
121
122 // Get Current rover pose.
123 geoops::RoverPose stCurrentRoverPose = globals::g_pStateMachineHandler->SmartRetrieveRoverPose();
124
125 // Calculate distance and bearing from goal waypoint.
126 geoops::GeoMeasurement stGoalWaypointMeasurement = geoops::CalculateGeoMeasurement(stCurrentRoverPose.GetUTMCoordinate(), m_stGoalWaypoint.GetUTMCoordinate());
127
128 // Only print out every so often.
129 static bool bAlreadyPrinted = false;
130 if ((std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count() % 5) == 0 && !bAlreadyPrinted)
131 {
132 // Assemble the error metrics into a single string. We are going to include the distance and bearing to the goal waypoint and
133 // the error between the rover pose and the GPS position. The rover pose could be from VIO or GNSS fusion, or just GPS.
134 std::string szErrorMetrics =
135 "--------[ Navigating Error Report ]--------\nDistance to Goal Waypoint: " + std::to_string(stGoalWaypointMeasurement.dDistanceMeters) + " meters\n" +
136 "Bearing to Goal Waypoint: " + std::to_string(stGoalWaypointMeasurement.dStartRelativeBearing) + " degrees\n";
137 // Submit the error metrics to the logger.
138 LOG_INFO(logging::g_qSharedLogger, "{}", szErrorMetrics);
139
140 // Set toggle.
141 bAlreadyPrinted = true;
142 }
143 else if ((std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count() % 5) != 0 && bAlreadyPrinted)
144 {
145 // Reset toggle.
146 bAlreadyPrinted = false;
147 }
148
149 /*
150 The overall flow of this state is as follows.
151 1. Is there a tag -> MarkerSeen
152 2. Is there an object -> ObjectSeen
153 3. Is there an obstacle -> TBD
154 4. Navigate to goal waypoint.
155 5. Is the rover stuck -> Stuck
156 */
157
159 /* --- Detect Tags --- */
161
162 // 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.
163 if (m_stGoalWaypoint.eType == geoops::WaypointType::eTagWaypoint && stGoalWaypointMeasurement.dDistanceMeters <= m_stGoalWaypoint.dRadius)
164 {
165 // Create instance variables.
166 tagdetectutils::ArucoTag stBestArucoTag, stBestTorchTag;
167 // Identify target marker.
168 statemachine::IdentifyTargetMarker(m_vTagDetectors, stBestArucoTag, stBestTorchTag, m_stGoalWaypoint.nID);
169 // Check if either tag type is seen.
170 if (stBestArucoTag.nID != -1 || stBestTorchTag.dConfidence != 0.0)
171 {
172 // Submit logger message.
173 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Rover has seen a target marker!");
174 // Handle state transition and save the current search pattern state.
175 globals::g_pStateMachineHandler->HandleEvent(Event::eMarkerSeen, true);
176 // Don't execute the rest of the state.
177 return;
178 }
179 }
180
182 /* --- Detect Objects --- */
184
185 // 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
186 // waypoint.
187 if ((m_stGoalWaypoint.eType == geoops::WaypointType::eObjectWaypoint || m_stGoalWaypoint.eType == geoops::WaypointType::eMalletWaypoint ||
188 m_stGoalWaypoint.eType == geoops::WaypointType::eWaterBottleWaypoint || m_stGoalWaypoint.eType == geoops::WaypointType::eRockPickWaypoint) &&
189 stGoalWaypointMeasurement.dDistanceMeters <= m_stGoalWaypoint.dRadius)
190 {
191 // Create instance variables.
192 objectdetectutils::Object stBestTorchObject;
193 // Identify target object.
194 statemachine::IdentifyTargetObject(m_vObjectDetectors, stBestTorchObject, m_stGoalWaypoint.eType);
195 // Check if either tag type is seen.
196 if (stBestTorchObject.dConfidence != 0.0)
197 {
198 // Submit logger message.
199 LOG_NOTICE(logging::g_qSharedLogger, "NavigatingState: Rover has seen a target object!");
200
201 // Handle state transition and save the current search pattern state.
202 globals::g_pStateMachineHandler->HandleEvent(Event::eObjectSeen, true);
203 // Don't execute the rest of the state.
204 return;
205 }
206 }
207
209 /* --- Detect Obstacles --- */
211
212 // TODO: Add obstacle detection to Navigating state
213
215 /* --- Navigate to goal waypoint --- */
217 // Check if we are at the goal waypoint.
218 if (stGoalWaypointMeasurement.dDistanceMeters > constants::NAVIGATING_REACHED_GOAL_RADIUS)
219 {
220 // Default to normal navigating speed.
221 double dNavigatingSpeed = constants::NAVIGATING_MOTOR_POWER;
222
223 // Check if we are at least withing the radius of the goal waypoint. If we are, slow down to search pattern speeds.
224 if (constants::NAVIGATING_SLOWDOWN_WITHIN_WAYPOINT_RADIUS && stGoalWaypointMeasurement.dDistanceMeters <= m_stGoalWaypoint.dRadius)
225 {
226 // Check if this is the first time entering the radius
227 if (!m_bWithinWaypointRadius)
228 {
229 LOG_NOTICE(logging::g_qSharedLogger,
230 "NavigatingState: Rover is now within waypoint radius of {}. Slowing down to search pattern speed...",
231 m_stGoalWaypoint.dRadius);
232 m_bWithinWaypointRadius = true;
233 }
234
235 // Update navigating power to match the search pattern power.
236 dNavigatingSpeed = constants::SEARCH_MOTOR_POWER;
237 }
238
239 // Use stanley to calculate drive move/powers.
240 controllers::PredictiveStanleyController::DriveVector stDriveVector = m_pStanleyController->Calculate(stCurrentRoverPose, dNavigatingSpeed);
241 // Calculate move from goal heading and desired speed.
242 diffdrive::DrivePowers stDriveSpeeds = globals::g_pDriveBoard->CalculateMove(stDriveVector.dVelocity,
243 stDriveVector.dThetaHeading,
244 stCurrentRoverPose.GetCompassHeading(),
245 diffdrive::DifferentialControlMethod::eArcadeDrive);
246 // Send drive powers over RoveComm.
247 globals::g_pDriveBoard->SendDrive(stDriveSpeeds);
248 }
249 else
250 {
251 // Stop drive.
252 globals::g_pDriveBoard->SendStop();
253
254 // Check waypoint type.
255 switch (m_stGoalWaypoint.eType)
256 {
257 // Goal waypoint is navigation.
258 case geoops::WaypointType::eNavigationWaypoint:
259 {
260 // Continuously navigate to the next waypoint if our current waypoint ID is set to -99.
261 if (globals::g_pWaypointHandler->GetWaypointCount() > 1 &&
262 m_stGoalWaypoint.nID == static_cast<int>(manifest::Autonomy::AUTONOMYWAYPOINTTYPES::CONTINUOUSNAVIGATE))
263 {
264 // Submit logger message.
265 LOG_NOTICE(logging::g_qSharedLogger,
266 "NavigatingState: The current waypoint ID is signalling continuous navigation ({}). Continuing to next waypoint...",
267 m_stGoalWaypoint.nID);
268 // Pop the next waypoint.
269 globals::g_pWaypointHandler->PopNextWaypoint();
270 // Trigger new waypoint event.
271 globals::g_pStateMachineHandler->HandleEvent(Event::eNewWaypoint, true);
272 }
273 else
274 {
275 // We are at the goal, signal event.
276 globals::g_pStateMachineHandler->HandleEvent(Event::eReachedGpsCoordinate, false);
277 }
278 return;
279 }
280 // Goal waypoint is marker.
281 case geoops::WaypointType::eTagWaypoint:
282 {
283 // We are at the goal, signal event.
284 globals::g_pStateMachineHandler->HandleEvent(Event::eReachedMarker, false);
285 return;
286 }
287 // Goal waypoint is object.
288 case geoops::WaypointType::eObjectWaypoint:
289 {
290 // We are at the goal, signal event.
291 globals::g_pStateMachineHandler->HandleEvent(Event::eReachedObject, false);
292 return;
293 }
294 // Goal waypoint is mallet.
295 case geoops::WaypointType::eMalletWaypoint:
296 {
297 // We are at the goal, signal event.
298 globals::g_pStateMachineHandler->HandleEvent(Event::eReachedObject, false);
299 return;
300 }
301 // Goal waypoint is water bottle.
302 case geoops::WaypointType::eWaterBottleWaypoint:
303 {
304 // We are at the goal, signal event.
305 globals::g_pStateMachineHandler->HandleEvent(Event::eReachedObject, false);
306 return;
307 }
308 // Goal waypoint is rock pick.
309 case geoops::WaypointType::eRockPickWaypoint:
310 {
311 // We are at the goal, signal event.
312 globals::g_pStateMachineHandler->HandleEvent(Event::eReachedObject, false);
313 return;
314 }
315 default:
316 {
317 // This waypoint type is not supported.
318 LOG_ERROR(logging::g_qSharedLogger, "NavigatingState: Unknown waypoint type!");
319 // Handle event.
320 globals::g_pStateMachineHandler->HandleEvent(Event::eAbort, true);
321 // Don't execute the rest of the state.
322 return;
323 }
324 }
325 }
326
328 /* --- Check if the rover is stuck --- */
330
331 // Check if stuck.
332 if (constants::NAVIGATING_ENABLE_STUCK_DETECT &&
333 m_StuckDetector.CheckIfStuck(globals::g_pStateMachineHandler->SmartRetrieveVelocity() * globals::g_pDriveBoard->GetMaxDriveEffort(),
334 globals::g_pStateMachineHandler->SmartRetrieveAngularVelocity(),
335 constants::NAVIGATING_STUCK_CHECK_VEL_THRESH * globals::g_pDriveBoard->GetMaxDriveEffort(),
336 constants::NAVIGATING_STUCK_CHECK_ROT_THRESH))
337 {
338 // Submit logger message.
339 LOG_NOTICE(logging::g_qSharedLogger, "NavigatingState: Rover has become stuck!");
340 // Save rover path for modification in stuck state
341 globals::g_pWaypointHandler->StorePath("stuckPath", m_vPathCoordinates);
342 m_bWasStuck = true;
343 // Handle state transition and save the current search pattern state.
344 globals::g_pStateMachineHandler->HandleEvent(Event::eStuck, true);
345 // Don't execute the rest of the state.
346 return;
347 }
348 }
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
void StorePath(const std::string &szPathName, const std::vector< geoops::Waypoint > &vWaypointPath)
Store a path in the WaypointHandler.
Definition WaypointHandler.cpp:120
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.

360 {
361 // Create instance variables.
362 States eNextState = States::eNavigating;
363 bool bCompleteStateExit = true;
364
365 switch (eEvent)
366 {
367 case Event::eNoWaypoint:
368 {
369 // Submit logger message.
370 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Handling No Waypoint event.");
371 // Change state.
372 eNextState = States::eIdle;
373 break;
374 }
375 case Event::eReachedGpsCoordinate:
376 {
377 // Submit logger message.
378 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Handling Reached GPS Coordinate event.");
379 // Check constants to see if we should go into verifying position or just trigger reached marker.
380 if (constants::NAVIGATING_VERIFY_POSITION)
381 {
382 // Send multimedia command to update state display.
383 globals::g_pMultimediaBoard->SendLightingState(MultimediaBoard::MultimediaBoardLightingState::eAutonomy);
384 // Change state.
385 eNextState = States::eVerifyingPosition;
386 }
387 else
388 {
389 // Send multimedia command to update state display.
390 globals::g_pMultimediaBoard->SendLightingState(MultimediaBoard::MultimediaBoardLightingState::eReachedGoal);
391 // Pop the next waypoint.
392 globals::g_pWaypointHandler->PopNextWaypoint();
393 // Change state.
394 eNextState = States::eIdle;
395 }
396 break;
397 }
398 case Event::eReachedMarker:
399 {
400 // Submit logger message.
401 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Handling Reached Marker Waypoint event.");
402 // Send multimedia command to update state display.
403 globals::g_pMultimediaBoard->SendLightingState(MultimediaBoard::MultimediaBoardLightingState::eAutonomy);
404 // Change state.
405 eNextState = States::eSearchPattern;
406 break;
407 }
408 case Event::eReachedObject:
409 {
410 // Submit logger message.
411 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Handling Reached Object Waypoint event.");
412 // Send multimedia command to update state display.
413 globals::g_pMultimediaBoard->SendLightingState(MultimediaBoard::MultimediaBoardLightingState::eAutonomy);
414 // Change state.
415 eNextState = States::eSearchPattern;
416 break;
417 }
418 case Event::eNewWaypoint:
419 {
420 // Check if the next goal waypoint equals the current one.
421 if (m_stGoalWaypoint == globals::g_pWaypointHandler->PeekNextWaypoint())
422 {
423 // Submit logger message.
424 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Reusing current Waypoint.");
425 }
426 else
427 {
428 // Submit logger message.
429 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Handling New Waypoint event.");
430
431 // Reset radius toggle for the new waypoint
432 m_bWithinWaypointRadius = false;
433
434 // Get and store new goal waypoint.
435 m_stGoalWaypoint = globals::g_pWaypointHandler->PeekNextWaypoint();
436 // Plan a new path using the GeoPlanner.
437 m_vPathCoordinates = globals::g_pGeoPlanner->PlanPath(globals::g_pLiDARHandler,
438 globals::g_pStateMachineHandler->SmartRetrieveRoverPose().GetUTMCoordinate(),
439 m_stGoalWaypoint.GetUTMCoordinate());
440 // Add the path to the waypoint handler for reference by other states or handlers.
441 globals::g_pWaypointHandler->StorePath("GeoPlannerPath", m_vPathCoordinates);
442 // Set the path of the stanley controller.
443 m_pStanleyController->SetReferencePath(m_vPathCoordinates);
444
445 // Get all obstacles from the obstacle handler.
446 std::vector<geoops::Waypoint> vObstacles = globals::g_pWaypointHandler->GetAllObstacles();
447
448 // Check if the path is empty. If it is, go to idle state.
449 if (m_vPathCoordinates.empty())
450 {
451 LOG_WARNING(logging::g_qSharedLogger, "NavigatingState: Planned path is empty! Transitioning to Idle State.");
452 eNextState = States::eIdle;
453 }
454 }
455
456 // Send multimedia command to update state display.
457 globals::g_pMultimediaBoard->SendLightingState(MultimediaBoard::MultimediaBoardLightingState::eAutonomy);
458 // Set toggle.
459 m_bFetchNewWaypoint = false;
460 break;
461 }
462 case Event::eStart:
463 {
464 // Submit logger message.
465 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Handling Start event.");
466 // Send multimedia command to update state display.
467 globals::g_pMultimediaBoard->SendLightingState(MultimediaBoard::MultimediaBoardLightingState::eAutonomy);
468 break;
469 }
470 case Event::eAbort:
471 {
472 // Submit logger message.
473 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Handling Abort event.");
474 // Stop drive.
475 globals::g_pDriveBoard->SendStop();
476 // Send multimedia command to update state display.
477 globals::g_pMultimediaBoard->SendLightingState(MultimediaBoard::MultimediaBoardLightingState::eOff);
478 // Set toggle.
479 m_bFetchNewWaypoint = true;
480 // Change states.
481 eNextState = States::eIdle;
482 break;
483 }
484 case Event::eMarkerSeen:
485 {
486 // Submit logger message.
487 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Handling MarkerSeen event.");
488 // Change states.
489 eNextState = States::eApproachingMarker;
490 break;
491 }
492 case Event::eObjectSeen:
493 {
494 // Submit logger message.
495 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Handling ObjectSeen event.");
496 // Change states.
497 eNextState = States::eApproachingObject;
498 break;
499 }
500 case Event::eReverse:
501 {
502 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Handling Reverse event.");
503 eNextState = States::eReversing;
504 break;
505 }
506 case Event::eStuck:
507 {
508 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Handling Stuck event.");
509 eNextState = States::eStuck;
510 break;
511 }
512 default:
513 {
514 LOG_WARNING(logging::g_qSharedLogger, "NavigatingState: Handling unknown event.");
515 eNextState = States::eIdle;
516 break;
517 }
518 }
519
520 if (eNextState != States::eNavigating)
521 {
522 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Transitioning to {} State.", StateToString(eNextState));
523
524 // Exit the current state
525 if (bCompleteStateExit)
526 {
527 Exit();
528 }
529 }
530
531 return eNextState;
532 }
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
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: