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_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< logging::graphing::PathTracerm_pRoverPathPlot
 
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)
Date
2024-01-17
74 : State(States::eNavigating)
75 {
76 // Submit logger message.
77 LOG_INFO(logging::g_qConsoleLogger, "Entering State: {}", ToString());
78
79 // Initialize member variables.
80 m_bInitialized = false;
81 m_StuckDetector = statemachine::TimeIntervalBasedStuckDetector(constants::STUCK_CHECK_ATTEMPTS,
82 constants::STUCK_CHECK_INTERVAL,
83 constants::STUCK_CHECK_VEL_THRESH,
84 constants::STUCK_CHECK_ROT_THRESH);
85 m_pRoverPathPlot = std::make_unique<logging::graphing::PathTracer>("NavigatingRoverPath");
86 m_pStanleyController = std::make_unique<controllers::PredictiveStanleyController>(constants::STANLEY_CROSSTRACK_CONTROL_GAIN,
87 constants::STANLEY_ANGULAR_VELOCITY_LIMIT,
88 constants::STANLEY_PREDICTION_HORIZON,
89 constants::STANLEY_PREDICTION_TIME_STEP);
90
91 // Start state.
92 if (!m_bInitialized)
93 {
94 Start();
95 m_bInitialized = true;
96 }
97 }
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)
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_bFetchNewWaypoint = true;
40 m_vTagDetectors = {globals::g_pTagDetectionHandler->GetTagDetector(TagDetectionHandler::TagDetectors::eHeadMainCam)};
41 m_vObjectDetectors = {globals::g_pObjectDetectionHandler->GetObjectDetector(ObjectDetectionHandler::ObjectDetectors::eHeadMainCam)};
42
43 // Create rover path layers.
44 m_pRoverPathPlot->CreatePathLayer("NavPath", "--b");
45 m_pRoverPathPlot->CreatePathLayer("RoverPath", "-k");
46 m_pRoverPathPlot->CreatePathLayer("GeoPath", "-m");
47 m_pRoverPathPlot->CreateDotLayer("StanleyTargetIndex", "or");
48 m_pRoverPathPlot->CreateDotLayer("ObstaclesLocation", "o");
49 m_pRoverPathPlot->CreateDotLayer("DetectedTags", "green");
50 m_pRoverPathPlot->CreateDotLayer("DetectedObjects", "red");
51 }
std::shared_ptr< ObjectDetector > GetObjectDetector(ObjectDetectors eDetectorName)
Accessor for ObjectDetector detectors.
Definition ObjectDetectionHandler.cpp:127
std::shared_ptr< TagDetector > GetTagDetector(TagDetectors eDetectorName)
Accessor for TagDetector detectors.
Definition TagDetectionHandler.cpp:132
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.

62 {
63 // Clean up the state before exiting
64 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Exiting state.");
65 }
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.

106 {
107 // Submit logger message.
108 LOG_DEBUG(logging::g_qSharedLogger, "NavigatingState: Running state-specific behavior.");
109
110 // Check if we should get a new goal waypoint and that the waypoint handler has one for us.
111 if (m_bFetchNewWaypoint && globals::g_pWaypointHandler->GetWaypointCount() > 0)
112 {
113 // Trigger new waypoint event.
114 globals::g_pStateMachineHandler->HandleEvent(Event::eNewWaypoint);
115 return;
116 }
117
118 // Get Current rover pose.
119 geoops::RoverPose stCurrentRoverPose = globals::g_pStateMachineHandler->SmartRetrieveRoverPose();
120 // Calculate distance and bearing from goal waypoint.
121 geoops::GeoMeasurement stGoalWaypointMeasurement = geoops::CalculateGeoMeasurement(stCurrentRoverPose.GetUTMCoordinate(), m_stGoalWaypoint.GetUTMCoordinate());
122 // Add the current rover pose to the path plot.
123 m_pRoverPathPlot->AddPathPoint(stCurrentRoverPose.GetUTMCoordinate(), "RoverPath", 1);
124
125 // Place a dot on the stanley target index.
126 geoops::Waypoint stStanleyTargetCoordinate =
127 m_pStanleyController->GetReferencePath().at(static_cast<size_t>(m_pStanleyController->GetReferencePathTargetIndex()));
128 m_pRoverPathPlot->ClearLayer("StanleyTargetIndex");
129 m_pRoverPathPlot->AddDot(stStanleyTargetCoordinate.GetUTMCoordinate(), "StanleyTargetIndex", 1);
130
131 // Only print out every so often.
132 static bool bAlreadyPrinted = false;
133 if ((std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count() % 5) == 0 && !bAlreadyPrinted)
134 {
135 // Get raw Navboard GPS position.
136 geoops::GPSCoordinate stCurrentGPSPosition = globals::g_pNavigationBoard->GetGPSData();
137 // Calculate error between pose and GPS.
138 geoops::GeoMeasurement stErrorMeasurement = geoops::CalculateGeoMeasurement(stCurrentRoverPose.GetGPSCoordinate(), stCurrentGPSPosition);
139
140 // Assemble the error metrics into a single string. We are going to include the distance and bearing to the goal waypoint and
141 // the error between the rover pose and the GPS position. The rover pose could be from VIO or GNSS fusion, or just GPS.
142 std::string szErrorMetrics =
143 "--------[ Navigating Error Report ]--------\nDistance to Goal Waypoint: " + std::to_string(stGoalWaypointMeasurement.dDistanceMeters) + " meters\n" +
144 "Bearing to Goal Waypoint: " + std::to_string(stGoalWaypointMeasurement.dStartRelativeBearing) + " degrees\n" +
145 "GPS/VIO Position Error (UTM for easy reading):\n" + std::to_string(stErrorMeasurement.dDistanceMeters) + " (distance) " +
146 std::to_string(stErrorMeasurement.dStartRelativeBearing) + " (bearing)";
147 // Submit the error metrics to the logger.
148 LOG_INFO(logging::g_qSharedLogger, "{}", szErrorMetrics);
149
150 // Set toggle.
151 bAlreadyPrinted = true;
152 }
153 else if ((std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count() % 5) != 0 && bAlreadyPrinted)
154 {
155 // Reset toggle.
156 bAlreadyPrinted = false;
157 }
158
159 /*
160 The overall flow of this state is as follows.
161 1. Is there a tag -> MarkerSeen
162 2. Is there an object -> ObjectSeen
163 3. Is there an obstacle -> TBD
164 4. Navigate to goal waypoint.
165 5. Is the rover stuck -> Stuck
166 */
167
169 /* --- Detect Tags --- */
171
172 // 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.
173 if (m_stGoalWaypoint.eType == geoops::WaypointType::eTagWaypoint && stGoalWaypointMeasurement.dDistanceMeters <= m_stGoalWaypoint.dRadius)
174 {
175 // Create instance variables.
176 tagdetectutils::ArucoTag stBestArucoTag, stBestTorchTag;
177 // Identify target marker.
178 statemachine::IdentifyTargetMarker(m_vTagDetectors, stBestArucoTag, stBestTorchTag, m_stGoalWaypoint.nID);
179 // Check if either tag type is seen.
180 if (stBestArucoTag.nID != -1 || stBestTorchTag.dConfidence != 0.0)
181 {
182 // Submit logger message.
183 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Rover has seen a target marker!");
184
185 // Check if the OpenCV tag has a good absolute position.
186 if (stBestArucoTag.nID != -1 && stBestArucoTag.stGeolocatedPosition.eType == geoops::WaypointType::eTagWaypoint)
187 {
188 // Add the tag to the path plot.
189 m_pRoverPathPlot->AddDot(stBestArucoTag.stGeolocatedPosition.GetUTMCoordinate(), "DetectedTags");
190 }
191 // Check if the torch tag has a good absolute position.
192 if (stBestTorchTag.dConfidence != 0.0 && stBestTorchTag.stGeolocatedPosition.eType == geoops::WaypointType::eTagWaypoint)
193 {
194 // Add the tag to the path plot.
195 m_pRoverPathPlot->AddDot(stBestTorchTag.stGeolocatedPosition.GetUTMCoordinate(), "DetectedTags");
196 }
197
198 // Handle state transition and save the current search pattern state.
199 globals::g_pStateMachineHandler->HandleEvent(Event::eMarkerSeen, true);
200 // Don't execute the rest of the state.
201 return;
202 }
203 }
204
206 /* --- Detect Objects --- */
208
209 // 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
210 // waypoint.
211 if ((m_stGoalWaypoint.eType == geoops::WaypointType::eObjectWaypoint || m_stGoalWaypoint.eType == geoops::WaypointType::eMalletWaypoint ||
212 m_stGoalWaypoint.eType == geoops::WaypointType::eWaterBottleWaypoint || m_stGoalWaypoint.eType == geoops::WaypointType::eRockPickWaypoint) &&
213 stGoalWaypointMeasurement.dDistanceMeters <= m_stGoalWaypoint.dRadius)
214 {
215 // Create instance variables.
216 objectdetectutils::Object stBestTorchObject;
217 // Identify target object.
218 statemachine::IdentifyTargetObject(m_vObjectDetectors, stBestTorchObject, m_stGoalWaypoint.eType);
219 // Check if either tag type is seen.
220 if (stBestTorchObject.dConfidence != 0.0)
221 {
222 // Submit logger message.
223 LOG_NOTICE(logging::g_qSharedLogger, "NavigatingState: Rover has seen a target object!");
224
225 // Check if the object has a good absolute position.
226 if (stBestTorchObject.stGeolocatedPosition.eType == geoops::WaypointType::eObjectWaypoint)
227 {
228 // Add the object to the path plot.
229 m_pRoverPathPlot->AddDot(stBestTorchObject.stGeolocatedPosition.GetUTMCoordinate(), "DetectedObjects");
230 }
231
232 // Handle state transition and save the current search pattern state.
233 globals::g_pStateMachineHandler->HandleEvent(Event::eObjectSeen, true);
234 // Don't execute the rest of the state.
235 return;
236 }
237 }
238
240 /* --- Detect Obstacles --- */
242
243 // TODO: Add obstacle detection to Navigating state
244
246 /* --- Navigate to goal waypoint --- */
248 // Check if we are at the goal waypoint.
249 if (stGoalWaypointMeasurement.dDistanceMeters > constants::NAVIGATING_REACHED_GOAL_RADIUS)
250 {
251 // NOTE: Optional - Uncomment the above code and comment out the below code to use stanley control to navigate to the goal waypoint.
252 // Use stanley to calculate drive move/powers.
253 controllers::PredictiveStanleyController::DriveVector stDriveVector = m_pStanleyController->Calculate(stCurrentRoverPose);
254 // Calculate move from goal heading and desired speed.
255 diffdrive::DrivePowers stDriveSpeeds = globals::g_pDriveBoard->CalculateMove(stDriveVector.dVelocity,
256 stDriveVector.dThetaHeading,
257 stCurrentRoverPose.GetCompassHeading(),
258 diffdrive::DifferentialControlMethod::eArcadeDrive);
259 // diffdrive::DrivePowers stDriveSpeeds = globals::g_pDriveBoard->CalculateMove(constants::NAVIGATING_MOTOR_POWER,
260 // stGoalWaypointMeasurement.dStartRelativeBearing,
261 // stCurrentRoverPose.GetCompassHeading(),
262 // diffdrive::DifferentialControlMethod::eArcadeDrive);
263 // Send drive powers over RoveComm.
264 globals::g_pDriveBoard->SendDrive(stDriveSpeeds);
265 }
266 else
267 {
268 // Stop drive.
269 globals::g_pDriveBoard->SendStop();
270
271 // Check waypoint type.
272 switch (m_stGoalWaypoint.eType)
273 {
274 // Goal waypoint is navigation.
275 case geoops::WaypointType::eNavigationWaypoint:
276 {
277 // Continuously navigate to the next waypoint if our current waypoint ID is set to -99.
278 if (globals::g_pWaypointHandler->GetWaypointCount() > 1 &&
279 m_stGoalWaypoint.nID == static_cast<int>(manifest::Autonomy::AUTONOMYWAYPOINTTYPES::CONTINUOUSNAVIGATE))
280 {
281 // Submit logger message.
282 LOG_NOTICE(logging::g_qSharedLogger, "NavigatingState: The current waypoint ID is {}. Continuing to next waypoint...", m_stGoalWaypoint.nID);
283 // Pop the next waypoint.
284 globals::g_pWaypointHandler->PopNextWaypoint();
285 // Trigger new waypoint event.
286 globals::g_pStateMachineHandler->HandleEvent(Event::eNewWaypoint, true);
287 }
288 else
289 {
290 // We are at the goal, signal event.
291 globals::g_pStateMachineHandler->HandleEvent(Event::eReachedGpsCoordinate, false);
292 }
293 return;
294 }
295 // Goal waypoint is marker.
296 case geoops::WaypointType::eTagWaypoint:
297 {
298 // We are at the goal, signal event.
299 globals::g_pStateMachineHandler->HandleEvent(Event::eReachedMarker, false);
300 return;
301 }
302 // Goal waypoint is object.
303 case geoops::WaypointType::eObjectWaypoint:
304 {
305 // We are at the goal, signal event.
306 globals::g_pStateMachineHandler->HandleEvent(Event::eReachedObject, false);
307 return;
308 }
309 // Goal waypoint is mallet.
310 case geoops::WaypointType::eMalletWaypoint:
311 {
312 // We are at the goal, signal event.
313 globals::g_pStateMachineHandler->HandleEvent(Event::eReachedObject, false);
314 return;
315 }
316 // Goal waypoint is water bottle.
317 case geoops::WaypointType::eWaterBottleWaypoint:
318 {
319 // We are at the goal, signal event.
320 globals::g_pStateMachineHandler->HandleEvent(Event::eReachedObject, false);
321 return;
322 }
323 // Goal waypoint is rock pick.
324 case geoops::WaypointType::eRockPickWaypoint:
325 {
326 // We are at the goal, signal event.
327 globals::g_pStateMachineHandler->HandleEvent(Event::eReachedObject, false);
328 return;
329 }
330 default:
331 {
332 // This waypoint type is not supported.
333 LOG_ERROR(logging::g_qSharedLogger, "NavigatingState: Unknown waypoint type!");
334 // Handle event.
335 globals::g_pStateMachineHandler->HandleEvent(Event::eAbort, true);
336 // Don't execute the rest of the state.
337 return;
338 }
339 }
340 }
341
343 /* --- Check if the rover is stuck --- */
345
346 // Check if stuck.
347 if (constants::NAVIGATING_ENABLE_STUCK_DETECT &&
348 m_StuckDetector.CheckIfStuck(globals::g_pStateMachineHandler->SmartRetrieveVelocity(), globals::g_pStateMachineHandler->SmartRetrieveAngularVelocity()))
349 {
350 // Submit logger message.
351 LOG_NOTICE(logging::g_qSharedLogger, "NavigatingState: Rover has become stuck!");
352 // Handle state transition and save the current search pattern state.
353 globals::g_pStateMachineHandler->HandleEvent(Event::eStuck, true);
354 // Don't execute the rest of the state.
355 return;
356 }
357 }
void SendDrive(const diffdrive::DrivePowers &stDrivePowers, const bool bEnableVariableDriveEffort=true)
Sets the left and right drive powers of the drive board.
Definition DriveBoard.cpp:118
void SendStop()
Stop the drivetrain of the Rover.
Definition DriveBoard.cpp:195
diffdrive::DrivePowers CalculateMove(const double dGoalSpeed, const double dGoalHeading, const double dActualHeading, const diffdrive::DifferentialControlMethod eKinematicsMethod=diffdrive::DifferentialControlMethod::eArcadeDrive, const bool bAlwaysProgressForward=false)
This method determines drive powers to make the Rover drive towards a given heading at a given speed.
Definition DriveBoard.cpp:88
geoops::GPSCoordinate GetGPSData()
Accessor for most recent GPS data received from NavBoard.
Definition NavigationBoard.cpp:78
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
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:353
geoops::Waypoint PopNextWaypoint()
Removes and returns the next waypoint at the front of the list.
Definition WaypointHandler.cpp:500
bool CheckIfStuck(double dCurrentVelocity, double dCurrentAngularVelocity)
Checks if the rover meets stuck criteria based in the given parameters.
Definition StuckDetection.hpp:105
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:91
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
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 stores/contains information about a GPS data.
Definition GeospatialOperations.hpp:100
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
const geoops::GPSCoordinate & GetGPSCoordinate() const
Accessor for the geoops::GPSCoordinate member variable.
Definition GeospatialOperations.hpp:756
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
This struct is used by the WaypointHandler class to store location, size, and type information about ...
Definition GeospatialOperations.hpp:423
const geoops::UTMCoordinate & GetUTMCoordinate() const
Accessor for the geoops::UTMCoordinate member variable.
Definition GeospatialOperations.hpp:508
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:

◆ 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.

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