Run the state machine. Returns the next state.
98 {
99
100 LOG_DEBUG(logging::g_qSharedLogger, "NavigatingState: Running state-specific behavior.");
101
102
103
104
105
106
107
108
109
110
112
114
115
116 if (m_bFetchNewWaypoint && globals::g_pWaypointHandler->GetWaypointCount() > 0)
117 {
118
119 globals::g_pStateMachineHandler->
HandleEvent(Event::eNewWaypoint,
true);
120 return;
121 }
122
123
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
134
136
137
138
139 std::string szErrorMetrics =
140 "--------[ Navigating Error Report ]--------\nDistance to Goal Waypoint: " + std::to_string(stGoalWaypointMeasurement.dDistanceMeters) + " meters\n" +
141 "Bearing to Goal Waypoint: " + std::to_string(stGoalWaypointMeasurement.dStartRelativeBearing) + " degrees\n" +
142 "GPS/VIO Position Error (UTM for easy reading):\n" + std::to_string(stErrorMeasurement.dDistanceMeters) + " (distance) " +
143 std::to_string(stErrorMeasurement.dStartRelativeBearing) + " (bearing)";
144
145 LOG_INFO(logging::g_qSharedLogger, "{}", szErrorMetrics);
146
147
148 bAlreadyPrinted = true;
149 }
150 else if ((std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count() % 5) != 0 && bAlreadyPrinted)
151 {
152
153 bAlreadyPrinted = false;
154 }
155
156
157 if (stGoalWaypointMeasurement.dDistanceMeters > constants::NAVIGATING_REACHED_GOAL_RADIUS)
158 {
159
161 stGoalWaypointMeasurement.dStartRelativeBearing,
163 diffdrive::DifferentialControlMethod::eArcadeDrive);
164
165 globals::g_pDriveBoard->
SendDrive(stDriveSpeeds);
166 }
167 else
168 {
169
171
172
173 switch (m_stGoalWaypoint.eType)
174 {
175
176 case geoops::WaypointType::eNavigationWaypoint:
177 {
178
179 globals::g_pStateMachineHandler->
HandleEvent(Event::eReachedGpsCoordinate,
false);
180 break;
181 }
182
183 case geoops::WaypointType::eTagWaypoint:
184 {
185
186 globals::g_pStateMachineHandler->
HandleEvent(Event::eReachedMarker,
false);
187 break;
188 }
189
190 case geoops::WaypointType::eObjectWaypoint:
191 {
192
193 globals::g_pStateMachineHandler->
HandleEvent(Event::eReachedObject,
false);
194 break;
195 }
196
197 case geoops::WaypointType::eMalletWaypoint:
198 {
199
200 globals::g_pStateMachineHandler->
HandleEvent(Event::eReachedObject,
false);
201 break;
202 }
203
204 case geoops::WaypointType::eWaterBottleWaypoint:
205 {
206
207 globals::g_pStateMachineHandler->
HandleEvent(Event::eReachedObject,
false);
208 break;
209 }
210 default: break;
211 }
212 }
213
215
217
218
219 if (m_stGoalWaypoint.eType == geoops::WaypointType::eTagWaypoint && stGoalWaypointMeasurement.dDistanceMeters <= m_stGoalWaypoint.dRadius)
220 {
221
222 std::vector<arucotag::ArucoTag> vDetectedArucoTags;
223 std::vector<tensorflowtag::TensorflowTag> vDetectedTensorflowTags;
225
226
227 if (vDetectedArucoTags.size() || vDetectedTensorflowTags.size())
228 {
229
230 if (std::any_of(vDetectedArucoTags.begin(),
231 vDetectedArucoTags.end(),
233 {
234
235 if (m_stGoalWaypoint.nID < 0)
236 {
237 return stTag.nHits >= constants::APPROACH_MARKER_DETECT_ATTEMPTS_LIMIT;
238 }
239 else
240 {
241 return (stTag.nID == m_stGoalWaypoint.nID && stTag.nHits >= constants::APPROACH_MARKER_DETECT_ATTEMPTS_LIMIT);
242 }
243 }) ||
244 std::any_of(vDetectedTensorflowTags.begin(),
245 vDetectedTensorflowTags.end(),
247 {
248
249 LOG_NOTICE(logging::g_qSharedLogger, "NavigatingState: Marker seen!");
250
251 globals::g_pStateMachineHandler->
HandleEvent(Event::eMarkerSeen);
252 return;
253 }
254 }
255 }
256
258
260
261
262
264
266
267
268
270
272
273
274 if (m_StuckDetector.
CheckIfStuck(globals::g_pWaypointHandler->SmartRetrieveVelocity(), globals::g_pWaypointHandler->SmartRetrieveAngularVelocity()))
275 {
276
277 LOG_NOTICE(logging::g_qSharedLogger, "NavigatingState: Rover has become stuck!");
278
279 globals::g_pStateMachineHandler->
HandleEvent(Event::eStuck,
true);
280
281 return;
282 }
283 }
diffdrive::DrivePowers CalculateMove(const double dGoalSpeed, const double dGoalHeading, const double dActualHeading, const diffdrive::DifferentialControlMethod eKinematicsMethod)
This method determines drive powers to make the Rover drive towards a given heading at a given speed.
Definition DriveBoard.cpp:92
void SendStop()
Stop the drivetrain of the Rover.
Definition DriveBoard.cpp:162
void SendDrive(diffdrive::DrivePowers &stDrivePowers)
Sets the left and right drive powers of the drive board.
Definition DriveBoard.cpp:120
geoops::GPSCoordinate GetGPSData()
Accessor for most recent GPS data received from NavBoard.
Definition NavigationBoard.cpp:78
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:337
geoops::RoverPose SmartRetrieveRoverPose(bool bVIOTracking=false)
Retrieve the rover's current position and heading. Automatically picks between getting the position/h...
Definition WaypointHandler.cpp:738
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:445
void LoadDetectedTags(std::vector< arucotag::ArucoTag > &vDetectedArucoTags, std::vector< tensorflowtag::TensorflowTag > &vDetectedTensorflowTags, const std::vector< TagDetector * > &vTagDetectors, bool bUnique=false)
Aggregates all detected tags from each provided tag detector for both OpenCV and Tensorflow detection...
Definition TagDetectionUtilty.hpp:50
Represents a single ArUco tag. Stores all information about a specific tag detection.
Definition ArucoDetection.hpp:44
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:148
This struct is used to store the distance, arc length, and relative bearing for a calculated geodesic...
Definition GeospatialOperations.hpp:82
This struct is used by the WaypointHandler to provide an easy way to store all pose data about the ro...
Definition GeospatialOperations.hpp:674
const geoops::GPSCoordinate & GetGPSCoordinate() const
Accessor for the geoops::GPSCoordinate member variable.
Definition GeospatialOperations.hpp:722
double GetCompassHeading() const
Accessor for the Compass Heading private member.
Definition GeospatialOperations.hpp:743
const geoops::UTMCoordinate & GetUTMCoordinate() const
Accessor for the geoops::UTMCoordinate member variable.
Definition GeospatialOperations.hpp:733
const geoops::UTMCoordinate & GetUTMCoordinate() const
Accessor for the geoops::UTMCoordinate member variable.
Definition GeospatialOperations.hpp:634
Represents a single ArUco tag. Stores all information about a specific tag detection.
Definition TensorflowTagDetection.hpp:43