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

The ApproachingObjectState class implements the Approaching Object state for the Autonomy State Machine. More...

#include <ApproachingObjectState.h>

Inheritance diagram for statemachine::ApproachingObjectState:
Collaboration diagram for statemachine::ApproachingObjectState:

Public Member Functions

 ApproachingObjectState ()
 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

std::vector< std::shared_ptr< ObjectDetector > > m_vObjectDetectors
 
statemachine::TimeIntervalBasedStuckDetector m_StuckDetector
 
States m_eTriggeringState
 
bool m_bInitialized
 
geoops::Waypoint m_stGoalWaypoint
 
std::unique_ptr< logging::graphing::PathTracerm_pRoverPathPlot
 

Detailed Description

The ApproachingObjectState class implements the Approaching Object state for the Autonomy State Machine.

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

Constructor & Destructor Documentation

◆ ApproachingObjectState()

statemachine::ApproachingObjectState::ApproachingObjectState ( )

Construct a new State object.

Author
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
73 : State(States::eApproachingObject)
74 {
75 LOG_INFO(logging::g_qConsoleLogger, "Entering State: {}", ToString());
76
77 m_bInitialized = false;
78
79 m_StuckDetector = statemachine::TimeIntervalBasedStuckDetector(constants::STUCK_CHECK_ATTEMPTS,
80 constants::STUCK_CHECK_INTERVAL,
81 constants::STUCK_CHECK_VEL_THRESH,
82 constants::STUCK_CHECK_ROT_THRESH);
83 m_pRoverPathPlot = std::make_unique<logging::graphing::PathTracer>("ApproachingObjectRoverPath");
84
85 if (!m_bInitialized)
86 {
87 Start();
88 m_bInitialized = true;
89 }
90 }
void Start() override
This method is called when the state is first started. It is used to initialize the state.
Definition ApproachingObjectState.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::ApproachingObjectState::Start ( )
overrideprotectedvirtual

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

Author
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.

34 {
35 // Schedule the next run of the state's logic
36 LOG_INFO(logging::g_qSharedLogger, "ApproachingObjectState: Scheduling next run of state logic.");
37
38 // Initialize member variables.
39 m_stGoalWaypoint = globals::g_pWaypointHandler->PeekNextWaypoint();
40
41 // Store the state that got stuck and triggered an ObjectSeen event.
42 m_eTriggeringState = globals::g_pStateMachineHandler->GetPreviousState();
43
44 // Add the search and rover path layers to the plot.
45 m_pRoverPathPlot->CreateDotLayer("DetectedObjects", "blue");
46 m_pRoverPathPlot->CreateDotLayer("FinalObject", "green");
47 m_pRoverPathPlot->CreatePathLayer("RoverPath", "-.r*");
48
49 m_vObjectDetectors = {globals::g_pObjectDetectionHandler->GetObjectDetector(ObjectDetectionHandler::ObjectDetectors::eHeadMainCam)};
50 }
std::shared_ptr< ObjectDetector > GetObjectDetector(ObjectDetectors eDetectorName)
Accessor for ObjectDetector detectors.
Definition ObjectDetectionHandler.cpp:127
statemachine::States GetPreviousState() const
Accessor for the Previous State private member.
Definition StateMachineHandler.cpp:423
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::ApproachingObjectState::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.

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

◆ Run()

void statemachine::ApproachingObjectState::Run ( )
overridevirtual

Run the state machine. Returns the next state.

Author
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

Implements statemachine::State.

99 {
100 // Submit logger message.
101 LOG_DEBUG(logging::g_qSharedLogger, "ApproachingObjectState: Running state-specific behavior.");
102
103 // Get the current rover pose.
104 geoops::RoverPose stCurrentRoverPose = globals::g_pWaypointHandler->SmartRetrieveRoverPose();
105
106 // Add the current rover pose to the path plot.
107 m_pRoverPathPlot->AddPathPoint(stCurrentRoverPose.GetUTMCoordinate(), "RoverPath");
108
109 // Check Rover radius from object waypoint.
110 geoops::GeoMeasurement stCurrentMeasurement = geoops::CalculateGeoMeasurement(m_stGoalWaypoint.GetGPSCoordinate(), stCurrentRoverPose.GetGPSCoordinate());
111 if (stCurrentMeasurement.dDistanceMeters > m_stGoalWaypoint.dRadius)
112 {
113 // Submit logger message.
114 LOG_WARNING(logging::g_qSharedLogger,
115 "ApproachingObjectState: Rover is too far from the original waypoint! Waypoint radius is {} meters, current distance is {} meters.",
116 m_stGoalWaypoint.dRadius,
117 stCurrentMeasurement.dDistanceMeters);
118 globals::g_pStateMachineHandler->HandleEvent(Event::eObjectUnseen);
119 return;
120 }
121
122 // Identify target object.
123 objectdetectutils::Object stBestObject;
124 statemachine::IdentifyTargetObject(m_vObjectDetectors, stBestObject, m_stGoalWaypoint.eType);
125
126 // Check if object is unseen.
127 static bool bAlreadyPrintedLost = false;
128 static std::chrono::system_clock::time_point tLastSeenTime = std::chrono::system_clock::now();
129 if (stBestObject.dConfidence == 0.0)
130 {
131 std::chrono::system_clock::time_point tmCurrentTime = std::chrono::system_clock::now();
132 if ((std::chrono::duration_cast<std::chrono::milliseconds>(tmCurrentTime - tLastSeenTime).count() / 1000.0) > constants::APPROACH_OBJECT_LOST_GIVE_UP_TIME)
133 {
134 // Submit logger message.
135 globals::g_pStateMachineHandler->HandleEvent(Event::eObjectUnseen);
136 return;
137 }
138 else
139 {
140 if (!bAlreadyPrintedLost)
141 {
142 bAlreadyPrintedLost = true;
143 // Submit logger message.
144 LOG_WARNING(logging::g_qSharedLogger, "ApproachingObjectState: No objects detected.");
145
146 // If an object is good and has a valid geoposition, don't stop the drive, we can keep driving to it.
147 if (stBestObject.dConfidence != 0.0 && stBestObject.stGeolocatedPosition.eType != geoops::WaypointType::eUNKNOWN)
148 {
149 // Submit logger message.
150 LOG_NOTICE(logging::g_qSharedLogger, "ApproachingObjectState: Object is geolocated.");
151 return;
152 }
153
154 // Stop the drive.
155 globals::g_pDriveBoard->SendStop();
156 return;
157 }
158 }
159 }
160
161 else
162 {
163 // Submit logger message.
164 if (bAlreadyPrintedLost)
165 {
166 LOG_NOTICE(logging::g_qSharedLogger, "ApproachingObjectState: Objects were detected again.");
167 }
168
169 // Reset the last seen time if a tag is detected.
170 tLastSeenTime = std::chrono::system_clock::now();
171 // Reset printed flag when tags are detected again.
172 bAlreadyPrintedLost = false;
173 }
174
175 // Create instance variables.
176 static double dHeadingSetPoint = 0.0;
177 static double dDistanceFromObject = 0.0;
178 // Check if we got a good object.
179 if (stBestObject.dConfidence != 0.0)
180 {
181 dDistanceFromObject = stBestObject.dStraightLineDistance;
182 // Check if the object has an absolute coordinate populated.
183 if (stBestObject.stGeolocatedPosition.eType != geoops::WaypointType::eUNKNOWN)
184 {
185 // Calculate the geomeasurement to the object.
186 geoops::GeoMeasurement stObjectMeasurement =
187 geoops::CalculateGeoMeasurement(stCurrentRoverPose.GetUTMCoordinate(), stBestObject.stGeolocatedPosition.GetUTMCoordinate());
188 // Update static variables.
189 dHeadingSetPoint = stObjectMeasurement.dStartRelativeBearing;
190 // Add the most recent geolocated object to the path plot.
191 m_pRoverPathPlot->AddDot(stBestObject.stGeolocatedPosition.GetUTMCoordinate(), "DetectedObjects");
192 }
193 else
194 {
195 dHeadingSetPoint = numops::InputAngleModulus(stBestObject.dYawAngle + stCurrentRoverPose.GetCompassHeading(), 0.0, 360.0);
196 }
197 }
198
199 // Move the rover to the target's estimated position.
200 diffdrive::DrivePowers stDrivePowers = globals::g_pDriveBoard->CalculateMove(constants::APPROACH_OBJECT_MOTOR_POWER,
201 dHeadingSetPoint,
202 stCurrentRoverPose.GetCompassHeading(),
203 diffdrive::DifferentialControlMethod::eArcadeDrive);
204 globals::g_pDriveBoard->SendDrive(stDrivePowers);
205
206 // Static variable to track last log time.
207 static std::chrono::system_clock::time_point tmLastOLogTime = std::chrono::system_clock::now();
208 std::chrono::system_clock::time_point tmCurrentTime = std::chrono::system_clock::now();
209 if (std::chrono::duration_cast<std::chrono::seconds>(tmCurrentTime - tmLastOLogTime).count() >= 1)
210 {
211 // Update the last log time.
212 tmLastOLogTime = tmCurrentTime;
213
214 if (stBestObject.dConfidence != 0.0)
215 {
216 LOG_NOTICE(logging::g_qSharedLogger,
217 "ApproachingObjectState: Object confidence: {:.2f}, Distance: {:.2f} m, Heading: {:.2f} deg",
218 stBestObject.dConfidence,
219 dDistanceFromObject,
220 dHeadingSetPoint);
221 }
222 }
223
224 // Check if tag is reached.
225 if (dDistanceFromObject != 0.0 && dDistanceFromObject < constants::APPROACH_OBJECT_PROXIMITY_THRESHOLD)
226 {
227 // Submit logger message.
228 LOG_NOTICE(logging::g_qSharedLogger, "ApproachingObjectState: Rover has reached the target object!");
229 // Check if the object has a good absolute position.
230 if (stBestObject.dConfidence != 0.0 && stBestObject.stGeolocatedPosition.eType == geoops::WaypointType::eObjectWaypoint)
231 {
232 // Add the object to the path plot.
233 m_pRoverPathPlot->AddDot(stBestObject.stGeolocatedPosition.GetUTMCoordinate(), "FinalObject", 7);
234 }
235
236 // Reset the object heading and distance.
237 dHeadingSetPoint = 0.0;
238 dDistanceFromObject = 0.0;
239
240 // Handle state transition and save the current search pattern state.
241 globals::g_pStateMachineHandler->HandleEvent(Event::eReachedObject, true);
242 // Don't execute the rest of the state.
243 return;
244 }
245
247 // --- Check if the rover is stuck --- //
249
250 // Check if stuck.
251 if (constants::APPROACH_OBJECT_ENABLE_STUCK_DETECT &&
252 m_StuckDetector.CheckIfStuck(globals::g_pWaypointHandler->SmartRetrieveVelocity(), globals::g_pWaypointHandler->SmartRetrieveAngularVelocity()))
253 {
254 // Submit logger message.
255 LOG_NOTICE(logging::g_qSharedLogger, "ApproachingObjectState: Rover has become stuck!");
256 // Handle state transition and save the current search pattern state.
257 globals::g_pStateMachineHandler->HandleEvent(Event::eStuck, true);
258 // Don't execute the rest of the state.
259 return;
260 }
261
262 return;
263 }
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 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:90
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 detected object. Combines attributes from TorchObject and TensorflowObject struct...
Definition ObjectDetectionUtility.hpp:73
Here is the call graph for this function:

◆ TriggerEvent()

States statemachine::ApproachingObjectState::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
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

Implements statemachine::State.

275 {
276 // Create instance variables.
277 States eNextState = States::eApproachingObject;
278 bool bCompleteStateExit = true;
279
280 switch (eEvent)
281 {
282 case Event::eReachedObject:
283 {
284 // Submit logger message.
285 LOG_INFO(logging::g_qSharedLogger, "ApproachingObjectState: Handling ReachedObject event.");
286
287 // Check if verifying object state is enabled.
288 if (constants::APPROACH_OBJECT_VERIFY_POSITION)
289 {
290 // Change states.
291 eNextState = States::eVerifyingObject;
292 }
293 else
294 {
295 // Send multimedia command to update state display.
296 globals::g_pMultimediaBoard->SendLightingState(MultimediaBoard::MultimediaBoardLightingState::eReachedGoal);
297 // Pop old waypoint out of queue.
298 globals::g_pWaypointHandler->PopNextWaypoint();
299 // Clear saved search pattern state.
300 globals::g_pStateMachineHandler->ClearSavedStates();
301 // Submit logger message.
302 LOG_NOTICE(logging::g_qSharedLogger, "ApproachingObjectState: Cleared old search pattern state and approaching object state from saved states.");
303 // Change state.
304 eNextState = States::eIdle;
305 }
306 break;
307 }
308 case Event::eStart:
309 {
310 // Submit logger message.
311 LOG_INFO(logging::g_qSharedLogger, "ApproachingObjectState: Handling Start event.");
312 // Send multimedia command to update state display.
313 globals::g_pMultimediaBoard->SendLightingState(MultimediaBoard::MultimediaBoardLightingState::eAutonomy);
314 break;
315 }
316 case Event::eObjectUnseen:
317 {
318 // Submit logger message.
319 LOG_INFO(logging::g_qSharedLogger, "ApproachingObjectState: Handling ObjectUnseen event.");
320 // Change states.
321 eNextState = m_eTriggeringState;
322 break;
323 }
324 case Event::eAbort:
325 {
326 // Submit logger message.
327 LOG_INFO(logging::g_qSharedLogger, "ApproachingObjectState: Handling Abort event.");
328 // Send multimedia command to update state display.
329 globals::g_pMultimediaBoard->SendLightingState(MultimediaBoard::MultimediaBoardLightingState::eOff);
330 // Change state.
331 eNextState = States::eIdle;
332 break;
333 }
334 default:
335 {
336 LOG_WARNING(logging::g_qSharedLogger, "ApproachingObjectState: Handling unknown event.");
337 eNextState = States::eIdle;
338 break;
339 }
340 }
341
342 if (eNextState != States::eApproachingMarker)
343 {
344 LOG_INFO(logging::g_qSharedLogger, "ApproachingObjectState: Transitioning to {} State.", StateToString(eNextState));
345
346 // Exit the current state
347 if (bCompleteStateExit)
348 {
349 Exit();
350 }
351 }
352
353 return eNextState;
354 }
void SendLightingState(MultimediaBoardLightingState eState)
Sends a predetermined color pattern to board.
Definition MultimediaBoard.cpp:55
void ClearSavedStates()
Clear all saved states.
Definition StateMachineHandler.cpp:376
geoops::Waypoint PopNextWaypoint()
Removes and returns the next waypoint at the front of the list.
Definition WaypointHandler.cpp:500
void Exit() override
This method is called when the state is exited. It is used to clean up the state.
Definition ApproachingObjectState.cpp:60
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: