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:75
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:156
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:97
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:118
::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:212
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::eReversing: return std::make_shared<statemachine::ReversingState>();
88 case statemachine::States::eStuck: return std::make_shared<statemachine::StuckState>();
89 default:
90 // Handle the default case or throw an exception if needed
91 LOG_ERROR(logging::g_qSharedLogger, "State {} not found.", static_cast<int>(eState));
92 }
93
94 return nullptr;
95}
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
111{
112 // Acquire write lock for changing states.
113 std::unique_lock<std::shared_mutex> lkStateProcessLock(m_muStateMutex);
114
115 // Check if we are already in this state.
116 if (m_pCurrentState->GetState() != eNextState)
117 {
118 // Set atomic toggle saying we are in the process if switching states.
119 m_bSwitchingStates = true;
120
121 // Save the current state as the previous state
122 m_pPreviousState = m_pCurrentState;
123
124 // Check if we should save this current state so it can be recalled in the future.
125 if (bSaveCurrentState)
126 {
127 // Save the current state before transitioning
129 }
130
131 // Check if the state exists in exitedStates
132 std::unordered_map<statemachine::States, std::shared_ptr<statemachine::State>>::iterator itState = m_umSavedStates.find(eNextState);
133 if (itState != m_umSavedStates.end())
134 {
135 // Load the existing state
136 m_pCurrentState = itState->second;
137 // Remove new current state state from saved states.
138 m_umSavedStates.erase(eNextState);
139
140 // Submit logger message.
141 LOG_INFO(logging::g_qSharedLogger, "Recalling State: {}", m_pCurrentState->ToString());
142 }
143 else
144 {
145 // Create and enter a new state
146 m_pCurrentState = CreateState(eNextState);
147 }
148
149 // Set atomic toggle saying we are done switching states.
150 m_bSwitchingStates = false;
151 }
152
153 // Send current robot state over RoveComm.
154 rovecomm::RoveCommPacket<uint8_t> stPacket;
155 stPacket.unDataId = manifest::Autonomy::TELEMETRY.find("CURRENTSTATE")->second.DATA_ID;
156 stPacket.unDataCount = manifest::Autonomy::TELEMETRY.find("CURRENTSTATE")->second.DATA_COUNT;
157 stPacket.eDataType = manifest::Autonomy::TELEMETRY.find("CURRENTSTATE")->second.DATA_TYPE;
158 stPacket.vData.emplace_back(static_cast<uint8_t>(this->GetCurrentState()));
159 // Send drive command over RoveComm to drive board to all subscribers.
160 network::g_pRoveCommUDPNode->SendUDPPacket(stPacket, "0.0.0.0", constants::ROVECOMM_OUTGOING_UDP_PORT);
161}
statemachine::States GetCurrentState() const
Accessor for the Current State private member.
Definition StateMachineHandler.cpp:413
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:172
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
173{
174 // Submit logger message.
175 LOG_INFO(logging::g_qSharedLogger, "Saving State: {}", m_pCurrentState->ToString());
176 // Add state to map.
177 m_umSavedStates[m_pCurrentState->GetState()] = m_pCurrentState;
178}
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 >.

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

337{}

◆ 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
188{
189 // Initialize the state machine with the initial state
190 m_pCurrentState = CreateState(statemachine::States::eIdle);
191 m_bSwitchingStates = false;
192
193 // Clear any saved states.
194 this->ClearSavedStates();
195
196 // Start the state machine thread
197 Start();
198
199 // Submit logger message.
200 LOG_INFO(logging::g_qSharedLogger, "Started State Machine.");
201}
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:379
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
213{
214 // No matter the current state, abort back to idle.
215 this->HandleEvent(statemachine::Event::eAbort);
216
217 // Stop main thread.
218 this->RequestStop();
219 this->Join();
220
221 // Send multimedia command to update state display.
222 globals::g_pMultimediaBoard->SendLightingState(MultimediaBoard::MultimediaBoardLightingState::eOff);
223 // Stop drive.
224 globals::g_pDriveBoard->SendStop();
225
226 // Submit logger message.
227 LOG_INFO(logging::g_qSharedLogger, "Stopped State Machine.");
228}
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:195
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:353
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
354{
355 // Acquire write lock for handling events.
356 std::unique_lock<std::shared_mutex> lkEventProcessLock(m_muEventMutex);
357
358 // Stop the drive.
359 globals::g_pDriveBoard->SendStop();
360
361 // Check if the current state is not null and the state machine is running.
362 if (m_pCurrentState != nullptr && this->GetThreadState() == AutonomyThreadState::eRunning)
363 {
364 // Trigger the event on the current state
365 statemachine::States eNextState = m_pCurrentState->TriggerEvent(eEvent);
366
367 // Transition to the next state
368 ChangeState(eNextState, bSaveCurrentState);
369 }
370}
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:110
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
380{
381 // Acquire write lock for clearing saved states.
382 std::unique_lock<std::shared_mutex> lkStateProcessLock(m_muStateMutex);
383 // Clear all saved states.
384 m_umSavedStates.clear();
385 // Reset previous state to nullptr;
386 m_pPreviousState = std::make_shared<statemachine::IdleState>();
387}
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
398{
399 // Acquire write lock for clearing saved states.
400 std::unique_lock<std::shared_mutex> lkStateProcessLock(m_muStateMutex);
401 // Remove all states that match the given state.
402 m_umSavedStates.erase(eState);
403}

◆ 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
414{
415 return m_pCurrentState->GetState();
416}
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
427{
428 // Check if the previous state exists and return it if it does otherwise return Idle
429 return m_pPreviousState ? m_pPreviousState->GetState() : statemachine::States::eIdle;
430}
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
446{
447 // Get and store the normal GPS position and heading from NavBoard.
448 geoops::GPSCoordinate stCurrentGPSPosition = globals::g_pNavigationBoard->GetGPSData();
449 double dCurrentGPSHeading = globals::g_pNavigationBoard->GetHeading();
450
451 // Create instance variables.
452 std::shared_ptr<ZEDCamera> pMainCam = globals::g_pCameraHandler->GetZED(CameraHandler::ZEDCamName::eHeadMainCam);
453 geoops::GPSCoordinate stCurrentVIOPosition = stCurrentGPSPosition;
454 double dCurrentHeading = dCurrentGPSHeading;
455 bool bVIOGPSFused = false;
456 static bool bAlreadyPrinted = false;
457
458 if ((bVIOHeading || bVIOTracking) && !constants::MODE_SIM)
459 {
460 // Check if the main ZED camera is opened and the fusion module is initialized.
461 if (pMainCam->GetCameraIsOpen() && pMainCam->GetPositionalTrackingEnabled())
462 {
463 // Get the fused positional tracking state of the main camera.
464 sl::GNSS_FUSION_STATUS slGNSSFusionStatus = pMainCam->GetFusedPositionalTrackingState().gnss_fusion_status;
465
466 // Check if GNSS fusion is enabled and current GPS data from has differential accuracy and GNSS fusion is calibrated.
467 if (constants::FUSION_ENABLE_GNSS_FUSION && pMainCam->GetIsFusionMaster() && stCurrentGPSPosition.bIsDifferential &&
468 (slGNSSFusionStatus == sl::GNSS_FUSION_STATUS::OK || slGNSSFusionStatus == sl::GNSS_FUSION_STATUS::RECALIBRATION_IN_PROGRESS))
469 {
470 // Create instance variables.
471 sl::GeoPose slCurrentCameraGeoPose;
472 ZEDCam::Pose stCurrentCameraVIOPose;
473
474 // Check if position VIO tracking should be used.
475 if (bVIOTracking)
476 {
477 // Get the current camera pose from the ZEDCam.
478 std::future<bool> fuResultStatus = pMainCam->RequestFusionGeoPoseCopy(slCurrentCameraGeoPose);
479 if (fuResultStatus.get())
480 {
481 // Repack the camera pose into a GPSCoordinate.
482 stCurrentVIOPosition.dLatitude = slCurrentCameraGeoPose.latlng_coordinates.getLatitude(false);
483 stCurrentVIOPosition.dLongitude = slCurrentCameraGeoPose.latlng_coordinates.getLongitude(false);
484 stCurrentVIOPosition.dAltitude = slCurrentCameraGeoPose.latlng_coordinates.getAltitude();
485
486 // Set fused toggle.
487 bVIOGPSFused = true;
488 }
489 }
490
491 // Check if heading VIO tracking should be used.
492 if (bVIOHeading)
493 {
494 // Get the current camera pose from the ZEDCam.
495 std::future<bool> fuResultStatus2 = pMainCam->RequestPositionalPoseCopy(stCurrentCameraVIOPose);
496 if (fuResultStatus2.get())
497 {
498 // Repack the camera pose into a UTMCoordinate.
499 dCurrentHeading = stCurrentCameraVIOPose.stEulerAngles.dYO;
500
501 // Set fused toggle.
502 bVIOGPSFused = true;
503 }
504 }
505
506 // Check toggle so we only print once.
507 if (bAlreadyPrinted)
508 {
509 // Submit logger message.
510 LOG_NOTICE(logging::g_qSharedLogger, "GNSS Fusion has now converged! Using GNSS Fusion for rover pose...");
511 // Set toggle.
512 bAlreadyPrinted = false;
513 }
514 }
515 else
516 {
517 // Create instance variables.
518 ZEDCam::Pose stCurrentCameraVIOPose;
519
520 // Get the current camera pose from the ZEDCam.
521 std::future<bool> fuResultStatus = pMainCam->RequestPositionalPoseCopy(stCurrentCameraVIOPose);
522 // Wait for future to be fulfilled.
523 if (fuResultStatus.get())
524 {
525 // Check if position VIO tracking should be used.
526 if (bVIOTracking)
527 {
528 // Camera is using UTM. Modify current GPS position to be camera's position.
529 geoops::UTMCoordinate stCameraUTMLocation = geoops::ConvertGPSToUTM(stCurrentGPSPosition);
530 // Repack the camera pose into a GPSCoordinate.
531 stCameraUTMLocation.dEasting = stCurrentCameraVIOPose.stTranslation.dX;
532 stCameraUTMLocation.dNorthing = stCurrentCameraVIOPose.stTranslation.dZ;
533 stCameraUTMLocation.dAltitude = stCurrentCameraVIOPose.stTranslation.dY;
534 // Convert back to GPS coordinate and store.
535 stCurrentVIOPosition = geoops::ConvertUTMToGPS(stCameraUTMLocation);
536 }
537
538 // Check if heading VIO tracking should be used.
539 if (bVIOHeading)
540 {
541 // Get compass heading based off of the ZED's aligned accelerometer.
542 dCurrentHeading = stCurrentCameraVIOPose.stEulerAngles.dYO;
543 }
544
545 // Set fused toggle.
546 bVIOGPSFused = false;
547 }
548
549 // Check toggle so we only print once.
550 if (!bAlreadyPrinted && constants::FUSION_ENABLE_GNSS_FUSION)
551 {
552 // Submit logger message.
553 LOG_NOTICE(logging::g_qSharedLogger, "GNSS Fusion is still calibrating. Using VIO tracking for rover pose...");
554 // Set toggle.
555 bAlreadyPrinted = true;
556 }
557 }
558 }
559 else
560 {
561 LOG_WARNING_LIMIT(std::chrono::seconds(5),
562 logging::g_qSharedLogger,
563 "Positional tracking is NOT ENABLED, NOT STABLE, or camera is NOT OPEN! Using NavBoard GPS data for rover pose...");
564 }
565 }
566
567 // Submit a debug print for the current rover pose.
568 geoops::UTMCoordinate stCurrentUTMPosition = geoops::ConvertGPSToUTM(stCurrentVIOPosition);
569 LOG_DEBUG(logging::g_qSharedLogger,
570 "Rover Pose is currently: {} (easting), {} (northing), {} (alt), {} (degrees), GNSS/VIO FUSED? = {}, VIOPosition = {}, VIOHeading = {}",
571 stCurrentUTMPosition.dEasting,
572 stCurrentUTMPosition.dNorthing,
573 stCurrentUTMPosition.dAltitude,
574 dCurrentHeading,
575 bVIOGPSFused ? "true" : "false",
576 bVIOTracking ? "true" : "false",
577 bVIOHeading ? "true" : "false");
578
579 // Check if VIO tracking or heading is being used.
580 if (bVIOHeading || bVIOTracking)
581 {
582 // Submit a debug print for some error metrics pertaining to the ZED camera and NavBoard locations and headings.
583 double dHeadingError = dCurrentHeading - dCurrentGPSHeading;
584 double dEastingError = ConvertGPSToUTM(stCurrentGPSPosition).dEasting - stCurrentUTMPosition.dEasting;
585 double dNorthingError = ConvertGPSToUTM(stCurrentGPSPosition).dNorthing - stCurrentUTMPosition.dNorthing;
586 // 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.
587 // Same thing for the heading data.
588 std::string szErrorMetrics = "--------[ Pose Tracking Error ]--------\nGPS/VIO Position Error (UTM for easy reading):\n" +
589 std::to_string(ConvertGPSToUTM(stCurrentGPSPosition).dEasting) + " (NavBoard) vs. " + std::to_string(stCurrentUTMPosition.dEasting) +
590 " (Camera) = " + std::to_string(dEastingError) + " (error)\n" + std::to_string(ConvertGPSToUTM(stCurrentGPSPosition).dNorthing) +
591 " (NavBoard) vs. " + std::to_string(stCurrentUTMPosition.dNorthing) + " (Camera) = " + std::to_string(dNorthingError) +
592 " (error)\n" + "Heading Error:\n" + std::to_string(dCurrentGPSHeading) + " (NavBoard) vs. " + std::to_string(dCurrentHeading) +
593 " (Camera) = " + std::to_string(dHeadingError) + " (error)\n GNSS/VIO FUSED? = " + (bVIOGPSFused ? "true" : "false") +
594 ", VIOPosition = " + (bVIOTracking ? "true" : "false") + ", VIOHeading = " + (bVIOHeading ? "true" : "false");
595 // Submit the error metrics to the logger.
596 LOG_DEBUG(logging::g_qSharedLogger, "{}", szErrorMetrics);
597 }
598
599 return geoops::RoverPose(stCurrentVIOPosition, dCurrentHeading);
600}
GPSCoordinate ConvertUTMToGPS(const UTMCoordinate &stUTMCoord)
Given a UTM coordinate, convert to GPS and create a new GPSCoordinate object.
Definition GeospatialOperations.hpp:378
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:708
This struct stores/contains information about a UTM coordinate.
Definition GeospatialOperations.hpp:211
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
613{
614 // Return the GPS-based velocity from the NavBoard.
615 return globals::g_pNavigationBoard->GetVelocity();
616}
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
629{
630 // Return the GPS-based angular velocity from the NavBoard.
631 return globals::g_pNavigationBoard->GetAngularVelocity();
632}
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
649{
650 // Get main ZEDCam.
651 std::shared_ptr<ZEDCamera> pMainCam = globals::g_pCameraHandler->GetZED(eCameraName);
652
653 // Check if main ZEDCam is opened and positional tracking is enabled.
654 if (pMainCam->GetCameraIsOpen() && pMainCam->GetPositionalTrackingEnabled())
655 {
656 // Request for the cameras current pose.
657 ZEDCam::Pose stCurrentCameraPose;
658 std::future<bool> fuPoseReturnStatus = pMainCam->RequestPositionalPoseCopy(stCurrentCameraPose);
659 // Wait for pose to be copied.
660 if (fuPoseReturnStatus.get())
661 {
662 // Pack the current camera pose into UTM coordinate.
663 geoops::UTMCoordinate stCurrentCameraUTM = geoops::UTMCoordinate(stCurrentCameraPose.stTranslation.dX,
664 stCurrentCameraPose.stTranslation.dZ,
665 stNewCameraPosition.nZone,
666 stNewCameraPosition.bWithinNorthernHemisphere,
667 stCurrentCameraPose.stTranslation.dY);
668 // Calculate the distance between the current and new camera position.
669 geoops::GeoMeasurement stError = geoops::CalculateGeoMeasurement(stCurrentCameraUTM, stNewCameraPosition);
670
671 // Check if the camera's current pose is close to the new position.
672 if (stError.dDistanceMeters >= constants::STATEMACHINE_ZED_REALIGN_THRESHOLD)
673 {
674 // Update camera Y heading with GPSs current heading.
675 pMainCam->SetPositionalPose(stNewCameraPosition.dEasting,
676 stNewCameraPosition.dAltitude,
677 stNewCameraPosition.dNorthing,
678 stCurrentCameraPose.stEulerAngles.dXO,
679 dNewCameraHeading,
680 stCurrentCameraPose.stEulerAngles.dZO);
681
682 // Submit logger message.
683 LOG_INFO(logging::g_qSharedLogger, "Realigned ZED stereo camera to current GPS position. Error was: {} meters.", stError.dDistanceMeters);
684 }
685 }
686 else
687 {
688 // Submit logger message.
689 LOG_ERROR(logging::g_qSharedLogger, "Failed to realign the ZEDCam's pose with the given UTM position and compass heading.");
690 }
691 }
692 else
693 {
694 // Submit logger message.
695 LOG_ERROR(logging::g_qSharedLogger,
696 "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 "
697 "suboptimal!");
698 }
699}
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
This struct is used to store the distance, arc length, and relative bearing for a calculated geodesic...
Definition GeospatialOperations.hpp:83
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
77 {
78 // Not using this.
79 (void) stPacket;
80 (void) stdAddr;
81
82 // Submit logger message.
83 LOG_INFO(logging::g_qSharedLogger, "Incoming Packet: Start Autonomy!");
84
85 // Signal statemachine handler with Start event.
86 this->HandleEvent(statemachine::Event::eStart);
87 };

◆ 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
99 {
100 // Not using this.
101 (void) stPacket;
102 (void) stdAddr;
103
104 // Submit logger message.
105 LOG_INFO(logging::g_qSharedLogger, "Incoming Packet: Abort Autonomy!");
106
107 // Signal statemachine handler with stop event.
108 this->HandleEvent(statemachine::Event::eAbort, true);
109 };

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

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

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