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
 
double m_dHeadingSetPoint
 
bool m_bDriveBackwards
 
geoops::Waypoint m_stLastGeolocatedPosition
 
bool m_bHasLastGeolocatedPosition
 
bool m_bHasSeenTarget
 
std::chrono::system_clock::time_point m_tmLastSeenTime
 
std::chrono::system_clock::time_point m_tmLastLogTime
 
bool m_bAlreadyPrintedLost
 
bool m_bAlreadyPrintedVisualLostFallback
 

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
85 : State(States::eApproachingObject)
86 {
87 LOG_INFO(logging::g_qConsoleLogger, "Entering State: {}", ToString());
88
89 m_bInitialized = false;
90
91 m_StuckDetector = statemachine::TimeIntervalBasedStuckDetector(constants::APPROACH_OBJECT_STUCK_CHECK_ATTEMPTS, constants::APPROACH_OBJECT_STUCK_CHECK_INTERVAL);
92
93 if (!m_bInitialized)
94 {
95 Start();
96 m_bInitialized = true;
97 }
98 }
void Start() override
This method is called when the state is first started. It is used to initialize the state.
Definition ApproachingObjectState.cpp:32
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
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.

33 {
34 // Schedule the next run of the state's logic.
35 LOG_INFO(logging::g_qSharedLogger, "ApproachingObjectState: Scheduling next run of state logic.");
36
37 // Initialize target parameters.
38 m_stGoalWaypoint = globals::g_pWaypointHandler->PeekNextWaypoint();
39 m_eTriggeringState = globals::g_pStateMachineHandler->GetPreviousState();
40
41 // Schedule the next run of the state's logic.
42 LOG_INFO(logging::g_qSharedLogger,
43 "ApproachingObjectState: Started. Goal Waypoint -> Lat: {:.6f}, Lon: {:.6f}, Radius: {:.2f}m. Previous State: {}",
44 m_stGoalWaypoint.GetGPSCoordinate().dLatitude,
45 m_stGoalWaypoint.GetGPSCoordinate().dLongitude,
46 m_stGoalWaypoint.dRadius,
47 StateToString(m_eTriggeringState));
48
49 // Fetch detectors.
50 m_vObjectDetectors = {globals::g_pObjectDetectionHandler->GetObjectDetector(ObjectDetectionHandler::ObjectDetectors::eHeadMainCam),
51 globals::g_pObjectDetectionHandler->GetObjectDetector(ObjectDetectionHandler::ObjectDetectors::eRearCam)};
52
53 LOG_INFO(logging::g_qSharedLogger, "ApproachingObjectState: Fetched {} object detectors for tracking.", m_vObjectDetectors.size());
54
55 // Reset all persistent tracking variables for a clean slate.
56 m_dHeadingSetPoint = 0.0;
57 m_bDriveBackwards = false;
58 m_bHasLastGeolocatedPosition = false;
59 m_bHasSeenTarget = false;
60 m_bAlreadyPrintedLost = false;
61 m_bAlreadyPrintedVisualLostFallback = false;
62 m_tmLastSeenTime = std::chrono::system_clock::now();
63 m_tmLastLogTime = std::chrono::system_clock::now();
64 }
std::shared_ptr< ObjectDetector > GetObjectDetector(ObjectDetectors eDetectorName)
Accessor for ObjectDetector detectors.
Definition ObjectDetectionHandler.cpp:153
statemachine::States GetPreviousState() const
Accessor for the Previous State private member.
Definition StateMachineHandler.cpp:358
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
std::string StateToString(States eState)
Converts a state object to a string.
Definition State.hpp:85
const geoops::GPSCoordinate & GetGPSCoordinate() const
Accessor for the geoops::GPSCoordinate member variable.
Definition GeospatialOperations.hpp:497
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.

74 {
75 // Clean up the state before exiting.
76 LOG_INFO(logging::g_qSharedLogger, "ApproachingObjectState: Exiting state.");
77 }
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

STATE LOGIC FLOW:

  1. Geofence Check: Verify the rover is within the goal waypoint's radius.
  2. Target Identification: Find the closest target across all cameras.
  3. High Confidence Check: If object is highly confident, STOP and verify.
  4. Navigation Decision Tree: Track low-confidence hits or fallbacks.
  5. Execution: Send drive commands and run stuck detection.

Implements statemachine::State.

107 {
108
117 LOG_DEBUG(logging::g_qSharedLogger, "ApproachingObjectState: Running state-specific behavior.");
118
119 // Get the current rover pose and add to plot.
120 geoops::RoverPose stCurrentRoverPose = globals::g_pStateMachineHandler->SmartRetrieveRoverPose();
121
122 // 1. Boundary Check: Verify rover radius from object waypoint.
123 geoops::GeoMeasurement stCurrentMeasurement = geoops::CalculateGeoMeasurement(m_stGoalWaypoint.GetGPSCoordinate(), stCurrentRoverPose.GetGPSCoordinate());
124 if (stCurrentMeasurement.dDistanceMeters > m_stGoalWaypoint.dRadius)
125 {
126 LOG_WARNING(logging::g_qSharedLogger,
127 "ApproachingObjectState: Rover broke geofence! Radius threshold is {} m, current distance is {:.2f} m. Triggering ObjectUnseen.",
128 m_stGoalWaypoint.dRadius,
129 stCurrentMeasurement.dDistanceMeters);
130 globals::g_pStateMachineHandler->HandleEvent(Event::eObjectUnseen);
131 return;
132 }
133
134 // 2. Identify target object.
135 objectdetectutils::Object stBestObject;
136 statemachine::IdentifyTargetObject(m_vObjectDetectors, stBestObject, m_stGoalWaypoint.eType);
137
138 std::chrono::system_clock::time_point tmCurrentTime = std::chrono::system_clock::now();
139 double dSecondsSinceLastSeen = std::chrono::duration_cast<std::chrono::milliseconds>(tmCurrentTime - m_tmLastSeenTime).count() / 1000.0;
140
141 // Clear stale session data if re-entered after a long time.
142 if (dSecondsSinceLastSeen > constants::APPROACH_OBJECT_LOST_GIVE_UP_TIME + 5.0)
143 {
144 m_bHasLastGeolocatedPosition = false;
145 }
146
147 // 3. Object Detected -> IMMEDIATE STOP AND VERIFY (No distance check!)
148 if (stBestObject.dConfidence > 0.0)
149 {
150 LOG_NOTICE(logging::g_qSharedLogger, "ApproachingObjectState: OBJECT DETECTED ({:.2f}%). Halting to verify!", stBestObject.dConfidence * 100.0);
151
152 globals::g_pDriveBoard->SendStop();
153 globals::g_pStateMachineHandler->HandleEvent(Event::eReachedObject, true);
154 return;
155 }
156
157 // 4. Object unseen fallback logic
158 if (dSecondsSinceLastSeen > constants::APPROACH_OBJECT_LOST_GIVE_UP_TIME)
159 {
160 LOG_WARNING(logging::g_qSharedLogger,
161 "ApproachingObjectState: Object has been unseen for {:.2f}s (Threshold: {:.2f}s). Giving up and triggering ObjectUnseen.",
162 dSecondsSinceLastSeen,
163 constants::APPROACH_OBJECT_LOST_GIVE_UP_TIME);
164 globals::g_pStateMachineHandler->HandleEvent(Event::eObjectUnseen);
165 return;
166 }
167
168 if (!m_bAlreadyPrintedLost)
169 {
170 m_bAlreadyPrintedLost = true;
171 LOG_WARNING(logging::g_qSharedLogger, "ApproachingObjectState: Tracking lost! No valid objects detected across any camera.");
172 }
173
174 // Fallback 1: Drive to last known geolocated position if available.
175 if (m_bHasLastGeolocatedPosition)
176 {
177 geoops::GeoMeasurement stLastMeasurement =
178 geoops::CalculateGeoMeasurement(stCurrentRoverPose.GetUTMCoordinate(), m_stLastGeolocatedPosition.GetUTMCoordinate());
179 m_dHeadingSetPoint = stLastMeasurement.dStartRelativeBearing;
180
181 if (!m_bAlreadyPrintedVisualLostFallback)
182 {
183 LOG_NOTICE(logging::g_qSharedLogger,
184 "ApproachingObjectState: [FALLBACK 1] Visual lost. Driving to last known geolocated UTM: [{:.2f}E, {:.2f}N]. Target Bearing: {:.2f} degrees",
185 m_stLastGeolocatedPosition.GetUTMCoordinate().dEasting,
186 m_stLastGeolocatedPosition.GetUTMCoordinate().dNorthing,
187 m_dHeadingSetPoint);
188 m_bAlreadyPrintedVisualLostFallback = true;
189 }
190 }
191 // Fallback 2: Coast along last known heading.
192 else if (m_bHasSeenTarget)
193 {
194 if (!m_bAlreadyPrintedVisualLostFallback)
195 {
196 LOG_NOTICE(logging::g_qSharedLogger,
197 "ApproachingObjectState: [FALLBACK 2] Visual lost & no geolocation history. Coasting along last known heading. Target Bearing: {:.2f} degrees",
198 m_dHeadingSetPoint);
199 m_bAlreadyPrintedVisualLostFallback = true;
200 }
201 }
202 // Wait in place: We have never seen the object.
203 else
204 {
205 globals::g_pDriveBoard->SendStop();
206 return;
207 }
208
209 // 5. Execute drive command based on the best available information and run stuck detection.
210 diffdrive::DrivePowers stDrivePowers = globals::g_pDriveBoard->CalculateMove(constants::APPROACH_OBJECT_MOTOR_POWER,
211 m_dHeadingSetPoint,
212 stCurrentRoverPose.GetCompassHeading(),
213 diffdrive::DifferentialControlMethod::eArcadeDrive,
214 m_bDriveBackwards, // Reverse control flag.
215 false,
216 false,
217 false);
218 globals::g_pDriveBoard->SendDrive(stDrivePowers);
219
220 // Check if the rover is stuck.
221 if (constants::APPROACH_OBJECT_ENABLE_STUCK_DETECT &&
222 m_StuckDetector.CheckIfStuck(globals::g_pStateMachineHandler->SmartRetrieveVelocity(),
223 globals::g_pStateMachineHandler->SmartRetrieveAngularVelocity(),
224 constants::APPROACH_OBJECT_STUCK_CHECK_VEL_THRESH * globals::g_pDriveBoard->GetMaxDriveEffort(),
225 constants::APPROACH_OBJECT_STUCK_CHECK_ROT_THRESH))
226 {
227 LOG_WARNING(logging::g_qSharedLogger,
228 "ApproachingObjectState: Rover has become stuck! Triggering Stuck event. Curr Vel: {:.2f}, Ang Vel: {:.2f}",
229 globals::g_pStateMachineHandler->SmartRetrieveVelocity(),
230 globals::g_pStateMachineHandler->SmartRetrieveAngularVelocity());
231 globals::g_pStateMachineHandler->HandleEvent(Event::eStuck, true);
232 return;
233 }
234 }
void SendDrive(const diffdrive::DrivePowers &stDrivePowers, const bool bEnableVariableDriveEffort=true)
Sets the left and right drive powers of the drive board.
Definition DriveBoard.cpp:166
diffdrive::DrivePowers CalculateMove(const double dGoalSpeed, const double dGoalHeading, const double dActualHeading, const diffdrive::DifferentialControlMethod eKinematicsMethod=diffdrive::DifferentialControlMethod::eArcadeDrive, const bool bDriveBackwards=false, const bool bAlwaysProgressForward=false, const bool bSquareControlInput=false, const bool bCurvatureDriveAllowTurningWhileStopped=true)
This method determines drive powers to make the Rover drive towards a given heading at a given speed.
Definition DriveBoard.cpp:89
void SendStop()
Stop the drivetrain of the Rover.
Definition DriveBoard.cpp:246
geoops::RoverPose SmartRetrieveRoverPose(bool bIMUHeading=true)
This method is used to retrieve the rover's current position and heading. It uses the GPS data from t...
Definition StateMachineHandler.cpp:375
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
bool CheckIfStuck(double dCurrentVelocity, double dCurrentAngularVelocity, double dVelocityThreshold=0.1, double dAngularVelocityThreshold=0.1)
Checks if the rover meets stuck criteria based in the given parameters.
Definition StuckDetection.hpp:96
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:553
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:101
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:83
This struct is used by the WaypointHandler to provide an easy way to store all pose data about the ro...
Definition GeospatialOperations.hpp:708
const geoops::GPSCoordinate & GetGPSCoordinate() const
Accessor for the geoops::GPSCoordinate member variable.
Definition GeospatialOperations.hpp:756
double GetCompassHeading() const
Accessor for the Compass Heading private member.
Definition GeospatialOperations.hpp:787
const geoops::UTMCoordinate & GetUTMCoordinate() const
Accessor for the geoops::UTMCoordinate member variable.
Definition GeospatialOperations.hpp:767
const geoops::UTMCoordinate & GetUTMCoordinate() const
Accessor for the geoops::UTMCoordinate member variable.
Definition GeospatialOperations.hpp:508
Represents a single detected object.
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.

246 {
247 // Create instance variables.
248 States eNextState = States::eApproachingObject;
249 bool bCompleteStateExit = true;
250
251 switch (eEvent)
252 {
253 case Event::eReachedObject:
254 {
255 // Submit logger message.
256 LOG_INFO(logging::g_qSharedLogger, "ApproachingObjectState: Handling ReachedObject event.");
257
258 if (constants::APPROACH_OBJECT_VERIFY_POSITION)
259 {
260 eNextState = States::eVerifyingObject;
261 }
262 else
263 {
264 globals::g_pMultimediaBoard->SendLightingState(MultimediaBoard::MultimediaBoardLightingState::eReachedGoal);
265 globals::g_pWaypointHandler->PopNextWaypoint();
266 globals::g_pStateMachineHandler->ClearSavedStates();
267 LOG_NOTICE(logging::g_qSharedLogger, "ApproachingObjectState: Cleared old search pattern state and approaching object state from saved states.");
268 eNextState = States::eIdle;
269 }
270 break;
271 }
272 case Event::eStart:
273 {
274 // Submit logger message.
275 LOG_INFO(logging::g_qSharedLogger, "ApproachingObjectState: Handling Start event.");
276 globals::g_pMultimediaBoard->SendLightingState(MultimediaBoard::MultimediaBoardLightingState::eAutonomy);
277 break;
278 }
279 case Event::eObjectUnseen:
280 {
281 // Submit logger message.
282 LOG_INFO(logging::g_qSharedLogger, "ApproachingObjectState: Handling ObjectUnseen event.");
283 // Change states.
284 eNextState = m_eTriggeringState;
285 break;
286 }
287 case Event::eStuck:
288 {
289 LOG_INFO(logging::g_qSharedLogger, "NavigatingState: Handling Stuck event.");
290 eNextState = States::eStuck;
291 break;
292 }
293 case Event::eAbort:
294 {
295 // Submit logger message.
296 LOG_INFO(logging::g_qSharedLogger, "ApproachingObjectState: Handling Abort event.");
297 // Send multimedia command to update state display.
298 globals::g_pMultimediaBoard->SendLightingState(MultimediaBoard::MultimediaBoardLightingState::eOff);
299 // Change state.
300 eNextState = States::eIdle;
301 break;
302 }
303 default:
304 {
305 LOG_WARNING(logging::g_qSharedLogger, "ApproachingObjectState: Handling unknown event ({}), defaulting to Idle.", static_cast<int>(eEvent));
306 eNextState = States::eIdle;
307 break;
308 }
309 }
310
311 if (eNextState != States::eApproachingMarker)
312 {
313 LOG_INFO(logging::g_qSharedLogger, "ApproachingObjectState: Transitioning to {} State.", StateToString(eNextState));
314
315 // Exit the current state.
316 if (bCompleteStateExit)
317 {
318 Exit();
319 }
320 }
321
322 return eNextState;
323 }
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
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:73
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: