Run the state machine. Returns the next state.
101 {
102
103 LOG_DEBUG(logging::g_qSharedLogger, "ApproachingMarkerState: Running state-specific behavior.");
104
105
107
108
109 m_pRoverPathPlot->AddPathPoint(stCurrentRoverPose.
GetUTMCoordinate(),
"RoverPath");
110
111
113 if (stCurrentMeasurement.dDistanceMeters > m_stGoalWaypoint.dRadius)
114 {
115
116 LOG_WARNING(logging::g_qSharedLogger,
117 "ApproachingMarkerState: Rover is too far from the original waypoint! Waypoint radius is {} meters, current distance is {} meters.",
118 m_stGoalWaypoint.dRadius,
119 stCurrentMeasurement.dDistanceMeters);
120 globals::g_pStateMachineHandler->
HandleEvent(Event::eMarkerUnseen);
121 return;
122 }
123
124
127
128
129 static bool bAlreadyPrintedLost = false;
130 static std::chrono::system_clock::time_point tLastSeenTime = std::chrono::system_clock::now();
131 if (stBestArucoTag.nID == -1 && stBestTorchTag.dConfidence == 0.0)
132 {
133 std::chrono::system_clock::time_point tmCurrentTime = std::chrono::system_clock::now();
134 if ((std::chrono::duration_cast<std::chrono::milliseconds>(tmCurrentTime - tLastSeenTime).count() / 1000.0) > constants::APPROACH_MARKER_LOST_GIVE_UP_TIME)
135 {
136
137 globals::g_pStateMachineHandler->
HandleEvent(Event::eMarkerUnseen);
138 return;
139 }
140 else
141 {
142 if (!bAlreadyPrintedLost)
143 {
144 bAlreadyPrintedLost = true;
145
146 LOG_WARNING(logging::g_qSharedLogger, "ApproachingMarkerState: No tags detected.");
147
148
149 if (stBestArucoTag.nID != -1 && stBestArucoTag.stGeolocatedPosition.eType != geoops::WaypointType::eUNKNOWN)
150 {
151
152 LOG_NOTICE(logging::g_qSharedLogger, "ApproachingMarkerState: OpenCV tag is geolocated.");
153 return;
154 }
155 if (stBestTorchTag.dConfidence != 0.0 && stBestTorchTag.stGeolocatedPosition.eType != geoops::WaypointType::eUNKNOWN)
156 {
157
158 LOG_NOTICE(logging::g_qSharedLogger, "ApproachingMarkerState: Torch tag is geolocated.");
159 return;
160 }
161
162
164 return;
165 }
166 }
167 }
168 else
169 {
170
171 if (bAlreadyPrintedLost)
172 {
173 LOG_NOTICE(logging::g_qSharedLogger, "ApproachingMarkerState: Tags were detected again.");
174 }
175
176
177 tLastSeenTime = std::chrono::system_clock::now();
178
179 bAlreadyPrintedLost = false;
180 }
181
182
183 static double dHeadingSetPoint = 0.0;
184 static double dDistanceFromTag = 0.0;
185
186 if (stBestArucoTag.nID != -1)
187 {
188 dDistanceFromTag = stBestArucoTag.dStraightLineDistance;
189
190 if (stBestArucoTag.stGeolocatedPosition.eType != geoops::WaypointType::eUNKNOWN)
191 {
192
195
196 dHeadingSetPoint = stTagMeasurement.dStartRelativeBearing;
197
198 m_pRoverPathPlot->AddDot(stBestArucoTag.stGeolocatedPosition.
GetUTMCoordinate(),
"DetectedTags");
199 }
200 else
201 {
203 }
204 }
205
206 else if (stBestTorchTag.dConfidence != 0.0)
207 {
208 dDistanceFromTag = stBestTorchTag.dStraightLineDistance;
209
210 if (stBestTorchTag.stGeolocatedPosition.eType != geoops::WaypointType::eUNKNOWN)
211 {
212
215
216 dHeadingSetPoint = stTagMeasurement.dStartRelativeBearing;
217
218 m_pRoverPathPlot->AddDot(stBestTorchTag.stGeolocatedPosition.
GetUTMCoordinate(),
"DetectedTags");
219 }
220 else
221 {
223 }
224 }
225
226
228 dHeadingSetPoint,
230 diffdrive::DifferentialControlMethod::eArcadeDrive);
231 globals::g_pDriveBoard->
SendDrive(stDrivePowers);
232
233
234 static std::chrono::system_clock::time_point tmLastLogTime = std::chrono::system_clock::now();
235 std::chrono::system_clock::time_point tmCurrentTime = std::chrono::system_clock::now();
236
237 if (std::chrono::duration_cast<std::chrono::seconds>(tmCurrentTime - tmLastLogTime).count() >= 1)
238 {
239
240 tmLastLogTime = tmCurrentTime;
241
242 if (stBestArucoTag.nID != -1)
243 {
244 LOG_NOTICE(logging::g_qSharedLogger,
245 "ApproachingMarkerState: OpenCV Tag ID: {}, Distance: {:.2f} m, Heading: {:.2f} deg",
246 stBestArucoTag.nID,
247 dDistanceFromTag,
248 dHeadingSetPoint);
249 }
250 else if (stBestTorchTag.dConfidence != 0.0)
251 {
252 LOG_NOTICE(logging::g_qSharedLogger,
253 "ApproachingMarkerState: Torch Tag Confidence: {:.2f}, Distance: {:.2f} m, Heading: {:.2f} deg",
254 stBestTorchTag.dConfidence,
255 dDistanceFromTag,
256 dHeadingSetPoint);
257 }
258 }
259
260
261 if (dDistanceFromTag != 0.0 && dDistanceFromTag < constants::APPROACH_MARKER_PROXIMITY_THRESHOLD)
262 {
263
264 LOG_NOTICE(logging::g_qSharedLogger, "ApproachingMarkerState: Rover has reached the target marker!");
265
266 if (stBestArucoTag.nID != -1 && stBestArucoTag.stGeolocatedPosition.eType == geoops::WaypointType::eTagWaypoint)
267 {
268
269 m_pRoverPathPlot->AddDot(stBestArucoTag.stGeolocatedPosition.
GetUTMCoordinate(),
"FinalTag", 7);
270 }
271
272 if (stBestTorchTag.dConfidence != 0.0 && stBestTorchTag.stGeolocatedPosition.eType == geoops::WaypointType::eTagWaypoint)
273 {
274
275 m_pRoverPathPlot->AddDot(stBestTorchTag.stGeolocatedPosition.
GetUTMCoordinate(),
"FinalTag", 7);
276 }
277
278
279 dHeadingSetPoint = 0.0;
280 dDistanceFromTag = 0.0;
281
282
283 globals::g_pStateMachineHandler->
HandleEvent(Event::eReachedMarker,
true);
284
285 return;
286 }
287
289
291
292
293 if (constants::APPROACH_MARKER_ENABLE_STUCK_DETECT &&
294 m_StuckDetector.
CheckIfStuck(globals::g_pWaypointHandler->SmartRetrieveVelocity(), globals::g_pWaypointHandler->SmartRetrieveAngularVelocity()))
295 {
296
297 LOG_NOTICE(logging::g_qSharedLogger, "ApproachingMarkerState: Rover has become stuck!");
298
299 globals::g_pStateMachineHandler->
HandleEvent(Event::eStuck,
true);
300
301 return;
302 }
303
304 return;
305 }
void SendDrive(const diffdrive::DrivePowers &stDrivePowers)
Sets the left and right drive powers of the drive board.
Definition DriveBoard.cpp:117
void SendStop()
Stop the drivetrain of the Rover.
Definition DriveBoard.cpp:163
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:87
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:350
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 WaypointHandler.cpp:742
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:522
constexpr T InputAngleModulus(T tValue, T tMinValue, T tMaxValue)
Calculates the modulus of an input angle.
Definition NumberOperations.hpp:165
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
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:82
This struct is used by the WaypointHandler to provide an easy way to store all pose data about the ro...
Definition GeospatialOperations.hpp:677
const geoops::GPSCoordinate & GetGPSCoordinate() const
Accessor for the geoops::GPSCoordinate member variable.
Definition GeospatialOperations.hpp:725
double GetCompassHeading() const
Accessor for the Compass Heading private member.
Definition GeospatialOperations.hpp:756
const geoops::UTMCoordinate & GetUTMCoordinate() const
Accessor for the geoops::UTMCoordinate member variable.
Definition GeospatialOperations.hpp:736
const geoops::GPSCoordinate & GetGPSCoordinate() const
Accessor for the geoops::GPSCoordinate member variable.
Definition GeospatialOperations.hpp:466
const geoops::UTMCoordinate & GetUTMCoordinate() const
Accessor for the geoops::UTMCoordinate member variable.
Definition GeospatialOperations.hpp:477
Represents a single ArUco tag. Combines attributes from TorchTag, TensorflowTag, and the original Aru...
Definition TagDetectionUtilty.hpp:59