Run the state machine. Returns the next state.
97 {
98
99 LOG_DEBUG(logging::g_qSharedLogger, "NavigatingState: Running state-specific behavior.");
100
101
102 if (m_bWasStuck)
103 {
104
105 m_vPathCoordinates = globals::g_pWaypointHandler->
RetrievePath(
"unstuckPath");
106
107
108 globals::g_pWaypointHandler->
StorePath(
"GeoPlannerPath", m_vPathCoordinates);
109 m_pStanleyController->SetReferencePath(m_vPathCoordinates);
110
111 m_bWasStuck = false;
112 }
113
114
115 if (m_bFetchNewWaypoint && globals::g_pWaypointHandler->GetWaypointCount() > 0)
116 {
117
118 globals::g_pStateMachineHandler->
HandleEvent(Event::eNewWaypoint);
119 return;
120 }
121
122
124
125
127
128
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
133
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
138 LOG_INFO(logging::g_qSharedLogger, "{}", szErrorMetrics);
139
140
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
146 bAlreadyPrinted = false;
147 }
148
149
150
151
152
153
154
155
156
157
159
161
162
163 if (m_stGoalWaypoint.eType == geoops::WaypointType::eTagWaypoint && stGoalWaypointMeasurement.dDistanceMeters <= m_stGoalWaypoint.dRadius)
164 {
165
167
169
170 if (stBestArucoTag.nID != -1 || stBestTorchTag.dConfidence != 0.0)
171 {
172
173 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Rover has seen a target marker!");
174
175 globals::g_pStateMachineHandler->
HandleEvent(Event::eMarkerSeen,
true);
176
177 return;
178 }
179 }
180
182
184
185
186
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
193
195
196 if (stBestTorchObject.dConfidence != 0.0)
197 {
198
199 LOG_NOTICE(logging::g_qSharedLogger, "NavigatingState: Rover has seen a target object!");
200
201
202 globals::g_pStateMachineHandler->
HandleEvent(Event::eObjectSeen,
true);
203
204 return;
205 }
206 }
207
209
211
212
213
215
217
218 if (stGoalWaypointMeasurement.dDistanceMeters > constants::NAVIGATING_REACHED_GOAL_RADIUS)
219 {
220
221 double dNavigatingSpeed = constants::NAVIGATING_MOTOR_POWER;
222
223
224 if (constants::NAVIGATING_SLOWDOWN_WITHIN_WAYPOINT_RADIUS && stGoalWaypointMeasurement.dDistanceMeters <= m_stGoalWaypoint.dRadius)
225 {
226
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
236 dNavigatingSpeed = constants::SEARCH_MOTOR_POWER;
237 }
238
239
241
243 stDriveVector.dThetaHeading,
245 diffdrive::DifferentialControlMethod::eArcadeDrive);
246
247 globals::g_pDriveBoard->
SendDrive(stDriveSpeeds);
248 }
249 else
250 {
251
253
254
255 switch (m_stGoalWaypoint.eType)
256 {
257
258 case geoops::WaypointType::eNavigationWaypoint:
259 {
260
261 if (globals::g_pWaypointHandler->GetWaypointCount() > 1 &&
262 m_stGoalWaypoint.nID == static_cast<int>(manifest::Autonomy::AUTONOMYWAYPOINTTYPES::CONTINUOUSNAVIGATE))
263 {
264
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
270
271 globals::g_pStateMachineHandler->
HandleEvent(Event::eNewWaypoint,
true);
272 }
273 else
274 {
275
276 globals::g_pStateMachineHandler->
HandleEvent(Event::eReachedGpsCoordinate,
false);
277 }
278 return;
279 }
280
281 case geoops::WaypointType::eTagWaypoint:
282 {
283
284 globals::g_pStateMachineHandler->
HandleEvent(Event::eReachedMarker,
false);
285 return;
286 }
287
288 case geoops::WaypointType::eObjectWaypoint:
289 {
290
291 globals::g_pStateMachineHandler->
HandleEvent(Event::eReachedObject,
false);
292 return;
293 }
294
295 case geoops::WaypointType::eMalletWaypoint:
296 {
297
298 globals::g_pStateMachineHandler->
HandleEvent(Event::eReachedObject,
false);
299 return;
300 }
301
302 case geoops::WaypointType::eWaterBottleWaypoint:
303 {
304
305 globals::g_pStateMachineHandler->
HandleEvent(Event::eReachedObject,
false);
306 return;
307 }
308
309 case geoops::WaypointType::eRockPickWaypoint:
310 {
311
312 globals::g_pStateMachineHandler->
HandleEvent(Event::eReachedObject,
false);
313 return;
314 }
315 default:
316 {
317
318 LOG_ERROR(logging::g_qSharedLogger, "NavigatingState: Unknown waypoint type!");
319
320 globals::g_pStateMachineHandler->
HandleEvent(Event::eAbort,
true);
321
322 return;
323 }
324 }
325 }
326
328
330
331
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
339 LOG_NOTICE(logging::g_qSharedLogger, "NavigatingState: Rover has become stuck!");
340
341 globals::g_pWaypointHandler->
StorePath(
"stuckPath", m_vPathCoordinates);
342 m_bWasStuck = true;
343
344 globals::g_pStateMachineHandler->
HandleEvent(Event::eStuck,
true);
345
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