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::VerifyingMarkerState Class Reference

The VerifyingMarkerState class implements the Verifying Marker state for the Autonomy State Machine. More...

#include <VerifyingMarkerState.h>

Inheritance diagram for statemachine::VerifyingMarkerState:
Collaboration diagram for statemachine::VerifyingMarkerState:

Public Member Functions

 VerifyingMarkerState ()
 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 Attributes

bool m_bInitialized
 
geoops::Waypoint m_stGoalWaypoint
 
tagdetectutils::ArucoTag m_stBestArucoTag
 
tagdetectutils::ArucoTag m_stBestTorchTag
 
std::vector< std::shared_ptr< TagDetector > > m_vTagDetectors
 
std::chrono::system_clock::time_point m_tmTagVerificationStartTime
 
std::chrono::system_clock::time_point m_tmTagLastSeenTime
 

Detailed Description

The VerifyingMarkerState class implements the Verifying Marker state for the Autonomy State Machine.

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

Constructor & Destructor Documentation

◆ VerifyingMarkerState()

statemachine::VerifyingMarkerState::VerifyingMarkerState ( )

Construct a new State object.

Author
Eli Byrd (edbgk.nosp@m.k@ms.nosp@m.t.edu)
Date
2024-01-17
71 : State(States::eVerifyingMarker)
72 {
73 LOG_INFO(logging::g_qConsoleLogger, "Entering State: {}", ToString());
74
75 m_bInitialized = false;
76
77 if (!m_bInitialized)
78 {
79 Start();
80 m_bInitialized = true;
81 }
82 }
virtual std::string ToString() const
Accessor for the State private member. Returns the state as a string.
Definition State.hpp:202
State(States eState)
Construct a new State object.
Definition State.hpp:145
void Start() override
This method is called when the state is first started. It is used to initialize the state.
Definition VerifyingMarkerState.cpp:35
Here is the call graph for this function:

Member Function Documentation

◆ Start()

void statemachine::VerifyingMarkerState::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), Sam Hajdukiewicz (saman.nosp@m.thah.nosp@m.ajduk.nosp@m.iewi.nosp@m.cz@gm.nosp@m.ail..nosp@m.com)
Date
2024-01-17

Reimplemented from statemachine::State.

36 {
37 // Schedule the next run of the state's logic
38 LOG_INFO(logging::g_qSharedLogger, "VerifyingMarkerState: Scheduling next run of state logic.");
39
40 // Initialize member variables.
41 m_stGoalWaypoint = globals::g_pWaypointHandler->PeekNextWaypoint();
42 m_tmTagVerificationStartTime = std::chrono::system_clock::now();
43 m_tmTagLastSeenTime = std::chrono::system_clock::now();
44
45 // Get tag detectors.
46 m_vTagDetectors = {globals::g_pTagDetectionHandler->GetTagDetector(TagDetectionHandler::TagDetectors::eHeadMainCam),
47 globals::g_pTagDetectionHandler->GetTagDetector(TagDetectionHandler::TagDetectors::eRearCam)};
48 }
std::shared_ptr< TagDetector > GetTagDetector(TagDetectors eDetectorName)
Accessor for TagDetector detectors.
Definition TagDetectionHandler.cpp:163
const geoops::Waypoint PeekNextWaypoint()
Returns an immutable reference to the geoops::Waypoint struct at the front of the list without removi...
Definition WaypointHandler.cpp:540
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Exit()

void statemachine::VerifyingMarkerState::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.

59 {
60 // Clean up the state before exiting
61 LOG_INFO(logging::g_qSharedLogger, "VerifyingMarkerState: Exiting state.");
62 }
Here is the caller graph for this function:

◆ Run()

void statemachine::VerifyingMarkerState::Run ( )
overridevirtual

Run the state machine. Returns the next state.

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

Implements statemachine::State.

91 {
92 // Submit logger message.
93 LOG_DEBUG(logging::g_qSharedLogger, "VerifyingMarkerState: Running state-specific behavior.");
94
95 // Identify target marker.
96 tagdetectutils::ArucoTag stBestArucoTag, stBestTorchTag;
97 statemachine::IdentifyTargetMarker(m_vTagDetectors, stBestArucoTag, stBestTorchTag, m_stGoalWaypoint.nID);
98
99 // Calculate how long we've been in this state.
100 std::chrono::system_clock::time_point tmCurrentTime = std::chrono::system_clock::now();
101 double dElapsedTime = std::chrono::duration_cast<std::chrono::milliseconds>(tmCurrentTime - m_tmTagVerificationStartTime).count() / 1000.0;
102 // Calculate the time since the last time we saw a tag.
103 double dTimeSinceLastSeen = std::chrono::duration_cast<std::chrono::milliseconds>(tmCurrentTime - m_tmTagLastSeenTime).count() / 1000.0;
104
105 /*
106 If we consistently detect a marker for a certain amount of time, we can assume that we are in fact in front of the marker.
107 At this point, we can also assume we are close enough for the pointcloud to be usable and for aruco to pick up the tag.
108 */
109 // Check if ArUco tag is detected.
110 if (stBestArucoTag.nID == -1 && stBestTorchTag.dConfidence == 0.0)
111 {
112 // Check if the time last seen is greater than the time to give up.
113 if (dTimeSinceLastSeen > constants::APPROACH_MARKER_TAG_LOST_BUFFER_TIME)
114 {
115 // No tags are detected, trigger verify failed event.
116 LOG_INFO(logging::g_qSharedLogger, "VerifyingMarkerState: No tags detected. Triggering verify failed event.");
117 globals::g_pStateMachineHandler->HandleEvent(Event::eVerifyingFailed);
118 return;
119 }
120 }
121 else
122 {
123 // Check the tags distance.
124 if (stBestArucoTag.nID != -1 && stBestArucoTag.dStraightLineDistance > constants::APPROACH_MARKER_PROXIMITY_THRESHOLD)
125 {
126 // Tag is too far away, trigger verify failed event.
127 LOG_INFO(logging::g_qSharedLogger, "VerifyingMarkerState: ArUco tag detected but too far away. Triggering verify failed event.");
128 globals::g_pStateMachineHandler->HandleEvent(Event::eVerifyingFailed);
129 return;
130 }
131 else if (stBestTorchTag.dConfidence > 0.0 && stBestTorchTag.dStraightLineDistance > constants::APPROACH_MARKER_PROXIMITY_THRESHOLD)
132 {
133 // Tag is too far away, trigger verify failed event.
134 LOG_INFO(logging::g_qSharedLogger, "VerifyingMarkerState: Torch tag detected but too far away. Triggering verify failed event.");
135 globals::g_pStateMachineHandler->HandleEvent(Event::eVerifyingFailed);
136 return;
137 }
138
139 // Update time last seen.
140 m_tmTagLastSeenTime = std::chrono::system_clock::now();
141
142 // Update best tags.
143 m_stBestArucoTag = stBestArucoTag;
144 m_stBestTorchTag = stBestTorchTag;
145
146 // Check if we have been in this state long enough to verify the marker.
147 if (dElapsedTime >= constants::APPROACH_MARKER_VERIFY_TIME)
148 {
149 // Submit logger message.
150 LOG_INFO(logging::g_qSharedLogger, "VerifyingMarkerState: Marker verified. Triggering verify complete event.");
151 // Trigger verify complete event.
152 globals::g_pStateMachineHandler->HandleEvent(Event::eVerifyingComplete);
153 return;
154 }
155 }
156 }
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
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
Represents a single ArUco tag.
Definition TagDetectionUtilty.hpp:57
Here is the call graph for this function:

◆ TriggerEvent()

States statemachine::VerifyingMarkerState::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.

168 {
169 // Create instance variables.
170 States eNextState = States::eVerifyingMarker;
171 bool bCompleteStateExit = true;
172
173 switch (eEvent)
174 {
175 case Event::eStart:
176 {
177 // Submit logger message.
178 LOG_INFO(logging::g_qSharedLogger, "VerifyingMarkerState: Handling Start event.");
179 // Send multimedia command to update state display.
180 globals::g_pMultimediaBoard->SendLightingState(MultimediaBoard::MultimediaBoardLightingState::eAutonomy);
181 break;
182 }
183 case Event::eVerifyingComplete:
184 {
185 // Submit logger message.
186 LOG_INFO(logging::g_qSharedLogger, "VerifyingMarkerState: Handling Verifying Complete event.");
187 // Send multimedia command to update state display.
188 globals::g_pMultimediaBoard->SendLightingState(MultimediaBoard::MultimediaBoardLightingState::eReachedGoal);
189
190 // Loop through the detectors vector and find which ones UUID matches the winning tag's UUID.
191 // If a match is found, request the snapshot from that detector and save it to disk with a unique filename.
192 cv::Mat cvSnapshot;
193 for (const std::shared_ptr<TagDetector>& pTagDetector : m_vTagDetectors)
194 {
195 if (pTagDetector->GetThreadUUID() == m_stBestArucoTag.szDetectorUUID || pTagDetector->GetThreadUUID() == m_stBestTorchTag.szDetectorUUID)
196 {
197 std::future<bool> fuFrame = pTagDetector->RequestLastGoodOverlayFrame(cvSnapshot);
198 if (!fuFrame.get())
199 {
200 LOG_WARNING(logging::g_qSharedLogger, "VerifyingMarkerState: Failed to request detection overlay frame.");
201 }
202 break;
203 }
204 }
205
206 // Make sure the snapshot is not empty before trying to save it.
207 if (!cvSnapshot.empty())
208 {
209 // Ensure the directory exists
210 std::string szLogDir = logging::g_szLoggingOutputPath + "/detections/";
211 if (!std::filesystem::exists(szLogDir))
212 {
213 std::filesystem::create_directories(szLogDir);
214 }
215
216 // Create a unique filename using the current timestamp
217 std::string szTimestamp = timeops::GetTimestamp();
218 std::string szFilename = szLogDir + "marker_" + szTimestamp + ".png";
219
220 // Save the image to the disk
221 bool bSuccess = cv::imwrite(szFilename, cvSnapshot);
222
223 if (bSuccess)
224 {
225 LOG_NOTICE(logging::g_qSharedLogger, "VerifyingMarkerState: Saved detection snapshot to {}", szFilename);
226 }
227 else
228 {
229 LOG_ERROR(logging::g_qSharedLogger, "VerifyingMarkerState: Failed to write snapshot to disk.");
230 }
231 }
232 else
233 {
234 LOG_WARNING(logging::g_qSharedLogger, "VerifyingMarkerState: Overlay frame was empty. No snapshot taken.");
235 }
236
237 // Pop old waypoint out of queue.
238 globals::g_pWaypointHandler->PopNextWaypoint();
239 // Clear saved states.
240 globals::g_pStateMachineHandler->ClearSavedStates();
241 // Submit logger message.
242 LOG_NOTICE(logging::g_qSharedLogger, "VerifyingMarkerState: Cleared old saved states.");
243 // Change state.
244 eNextState = States::eIdle;
245 break;
246 }
247 case Event::eVerifyingFailed:
248 {
249 // Submit logger message.
250 LOG_INFO(logging::g_qSharedLogger, "VerifyingMarkerState: Handling Verifying Failed event.");
251 // Send multimedia command to update state display.
252 globals::g_pMultimediaBoard->SendLightingState(MultimediaBoard::MultimediaBoardLightingState::eAutonomy);
253 // Recall the previous state.
254 eNextState = globals::g_pStateMachineHandler->GetPreviousState();
255 break;
256 }
257 case Event::eAbort:
258 {
259 // Submit logger message.
260 LOG_INFO(logging::g_qSharedLogger, "VerifyingMarkerState: Handling Abort event.");
261 // Send multimedia command to update state display.
262 globals::g_pMultimediaBoard->SendLightingState(MultimediaBoard::MultimediaBoardLightingState::eOff);
263 // Change state.
264 eNextState = States::eIdle;
265 break;
266 }
267 default:
268 {
269 LOG_WARNING(logging::g_qSharedLogger, "VerifyingMarkerState: Handling unknown event.");
270 eNextState = States::eIdle;
271 break;
272 }
273 }
274
275 if (eNextState != States::eVerifyingMarker)
276 {
277 LOG_INFO(logging::g_qSharedLogger, "VerifyingMarkerState: Transitioning to {} State.", StateToString(eNextState));
278
279 // Exit the current state
280 if (bCompleteStateExit)
281 {
282 Exit();
283 }
284 }
285
286 return eNextState;
287 }
void SendLightingState(MultimediaBoardLightingState eState)
Sends a predetermined color pattern to board.
Definition MultimediaBoard.cpp:55
void ClearSavedStates()
Clear all saved states.
Definition StateMachineHandler.cpp:311
statemachine::States GetPreviousState() const
Accessor for the Previous State private member.
Definition StateMachineHandler.cpp:358
geoops::Waypoint PopNextWaypoint()
Removes and returns the next waypoint at the front of the list.
Definition WaypointHandler.cpp:500
bool empty() const
void Exit() override
This method is called when the state is exited. It is used to clean up the state.
Definition VerifyingMarkerState.cpp:58
bool imwrite(const String &filename, InputArray img, const std::vector< int > &params=std::vector< int >())
std::string StateToString(States eState)
Converts a state object to a string.
Definition State.hpp:85
States
The states that the state machine can be in.
Definition State.hpp:31
std::string GetTimestamp(const std::string &szFormat="%Y%m%d-%H%M%S")
Accessor for getting the current time in a specified format.
Definition TimeOperations.hpp:42
Here is the call graph for this function:

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