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(
"GeoPlannerPath");
106
107
108 m_pStanleyController->SetReferencePath(m_vPathCoordinates);
109
110 m_bWasStuck = false;
111 }
112
113
114 if (m_bFetchNewWaypoint && globals::g_pWaypointHandler->GetWaypointCount() > 0)
115 {
116
117 globals::g_pStateMachineHandler->
HandleEvent(Event::eNewWaypoint);
118 return;
119 }
120
121
123
124
126
127
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
132
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
137 LOG_INFO(logging::g_qSharedLogger, "{}", szErrorMetrics);
138
139
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
145 bAlreadyPrinted = false;
146 }
147
148
149
150
151
152
153
154
155
156
158
160
161
162 if (m_stGoalWaypoint.eType == geoops::WaypointType::eTagWaypoint && stGoalWaypointMeasurement.dDistanceMeters <= m_stGoalWaypoint.dRadius)
163 {
164
166
168
169 if (stBestArucoTag.nID != -1 || stBestTorchTag.dConfidence != 0.0)
170 {
171
172 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Rover has seen a target marker!");
173
174 globals::g_pStateMachineHandler->
HandleEvent(Event::eMarkerSeen,
true);
175
176 return;
177 }
178 }
179
181
183
184
185
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
192
194
195 if (stBestTorchObject.dConfidence != 0.0)
196 {
197
198 LOG_NOTICE(logging::g_qSharedLogger, "NavigatingState: Rover has seen a target object!");
199
200
201 globals::g_pStateMachineHandler->
HandleEvent(Event::eObjectSeen,
true);
202
203 return;
204 }
205 }
206
208
210
211
212
214
216
217 if (stGoalWaypointMeasurement.dDistanceMeters > constants::NAVIGATING_REACHED_GOAL_RADIUS)
218 {
219
220 double dNavigatingSpeed = constants::NAVIGATING_MOTOR_POWER;
221
222
223 if (constants::NAVIGATING_SLOWDOWN_WITHIN_WAYPOINT_RADIUS && stGoalWaypointMeasurement.dDistanceMeters <= m_stGoalWaypoint.dRadius)
224 {
225
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
235 dNavigatingSpeed = constants::SEARCH_MOTOR_POWER;
236 }
237
238
240
242 stDriveVector.dThetaHeading,
244 diffdrive::DifferentialControlMethod::eArcadeDrive);
245
246 globals::g_pDriveBoard->
SendDrive(stDriveSpeeds);
247 }
248 else
249 {
250
252
253
254 switch (m_stGoalWaypoint.eType)
255 {
256
257 case geoops::WaypointType::eNavigationWaypoint:
258 {
259
260 if (globals::g_pWaypointHandler->GetWaypointCount() > 1 &&
261 m_stGoalWaypoint.nID == static_cast<int>(manifest::Autonomy::AUTONOMYWAYPOINTTYPES::CONTINUOUSNAVIGATE))
262 {
263
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
269
270 globals::g_pStateMachineHandler->
HandleEvent(Event::eNewWaypoint,
true);
271 }
272 else
273 {
274
275 globals::g_pStateMachineHandler->
HandleEvent(Event::eReachedGpsCoordinate,
false);
276 }
277 return;
278 }
279
280 case geoops::WaypointType::eTagWaypoint:
281 {
282
283 globals::g_pStateMachineHandler->
HandleEvent(Event::eReachedMarker,
false);
284 return;
285 }
286
287 case geoops::WaypointType::eObjectWaypoint:
288 {
289
290 globals::g_pStateMachineHandler->
HandleEvent(Event::eReachedObject,
false);
291 return;
292 }
293
294 case geoops::WaypointType::eMalletWaypoint:
295 {
296
297 globals::g_pStateMachineHandler->
HandleEvent(Event::eReachedObject,
false);
298 return;
299 }
300
301 case geoops::WaypointType::eWaterBottleWaypoint:
302 {
303
304 globals::g_pStateMachineHandler->
HandleEvent(Event::eReachedObject,
false);
305 return;
306 }
307
308 case geoops::WaypointType::eRockPickWaypoint:
309 {
310
311 globals::g_pStateMachineHandler->
HandleEvent(Event::eReachedObject,
false);
312 return;
313 }
314 default:
315 {
316
317 LOG_ERROR(logging::g_qSharedLogger, "NavigatingState: Unknown waypoint type!");
318
319 globals::g_pStateMachineHandler->
HandleEvent(Event::eAbort,
true);
320
321 return;
322 }
323 }
324 }
325
327
329
330
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
338 LOG_NOTICE(logging::g_qSharedLogger, "NavigatingState: Rover has become stuck!");
339 m_bWasStuck = true;
340
341 globals::g_pStateMachineHandler->
HandleEvent(Event::eStuck,
true);
342
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