Run the state machine. Returns the next state.
106 {
107
108 LOG_DEBUG(logging::g_qSharedLogger, "NavigatingState: Running state-specific behavior.");
109
110
111 if (m_bFetchNewWaypoint && globals::g_pWaypointHandler->GetWaypointCount() > 0)
112 {
113
114 globals::g_pStateMachineHandler->
HandleEvent(Event::eNewWaypoint);
115 return;
116 }
117
118
120
122
123 m_pRoverPathPlot->AddPathPoint(stCurrentRoverPose.
GetUTMCoordinate(),
"RoverPath", 1);
124
125
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
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
137
139
140
141
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
148 LOG_INFO(logging::g_qSharedLogger, "{}", szErrorMetrics);
149
150
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
156 bAlreadyPrinted = false;
157 }
158
159
160
161
162
163
164
165
166
167
169
171
172
173 if (m_stGoalWaypoint.eType == geoops::WaypointType::eTagWaypoint && stGoalWaypointMeasurement.dDistanceMeters <= m_stGoalWaypoint.dRadius)
174 {
175
177
179
180 if (stBestArucoTag.nID != -1 || stBestTorchTag.dConfidence != 0.0)
181 {
182
183 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Rover has seen a target marker!");
184
185
186 if (stBestArucoTag.nID != -1 && stBestArucoTag.stGeolocatedPosition.eType == geoops::WaypointType::eTagWaypoint)
187 {
188
189 m_pRoverPathPlot->AddDot(stBestArucoTag.stGeolocatedPosition.
GetUTMCoordinate(),
"DetectedTags");
190 }
191
192 if (stBestTorchTag.dConfidence != 0.0 && stBestTorchTag.stGeolocatedPosition.eType == geoops::WaypointType::eTagWaypoint)
193 {
194
195 m_pRoverPathPlot->AddDot(stBestTorchTag.stGeolocatedPosition.
GetUTMCoordinate(),
"DetectedTags");
196 }
197
198
199 globals::g_pStateMachineHandler->
HandleEvent(Event::eMarkerSeen,
true);
200
201 return;
202 }
203 }
204
206
208
209
210
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
217
219
220 if (stBestTorchObject.dConfidence != 0.0)
221 {
222
223 LOG_NOTICE(logging::g_qSharedLogger, "NavigatingState: Rover has seen a target object!");
224
225
226 if (stBestTorchObject.stGeolocatedPosition.eType == geoops::WaypointType::eObjectWaypoint)
227 {
228
229 m_pRoverPathPlot->AddDot(stBestTorchObject.stGeolocatedPosition.
GetUTMCoordinate(),
"DetectedObjects");
230 }
231
232
233 globals::g_pStateMachineHandler->
HandleEvent(Event::eObjectSeen,
true);
234
235 return;
236 }
237 }
238
240
242
243
244
246
248
249 if (stGoalWaypointMeasurement.dDistanceMeters > constants::NAVIGATING_REACHED_GOAL_RADIUS)
250 {
251
252
254
256 stDriveVector.dThetaHeading,
258 diffdrive::DifferentialControlMethod::eArcadeDrive);
259
260
261
262
263
264 globals::g_pDriveBoard->
SendDrive(stDriveSpeeds);
265 }
266 else
267 {
268
270
271
272 switch (m_stGoalWaypoint.eType)
273 {
274
275 case geoops::WaypointType::eNavigationWaypoint:
276 {
277
278 if (globals::g_pWaypointHandler->GetWaypointCount() > 1 &&
279 m_stGoalWaypoint.nID == static_cast<int>(manifest::Autonomy::AUTONOMYWAYPOINTTYPES::CONTINUOUSNAVIGATE))
280 {
281
282 LOG_NOTICE(logging::g_qSharedLogger, "NavigatingState: The current waypoint ID is {}. Continuing to next waypoint...", m_stGoalWaypoint.nID);
283
285
286 globals::g_pStateMachineHandler->
HandleEvent(Event::eNewWaypoint,
true);
287 }
288 else
289 {
290
291 globals::g_pStateMachineHandler->
HandleEvent(Event::eReachedGpsCoordinate,
false);
292 }
293 return;
294 }
295
296 case geoops::WaypointType::eTagWaypoint:
297 {
298
299 globals::g_pStateMachineHandler->
HandleEvent(Event::eReachedMarker,
false);
300 return;
301 }
302
303 case geoops::WaypointType::eObjectWaypoint:
304 {
305
306 globals::g_pStateMachineHandler->
HandleEvent(Event::eReachedObject,
false);
307 return;
308 }
309
310 case geoops::WaypointType::eMalletWaypoint:
311 {
312
313 globals::g_pStateMachineHandler->
HandleEvent(Event::eReachedObject,
false);
314 return;
315 }
316
317 case geoops::WaypointType::eWaterBottleWaypoint:
318 {
319
320 globals::g_pStateMachineHandler->
HandleEvent(Event::eReachedObject,
false);
321 return;
322 }
323
324 case geoops::WaypointType::eRockPickWaypoint:
325 {
326
327 globals::g_pStateMachineHandler->
HandleEvent(Event::eReachedObject,
false);
328 return;
329 }
330 default:
331 {
332
333 LOG_ERROR(logging::g_qSharedLogger, "NavigatingState: Unknown waypoint type!");
334
335 globals::g_pStateMachineHandler->
HandleEvent(Event::eAbort,
true);
336
337 return;
338 }
339 }
340 }
341
343
345
346
347 if (constants::NAVIGATING_ENABLE_STUCK_DETECT &&
348 m_StuckDetector.
CheckIfStuck(globals::g_pStateMachineHandler->SmartRetrieveVelocity(), globals::g_pStateMachineHandler->SmartRetrieveAngularVelocity()))
349 {
350
351 LOG_NOTICE(logging::g_qSharedLogger, "NavigatingState: Rover has become stuck!");
352
353 globals::g_pStateMachineHandler->
HandleEvent(Event::eStuck,
true);
354
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