Autonomy Software C++ 24.5.1
Welcome to the Autonomy Software repository of the Mars Rover Design Team (MRDT) at Missouri University of Science and Technology (Missouri S&T)! API reference contains the source code and other resources for the development of the autonomy software for our Mars rover. The Autonomy Software project aims to compete in the University Rover Challenge (URC) by demonstrating advanced autonomous capabilities and robust navigation algorithms.
Loading...
Searching...
No Matches
statemachine::SearchPatternState Class Reference

The SearchPatternState class implements the Search Pattern state for the Autonomy State Machine. More...

#include <SearchPatternState.h>

Inheritance diagram for statemachine::SearchPatternState:
Collaboration diagram for statemachine::SearchPatternState:

Public Member Functions

 SearchPatternState ()
 Construct a new State object.
 
void Run () override
 Run the state machine. Returns the next state.
 
States TriggerEvent (Event eEvent) override
 Trigger an event in the state machine. Returns the next state.
 
- Public Member Functions inherited from statemachine::State
 State (States eState)
 Construct a new State object.
 
virtual ~State ()=default
 Destroy the State object.
 
States GetState () const
 Accessor for the State private member.
 
virtual std::string ToString () const
 Accessor for the State private member. Returns the state as a string.
 
virtual bool operator== (const State &other) const
 Checks to see if the current state is equal to the passed state.
 
virtual bool operator!= (const State &other) const
 Checks to see if the current state is not equal to the passed state.
 

Protected Member Functions

void Start () override
 This method is called when the state is first started. It is used to initialize the state.
 
void Exit () override
 This method is called when the state is exited. It is used to clean up the state.
 

Private Types

enum  SearchPatternType { eSpiral , eZigZag , END }
 

Private Attributes

bool m_bInitialized
 
geoops::Waypoint m_stSearchPatternCenter
 
std::vector< TagDetector * > m_vTagDetectors
 
std::vector< geoops::Waypointm_vSearchPath
 
int m_nSearchPathIdx
 
SearchPatternType m_eCurrentSearchPatternType
 
statemachine::TimeIntervalBasedStuckDetector m_StuckDetector
 

Detailed Description

The SearchPatternState class implements the Search Pattern state for the Autonomy State Machine.

Author
Eli Byrd (edbgk.nosp@m.k@ms.nosp@m.t.edu)
Date
2024-01-17

Member Enumeration Documentation

◆ SearchPatternType

enum statemachine::SearchPatternState::SearchPatternType
private
47 {
48 eSpiral,
49 eZigZag,
50 END
51 };

Constructor & Destructor Documentation

◆ SearchPatternState()

statemachine::SearchPatternState::SearchPatternState ( )

Construct a new State object.

Author
Eli Byrd (edbgk.nosp@m.k@ms.nosp@m.t.edu)
Date
2024-01-17
82 : State(States::eSearchPattern)
83 {
84 // Submit logger message.
85 LOG_INFO(logging::g_qConsoleLogger, "Entering State: {}", ToString());
86
87 // Initialize member variables.
88 m_bInitialized = false;
89 m_StuckDetector = statemachine::TimeIntervalBasedStuckDetector(constants::STUCK_CHECK_ATTEMPTS,
90 constants::STUCK_CHECK_INTERVAL,
91 constants::STUCK_CHECK_VEL_THRESH,
92 constants::STUCK_CHECK_ROT_THRESH);
93 // Start state.
94 if (!m_bInitialized)
95 {
96 Start();
97 m_bInitialized = true;
98 }
99 }
void Start() override
This method is called when the state is first started. It is used to initialize the state.
Definition SearchPatternState.cpp:33
virtual std::string ToString() const
Accessor for the State private member. Returns the state as a string.
Definition State.hpp:207
State(States eState)
Construct a new State object.
Definition State.hpp:150
This class should be instantiated within another state to be used for detection of if the rover is st...
Definition StuckDetection.hpp:43
Here is the call graph for this function:

Member Function Documentation

◆ Start()

void statemachine::SearchPatternState::Start ( )
overrideprotectedvirtual

This method is called when the state is first started. It is used to initialize the state.

Author
Eli Byrd (edbgk.nosp@m.k@ms.nosp@m.t.edu)
Date
2024-01-17

Reimplemented from statemachine::State.

34 {
35 // Schedule the next run of the state's logic
36 LOG_INFO(logging::g_qSharedLogger, "SearchPatternState: Scheduling next run of state logic.");
37
38 // Initialize member variables.
39 m_eCurrentSearchPatternType = eSpiral;
40 m_nSearchPathIdx = 0;
41 m_stSearchPatternCenter = globals::g_pWaypointHandler->PeekNextWaypoint();
42
43 // Get the current rover pose.
44 geoops::RoverPose stCurrentRoverPose = globals::g_pWaypointHandler->SmartRetrieveRoverPose();
45
46 // Calculate the search path.
47 m_vSearchPath = searchpattern::CalculateSpiralPatternWaypoints(m_stSearchPatternCenter.GetGPSCoordinate(),
48 constants::SEARCH_ANGULAR_STEP_DEGREES,
49 m_stSearchPatternCenter.dRadius,
50 stCurrentRoverPose.GetCompassHeading(),
51 constants::SEARCH_SPIRAL_SPACING);
52
53 m_vTagDetectors = {globals::g_pTagDetectionHandler->GetTagDetector(TagDetectionHandler::TagDetectors::eHeadMainCam),
54 globals::g_pTagDetectionHandler->GetTagDetector(TagDetectionHandler::TagDetectors::eFrameLeftCam),
55 globals::g_pTagDetectionHandler->GetTagDetector(TagDetectionHandler::TagDetectors::eFrameRightCam)};
56 }
TagDetector * GetTagDetector(TagDetectors eDetectorName)
Accessor for TagDetector detectors.
Definition TagDetectionHandler.cpp:197
const geoops::Waypoint PeekNextWaypoint()
Returns an immutable reference to the geoops::Waypoint struct at the front of the list without removi...
Definition WaypointHandler.cpp:539
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
std::vector< geoops::Waypoint > CalculateSpiralPatternWaypoints(const geoops::UTMCoordinate &stStartingPoint, const double dAngularStepDegrees=57, const double dMaxRadius=25, const double dStartingHeadingDegrees=0, const double dStartSpacing=1)
Perform a spiral search pattern starting from a given point.
Definition SearchPattern.hpp:49
This struct is used by the WaypointHandler to provide an easy way to store all pose data about the ro...
Definition GeospatialOperations.hpp:674
double GetCompassHeading() const
Accessor for the Compass Heading private member.
Definition GeospatialOperations.hpp:743
const geoops::GPSCoordinate & GetGPSCoordinate() const
Accessor for the geoops::GPSCoordinate member variable.
Definition GeospatialOperations.hpp:623
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Exit()

void statemachine::SearchPatternState::Exit ( )
overrideprotectedvirtual

This method is called when the state is exited. It is used to clean up the state.

Author
Eli Byrd (edbgk.nosp@m.k@ms.nosp@m.t.edu)
Date
2024-01-17

Reimplemented from statemachine::State.

67 {
68 // Clean up the state before exiting
69 LOG_INFO(logging::g_qSharedLogger, "SearchPatternState: Exiting state.");
70
71 // Stop drive.
72 globals::g_pDriveBoard->SendStop();
73 }
void SendStop()
Stop the drivetrain of the Rover.
Definition DriveBoard.cpp:162
Here is the call graph for this function:

◆ Run()

void statemachine::SearchPatternState::Run ( )
overridevirtual

Run the state machine. Returns the next state.

Author
Jason Pittman (jspen.nosp@m.cerp.nosp@m.ittma.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-01-17

Implements statemachine::State.

108 {
109 // Submit logger message.
110 LOG_DEBUG(logging::g_qSharedLogger, "SearchPatternState: Running state-specific behavior.");
111
112 // Get the current rover pose.
113 geoops::RoverPose stCurrentRoverPose = globals::g_pWaypointHandler->SmartRetrieveRoverPose();
114
115 /*
116 The overall flow of this state is as follows.
117 1. Is there a tag -> MarkerSeen
118 2. Is there an object -> ObjectSeen
119 3. Is there an obstacle -> TBD
120 4. Is the rover stuck -> Stuck
121 5. Is the search pattern complete -> Abort
122 6. Follow the search pattern.
123 */
124
126 /* --- Detect Tags --- */
128
129 // Get a list of the currently detected tags, and their stats.
130 std::vector<arucotag::ArucoTag> vDetectedArucoTags;
131 std::vector<tensorflowtag::TensorflowTag> vDetectedTensorflowTags;
132 tagdetectutils::LoadDetectedTags(vDetectedArucoTags, vDetectedTensorflowTags, m_vTagDetectors, false);
133
134 // Check if we have detected any tags.
135 if (vDetectedArucoTags.size() || vDetectedTensorflowTags.size())
136 {
137 // Check if any of the tags have a detection counter or confidence greater than the threshold.
138 if (std::any_of(vDetectedArucoTags.begin(),
139 vDetectedArucoTags.end(),
140 [this](arucotag::ArucoTag& stTag)
141 {
142 // If the Tag ID given by the user in the waypoint is less than 0, then we don't care about the ID.
143 if (m_stSearchPatternCenter.nID < 0)
144 {
145 return stTag.nHits >= constants::APPROACH_MARKER_DETECT_ATTEMPTS_LIMIT;
146 }
147 else
148 {
149 return (stTag.nID == m_stSearchPatternCenter.nID && stTag.nHits >= constants::APPROACH_MARKER_DETECT_ATTEMPTS_LIMIT);
150 }
151 }) ||
152 std::any_of(vDetectedTensorflowTags.begin(),
153 vDetectedTensorflowTags.end(),
154 [](tensorflowtag::TensorflowTag& stTag) { return stTag.dConfidence >= constants::APPROACH_MARKER_TF_CONFIDENCE_THRESHOLD; }))
155 {
156 // Submit logger message.
157 LOG_NOTICE(logging::g_qSharedLogger, "NavigatingState: Marker seen!");
158 // Handle state transition.
159 globals::g_pStateMachineHandler->HandleEvent(Event::eMarkerSeen, true);
160 return;
161 }
162 }
163
165 /* --- Detect Objects --- */
167
168 // TODO: Add object detection to SearchPattern state
169
171 /* --- Detect Obstacles --- */
173
174 // TODO: Add obstacle detection to SearchPattern state
175
177 /* --- Check if the rover is stuck --- */
179
180 // Check if stuck.
181 if (m_StuckDetector.CheckIfStuck(globals::g_pWaypointHandler->SmartRetrieveVelocity(), globals::g_pWaypointHandler->SmartRetrieveAngularVelocity()))
182 {
183 // Submit logger message.
184 LOG_WARNING(logging::g_qSharedLogger, "SearchPattern: Rover has become stuck!");
185 // Increment search path index so we skip the waypoint where we got stuck when reentering searchpattern.
186 m_nSearchPathIdx += 1;
187 // Check path index is within bounds.
188 if (m_nSearchPathIdx >= int(m_vSearchPath.size()))
189 {
190 m_nSearchPathIdx = m_vSearchPath.size() - 1;
191 }
192 // Handle state transition and save the current search pattern state.
193 globals::g_pStateMachineHandler->HandleEvent(Event::eStuck, true);
194 // Don't execute the rest of the state.
195 return;
196 }
197
199 /* --- Follow Search Pattern --- */
201
202 // Check if the search path is empty.
203 if (m_vSearchPath.empty())
204 {
205 // Submit logger message.
206 LOG_WARNING(logging::g_qSharedLogger, "SearchPatternState: Search path is empty, aborting search.");
207 // Handle state transition.
208 globals::g_pStateMachineHandler->HandleEvent(Event::eAbort);
209 return;
210 }
211
212 // Have we reached the current waypoint?
213 geoops::GPSCoordinate stCurrTargetGPS = m_vSearchPath[m_nSearchPathIdx].GetGPSCoordinate();
214 geoops::GeoMeasurement stCurrRelToTarget = geoops::CalculateGeoMeasurement(stCurrentRoverPose.GetGPSCoordinate(), stCurrTargetGPS);
215 bool bReachedTarget = stCurrRelToTarget.dDistanceMeters <= constants::SEARCH_WAYPOINT_PROXIMITY;
216
217 // If the entire search pattern has been completed without seeing tags or objects, try different search pattern.
218 if (bReachedTarget && m_nSearchPathIdx >= int(m_vSearchPath.size() - 1))
219 {
220 globals::g_pStateMachineHandler->HandleEvent(Event::eSearchFailed);
221 return;
222 }
223 // Move on to the next waypoint in the search path.
224 else if (bReachedTarget)
225 {
226 ++m_nSearchPathIdx;
227 stCurrTargetGPS = m_vSearchPath[m_nSearchPathIdx].GetGPSCoordinate();
228 stCurrRelToTarget = geoops::CalculateGeoMeasurement(stCurrentRoverPose.GetGPSCoordinate(), stCurrTargetGPS);
229 }
230
231 // Drive to target waypoint.
232 diffdrive::DrivePowers stDrivePowers = globals::g_pDriveBoard->CalculateMove(constants::SEARCH_MOTOR_POWER,
233 stCurrRelToTarget.dStartRelativeBearing,
234 stCurrentRoverPose.GetCompassHeading(),
235 diffdrive::DifferentialControlMethod::eArcadeDrive);
236 globals::g_pDriveBoard->SendDrive(stDrivePowers);
237
238 return;
239 }
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 SendDrive(diffdrive::DrivePowers &stDrivePowers)
Sets the left and right drive powers of the drive board.
Definition DriveBoard.cpp:120
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
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
const geoops::GPSCoordinate & GetGPSCoordinate() const
Accessor for the geoops::GPSCoordinate member variable.
Definition GeospatialOperations.hpp:722
Represents a single ArUco tag. Stores all information about a specific tag detection.
Definition TensorflowTagDetection.hpp:43
Here is the call graph for this function:

◆ TriggerEvent()

States statemachine::SearchPatternState::TriggerEvent ( Event  eEvent)
overridevirtual

Trigger an event in the state machine. Returns the next state.

Parameters
eEvent- The event to trigger.
Returns
std::shared_ptr<State> - The next state.
Author
Eli Byrd (edbgk.nosp@m.k@ms.nosp@m.t.edu)
Date
2024-01-17

Implements statemachine::State.

251 {
252 // Create instance variables.
253 States eNextState = States::eSearchPattern;
254 bool bCompleteStateExit = true;
255
256 switch (eEvent)
257 {
258 case Event::eMarkerSeen:
259 {
260 // Submit logger message.
261 LOG_INFO(logging::g_qSharedLogger, "SearchPatternState: Handling MarkerSeen event.");
262 // Change states.
263 eNextState = States::eApproachingMarker;
264 break;
265 }
266 case Event::eObjectSeen:
267 {
268 // Submit logger message.
269 LOG_INFO(logging::g_qSharedLogger, "SearchPatternState: Handling ObjectSeen event.");
270 // Change state.
271 eNextState = States::eApproachingObject;
272 break;
273 }
274 case Event::eStart:
275 {
276 // Submit logger message
277 LOG_NOTICE(logging::g_qSharedLogger, "SearchPatternState: Handling Start event.");
278 // Send multimedia command to update state display.
279 globals::g_pMultimediaBoard->SendLightingState(MultimediaBoard::MultimediaBoardLightingState::eAutonomy);
280 break;
281 }
282 case Event::eSearchFailed:
283 {
284 // Submit logger message.
285 LOG_INFO(logging::g_qSharedLogger, "SearchPatternState: Handling SearchFailed event.");
286 // Stop drive.
287 globals::g_pDriveBoard->SendStop();
288
289 // Regenerate a new search pattern.
290 switch (m_eCurrentSearchPatternType)
291 {
292 // Check which pattern to do next.
293 case eSpiral:
294 {
295 // Submit logger message.
296 LOG_NOTICE(logging::g_qSharedLogger, "SearchPatternState: Spiral search pattern failed, trying vertical ZigZag...");
297 // Generate vertical zigzag pattern.
298 m_vSearchPath = searchpattern::CalculateZigZagPatternWaypoints(m_stSearchPatternCenter.GetGPSCoordinate(),
299 m_stSearchPatternCenter.dRadius * 2,
300 m_stSearchPatternCenter.dRadius * 2,
301 constants::SEARCH_ZIGZAG_SPACING,
302 true);
303 // Reset index counter.
304 m_nSearchPathIdx = 0;
305 // Update current search pattern
306 m_eCurrentSearchPatternType = eZigZag;
307 break;
308 }
309 case eZigZag:
310 {
311 // Submit logger message.
312 LOG_NOTICE(logging::g_qSharedLogger, "SearchPatternState: Vertical ZigZag search pattern failed, trying horizontal ZigZag...");
313 // Generate vertical zigzag pattern.
314 m_vSearchPath = searchpattern::CalculateZigZagPatternWaypoints(m_stSearchPatternCenter.GetGPSCoordinate(),
315 m_stSearchPatternCenter.dRadius * 2,
316 m_stSearchPatternCenter.dRadius * 2,
317 constants::SEARCH_ZIGZAG_SPACING,
318 false);
319 // Reset index counter.
320 m_nSearchPathIdx = 0;
321 // Update current search pattern
322 m_eCurrentSearchPatternType = END;
323 break;
324 }
325 case END:
326 {
327 // Submit logger message.
328 LOG_WARNING(logging::g_qSharedLogger, "SearchPatternState: All patterns failed to find anything, giving up...");
329 // Pop old waypoint out of queue.
330 globals::g_pWaypointHandler->PopNextWaypoint();
331 // Change states.
332 eNextState = States::eIdle;
333 break;
334 }
335 default:
336 {
337 // Change states.
338 eNextState = States::eIdle;
339 break;
340 }
341 }
342 break;
343 }
344 case Event::eAbort:
345 {
346 // Submit logger message.
347 LOG_INFO(logging::g_qSharedLogger, "SearchPatternState: Handling Abort event.");
348 // Send multimedia command to update state display.
349 globals::g_pMultimediaBoard->SendLightingState(MultimediaBoard::MultimediaBoardLightingState::eAutonomy);
350 // Change state.
351 eNextState = States::eIdle;
352 break;
353 }
354 case Event::eStuck:
355 {
356 LOG_INFO(logging::g_qSharedLogger, "SearchPatternState: Handling Stuck event.");
357 eNextState = States::eStuck;
358 break;
359 }
360 default:
361 {
362 LOG_WARNING(logging::g_qSharedLogger, "SearchPatternState: Handling unknown event.");
363 eNextState = States::eIdle;
364 break;
365 }
366 }
367
368 if (eNextState != States::eSearchPattern)
369 {
370 LOG_INFO(logging::g_qSharedLogger, "SearchPatternState: Transitioning to {} State.", StateToString(eNextState));
371
372 // Exit the current state
373 if (bCompleteStateExit)
374 {
375 Exit();
376 }
377 }
378
379 return eNextState;
380 }
void SendLightingState(MultimediaBoardLightingState eState)
Sends a predetermined color pattern to board.
Definition MultimediaBoard.cpp:55
geoops::Waypoint PopNextWaypoint()
Removes and returns the next waypoint at the front of the list.
Definition WaypointHandler.cpp:499
void Exit() override
This method is called when the state is exited. It is used to clean up the state.
Definition SearchPatternState.cpp:66
std::vector< geoops::Waypoint > CalculateZigZagPatternWaypoints(const geoops::UTMCoordinate &stCenterPoint, const double dWidth=20.0, const double dHeight=20.0, const double dSpacing=1.0, const bool bVertical=true)
Calculate waypoints for a zigzag pattern. This function generates waypoints for a zigzag pattern star...
Definition SearchPattern.hpp:200
std::string StateToString(States eState)
Converts a state object to a string.
Definition State.hpp:89
States
The states that the state machine can be in.
Definition State.hpp:31
Here is the call graph for this function:

The documentation for this class was generated from the following files: