I've attached a generic state machine class that could be useful in autonomous programming this year. My team is looking at using the IterativeRobot base class so we needed a way to keep state information in between iterations. I have not yet tested this on a robot but will try to this week as we get our control system setup.
The class uses templates to let you customize things a bit. The first parameter is the state identifier type, we will most likely use an enum, but you could use anything most likely including strings. The other two parameters are for the method callbacks (the class type we are passing an instance of in the constructor and the method signature). You then need to associate states with method callbacks for each state you want to use then set the initial state. During the perodic call the call to CallCurrentState will delegate control to whatever callback you've set using AddStateCallback.
It has been a while since I've written C++ (I work more with C# these days) so this code may be rough. Below is an example I wrote from memory without testing so it definitely won't compile without some work.
Example (not tested):
Code:
#include "StateMachine.h"
enum AutoState
{
AUTO_START,
AUTO_TURN,
AUTO_GOAL1
};
class MyBot : public IterativeRobot
{
private:
StateMachine<AutoState, MyBot, void (MyBot::*)(void)> *m_state;
public:
MyBot(void)
{
m_state = new StateMachine<AutoState, MyBot, void (MyBot::*)(void)>(this);
m_state->AddStateCallback(AUTO_START, &MyBot::Autonomous_State_Start);
m_state->AddStateCallback(AUTO_TURN, &MyBot::Autonomous_State_Turn);
m_state->AddStateCallback(AUTO_GOAL1, &MyBot::Autonomous_State_Goal1);
}
~MyBot(void)
{
delete m_state;
}
void AutonomousInit(void)
{
m_state->SetCurrentState(AUTO_START);
}
void AutonomousPeriodic(void)
{
m_state->CallCurrentState();
}
void Autonomous_State_Start(void)
{
//... DO STUFF ...
m_state->SetCurrentState(AUTO_TURN);
}
void Autonomous_State_Turn(void)
{
//... DO STUFF ...
m_state->SetCurrentState(AUTO_GOAL1);
}
void Autonomous_State_Goal1(void)
{
//... DO STUFF ...
m_state->SetCurrentState(AUTO_TURN);
}
};