/**************************************************************************** Module JoustSM.c Revision 2.0.1 Description This is a template file for implementing state machines. Notes History When Who What/Why -------------- --- -------- 02/07/13 21:00 jec corrections to return variable (should have been ReturnEvent, not CurrentEvent) and several EV_xxx event names that were left over from the old version 02/08/12 09:56 jec revisions for the Events and Services Framework Gen2 02/13/10 14:29 jec revised Start and run to add new kind of entry function to make implementing history entry cleaner 02/13/10 12:29 jec added NewEvent local variable to During function and comments about using either it or Event as the return 02/11/10 15:54 jec more revised comments, removing last comment in during function that belongs in the run function 02/09/10 17:21 jec updated comments about internal transitions on During funtion 02/18/09 10:14 jec removed redundant call to RunLowerlevelSM in EV_Entry processing in During function 02/20/07 21:37 jec converted to use enumerated type for events & states 02/13/05 19:38 jec added support for self-transitions, reworked to eliminate repeated transition code 02/11/05 16:54 jec converted to implment hierarchy explicitly 02/25/03 10:32 jec converted to take a passed event parameter 02/18/99 10:19 jec built template from MasterMachine.c 02/14/99 10:34 jec Began Coding ****************************************************************************/ /*----------------------------- Include Files -----------------------------*/ // Basic includes for a program using the Events and Services Framework #include "ES_Configure.h" #include "ES_Framework.h" /* include header files for this state machine as well as any machines at the next lower level in the hierarchy that are sub-machines to this machine */ #include "JoustSM.h" #include "ServoControl.h" #include "Pins.h" #include <stdio.h> /*----------------------------- Module Defines ----------------------------*/ // define constants for the states for this machine // and any other local defines /*---------------------------- Module Functions ---------------------------*/ /* prototypes for private functions for this machine, things like during functions, entry & exit functions.They should be functions relevant to the behavior of this state machine */ static ES_Event DuringRetracted( ES_Event Event); static ES_Event DuringHonorablePause( ES_Event Event); static ES_Event DuringDeployed( ES_Event Event); static ES_Event DuringStoppedSwinging( ES_Event Event); /*---------------------------- Module Variables ---------------------------*/ // everybody needs a state variable, you may need others as well static JoustState_t CurrentState; /*------------------------------ Module Code ------------------------------*/ /**************************************************************************** Function RunJoustSM Parameters ES_Event: the event to process Returns ES_Event: an event to return Description add your description here Notes uses nested switch/case to implement the machine. Author J. Edward Carryer, 2/11/05, 10:45AM ****************************************************************************/ ES_Event RunJoustSM( ES_Event CurrentEvent ) { unsigned char MakeTransition = false;/* are we making a state transition? */ JoustState_t NextState = CurrentState; ES_Event EntryEventKind = { ES_ENTRY, 0 };// default to normal entry to new state ES_Event ReturnEvent = CurrentEvent; // assume we are not consuming event static int position = FORWARD_POSITION; switch ( CurrentState ) { case ST_Retracted : // If current state is Retract // Execute During function for state one. ES_ENTRY & ES_EXIT are // processed here allow the lowere level state machines to re-map // or consume the event CurrentEvent = DuringRetracted(CurrentEvent); //process any events if ( CurrentEvent.EventType != ES_NO_EVENT ) //If an event is active { switch (CurrentEvent.EventType) { case EV_START_JOUSTING : //If opponent is near printf("Deploy Lance! \n\r"); // Execute action function for state one : event one NextState = ST_Deployed;//Decide what the next state will be // for internal transitions, skip changing MakeTransition MakeTransition = true; //mark that we are taking a transition //No-remapping ReturnEvent.EventType = ES_NO_EVENT; break; } } break; case ST_Deployed : // If current state is Retract // Execute During function for state one. ES_ENTRY & ES_EXIT are // processed here allow the lowere level state machines to re-map // or consume the event CurrentEvent = DuringDeployed(CurrentEvent); //process any events if ( CurrentEvent.EventType != ES_NO_EVENT ) //If an event is active { switch (CurrentEvent.EventType) { case ES_TIMEOUT : //If opponent is near if( JOUST_TIMER == CurrentEvent.EventParam ) { // Execute action function for state one : event one NextState = ST_HonorablePause;//Decide what the next state will be // for internal transitions, skip changing MakeTransition MakeTransition = true; //mark that we are taking a transition //No-remapping ReturnEvent.EventType = ES_NO_EVENT; printf("Stop Jousting \n\r"); } else if(SWING_TIMER == CurrentEvent.EventParam){ if(FORWARD_POSITION == position){ //Swing lance backward SwingServoToPosition(BACKWARD_POSITION); position = BACKWARD_POSITION; printf("Swing Backward \n\r"); } else{ //Swing lance forward SwingServoToPosition(FORWARD_POSITION); position = FORWARD_POSITION; printf("Swing Fowrward \n\r"); } ES_Timer_InitTimer(SWING_TIMER, SWING_INTERVAL); } break; } } break; case ST_HonorablePause : // If current state is Retract // Execute During function for state one. ES_ENTRY & ES_EXIT are // processed here allow the lowere level state machines to re-map // or consume the event CurrentEvent = DuringHonorablePause(CurrentEvent); //process any events if ( CurrentEvent.EventType != ES_NO_EVENT ) //If an event is active { switch (CurrentEvent.EventType) { case ES_TIMEOUT : //If opponent is near if( HONORABLE_PAUSE_TIMER == CurrentEvent.EventParam ) { // Execute action function for state one : event one NextState = ST_Retracted;//Decide what the next state will be // for internal transitions, skip changing MakeTransition MakeTransition = true; //mark that we are taking a transition //No-remapping ReturnEvent.EventType = ES_NO_EVENT; } else if(SWING_TIMER == CurrentEvent.EventParam){ //Retract Lance LanceServoToPosition(RETRACTED_POSITION); } break; // repeat cases as required for relevant events } } break; // repeat state pattern as required for other states } // If we are making a state transition if (MakeTransition == true) { // Execute exit function for current state CurrentEvent.EventType = ES_EXIT; RunJoustSM(CurrentEvent); CurrentState = NextState; //Modify state variable // Execute entry function for new state // this defaults to ES_ENTRY RunJoustSM(EntryEventKind); } return(ReturnEvent); } /**************************************************************************** Function StartJoustSM Parameters None Returns None Description Does any required initialization for this state machine Notes Author J. Edward Carryer, 2/18/99, 10:38AM ****************************************************************************/ void StartJoustSM ( ES_Event CurrentEvent ) { // local variable to get debugger to display the value of CurrentEvent ES_Event LocalEvent = CurrentEvent; // to implement entry to a history state or directly to a substate // you can modify the initialization of the CurrentState variable // otherwise just start in the entry state every time the state machine // is started CurrentState = ST_Retracted; // call the entry function (if any) for the ENTRY_STATE RunJoustSM(CurrentEvent); } /**************************************************************************** Function QueryJoustSM Parameters None Returns JoustState_t The current state of the JoustSM Description returns the current state of the JoustSM Notes Author J. Edward Carryer, 2/11/05, 10:38AM ****************************************************************************/ JoustState_t QueryJoustSM ( void ) { return(CurrentState); } /*************************************************************************** private functions ***************************************************************************/ static ES_Event DuringRetracted( ES_Event Event) { ES_Event ReturnEvent = Event; // assmes no re-mapping or comsumption // process ES_ENTRY, ES_ENTRY_HISTORY & ES_EXIT events if ( (Event.EventType == ES_ENTRY) || (Event.EventType == ES_ENTRY_HISTORY) ) { //no entry function } else if ( Event.EventType == ES_EXIT ) { //no exit function }else // do the 'during' function for this state { //no lower level state machine } return(Event); } static ES_Event DuringDeployed( ES_Event Event) { ES_Event ReturnEvent = Event; // assmes no re-mapping or comsumption // process ES_ENTRY, ES_ENTRY_HISTORY & ES_EXIT events if ( (Event.EventType == ES_ENTRY) || (Event.EventType == ES_ENTRY_HISTORY) ) { //start Joust timer for deploy interval ES_Timer_InitTimer(SWING_TIMER, SWING_INTERVAL); ES_Timer_InitTimer(JOUST_TIMER, JOUST_DEPLOY_INTERVAL); //deploy lance LanceServoToPosition(DEPLOYED_POSITION); //start sweeping forward SwingServoToPosition(FORWARD_POSITION); } else if ( Event.EventType == ES_EXIT ) { SwingServoToPosition(FORWARD_POSITION); ES_Timer_InitTimer(SWING_TIMER, SWING_INTERVAL); //Start Honorable Pause Timer ES_Timer_InitTimer(HONORABLE_PAUSE_TIMER, HONORABLE_PAUSE_INTERVAL); }else // do the 'during' function for this state { //no lower level state machine } // return either Event, if you don't want to allow the lower level machine // to remap the current event, or ReturnEvent if you do want to allow it. return(ReturnEvent); } static ES_Event DuringHonorablePause( ES_Event Event) { ES_Event ReturnEvent = Event; // assmes no re-mapping or comsumption // process ES_ENTRY, ES_ENTRY_HISTORY & ES_EXIT events if ( (Event.EventType == ES_ENTRY) || (Event.EventType == ES_ENTRY_HISTORY) ) { } else if ( Event.EventType == ES_EXIT ) { //No exit function }else // do the 'during' function for this state { //no lower level state machine } // return either Event, if you don't want to allow the lower level machine // to remap the current event, or ReturnEvent if you do want to allow it. return(ReturnEvent); }