Go to Post So... the question is this: Does Grady keep his stuffed animals on his Barbie House for playtime, or in his bed to help him go sleepy-pie at night-night time? - Andy Baker [more]
Home
Go Back   Chief Delphi > Technical > Programming
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Closed Thread
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 07-12-2008, 21:52
jtdowney jtdowney is offline
Boiler Up
AKA: John Downey
FRC #4302 (Robophins)
Team Role: Mentor
 
Join Date: Sep 2006
Rookie Year: 2006
Location: Chicago
Posts: 300
jtdowney has a brilliant futurejtdowney has a brilliant futurejtdowney has a brilliant futurejtdowney has a brilliant futurejtdowney has a brilliant futurejtdowney has a brilliant futurejtdowney has a brilliant futurejtdowney has a brilliant futurejtdowney has a brilliant futurejtdowney has a brilliant futurejtdowney has a brilliant future
Simple C++ State Machine

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);
    }
};
Attached Files
File Type: h StateMachine.h (2.3 KB, 341 views)
__________________
John Downey
Lead Robot Inspector - Purdue IndianaFIRST District
Whitney Young Magnet High School/Robophins (FRC 4302) - Mentor (2013-current)
Midwest Regional Planning Committee - Member (2012-current)
Boilermaker Regional Planning Committee - Member (2011-2014)
Robot Inspector (2008-current)
Purdue FIRST Programs - Staff Advisor (2008-2011)
Lafayette-Jefferson High School/Precision Guessworks (FRC 1646) - Mentor (2006-2011)
  #2   Spotlight this post!  
Unread 07-12-2008, 22:05
EricVanWyk EricVanWyk is offline
Registered User
no team
 
Join Date: Jan 2007
Rookie Year: 2000
Location: Boston
Posts: 1,597
EricVanWyk has a reputation beyond reputeEricVanWyk has a reputation beyond reputeEricVanWyk has a reputation beyond reputeEricVanWyk has a reputation beyond reputeEricVanWyk has a reputation beyond reputeEricVanWyk has a reputation beyond reputeEricVanWyk has a reputation beyond reputeEricVanWyk has a reputation beyond reputeEricVanWyk has a reputation beyond reputeEricVanWyk has a reputation beyond reputeEricVanWyk has a reputation beyond repute
Send a message via AIM to EricVanWyk
Re: Simple C++ State Machine

I haven't written code for a FIRST robot in quite a while, with the exception of trying to teach myself LabVIEW this weekend. Can you explain to me why you are choosing the iterative robot class? I was excited about the possibility of non-iterative, because it feels more natural to me.

However, 98% of the code I've written in the last few years has been math/engineering/modeling, so I have a different view point: I'm interested in yours.
  #3   Spotlight this post!  
Unread 07-12-2008, 22:29
jtdowney jtdowney is offline
Boiler Up
AKA: John Downey
FRC #4302 (Robophins)
Team Role: Mentor
 
Join Date: Sep 2006
Rookie Year: 2006
Location: Chicago
Posts: 300
jtdowney has a brilliant futurejtdowney has a brilliant futurejtdowney has a brilliant futurejtdowney has a brilliant futurejtdowney has a brilliant futurejtdowney has a brilliant futurejtdowney has a brilliant futurejtdowney has a brilliant futurejtdowney has a brilliant futurejtdowney has a brilliant futurejtdowney has a brilliant future
Re: Simple C++ State Machine

My main motivation for doing iterative is for the similarity to how we've programmed in the past. Plus I am used to the whole main loop method of programming that you see a lot in game and GUI programming.

I am still exploring the RobotBase class and the possibility of just overriding StartCompetition and running our own flavor.
__________________
John Downey
Lead Robot Inspector - Purdue IndianaFIRST District
Whitney Young Magnet High School/Robophins (FRC 4302) - Mentor (2013-current)
Midwest Regional Planning Committee - Member (2012-current)
Boilermaker Regional Planning Committee - Member (2011-2014)
Robot Inspector (2008-current)
Purdue FIRST Programs - Staff Advisor (2008-2011)
Lafayette-Jefferson High School/Precision Guessworks (FRC 1646) - Mentor (2006-2011)
  #4   Spotlight this post!  
Unread 08-12-2008, 17:37
slavik262's Avatar
slavik262 slavik262 is offline
We do what we must because we can.
AKA: Matt Kline
FRC #0537 (Charger Robotics)
Team Role: Alumni
 
Join Date: Jan 2007
Rookie Year: 2007
Location: Sussex, WI
Posts: 310
slavik262 is a splendid one to beholdslavik262 is a splendid one to beholdslavik262 is a splendid one to beholdslavik262 is a splendid one to beholdslavik262 is a splendid one to beholdslavik262 is a splendid one to beholdslavik262 is a splendid one to behold
Send a message via AIM to slavik262
Re: Simple C++ State Machine

When you talk about iterative being similar to how you've programmed in the past, are you referring to the default code of previous years? WPILib was available for the past two years and previous versions resemble the "Simple Robot" class much more than interative.

At any rate,

It's possible I'm not understanding this properly but why would you create a specialized class to handle this? Can't information that you need to be maintained between iterations be kept as members of your robot class itself without having to be dynamically allocated? While the stacks for the functions may be popped off as you go through iterations, isn't the original instance of the entire class used throughought the running of the program? Wouldn't it be much simpler to use a simple switch statement in your periodic functions with an enumerator to determine which function to call at the appropriate time?
__________________

Last edited by slavik262 : 08-12-2008 at 17:40.
  #5   Spotlight this post!  
Unread 09-12-2008, 12:26
Kevin Sevcik's Avatar
Kevin Sevcik Kevin Sevcik is offline
(Insert witty comment here)
FRC #0057 (The Leopards)
Team Role: Mentor
 
Join Date: Jun 2001
Rookie Year: 1998
Location: Houston, Texas
Posts: 3,598
Kevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond repute
Send a message via AIM to Kevin Sevcik Send a message via Yahoo to Kevin Sevcik
Re: Simple C++ State Machine

I suspect the motivation is to help compartmentalize and organize the code. If you're doing any sort of complicated state machine, a switch statement can get out of hand rather quickly, unless you're building up separate functions for each case. Which makes the switch statement largely similar to this StateMachine Class, except that adding a new state requires adding a new case to your switch statement, etc. etc. Adding a new state to this state machine looks a bit easier. Also, since it's dynamically allocated, you can change the state callbacks at runtime. If, for instance, you wanted to run a different set of states depending on your alliance or robot position. Instead of having two switches, or a bunch of conditionals, or whatever else.
__________________
The difficult we do today; the impossible we do tomorrow. Miracles by appointment only.

Lone Star Regional Troubleshooter
  #6   Spotlight this post!  
Unread 09-12-2008, 14:24
jtdowney jtdowney is offline
Boiler Up
AKA: John Downey
FRC #4302 (Robophins)
Team Role: Mentor
 
Join Date: Sep 2006
Rookie Year: 2006
Location: Chicago
Posts: 300
jtdowney has a brilliant futurejtdowney has a brilliant futurejtdowney has a brilliant futurejtdowney has a brilliant futurejtdowney has a brilliant futurejtdowney has a brilliant futurejtdowney has a brilliant futurejtdowney has a brilliant futurejtdowney has a brilliant futurejtdowney has a brilliant futurejtdowney has a brilliant future
Re: Simple C++ State Machine

Quote:
Originally Posted by slavik262 View Post
When you talk about iterative being similar to how you've programmed in the past, are you referring to the default code of previous years? WPILib was available for the past two years and previous versions resemble the "Simple Robot" class much more than interative.
I was referring to the MPLAB C code not the old WPILib.

As Kevin pointed out the main reason for doing this as opposed to a switch is abstraction and cleanliness of code. With the power behind the new controller I am not to worried about using dynamic memory allocation or STL containers. Also this method opens up an interesting path of possible polymorphic state.

I've attached an update version that has been refactored a bit. The AddStateCallback method is now SetStateCallback method and the template only takes two parameters. I was able to change it so the third parameter is inferred.

Update example:
Code:
#include "StateMachine.h"

enum AutoState
{
    AUTO_START,
    AUTO_TURN,
    AUTO_GOAL1
};

class MyBot : public IterativeRobot
{
private:
    StateMachine<AutoState, MyBot> *m_state;

public:
    MyBot(void)
    {
        m_state = new StateMachine<AutoState, MyBot>(this);
        m_state->SetStateCallback(AUTO_START, &MyBot::Autonomous_State_Start);
        m_state->SetStateCallback(AUTO_TURN, &MyBot::Autonomous_State_Turn);
        m_state->SetStateCallback(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);
    }
};
Attached Files
File Type: h StateMachine.h (2.3 KB, 190 views)
__________________
John Downey
Lead Robot Inspector - Purdue IndianaFIRST District
Whitney Young Magnet High School/Robophins (FRC 4302) - Mentor (2013-current)
Midwest Regional Planning Committee - Member (2012-current)
Boilermaker Regional Planning Committee - Member (2011-2014)
Robot Inspector (2008-current)
Purdue FIRST Programs - Staff Advisor (2008-2011)
Lafayette-Jefferson High School/Precision Guessworks (FRC 1646) - Mentor (2006-2011)
  #7   Spotlight this post!  
Unread 09-12-2008, 16:18
slavik262's Avatar
slavik262 slavik262 is offline
We do what we must because we can.
AKA: Matt Kline
FRC #0537 (Charger Robotics)
Team Role: Alumni
 
Join Date: Jan 2007
Rookie Year: 2007
Location: Sussex, WI
Posts: 310
slavik262 is a splendid one to beholdslavik262 is a splendid one to beholdslavik262 is a splendid one to beholdslavik262 is a splendid one to beholdslavik262 is a splendid one to beholdslavik262 is a splendid one to beholdslavik262 is a splendid one to behold
Send a message via AIM to slavik262
Re: Simple C++ State Machine

Thanks for clearing that up. Right now we're focusing on the simple robot class, but this is something I'll definately check out.
__________________
  #8   Spotlight this post!  
Unread 09-12-2008, 16:31
kaszeta's Avatar
kaszeta kaszeta is offline
Registered User
FRC #0095 (Grasshoppers)
Team Role: Mentor
 
Join Date: Feb 2004
Rookie Year: 2002
Location: Lebanon, NH
Posts: 334
kaszeta is a glorious beacon of lightkaszeta is a glorious beacon of lightkaszeta is a glorious beacon of lightkaszeta is a glorious beacon of lightkaszeta is a glorious beacon of light
Re: Simple C++ State Machine

Thanks for posting this. I've preached state machines to several local teams for quite a few years now, and this is one place where C++ really helps clean up implementation.
  #9   Spotlight this post!  
Unread 09-12-2008, 17:17
Kevin Sevcik's Avatar
Kevin Sevcik Kevin Sevcik is offline
(Insert witty comment here)
FRC #0057 (The Leopards)
Team Role: Mentor
 
Join Date: Jun 2001
Rookie Year: 1998
Location: Houston, Texas
Posts: 3,598
Kevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond repute
Send a message via AIM to Kevin Sevcik Send a message via Yahoo to Kevin Sevcik
Re: Simple C++ State Machine

Possibly just a matter of preference, but wouldn't it make more sense to require the callbacks to return an AutoState and just use that to update the current state? That way, the callbacks can be blissfully ignorant of which instance of state machine is invoking them. I realize it's highly unlikely to have two state machine instances with the same state enumerations... but it still seems neater to me.

Also, who said you had to use this in in the IterativeRobot framework? It would work just fine in the SimpleRobot framework as well. You'd simply create a while loop around the CallCurrentState calls. Do whatever SimpleRobot stuff you want in the callbacks, with waits and everything else. Then when you've finished processing that state, it will loop around and process the next state. If your code has more than two or three cases to deal with, you'd be using switches, if-elses, and other things, and this helps clean those up regardless of what they're doing.
__________________
The difficult we do today; the impossible we do tomorrow. Miracles by appointment only.

Lone Star Regional Troubleshooter
Closed Thread


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
State machine in LabVIEW? JBotAlan National Instruments LabVIEW and Data Acquisition 3 23-10-2008 07:59
Hawaii Gov. Lingle State of State speech-FIRST and STEM MoeMom FIRST In the News... 0 29-01-2008 17:04
2 simple questions RDD Rules/Strategy 4 10-01-2007 16:41
EDU Demo Code: Serial Data Transmitter Using a State-Machine Kevin Watson Programming 3 28-12-2003 22:56
Choosing a machine shop (Re: How important is a machine shop archiver 2001 9 24-06-2002 04:20


All times are GMT -5. The time now is 09:28.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi