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
StateMachineHandler Class Reference

The StateMachineHandler class serves as the main state machine for Autonomy Software. It will handle all state transitions and run the logic for each state. More...

#include <StateMachineHandler.h>

Inheritance diagram for StateMachineHandler:
Collaboration diagram for StateMachineHandler:

Public Member Functions

 StateMachineHandler ()
 Construct a new State Machine Handler object.
 
 ~StateMachineHandler ()
 Destroy the State Machine Handler:: State Machine Handler object.
 
void StartStateMachine ()
 This method will start the state machine. It will set the first state to Idle and start the thread pool.
 
void StopStateMachine ()
 This method will stop the state machine. It will signal whatever state is currently running to abort back to idle and then stop the main code running in the ThreadedContinuousCode() method.
 
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 state and run the state's HandleEvent() method. It will then check the state's transition conditions and transition to the next state if the conditions are met.
 
void ClearSavedStates ()
 Clear all saved states.
 
void ClearSavedState (statemachine::States eState)
 Clear a saved state based on the given state.
 
statemachine::States GetCurrentState () const
 Accessor for the Current State private member.
 
statemachine::States GetPreviousState () const
 Accessor for the Previous State private member.
 
geoops::RoverPose SmartRetrieveRoverPose (bool bVIOHeading=true, bool bVIOTracking=false)
 Retrieve the rover's current position and heading. Automatically picks between getting the position/heading from the NavBoard, ZEDSDK Fusion module, or ZED positional tracking. In most cases, this will be the method that should be called over getting the data directly from NavBoard.
 
double SmartRetrieveVelocity ()
 Retrieve the rover's current velocity. Currently there is no easy way to get the velocity of the ZEDCam so this method just returns the GPS-based velocity.
 
double SmartRetrieveAngularVelocity ()
 Retrieve the rover's current velocity. Currently there is no easy way to get the velocity of the ZEDCam so this method just returns the GPS-based velocity.
 
void RealignZEDPosition (CameraHandler::ZEDCamName eCameraName, const geoops::UTMCoordinate &stNewCameraPosition, const double dNewCameraHeading)
 This is used to realign the ZEDs forward direction with the rover's current compass heading. Realigning GPS latlon is not necessary since we're using the ZEDSDK's Fusion module. The heading of the camera's GeoPose is actually automatically realigned too depending on what direction We are headed, but this is just to be safe.
 
IPSGetIPS ()
 Accessor for the Frame I P S private member.
 

Private Member Functions

std::shared_ptr< statemachine::StateCreateState (statemachine::States eState)
 Create a State object based of of the State enum.
 
void ChangeState (statemachine::States eNextState, const bool bSaveCurrentState=false)
 Transition to a new state. This function is called by the HandleEvent and checks to see if this state is already stored in the map of exited states. If it is, it loads the state from the map. If not, it creates a new state and stores it in the map.
 
void SaveCurrentState ()
 Save the current state to the map of exited states. This is used to store the state when the state machine is transitioning to a new state. And prevents the state from being deleted when the state machine transitions to a new state.
 
void ThreadedContinuousCode () override
 This code will run continuously in a separate thread. The State Machine Handler will check the current state and run the state's logic. It will then check the state's transition conditions and transition to the next state if the conditions are met.
 
void PooledLinearCode () override
 This method holds the code that is ran in the thread pool started by the ThreadedLinearCode() method. It currently does nothing and is not needed in the current implementation of the StateMachineHandler.
 
- Private Member Functions inherited from AutonomyThread< void >
 AutonomyThread ()
 Construct a new Autonomy Thread object.
 
virtual ~AutonomyThread ()
 Destroy the Autonomy Thread object. If the parent object or main thread is destroyed or exited while this thread is still running, a race condition will occur. Stopping and joining the thread here insures that the main program can't exit if the user forgot to stop and join the thread.
 
void Start ()
 When this method is called, it starts a new thread that runs the code within the ThreadedContinuousCode method. This is the users main code that will run the important and continuous code for the class.
 
void RequestStop ()
 Signals threads to stop executing user code, terminate. DOES NOT JOIN. This method will not force the thread to exit, if the user code is not written properly and contains WHILE statement or any other long-executing or blocking code, then the thread will not exit until the next iteration.
 
void Join ()
 Waits for thread to finish executing and then closes thread. This method will block the calling code until thread is finished.
 
bool Joinable () const
 Check if the code within the thread and all pools created by it are finished executing and the thread is ready to be closed.
 
AutonomyThreadState GetThreadState () const
 Accessor for the Threads State private member.
 
IPSGetIPS ()
 Accessor for the Frame I P S private member.
 
void RunPool (const unsigned int nNumTasksToQueue, const unsigned int nNumThreads=2, const bool bForceStopCurrentThreads=false)
 When this method is called, it starts/adds tasks to a thread pool that runs nNumTasksToQueue copies of the code within the PooledLinearCode() method using nNumThreads number of threads. This is meant to be used as an internal utility of the child class to further improve parallelization. Default value for nNumThreads is 2.
 
void RunDetachedPool (const unsigned int nNumTasksToQueue, const unsigned int nNumThreads=2, const bool bForceStopCurrentThreads=false)
 When this method is called, it starts a thread pool full of threads that don't return std::futures (like a placeholder for the thread return type). This means the thread will not have a return type and there is no way to determine if the thread has finished other than calling the Join() method. Only use this if you want to 'set and forget'. It will be faster as it doesn't return futures. Runs PooledLinearCode() method code. This is meant to be used as an internal utility of the child class to further improve parallelization.
 
void ParallelizeLoop (const int nNumThreads, const N tTotalIterations, F &&tLoopFunction)
 Given a ref-qualified looping function and an arbitrary number of iterations, this method will divide up the loop and run each section in a thread pool. This function must not return anything. This method will block until the loop has completed.
 
void ClearPoolQueue ()
 Clears any tasks waiting to be ran in the queue, tasks currently running will remain running.
 
void JoinPool ()
 Waits for pool to finish executing tasks. This method will block the calling code until thread is finished.
 
bool PoolJoinable () const
 Check if the internal pool threads are done executing code and the queue is empty.
 
void SetMainThreadIPSLimit (int nMaxIterationsPerSecond=0)
 Mutator for the Main Thread Max I P S private member.
 
int GetPoolNumOfThreads ()
 Accessor for the Pool Num Of Threads private member.
 
int GetPoolQueueLength ()
 Accessor for the Pool Queue Size private member.
 
std::vector< void > GetPoolResults ()
 Accessor for the Pool Results private member. The action of getting results will destroy and remove them from this object. This method blocks if the thread is not finished, so no need to call JoinPool() before getting results.
 
int GetMainThreadMaxIPS () const
 Accessor for the Main Thread Max I P S private member.
 

Private Attributes

std::shared_ptr< statemachine::Statem_pCurrentState
 
std::shared_ptr< statemachine::Statem_pPreviousState
 
std::unordered_map< statemachine::States, std::shared_ptr< statemachine::State > > m_umSavedStates
 
std::shared_mutex m_muStateMutex
 
std::shared_mutex m_muEventMutex
 
std::atomic_bool m_bSwitchingStates
 
std::shared_ptr< ZEDCameram_pMainCam
 
geoops::GPSCoordinate m_stCurrentGPSLocation
 
const std::function< void(const rovecomm::RoveCommPacket< uint8_t > &, const sockaddr_in &)> AutonomyStartCallback
 Callback function used to trigger the start of autonomy. No matter what state we are in, signal a StartAutonomy Event.
 
const std::function< void(const rovecomm::RoveCommPacket< uint8_t > &, const sockaddr_in &)> AutonomyStopCallback
 Callback function used to trigger autonomy to stop. No matter what state we are in, signal an Abort Event.
 
const std::function< void(const rovecomm::RoveCommPacket< uint8_t > &, const sockaddr_in &)> ClearWaypointsCallback
 Callback function that is called whenever RoveComm receives new CLEARWAYPOINTS packet.
 
const std::function< void(const rovecomm::RoveCommPacket< float > &, const sockaddr_in &)> PMSCellVoltageCallback
 Callback function used to force autonomy into Idle state if battery voltage gets too low. No matter what state we are in, signal an Abort Event.
 
- Private Attributes inherited from AutonomyThread< void >
IPS m_IPS
 

Additional Inherited Members

- Private Types inherited from AutonomyThread< void >
enum  AutonomyThreadState
 

Detailed Description

The StateMachineHandler class serves as the main state machine for Autonomy Software. It will handle all state transitions and run the logic for each state.

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

Constructor & Destructor Documentation

◆ StateMachineHandler()

StateMachineHandler::StateMachineHandler ( )

Construct a new State Machine Handler object.

Author
Eli Byrd (edbgk.nosp@m.k@ms.nosp@m.t.edu)
Date
2024-01-17
24{
25 // Submit logger message.
26 LOG_INFO(logging::g_qSharedLogger, "Initializing State Machine.");
27
28 // Subscribe to PMS packets.
29 rovecomm::RoveCommPacket<u_int8_t> stSubscribePacket;
30 stSubscribePacket.unDataId = manifest::System::SUBSCRIBE_DATA_ID;
31 stSubscribePacket.unDataCount = 0;
32 stSubscribePacket.eDataType = manifest::DataTypes::UINT8_T;
33 stSubscribePacket.vData = std::vector<uint8_t>{};
34 network::g_pRoveCommUDPNode->SendUDPPacket(stSubscribePacket, manifest::PMS::IP_ADDRESS.IP_STR.c_str(), constants::ROVECOMM_OUTGOING_UDP_PORT);
35
36 // Set RoveComm Node callbacks.
37 network::g_pRoveCommUDPNode->AddUDPCallback<uint8_t>(AutonomyStartCallback, manifest::Autonomy::COMMANDS.find("STARTAUTONOMY")->second.DATA_ID);
38 network::g_pRoveCommUDPNode->AddUDPCallback<uint8_t>(AutonomyStopCallback, manifest::Autonomy::COMMANDS.find("DISABLEAUTONOMY")->second.DATA_ID);
39 network::g_pRoveCommUDPNode->AddUDPCallback<uint8_t>(ClearWaypointsCallback, manifest::Autonomy::COMMANDS.find("CLEARWAYPOINTS")->second.DATA_ID);
40 network::g_pRoveCommUDPNode->AddUDPCallback<float>(PMSCellVoltageCallback, manifest::PMS::TELEMETRY.find("CELLVOLTAGE")->second.DATA_ID);
41
42 // Initialize member variables.
43 m_pMainCam = globals::g_pCameraHandler->GetZED(CameraHandler::ZEDCamName::eHeadMainCam);
44
45 // State machine doesn't need to run at an unlimited speed. Cap main thread to a certain amount of iterations per second.
46 this->SetMainThreadIPSLimit(constants::STATEMACHINE_MAX_IPS);
47}
void SetMainThreadIPSLimit(int nMaxIterationsPerSecond=0)
Mutator for the Main Thread Max I P S private member.
Definition AutonomyThread.hpp:467
std::shared_ptr< ZEDCamera > GetZED(ZEDCamName eCameraName)
Accessor for ZED cameras.
Definition CameraHandler.cpp:170
const std::function< void(const rovecomm::RoveCommPacket< uint8_t > &, const sockaddr_in &)> AutonomyStartCallback
Callback function used to trigger the start of autonomy. No matter what state we are in,...
Definition StateMachineHandler.h:76
const std::function< void(const rovecomm::RoveCommPacket< float > &, const sockaddr_in &)> PMSCellVoltageCallback
Callback function used to force autonomy into Idle state if battery voltage gets too low....
Definition StateMachineHandler.h:157
const std::function< void(const rovecomm::RoveCommPacket< uint8_t > &, const sockaddr_in &)> AutonomyStopCallback
Callback function used to trigger autonomy to stop. No matter what state we are in,...
Definition StateMachineHandler.h:98
const std::function< void(const rovecomm::RoveCommPacket< uint8_t > &, const sockaddr_in &)> ClearWaypointsCallback
Callback function that is called whenever RoveComm receives new CLEARWAYPOINTS packet.
Definition StateMachineHandler.h:119
::uint8_t uint8_t
Here is the call graph for this function:

◆ ~StateMachineHandler()

StateMachineHandler::~StateMachineHandler ( )

Destroy the State Machine Handler:: State Machine Handler object.

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-03-15
57{
58 // Check if state machine is running.
59 if (this->GetThreadState() == AutonomyThreadState::eRunning)
60 {
61 // Stop state machine.
62 this->StopStateMachine();
63 }
64}
AutonomyThreadState GetThreadState() const
Accessor for the Threads State private member.
Definition AutonomyThread.hpp:214
void StopStateMachine()
This method will stop the state machine. It will signal whatever state is currently running to abort ...
Definition StateMachineHandler.cpp:213
Here is the call graph for this function:

Member Function Documentation

◆ CreateState()

std::shared_ptr< statemachine::State > StateMachineHandler::CreateState ( statemachine::States  eState)
private

Create a State object based of of the State enum.

Parameters
eState- The State enum to create a State object from.
Returns
std::shared_ptr<State> - The State object created from the State enum.
Author
Eli Byrd (edbgk.nosp@m.k@ms.nosp@m.t.edu)
Date
2024-01-17
76{
77 switch (eState)
78 {
79 case statemachine::States::eIdle: return std::make_shared<statemachine::IdleState>();
80 case statemachine::States::eNavigating: return std::make_shared<statemachine::NavigatingState>();
81 case statemachine::States::eSearchPattern: return std::make_shared<statemachine::SearchPatternState>();
82 case statemachine::States::eApproachingMarker: return std::make_shared<statemachine::ApproachingMarkerState>();
83 case statemachine::States::eApproachingObject: return std::make_shared<statemachine::ApproachingObjectState>();
84 case statemachine::States::eVerifyingPosition: return std::make_shared<statemachine::VerifyingPositionState>();
85 case statemachine::States::eVerifyingMarker: return std::make_shared<statemachine::VerifyingMarkerState>();
86 case statemachine::States::eVerifyingObject: return std::make_shared<statemachine::VerifyingObjectState>();
87 case statemachine::States::eAvoidance: return std::make_shared<statemachine::AvoidanceState>();
88 case statemachine::States::eReversing: return std::make_shared<statemachine::ReversingState>();
89 case statemachine::States::eStuck: return std::make_shared<statemachine::StuckState>();
90 default:
91 // Handle the default case or throw an exception if needed
92 LOG_ERROR(logging::g_qSharedLogger, "State {} not found.", static_cast<int>(eState));
93 }
94
95 return nullptr;
96}
Here is the caller graph for this function:

◆ ChangeState()

void StateMachineHandler::ChangeState ( statemachine::States  eNextState,
const bool  bSaveCurrentState = false 
)
private

Transition to a new state. This function is called by the HandleEvent and checks to see if this state is already stored in the map of exited states. If it is, it loads the state from the map. If not, it creates a new state and stores it in the map.

Parameters
eNextState- The State enum to transition to.
bSaveCurrentState- Whether or not to save the current state so it can be recalled next time it is triggered. Default value is false.
Author
Eli Byrd (edbgk.nosp@m.k@ms.nosp@m.t.edu), clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-01-17
112{
113 // Acquire write lock for changing states.
114 std::unique_lock<std::shared_mutex> lkStateProcessLock(m_muStateMutex);
115
116 // Check if we are already in this state.
117 if (m_pCurrentState->GetState() != eNextState)
118 {
119 // Set atomic toggle saying we are in the process if switching states.
120 m_bSwitchingStates = true;
121
122 // Save the current state as the previous state
123 m_pPreviousState = m_pCurrentState;
124
125 // Check if we should save this current state so it can be recalled in the future.
126 if (bSaveCurrentState)
127 {
128 // Save the current state before transitioning
130 }
131
132 // Check if the state exists in exitedStates
133 std::unordered_map<statemachine::States, std::shared_ptr<statemachine::State>>::iterator itState = m_umSavedStates.find(eNextState);
134 if (itState != m_umSavedStates.end())
135 {
136 // Load the existing state
137 m_pCurrentState = itState->second;
138 // Remove new current state state from saved states.
139 m_umSavedStates.erase(eNextState);
140
141 // Submit logger message.
142 LOG_INFO(logging::g_qSharedLogger, "Recalling State: {}", m_pCurrentState->ToString());
143 }
144 else
145 {
146 // Create and enter a new state
147 m_pCurrentState = CreateState(eNextState);
148 }
149
150 // Set atomic toggle saying we are done switching states.
151 m_bSwitchingStates = false;
152 }
153
154 // Send current robot state over RoveComm.
155 rovecomm::RoveCommPacket<uint8_t> stPacket;
156 stPacket.unDataId = manifest::Autonomy::TELEMETRY.find("CURRENTSTATE")->second.DATA_ID;
157 stPacket.unDataCount = manifest::Autonomy::TELEMETRY.find("CURRENTSTATE")->second.DATA_COUNT;
158 stPacket.eDataType = manifest::Autonomy::TELEMETRY.find("CURRENTSTATE")->second.DATA_TYPE;
159 stPacket.vData.emplace_back(static_cast<uint8_t>(this->GetCurrentState()));
160 // Send drive command over RoveComm to drive board to all subscribers.
161 network::g_pRoveCommUDPNode->SendUDPPacket(stPacket, "0.0.0.0", constants::ROVECOMM_OUTGOING_UDP_PORT);
162}
statemachine::States GetCurrentState() const
Accessor for the Current State private member.
Definition StateMachineHandler.cpp:414
std::shared_ptr< statemachine::State > CreateState(statemachine::States eState)
Create a State object based of of the State enum.
Definition StateMachineHandler.cpp:75
void SaveCurrentState()
Save the current state to the map of exited states. This is used to store the state when the state ma...
Definition StateMachineHandler.cpp:173
Here is the call graph for this function:
Here is the caller graph for this function:

◆ SaveCurrentState()

void StateMachineHandler::SaveCurrentState ( )
private

Save the current state to the map of exited states. This is used to store the state when the state machine is transitioning to a new state. And prevents the state from being deleted when the state machine transitions to a new state.

Author
Eli Byrd (edbgk.nosp@m.k@ms.nosp@m.t.edu)
Date
2024-01-17
174{
175 // Submit logger message.
176 LOG_INFO(logging::g_qSharedLogger, "Saving State: {}", m_pCurrentState->ToString());
177 // Add state to map.
178 m_umSavedStates[m_pCurrentState->GetState()] = m_pCurrentState;
179}
Here is the caller graph for this function:

◆ ThreadedContinuousCode()

void StateMachineHandler::ThreadedContinuousCode ( )
overrideprivatevirtual

This code will run continuously in a separate thread. The State Machine Handler will check the current state and run the state's logic. It will then check the state's transition conditions and transition to the next state if the conditions are met.

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

Implements AutonomyThread< void >.

241{
242 /*
243 Verify that the state machine has been initialized so that it doesn't
244 try to run before a state has been initialized. Also verify that the
245 state machine is not currently switching states. This prevents the
246 state machine from running while it is in the middle of switching
247 states. And verify that the state machine is not exiting. This prevents
248 the state machine from running after it has been stopped.
249 */
250 if (!m_bSwitchingStates)
251 {
252 // Run the current state
253 m_pCurrentState->Run();
254 }
255
256 // Create instance variable.
257 static geoops::GPSCoordinate stNewGPSLocation;
258 // Check if GPS data is recent and updated.
259 if (std::chrono::duration_cast<std::chrono::milliseconds>(globals::g_pNavigationBoard->GetGPSLastUpdateTime()).count() <= 100 ||
260 (stNewGPSLocation.dLatitude == 0.0 && stNewGPSLocation.dLongitude == 0.0))
261 {
262 // Get the current NavBoard GPS data.
263 stNewGPSLocation = globals::g_pNavigationBoard->GetGPSData();
264 }
265
266 // Create static boolean value for toggling DiffGPS warning log print.
267 static bool bAlreadyPrintedDiffGPSWarning = false;
268 // Check if the current GPS data is different from the old.
269 if (stNewGPSLocation.dLatitude != m_stCurrentGPSLocation.dLatitude && stNewGPSLocation.dLongitude != m_stCurrentGPSLocation.dLongitude &&
270 stNewGPSLocation.dAltitude != m_stCurrentGPSLocation.dAltitude)
271 {
272 // Check if GNSS fusion is enabled.
273 if (constants::FUSION_ENABLE_GNSS_FUSION)
274 {
275 // Check if our GPS coordinate from NavBoard is differential.
276 if (stNewGPSLocation.bIsDifferential)
277 {
278 // Check if main ZED camera is setup to use GPS fusion.
279 if (m_pMainCam->GetIsFusionMaster() && m_pMainCam->GetPositionalTrackingEnabled())
280 {
281 // Update current GPS position.
282 m_stCurrentGPSLocation = stNewGPSLocation;
283 // Feed current GPS location to main ZED camera.
284 m_pMainCam->IngestGPSDataToFusion(m_stCurrentGPSLocation);
285 }
286
287 // Reset DiffGPS warning print toggle.
288 if (bAlreadyPrintedDiffGPSWarning)
289 {
290 // Submit logger message.
291 LOG_NOTICE(logging::g_qSharedLogger,
292 "Incoming GPS position to NavBoard now has differential accuracy! Autonomy will switch to using GPS Fusion for high accuracy navigation!");
293
294 // Rest toggle.
295 bAlreadyPrintedDiffGPSWarning = false;
296 }
297 }
298 // Check if GPS coordinate from NavBoard is not differential and print warning log.
299 else if (!bAlreadyPrintedDiffGPSWarning)
300 {
301 // Submit logger message.
302 LOG_NOTICE(logging::g_qSharedLogger,
303 "Incoming GPS position to NavBoard does not have differential accuracy! Autonomy will not use GPS Fusion but instead fallback to aligning "
304 "the ZED pose while the rover is in Idle state and not moving. Autonomous navigation performance of the rover will be degraded...");
305
306 // Set already printed toggle.
307 bAlreadyPrintedDiffGPSWarning = true;
308 }
309 }
310
311 // Realign the camera's relative position to current GPS position when in Idle. This does not affect fusion, but makes sure we can fallback to the camera pose for
312 // positioning.
313 if (m_pCurrentState->GetState() == statemachine::States::eIdle && m_pMainCam->GetPositionalTrackingEnabled())
314 {
315 // Check if the rover is currently not driving of turning. Use only GPS based and use stuck state parameters for checking.
316 if (globals::g_pNavigationBoard->GetVelocity() <= constants::STUCK_CHECK_VEL_THRESH &&
317 globals::g_pNavigationBoard->GetAngularVelocity() <= constants::STUCK_CHECK_ROT_THRESH)
318 {
319 // Update current GPS position.
320 m_stCurrentGPSLocation = stNewGPSLocation;
321 // Get current compass heading.
322 double dCurrentCompassHeading = globals::g_pNavigationBoard->GetHeading();
323 // Realign the main ZED cameras pose with current GPS-based position and heading.
324 this->RealignZEDPosition(CameraHandler::ZEDCamName::eHeadMainCam, geoops::ConvertGPSToUTM(m_stCurrentGPSLocation), dCurrentCompassHeading);
325 }
326 }
327 }
328}
double GetHeading()
Accessor for the most recent compass heading received from the NavBoard.
Definition NavigationBoard.cpp:161
geoops::GPSCoordinate GetGPSData()
Accessor for most recent GPS data received from NavBoard.
Definition NavigationBoard.cpp:78
void RealignZEDPosition(CameraHandler::ZEDCamName eCameraName, const geoops::UTMCoordinate &stNewCameraPosition, const double dNewCameraHeading)
This is used to realign the ZEDs forward direction with the rover's current compass heading....
Definition StateMachineHandler.cpp:649
UTMCoordinate ConvertGPSToUTM(const GPSCoordinate &stGPSCoord)
Given a GPS coordinate, convert to UTM and create a new UTMCoordinate object.
Definition GeospatialOperations.hpp:332
This struct stores/contains information about a GPS data.
Definition GeospatialOperations.hpp:99
Here is the call graph for this function:

◆ PooledLinearCode()

void StateMachineHandler::PooledLinearCode ( )
overrideprivatevirtual

This method holds the code that is ran in the thread pool started by the ThreadedLinearCode() method. It currently does nothing and is not needed in the current implementation of the StateMachineHandler.

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

Implements AutonomyThread< void >.

338{}

◆ StartStateMachine()

void StateMachineHandler::StartStateMachine ( )

This method will start the state machine. It will set the first state to Idle and start the thread pool.

Author
Eli Byrd (edbgk.nosp@m.k@ms.nosp@m.t.edu)
Date
2024-01-17
189{
190 // Initialize the state machine with the initial state
191 m_pCurrentState = CreateState(statemachine::States::eIdle);
192 m_bSwitchingStates = false;
193
194 // Clear any saved states.
195 this->ClearSavedStates();
196
197 // Start the state machine thread
198 Start();
199
200 // Submit logger message.
201 LOG_INFO(logging::g_qSharedLogger, "Started State Machine.");
202}
void Start()
When this method is called, it starts a new thread that runs the code within the ThreadedContinuousCo...
Definition AutonomyThread.hpp:117
void ClearSavedStates()
Clear all saved states.
Definition StateMachineHandler.cpp:380
Here is the call graph for this function:
Here is the caller graph for this function:

◆ StopStateMachine()

void StateMachineHandler::StopStateMachine ( )

This method will stop the state machine. It will signal whatever state is currently running to abort back to idle and then stop the main code running in the ThreadedContinuousCode() method.

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-01-19
214{
215 // No matter the current state, abort back to idle.
216 this->HandleEvent(statemachine::Event::eAbort);
217
218 // Stop main thread.
219 this->RequestStop();
220 this->Join();
221
222 // Send multimedia command to update state display.
223 globals::g_pMultimediaBoard->SendLightingState(MultimediaBoard::MultimediaBoardLightingState::eOff);
224 // Stop drive.
225 globals::g_pDriveBoard->SendStop();
226
227 // Submit logger message.
228 LOG_INFO(logging::g_qSharedLogger, "Stopped State Machine.");
229}
void Join()
Waits for thread to finish executing and then closes thread. This method will block the calling code ...
Definition AutonomyThread.hpp:180
void RequestStop()
Signals threads to stop executing user code, terminate. DOES NOT JOIN. This method will not force the...
Definition AutonomyThread.hpp:164
void SendStop()
Stop the drivetrain of the Rover.
Definition DriveBoard.cpp:163
void SendLightingState(MultimediaBoardLightingState eState)
Sends a predetermined color pattern to board.
Definition MultimediaBoard.cpp:55
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:354
Here is the call graph for this function:
Here is the caller graph for this function:

◆ HandleEvent()

void StateMachineHandler::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 state and run the state's HandleEvent() method. It will then check the state's transition conditions and transition to the next state if the conditions are met.

Parameters
eEvent- The Event enum to handle.
bSaveCurrentState- Whether or not to save the current state so it can be recalled next time it is triggered. Default value is false.
Author
Eli Byrd (edbgk.nosp@m.k@ms.nosp@m.t.edu)
Date
2024-01-17
355{
356 // Acquire write lock for handling events.
357 std::unique_lock<std::shared_mutex> lkEventProcessLock(m_muEventMutex);
358
359 // Stop the drive.
360 globals::g_pDriveBoard->SendStop();
361
362 // Check if the current state is not null and the state machine is running.
363 if (m_pCurrentState != nullptr && this->GetThreadState() == AutonomyThreadState::eRunning)
364 {
365 // Trigger the event on the current state
366 statemachine::States eNextState = m_pCurrentState->TriggerEvent(eEvent);
367
368 // Transition to the next state
369 ChangeState(eNextState, bSaveCurrentState);
370 }
371}
void ChangeState(statemachine::States eNextState, const bool bSaveCurrentState=false)
Transition to a new state. This function is called by the HandleEvent and checks to see if this state...
Definition StateMachineHandler.cpp:111
States
The states that the state machine can be in.
Definition State.hpp:31
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ClearSavedStates()

void StateMachineHandler::ClearSavedStates ( )

Clear all saved states.

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-04-01
381{
382 // Acquire write lock for clearing saved states.
383 std::unique_lock<std::shared_mutex> lkStateProcessLock(m_muStateMutex);
384 // Clear all saved states.
385 m_umSavedStates.clear();
386 // Reset previous state to nullptr;
387 m_pPreviousState = std::make_shared<statemachine::IdleState>();
388}
Here is the caller graph for this function:

◆ ClearSavedState()

void StateMachineHandler::ClearSavedState ( statemachine::States  eState)

Clear a saved state based on the given state.

Parameters
eState- The state to clear from the saved states.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2025-01-06
399{
400 // Acquire write lock for clearing saved states.
401 std::unique_lock<std::shared_mutex> lkStateProcessLock(m_muStateMutex);
402 // Remove all states that match the given state.
403 m_umSavedStates.erase(eState);
404}

◆ GetCurrentState()

statemachine::States StateMachineHandler::GetCurrentState ( ) const

Accessor for the Current State private member.

Returns
States - The current state of the state machine.
Author
Eli Byrd (edbgk.nosp@m.k@ms.nosp@m.t.edu)
Date
2024-01-17
415{
416 return m_pCurrentState->GetState();
417}
Here is the caller graph for this function:

◆ GetPreviousState()

statemachine::States StateMachineHandler::GetPreviousState ( ) const

Accessor for the Previous State private member.

Returns
States - The previous state of the state machine.
Author
Eli Byrd (edbgk.nosp@m.k@ms.nosp@m.t.edu)
Date
2024-01-17
428{
429 // Check if the previous state exists and return it if it does otherwise return Idle
430 return m_pPreviousState ? m_pPreviousState->GetState() : statemachine::States::eIdle;
431}
Here is the caller graph for this function:

◆ SmartRetrieveRoverPose()

geoops::RoverPose StateMachineHandler::SmartRetrieveRoverPose ( bool  bVIOHeading = true,
bool  bVIOTracking = false 
)

Retrieve the rover's current position and heading. Automatically picks between getting the position/heading from the NavBoard, ZEDSDK Fusion module, or ZED positional tracking. In most cases, this will be the method that should be called over getting the data directly from NavBoard.

Parameters
bVIOHeading- Whether to use ZED Heading Fusion.
bVIOTracking- Whether to use ZED Positional Tracking.
Returns
geoops::RoverPose - The current position and heading (pose) of the rover stored in a RoverPose struct.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-04-06
447{
448 // Get and store the normal GPS position and heading from NavBoard.
449 geoops::GPSCoordinate stCurrentGPSPosition = globals::g_pNavigationBoard->GetGPSData();
450 double dCurrentGPSHeading = globals::g_pNavigationBoard->GetHeading();
451
452 // Create instance variables.
453 std::shared_ptr<ZEDCamera> pMainCam = globals::g_pCameraHandler->GetZED(CameraHandler::ZEDCamName::eHeadMainCam);
454 geoops::GPSCoordinate stCurrentVIOPosition = stCurrentGPSPosition;
455 double dCurrentHeading = dCurrentGPSHeading;
456 bool bVIOGPSFused = false;
457 static bool bAlreadyPrinted = false;
458
459 if ((bVIOHeading || bVIOTracking) && !constants::MODE_SIM)
460 {
461 // Check if the main ZED camera is opened and the fusion module is initialized.
462 if (pMainCam->GetCameraIsOpen() && pMainCam->GetPositionalTrackingEnabled())
463 {
464 // Get the fused positional tracking state of the main camera.
465 sl::GNSS_FUSION_STATUS slGNSSFusionStatus = pMainCam->GetFusedPositionalTrackingState().gnss_fusion_status;
466
467 // Check if GNSS fusion is enabled and current GPS data from has differential accuracy and GNSS fusion is calibrated.
468 if (constants::FUSION_ENABLE_GNSS_FUSION && pMainCam->GetIsFusionMaster() && stCurrentGPSPosition.bIsDifferential &&
469 (slGNSSFusionStatus == sl::GNSS_FUSION_STATUS::OK || slGNSSFusionStatus == sl::GNSS_FUSION_STATUS::RECALIBRATION_IN_PROGRESS))
470 {
471 // Create instance variables.
472 sl::GeoPose slCurrentCameraGeoPose;
473 ZEDCam::Pose stCurrentCameraVIOPose;
474
475 // Check if position VIO tracking should be used.
476 if (bVIOTracking)
477 {
478 // Get the current camera pose from the ZEDCam.
479 std::future<bool> fuResultStatus = pMainCam->RequestFusionGeoPoseCopy(slCurrentCameraGeoPose);
480 if (fuResultStatus.get())
481 {
482 // Repack the camera pose into a GPSCoordinate.
483 stCurrentVIOPosition.dLatitude = slCurrentCameraGeoPose.latlng_coordinates.getLatitude(false);
484 stCurrentVIOPosition.dLongitude = slCurrentCameraGeoPose.latlng_coordinates.getLongitude(false);
485 stCurrentVIOPosition.dAltitude = slCurrentCameraGeoPose.latlng_coordinates.getAltitude();
486
487 // Set fused toggle.
488 bVIOGPSFused = true;
489 }
490 }
491
492 // Check if heading VIO tracking should be used.
493 if (bVIOHeading)
494 {
495 // Get the current camera pose from the ZEDCam.
496 std::future<bool> fuResultStatus2 = pMainCam->RequestPositionalPoseCopy(stCurrentCameraVIOPose);
497 if (fuResultStatus2.get())
498 {
499 // Repack the camera pose into a UTMCoordinate.
500 dCurrentHeading = stCurrentCameraVIOPose.stEulerAngles.dYO;
501
502 // Set fused toggle.
503 bVIOGPSFused = true;
504 }
505 }
506
507 // Check toggle so we only print once.
508 if (bAlreadyPrinted)
509 {
510 // Submit logger message.
511 LOG_NOTICE(logging::g_qSharedLogger, "GNSS Fusion has now converged! Using GNSS Fusion for rover pose...");
512 // Set toggle.
513 bAlreadyPrinted = false;
514 }
515 }
516 else
517 {
518 // Create instance variables.
519 ZEDCam::Pose stCurrentCameraVIOPose;
520
521 // Get the current camera pose from the ZEDCam.
522 std::future<bool> fuResultStatus = pMainCam->RequestPositionalPoseCopy(stCurrentCameraVIOPose);
523 // Wait for future to be fulfilled.
524 if (fuResultStatus.get())
525 {
526 // Check if position VIO tracking should be used.
527 if (bVIOTracking)
528 {
529 // Camera is using UTM. Modify current GPS position to be camera's position.
530 geoops::UTMCoordinate stCameraUTMLocation = geoops::ConvertGPSToUTM(stCurrentGPSPosition);
531 // Repack the camera pose into a GPSCoordinate.
532 stCameraUTMLocation.dEasting = stCurrentCameraVIOPose.stTranslation.dX;
533 stCameraUTMLocation.dNorthing = stCurrentCameraVIOPose.stTranslation.dZ;
534 stCameraUTMLocation.dAltitude = stCurrentCameraVIOPose.stTranslation.dY;
535 // Convert back to GPS coordinate and store.
536 stCurrentVIOPosition = geoops::ConvertUTMToGPS(stCameraUTMLocation);
537 }
538
539 // Check if heading VIO tracking should be used.
540 if (bVIOHeading)
541 {
542 // Get compass heading based off of the ZED's aligned accelerometer.
543 dCurrentHeading = stCurrentCameraVIOPose.stEulerAngles.dYO;
544 }
545
546 // Set fused toggle.
547 bVIOGPSFused = false;
548 }
549
550 // Check toggle so we only print once.
551 if (!bAlreadyPrinted && constants::FUSION_ENABLE_GNSS_FUSION)
552 {
553 // Submit logger message.
554 LOG_NOTICE(logging::g_qSharedLogger, "GNSS Fusion is still calibrating. Using VIO tracking for rover pose...");
555 // Set toggle.
556 bAlreadyPrinted = true;
557 }
558 }
559 }
560 else
561 {
562 LOG_WARNING_LIMIT(std::chrono::seconds(5),
563 logging::g_qSharedLogger,
564 "Positional tracking is not enabled or camera is not open! Using NavBoard GPS data for rover pose...");
565 }
566 }
567
568 // Submit a debug print for the current rover pose.
569 geoops::UTMCoordinate stCurrentUTMPosition = geoops::ConvertGPSToUTM(stCurrentVIOPosition);
570 LOG_DEBUG(logging::g_qSharedLogger,
571 "Rover Pose is currently: {} (easting), {} (northing), {} (alt), {} (degrees), GNSS/VIO FUSED? = {}, VIOPosition = {}, VIOHeading = {}",
572 stCurrentUTMPosition.dEasting,
573 stCurrentUTMPosition.dNorthing,
574 stCurrentUTMPosition.dAltitude,
575 dCurrentHeading,
576 bVIOGPSFused ? "true" : "false",
577 bVIOTracking ? "true" : "false",
578 bVIOHeading ? "true" : "false");
579
580 // Check if VIO tracking or heading is being used.
581 if (bVIOHeading || bVIOTracking)
582 {
583 // Submit a debug print for some error metrics pertaining to the ZED camera and NavBoard locations and headings.
584 double dHeadingError = dCurrentHeading - dCurrentGPSHeading;
585 double dEastingError = ConvertGPSToUTM(stCurrentGPSPosition).dEasting - stCurrentUTMPosition.dEasting;
586 double dNorthingError = ConvertGPSToUTM(stCurrentGPSPosition).dNorthing - stCurrentUTMPosition.dNorthing;
587 // Assemble the error metrics into a single string. We are going to include the original GPS positions of the NavBoard and the Camera and then include the error.
588 // Same thing for the heading data.
589 std::string szErrorMetrics = "--------[ Pose Tracking Error ]--------\nGPS/VIO Position Error (UTM for easy reading):\n" +
590 std::to_string(ConvertGPSToUTM(stCurrentGPSPosition).dEasting) + " (NavBoard) vs. " + std::to_string(stCurrentUTMPosition.dEasting) +
591 " (Camera) = " + std::to_string(dEastingError) + " (error)\n" + std::to_string(ConvertGPSToUTM(stCurrentGPSPosition).dNorthing) +
592 " (NavBoard) vs. " + std::to_string(stCurrentUTMPosition.dNorthing) + " (Camera) = " + std::to_string(dNorthingError) +
593 " (error)\n" + "Heading Error:\n" + std::to_string(dCurrentGPSHeading) + " (NavBoard) vs. " + std::to_string(dCurrentHeading) +
594 " (Camera) = " + std::to_string(dHeadingError) + " (error)\n GNSS/VIO FUSED? = " + (bVIOGPSFused ? "true" : "false") +
595 ", VIOPosition = " + (bVIOTracking ? "true" : "false") + ", VIOHeading = " + (bVIOHeading ? "true" : "false");
596 // Submit the error metrics to the logger.
597 LOG_DEBUG(logging::g_qSharedLogger, "{}", szErrorMetrics);
598 }
599
600 return geoops::RoverPose(stCurrentVIOPosition, dCurrentHeading);
601}
GPSCoordinate ConvertUTMToGPS(const UTMCoordinate &stUTMCoord)
Given a UTM coordinate, convert to GPS and create a new GPSCoordinate object.
Definition GeospatialOperations.hpp:377
This struct is used within the ZEDCam class to store the camera pose with high precision....
Definition ZEDCamera.hpp:77
This struct is used by the WaypointHandler to provide an easy way to store all pose data about the ro...
Definition GeospatialOperations.hpp:707
This struct stores/contains information about a UTM coordinate.
Definition GeospatialOperations.hpp:210
Here is the call graph for this function:
Here is the caller graph for this function:

◆ SmartRetrieveVelocity()

double StateMachineHandler::SmartRetrieveVelocity ( )

Retrieve the rover's current velocity. Currently there is no easy way to get the velocity of the ZEDCam so this method just returns the GPS-based velocity.

Returns
double - The current velocity of the rover. (m/s)
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-04-06
614{
615 // Return the GPS-based velocity from the NavBoard.
616 return globals::g_pNavigationBoard->GetVelocity();
617}
double GetVelocity()
The rover's current velocity based off of the distance covered over the last two GPSCoordinates.
Definition NavigationBoard.cpp:244
Here is the call graph for this function:
Here is the caller graph for this function:

◆ SmartRetrieveAngularVelocity()

double StateMachineHandler::SmartRetrieveAngularVelocity ( )

Retrieve the rover's current velocity. Currently there is no easy way to get the velocity of the ZEDCam so this method just returns the GPS-based velocity.

Returns
double - The current angular velocity of the rover. (deg/s)
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-04-06
630{
631 // Return the GPS-based angular velocity from the NavBoard.
632 return globals::g_pNavigationBoard->GetAngularVelocity();
633}
double GetAngularVelocity()
The rover's current angular velocity based off of the change in angle over the last two headings.
Definition NavigationBoard.cpp:286
Here is the call graph for this function:
Here is the caller graph for this function:

◆ RealignZEDPosition()

void StateMachineHandler::RealignZEDPosition ( CameraHandler::ZEDCamName  eCameraName,
const geoops::UTMCoordinate stNewCameraPosition,
const double  dNewCameraHeading 
)

This is used to realign the ZEDs forward direction with the rover's current compass heading. Realigning GPS latlon is not necessary since we're using the ZEDSDK's Fusion module. The heading of the camera's GeoPose is actually automatically realigned too depending on what direction We are headed, but this is just to be safe.

Parameters
eCameraName- The camera name represented as an enum from the CameraHandler class.
stNewCameraPosition- The new UTM position of the ZED camera.
dNewCameraHeading- The new compass heading of the ZED camera.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-04-17
650{
651 // Get main ZEDCam.
652 std::shared_ptr<ZEDCamera> pMainCam = globals::g_pCameraHandler->GetZED(eCameraName);
653
654 // Check if main ZEDCam is opened and positional tracking is enabled.
655 if (pMainCam->GetCameraIsOpen() && pMainCam->GetPositionalTrackingEnabled())
656 {
657 // Request for the cameras current pose.
658 ZEDCam::Pose stCurrentCameraPose;
659 std::future<bool> fuPoseReturnStatus = pMainCam->RequestPositionalPoseCopy(stCurrentCameraPose);
660 // Wait for pose to be copied.
661 if (fuPoseReturnStatus.get())
662 {
663 // Pack the current camera pose into UTM coordinate.
664 geoops::UTMCoordinate stCurrentCameraUTM = geoops::UTMCoordinate(stCurrentCameraPose.stTranslation.dX,
665 stCurrentCameraPose.stTranslation.dZ,
666 stNewCameraPosition.nZone,
667 stNewCameraPosition.bWithinNorthernHemisphere,
668 stCurrentCameraPose.stTranslation.dY);
669 // Calculate the distance between the current and new camera position.
670 geoops::GeoMeasurement stError = geoops::CalculateGeoMeasurement(stCurrentCameraUTM, stNewCameraPosition);
671
672 // Check if the camera's current pose is close to the new position.
673 if (stError.dDistanceMeters >= constants::STATEMACHINE_ZED_REALIGN_THRESHOLD)
674 {
675 // Update camera Y heading with GPSs current heading.
676 pMainCam->SetPositionalPose(stNewCameraPosition.dEasting,
677 stNewCameraPosition.dAltitude,
678 stNewCameraPosition.dNorthing,
679 stCurrentCameraPose.stEulerAngles.dXO,
680 dNewCameraHeading,
681 stCurrentCameraPose.stEulerAngles.dZO);
682
683 // Submit logger message.
684 LOG_INFO(logging::g_qSharedLogger, "Realigned ZED stereo camera to current GPS position. Error was: {} meters.", stError.dDistanceMeters);
685 }
686 }
687 else
688 {
689 // Submit logger message.
690 LOG_ERROR(logging::g_qSharedLogger, "Failed to realign the ZEDCam's pose with the given UTM position and compass heading.");
691 }
692 }
693 else
694 {
695 // Submit logger message.
696 LOG_ERROR(logging::g_qSharedLogger,
697 "Failed to realign the ZEDCam's pose with the given UTM position and compass heading. The camera is not open yet or positional tracking status is "
698 "suboptimal!");
699 }
700}
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:552
This struct is used to store the distance, arc length, and relative bearing for a calculated geodesic...
Definition GeospatialOperations.hpp:82
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetIPS()

IPS & AutonomyThread< T >::GetIPS ( )
inline

Accessor for the Frame I P S private member.

Returns
IPS& - The iteration per second counter for the ThreadedContinuousCode()
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-08-20
224{ return m_IPS; }

Member Data Documentation

◆ AutonomyStartCallback

const std::function<void(const rovecomm::RoveCommPacket<uint8_t>&, const sockaddr_in&)> StateMachineHandler::AutonomyStartCallback
private
Initial value:
=
[this](const rovecomm::RoveCommPacket<uint8_t>& stPacket, const sockaddr_in& stdAddr)
{
(void) stPacket;
(void) stdAddr;
LOG_INFO(logging::g_qSharedLogger, "Incoming Packet: Start Autonomy!");
this->HandleEvent(statemachine::Event::eStart);
}

Callback function used to trigger the start of autonomy. No matter what state we are in, signal a StartAutonomy Event.

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-03-15
78 {
79 // Not using this.
80 (void) stPacket;
81 (void) stdAddr;
82
83 // Submit logger message.
84 LOG_INFO(logging::g_qSharedLogger, "Incoming Packet: Start Autonomy!");
85
86 // Signal statemachine handler with Start event.
87 this->HandleEvent(statemachine::Event::eStart);
88 };

◆ AutonomyStopCallback

const std::function<void(const rovecomm::RoveCommPacket<uint8_t>&, const sockaddr_in&)> StateMachineHandler::AutonomyStopCallback
private
Initial value:
=
[this](const rovecomm::RoveCommPacket<uint8_t>& stPacket, const sockaddr_in& stdAddr)
{
(void) stPacket;
(void) stdAddr;
LOG_INFO(logging::g_qSharedLogger, "Incoming Packet: Abort Autonomy!");
this->HandleEvent(statemachine::Event::eAbort, true);
}

Callback function used to trigger autonomy to stop. No matter what state we are in, signal an Abort Event.

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-03-15
100 {
101 // Not using this.
102 (void) stPacket;
103 (void) stdAddr;
104
105 // Submit logger message.
106 LOG_INFO(logging::g_qSharedLogger, "Incoming Packet: Abort Autonomy!");
107
108 // Signal statemachine handler with stop event.
109 this->HandleEvent(statemachine::Event::eAbort, true);
110 };

◆ ClearWaypointsCallback

const std::function<void(const rovecomm::RoveCommPacket<uint8_t>&, const sockaddr_in&)> StateMachineHandler::ClearWaypointsCallback
private
Initial value:
=
[this](const rovecomm::RoveCommPacket<uint8_t>& stPacket, const sockaddr_in& stdAddr)
{
(void) stPacket;
(void) stdAddr;
if (this->GetCurrentState() == statemachine::States::eIdle)
{
LOG_NOTICE(logging::g_qSharedLogger, "Incoming Clear Waypoints packet: Deleting all saved states in StateMachineHandler...");
}
else
{
LOG_WARNING(logging::g_qSharedLogger,
"Incoming Clear Waypoints packet: Cannot clear saved states in StateMachineHandler unless in Idle state. Current state is {}.",
static_cast<int>(this->GetCurrentState()));
}
}

Callback function that is called whenever RoveComm receives new CLEARWAYPOINTS packet.

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-03-03
121 {
122 // Not using this.
123 (void) stPacket;
124 (void) stdAddr;
125
126 /*
127 The clear waypoints command will clear all waypoints in the WaypointHandler, but it also clears all saved states in the StateMachineHandler
128 to prevent any conflicts when restarting autonomy with previously saved states that may have waypoints associated with them.
129 However, we only want to delete our saved states if we are currently in IdleState.
130 */
131
132 // Check if the current state is IdleState.
133 if (this->GetCurrentState() == statemachine::States::eIdle)
134 {
135 // Submit logger message.
136 LOG_NOTICE(logging::g_qSharedLogger, "Incoming Clear Waypoints packet: Deleting all saved states in StateMachineHandler...");
137 // Clear the saved states.
138 this->ClearSavedStates();
139 }
140 else
141 {
142 // Submit logger message.
143 LOG_WARNING(logging::g_qSharedLogger,
144 "Incoming Clear Waypoints packet: Cannot clear saved states in StateMachineHandler unless in Idle state. Current state is {}.",
145 static_cast<int>(this->GetCurrentState()));
146 }
147 };

◆ PMSCellVoltageCallback

const std::function<void(const rovecomm::RoveCommPacket<float>&, const sockaddr_in&)> StateMachineHandler::PMSCellVoltageCallback
private

Callback function used to force autonomy into Idle state if battery voltage gets too low. No matter what state we are in, signal an Abort Event.

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-04-04
159 {
160 // Not using this.
161 (void) stdAddr;
162
163 // Create instance variables.
164 double dTotalCellVoltages = 0.0;
165 int nValidCellVoltageValues = 0;
166
167 // Loop through voltage values and average all of the valid ones.
168 for (int nIter = 0; nIter < stPacket.unDataCount; ++nIter)
169 {
170 // Check if the voltage values is greater than at least 0.1.
171 if (stPacket.vData[nIter] >= 0.1)
172 {
173 // Add cell voltage value to total.
174 dTotalCellVoltages += stPacket.vData[nIter];
175 // Increment voltage voltage counter.
176 ++nValidCellVoltageValues;
177 }
178 }
179 // Calculate average cell voltage.
180 double dAverageCellVoltage = dTotalCellVoltages / nValidCellVoltageValues;
181
182 // Submit logger message.
183 LOG_DEBUG(logging::g_qSharedLogger, "Incoming Packet: PMS Cell Voltages. Average voltage is: {}", dAverageCellVoltage);
184
185 // Check if voltage is above the safe minimum for lithium ion batteries.
186 if (constants::BATTERY_CHECKS_ENABLED && dAverageCellVoltage < constants::BATTERY_MINIMUM_CELL_VOLTAGE &&
187 this->GetCurrentState() != statemachine::States::eIdle)
188 {
189 // Submit logger message.
190 LOG_CRITICAL(logging::g_qSharedLogger,
191 "Incoming PMS Packet: Average cell voltage is {} which is below the safe minimum of {}. Entering Idle state...",
192 dAverageCellVoltage,
193 constants::BATTERY_MINIMUM_CELL_VOLTAGE);
194
195 // Signal statemachine handler with stop event.
196 this->HandleEvent(statemachine::Event::eAbort, true);
197 }
198 };

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