コード例 #1
0
/**
 * @Function RunTemplateSubHSM(ES_Event ThisEvent)
 * @param ThisEvent - the event (type and param) to be responded.
 * @return Event - return event (type and param), in general should be ES_NO_EVENT
 * @brief This function is where you implement the whole of the heirarchical state
 *        machine, as this is called any time a new event is passed to the event
 *        queue. This function will be called recursively to implement the correct
 *        order for a state transition to be: exit current state -> enter next state
 *        using the ES_EXIT and ES_ENTRY events.
 * @note Remember to rename to something appropriate.
 *       The lower level state machines are run first, to see if the event is dealt
 *       with there rather than at the current level. ES_EXIT and ES_ENTRY events are
 *       not consumed as these need to pass pack to the higher level state machine.
 * @author J. Edward Carryer, 2011.10.23 19:25
 * @author Gabriel H Elkaim, 2011.10.23 19:25 */
ES_Event RunAlignCollect_SubHSM(ES_Event ThisEvent) {
    uint8_t makeTransition = FALSE; // use to flag transition
    SubAlignCollect_SubHSMState_t nextState; // <- change type to correct enum

    ES_Tattle(); // trace call stack
    ES_Event Tcontrol;

    static int aligning_start_time, aligning_end_time;
    static int aligning_difference_time = 0;
    static int  back_tape_flag = 0;

    switch (CurrentState) {
        case InitPSubState: // If current state is initial Psedudo State
            if (ThisEvent.EventType == ES_INIT)// only respond to ES_Init
            {
                nextState = Buffer_State;
                makeTransition = TRUE;
                ThisEvent.EventType = ES_NO_EVENT;
            }
            break;

        case Buffer_State:
            if (ThisEvent.EventType != ES_NO_EVENT) { // An event is still active
                switch (ThisEvent.EventType) {

                    case ES_ENTRY:
                        //PivotRight(newspeed);
                        break;

                    case ES_EXIT:
                        break;

                    case FORCED:
                        nextState = Checking;
                        makeTransition = TRUE;
                        ThisEvent.EventType = ES_NO_EVENT;
                        //                        ThisEvent.EventParam = ThisEvent.EventParam;
                        break;


                    case ES_TIMEOUT:
                        //                        makeTransition = TRUE;
                        //                        ThisEvent.EventType = ES_NO_EVENT;
                        break;

                    default:
                        break;
                }
            }
            break;

        case Checking:
            if (ThisEvent.EventType != ES_NO_EVENT) { // An event is still active
                switch (ThisEvent.EventType) {

                    case ES_ENTRY:
                         PivotRight(speed*1.2);//(speed*.5);
                        //                        TurnRight(speed);
                        //                        StraightForward(speed);
                        //                        ES_Timer_InitTimer(replungetimer, 300);
                        break;

                    case ES_EXIT:
                        break;

                    case TAPE:
                        if ((ThisEvent.EventParam & 0x01) == 0x01) { // B
                            printf("\nback on\n");
                            aligning_start_time = ES_Timer_GetTime();
                            back_tape_flag = 1;
                            int i;
                            for(i = 0; i < 100000; i++)
                            {
                                asm("nop");
                            }
                            //                            nextState = Pivoting_Right_AC;
                            //                            makeTransition = TRUE;
                            ThisEvent.EventType = ES_NO_EVENT;
                        } else if (((ThisEvent.EventParam & 0b000001) == 0b000000) && back_tape_flag)   { // Back tape off T

                            aligning_end_time = ES_Timer_GetTime();
                            FullStop();
                            printf("\nback tape off\n");
                            int i;
                            for(i = 0; i < 100000; i++)
                            {
                                asm("nop");
                            }
                            aligning_difference_time = aligning_end_time - aligning_start_time;
//                            printf("\n\naligning_diff_time %d\n", aligning_difference_time);
                            nextState = Pivoting_Left_AC;
                            makeTransition = TRUE;
                            ThisEvent.EventType = ES_NO_EVENT;
                        }//                        if ((ThisEvent.EventParam & 0b110000) == 0b110000) { // LL, L: if miss most of the stem/land on T top
                            //                            nextState = Pivoting_Right_AC;
                            //                            makeTransition = TRUE;
                            //                            ThisEvent.EventType = ES_NO_EVENT;
                            //                        }
                            //                        else if ((ThisEvent.EventParam & 0b111100) == 0b111100) { // LL, L,F, R: if hit T stem head-on
                            //                            nextState = Turning_Right_AC;
                            //                            makeTransition = TRUE;
                            //                            ThisEvent.EventType = ES_NO_EVENT;
                            //                        } else if ((ThisEvent.EventParam & 0b100000) == 0b100000) { // LL entry
                            //                            nextState = Turning_Left_AC;
                            //                            makeTransition = TRUE;
                            //                            ThisEvent.EventType = ES_NO_EVENT;
                            //                        }
                        else {
                            ThisEvent.EventType = ES_NO_EVENT;
                        }
                        //                        else if ((ThisEvent.EventParam & T_Left) == T_Left) {
                        //                            nextState = Pivoting_Right;
                        //                            makeTransition = TRUE;
                        //                            ThisEvent.EventType = ES_NO_EVENT;
                        //                        } else if ((ThisEvent.EventParam & T_Right) == T_Right) {
                        //                            nextState = Pivoting_Left;
                        //                            makeTransition = TRUE;
                        //                            ThisEvent.EventType = ES_NO_EVENT;
                        //                        }
                        break;
                    case ES_TIMEOUT:
                        //                         nextState = Pivoting_Right_AC;
                        //                            makeTransition = TRUE;
                        //                            ThisEvent.EventType = ES_NO_EVENT;
                        //                        makeTransition = TRUE;
                        //                        ThisEvent.EventType = ES_NO_EVENT;
                        break;

                    default:
                        break;
                }
            }
            break;

        case Pivoting_Right_AC:
            if (ThisEvent.EventType != ES_NO_EVENT) {
                switch (ThisEvent.EventType) {
                    case ES_ENTRY:
                        PivotRight(tspeed * 1);
                        ES_Timer_InitTimer(replungetimer, 900);
                        break;

                        //                    case TAPE:
                        //                        if ((ThisEvent.EventParam & 0x01) == 0x01) { // B
                        //                            nextState = Reverse_Adjusting_Right;
                        //                            makeTransition = TRUE;
                        //                            ThisEvent.EventType = ES_NO_EVENT;
                        //                        }
                        //                        else {
                        //                            ThisEvent.EventType = ES_NO_EVENT;
                        //                        }
                        //                        break;


                    case ES_EXIT:
                        FullStop();
                        break;

                    case ES_TIMEOUT:
                        //                        nextState = Lost;
                        //                        makeTransition = TRUE;
                        //                        ThisEvent.EventType = ES_NO_EVENT;
                        if (ThisEvent.EventParam == replungetimer) {
                            nextState = Reverse_Adjusting_Right;
                            makeTransition = TRUE;
                            ThisEvent.EventType = ES_NO_EVENT;
                        }
                        break;

                    default:
                        break;
                }
            }
            break;

        case Pivoting_Left_AC:
            if (ThisEvent.EventType != ES_NO_EVENT) {
                switch (ThisEvent.EventType) {
                    case ES_ENTRY:
                        PivotLeft_WH(speed * .7);
                        int spintime = aligning_difference_time / 2;
                        //                        printf("\n\n%dcheck spin time\n", spintime);
                        ES_Timer_InitTimer(replungetimer, spintime);
                        break;

                    case ES_EXIT:
                        FullStop();
                        break;

                    case ES_TIMEOUT:
                        //                        nextState = Lost;
                        //                        makeTransition = TRUE;
                        //                        ThisEvent.EventType = ES_NO_EVENT;
                        if (ThisEvent.EventParam == replungetimer) {
                            FullStop();
                            //                            printf("\n\ncheck\n");
                            nextState = Reverse_Adjusting_Right;
                            makeTransition = TRUE;
                            ThisEvent.EventType = ES_NO_EVENT;
                        }
                        break;

                    default:
                        break;
                }
            }
            break;

        case Turning_Left_AC:
            //ThisEvent = Run_AA_LineFollowing_SubHSM(ThisEvent); // run sub-state machine for this state
            if (ThisEvent.EventType != ES_NO_EVENT) {
                switch (ThisEvent.EventType) {
                    case ES_ENTRY:
                        TurnLeft(speed);
                        break;

                    case TAPE:
                        if ((ThisEvent.EventParam & 0b000100) == 0b000100) { // R
                            nextState = Turning_Right_AC; //TODO: straight on
                            makeTransition = TRUE;
                            ThisEvent.EventType = ES_NO_EVENT;
                        } else {
                            ThisEvent.EventType = ES_NO_EVENT;
                        }
                        break;

                    case ES_EXIT:
                        FullStop();
                        break;

                    case ES_TIMEOUT:
                        //                        ThisEvent.EventType = ES_NO_EVENT;

                    default: break;
                }
            }
            break;

        case Turning_Right_AC:
            if (ThisEvent.EventType != ES_NO_EVENT) {
                switch (ThisEvent.EventType) {
                    case ES_ENTRY:
                        TurnRight(speed);
                        break;
                        //        case BUMPED:
                        //                nextState = Wall_Hugging;
                        //                makeTransition = TRUE;
                        //                ThisEvent.EventType = ES_NO_EVENT;
                        //                break;

                    case TAPE:
                        if ((ThisEvent.EventParam & 0x01) == 0x01) { // B
                            nextState = Reverse_Adjusting_Right;
                            makeTransition = TRUE;
                            ThisEvent.EventType = ES_NO_EVENT;
                        } else {
                            ThisEvent.EventType = ES_NO_EVENT;
                        }
                        break;


                    case ES_EXIT:
                        FullStop();
                        break;

                    case ES_TIMEOUT:
                        //                        nextState = Lost;
                        //                        makeTransition = TRUE;
                        //                        ThisEvent.EventType = ES_NO_EVENT;
                        break;

                    default: break;
                }
            }
            break;

        case Stopping_AC:
            FullStop();
            break;

        case Reversing_AC:
            if (ThisEvent.EventType != ES_NO_EVENT) {
                switch (ThisEvent.EventType) {
                    case ES_ENTRY:
                        StraightReverse(speed * 1.3);
                        ES_Timer_InitTimer(ammofindtimer, ammofindtimervalue);
                        break;

                    case ES_EXIT:
                        ES_Timer_StopTimer(ammofindtimer);
                        ES_Timer_StopTimer(portalsearchingtimer);
                        break;

                    case ES_TIMEOUT:
                        if (ThisEvent.EventParam == ammofindtimer) {
                            ES_Timer_InitTimer(portalsearchingtimer, 600);
                            StraightForward(speed);
                            ThisEvent.EventType = ES_NO_EVENT;
                        } else if (ThisEvent.EventParam == portalsearchingtimer) {
                            FullStop();
                            Tcontrol.EventType = AMMO;
                            Tcontrol.EventParam = 0;
                            ThisEvent.EventType = ES_NO_EVENT;
                            PostDagobotHSM(Tcontrol);
                        }

                        break;

                    default:
                        break;
                }
            }
            break;

        case Forwarding_AC:
            if (ThisEvent.EventType != ES_NO_EVENT) {
                switch (ThisEvent.EventType) {
                    case ES_ENTRY:
                        StraightForward(speed);
                        break;

                    case TAPE:
                        if ((ThisEvent.EventParam & 0b001000) == 0b000000) { // Front off the T
                            nextState = Reversing_AC;
                            makeTransition = TRUE;
                            ThisEvent.EventType = ES_NO_EVENT;
                        } else {
                            ThisEvent.EventType = ES_NO_EVENT;
                        }
                        break;

                    case ES_EXIT:
                        break;

                    case ES_TIMEOUT:
                        break;

                    default:
                        break;
                }
            }
            break;

        case Reverse_Adjusting_Right:
            if (ThisEvent.EventType != ES_NO_EVENT) {
                switch (ThisEvent.EventType) {
                    case ES_ENTRY:
                        //                        GentleLeft(-6 - .3); // backwards left = front of robot pivoting right
                        GentleRight(-6 - .3);
                        ES_Timer_InitTimer(replungetimer, replungetimervalue);
                        break;

                        //                    case TAPE:
                        //                        if ((ThisEvent.EventParam & 0b111110) == 0b000000) { // F
                        //                            nextState = Stopping_AC;
                        //                            makeTransition = TRUE;
                        //                            ThisEvent.EventType = ES_NO_EVENT;
                        //                        } else {
                        //                            ThisEvent.EventType = ES_NO_EVENT;
                        //                        }
                        //                        break;

                    case ES_EXIT:
                        ES_Timer_StopTimer(replungetimer);
                        break;

                    case ES_TIMEOUT:
                        if (ThisEvent.EventParam == replungetimer) {
                            nextState = Forwarding_AC;
                            makeTransition = TRUE;
                            ThisEvent.EventType = ES_NO_EVENT;
                        }
                        break;

                    default:
                        break;
                }
            }
            break;

        case Adjusting_Right_AC:
            if (ThisEvent.EventType != ES_NO_EVENT) { // An event is still active
                switch (ThisEvent.EventType) {
                    case ES_ENTRY:
                        GentleRight(speed);
                        break;

                    case TAPE:
                        if ((ThisEvent.EventParam & 0b011100) == 0b011100) { // L, C, R
                            nextState = Reverse_Adjusting_Right;
                            makeTransition = TRUE;
                            ThisEvent.EventType = ES_NO_EVENT;
                        } else {
                            ThisEvent.EventType = ES_NO_EVENT;
                        }
                        break;


                    case ES_EXIT:
                        break;
                }
            }
            break;

        case Reverse_Turning_Left:
            if (ThisEvent.EventType != ES_NO_EVENT) { // An event is still active
                switch (ThisEvent.EventType) {
                    case ES_ENTRY:
                        //ES_Timer_InitTimer(pivotingtimer, pivotingtimervalue);
                        ReverseLeft(speed); // fiz thinks this means reverse right // previously 5
                        ES_Timer_InitTimer(ammofindtimer, ammofindtimervalue);
                        break;

                        //                    case TAPE:
                        //                        if ((ThisEvent.EventParam & 0b011100) == 0b011100){ // L, C, R
                        //                            nextState = Reverse_Adjusting_Right;
                        //                            makeTransition = TRUE;
                        //                            ThisEvent.EventType = ES_NO_EVENT;
                        //                        }
                        //                        break;
                        //
                    case ES_TIMEOUT:
                        if (ThisEvent.EventParam == ammofindtimer) {
                            Tcontrol.EventType = MISSED_T;
                            Tcontrol.EventParam = 0;
                            PostDagobotHSM(Tcontrol);
                            ThisEvent.EventType = ES_NO_EVENT;
                        }
                        //                        else if (plungecount == 4){
                        //                            debug("Oh, shit!");
                        //                            nextState = Stopping_AC;
                        //                            makeTransition = TRUE;
                        //                            ThisEvent.EventType = ES_NO_EVENT;
                        //                            //TODO: Deal with later!
                        //                            // post event to pop into higher state
                        //                        }
                        break;

                    case ES_EXIT:
                        ES_Timer_StopTimer(ammofindtimer);
                        break;
                }
            }
            break;

        default: // all unhandled states fall into here
            break;
    } // end switch on Current State

    if (makeTransition == TRUE) {
        RunAlignCollect_SubHSM(EXIT_EVENT); // <- rename to your own Run function
        CurrentState = nextState;
        RunAlignCollect_SubHSM(ENTRY_EVENT); // <- rename to your own Run function
    }

    ES_Tail(); // trace call stack end
    return ThisEvent;
}
コード例 #2
0
/**
 * @Function RunEngage_DestroySubHSM(ES_Event ThisEvent)
 * @param ThisEvent - the event (type and param) to be responded.
 * @return Event - return event (type and param), in general should be ES_NO_EVENT
 * @brief This function is where you implement the whole of the heirarchical state
 *        machine, as this is called any time a new event is passed to the event
 *        queue. This function will be called recursively to implement the correct
 *        order for a state transition to be: exit current state -> enter next state
 *        using the ES_EXIT and ES_ENTRY events.
 * @note Remember to rename to something appropriate.
 *       The lower level state machines are run first, to see if the event is dealt
 *       with there rather than at the current level. ES_EXIT and ES_ENTRY events are
 *       not consumed as these need to pass pack to the higher level state machine.
 * @author J. Edward Carryer, 2011.10.23 19:25
 * @author Gabriel H Elkaim, 2011.10.23 19:25 */
ES_Event RunEngage_DestroySubHSM(ES_Event ThisEvent) {
    uint8_t makeTransition = FALSE; // use to flag transition
    SubEngage_DestroyState_t nextState;

    ES_Event eventtopost, donefiring;
    ES_Tattle(); // trace call stack


    switch (CurrentState) {
        case Init_ED: // If current state is initial Psedudo State
            if (ThisEvent.EventType == ES_INIT) {// only respond to ES_Init

                //call all substate run functions here
                InitEngage_Destroy_Wall_Hugging_SubHSM();

                nextState = Engage_Destroy_Searching;
                makeTransition = TRUE;
                ThisEvent.EventType = ES_NO_EVENT;
            }
            break;

        case Engage_Destroy_Searching:
            if (ThisEvent.EventType != ES_NO_EVENT) { // An event is still active
                switch (ThisEvent.EventType) {

                    case ES_ENTRY:
//                        ES_Timer_InitTimer(15, 2500); //TODO: Move to exit from acquiring_ammo
//                        PivotRight(speed);
//                        PivotRight(speed);
                        StraightForward(speed); //speed // move forwards away from the ammo dump
                        //pivot timer
                        // start pivoting
                        Dagobot_SetLoaderServo(1200);
                        ThisEvent.EventType = ES_NO_EVENT;
//                        ThisEvent.EventParam = 0;
//                        PostDagobotHSM(ThisEvent);
                        //TODO: Add flag to only go forwards if just from Acquiring_Ammo?

                        break;

//                    case AMMO:
//                        ThisEvent.EventType = ES_NO_EVENT;
//                        break;

                    case ES_EXIT:
                        FullStop(); // aimed at the enemy: stop and fire
                        ES_Timer_StopTimer(15);
                       // ES_Timer_StopTimer(forwardtimer);
                        break;

                    case SNIPED:
//                        debug("check event");
                         FullStop();
                        nextState = Firing;
                        makeTransition = TRUE;
                        ThisEvent.EventType = ES_NO_EVENT;
                        break;

                    case BUMPED:
                        nextState = Engage_Destroy_Wall_Hugging;
                        makeTransition = TRUE;
                        eventtopost.EventType = BUMP_CHECK;
                        eventtopost.EventParam = ThisEvent.EventParam;
//                          ThisEvent.EventType = BUMP_CHECK;
//                        ThisEvent.EventParam = ThisEvent.EventParam;
                        PostDagobotHSM(eventtopost);
                        break;
//
//                    case TAPE:
//                        nextState = Redirecting;
//                        makeTransition = TRUE;
//                        ThisEvent.EventType = ES_NO_EVENT;
//                        break;

                    case ES_TIMEOUT:
                        //if (ThisEvent.EventParam == forwardtimer) {
                        //    ES_Timer_InitTimer(pivotingtimer, 800);
                        //    PivotRight(newspeed);
                        //}
//                        if (ThisEvent.EventParam == 15) {
//                            FullStop(); // stop after spinning
//                            StraightForward(speed*1.25); // didn't find enemy, head towards obstacle (or at least forwards)
//                        }

//                        ThisEvent.EventType = ES_NO_EVENT;
                        break;

                    default: // all unhandled events pass the event back up to the next level
                        break;
                }
            }
            break;

        case Firing:
            if (ThisEvent.EventType != ES_NO_EVENT) { // An event is active
                switch (ThisEvent.EventType) {
                    case ES_ENTRY:
//                        int AmmoState = Dagobot_ReadLoaderTape();
//                        if (AmmoState == 1) { // have ammo!
//                        debug("check");
                            FullStop();
                            ES_Timer_InitTimer(ammofindtimer, 2000); // head towards deadbot
                            StraightForward(speed);
//                        }
                        break;
                        
//                    case SNIPED:
//                        if(ThisEvent.EventParam == 0)
//                        {
//                            
//                        }

//                    case BUMPED:
//                        if ((ThisEvent.EventParam & FRONT_LEFT_BUMP) == FRONT_LEFT_BUMP) { // front left bump
//
//                                ThisEvent.EventType = ES_NO_EVENT;
//                            } else if ((ThisEvent.EventParam & FRONT_RIGHT_BUMP) == FRONT_RIGHT_BUMP) { // front right bump
//                                nextState = Reversing_WH;
//                                makeTransition = TRUE;
//                                ThisEvent.EventType = ES_NO_EVENT;
//                            } else if ((ThisEvent.EventParam & FRONT_BUMPS) == FRONT_BUMPS) { // both front bumpers
//                                nextState = Reversing_WH;
//                                makeTransition = TRUE;
//                                ThisEvent.EventType = ES_NO_EVENT;
//                            }
//                        else {
//                            ThisEvent.EventType = ES_NO_EVENT;
//                        }
//                        break;

                    case ES_EXIT:
//                        ES_TIMER_StopTimer(motortimer);
                        Dagobot_SetLoaderServo(1200);
                        ES_Timer_StopTimer(shootingtimer);
                        ES_Timer_StopTimer(ammofindtimer);
//                        ThisEvent.EventType = ES_NO_EVENT; //TODO: remove??
                        break;

                    case ES_TIMEOUT:
                        if(ThisEvent.EventParam == ammofindtimer){
                            FullStop();
                            int i;
                            for(i = 0; i < 30000; i++)
                            {
                                asm("nop");
                            }
                            Dagobot_SetLoaderServo(2000); // start running up motor
                            ES_Timer_InitTimer(shootingtimer, shootingtimervalue);
                            ThisEvent.EventType = ES_NO_EVENT;
                        }
//                        if (ThisEvent.EventParam == motortimervalue) {//done spinning up motor
//                            Dagobot_SetLoaderServo(servorelease); // drop balls into shooter
//                            ES_Timer_InitTimer(shootingtimer, shootingtimervalue);
//                        }
                        if (ThisEvent.EventParam == shootingtimer) {
                            donefiring.EventType = DONE_FIRING; // upper level deal with getting to portal
                            donefiring.EventParam = 0;
                            PostDagobotHSM(donefiring);
                            ThisEvent.EventType = ES_NO_EVENT;
                        }
                        break;

                    default: // all unhandled events pass the event back up to the next level
                        break;
                }
            }
            break;

        case Engage_Destroy_Wall_Hugging:
            ThisEvent = RunEngage_Destroy_Wall_Hugging_SubHSM(ThisEvent); // run sub-state machine for this state
            //TODO: make new wall_hugging file/fn?
            // and/or deal with entry from differet events
            
            if (ThisEvent.EventType != ES_NO_EVENT) { // An event is active
                switch (ThisEvent.EventType) {
                    case ES_ENTRY:
                        // this is where you would put any actions associated with the
                        // entry to this state
//                        ES_Timer_InitTimer(wallhuggingtimer, 8000);
                        break;

                    case SNIPED:
                         FullStop();
                        nextState = Firing;
                        makeTransition = TRUE;
                        ThisEvent.EventType = ES_NO_EVENT;
                        break;

//                    case TAPE:
//                        if((ThisEvent.EventParam & 0x000010) != 0x000010) {
//                        nextState = Redirecting;
//                        makeTransition = TRUE;
//                        ThisEvent.EventType = ES_NO_EVENT;
//                        }
//                        break;

                    case ES_EXIT:
                        // this is where you would put any actions associated with the
                        // exit from this state
//                        ES_Timer_StopTimer(wallhuggingtimer);
                        FullStop();
                        break;

                    case ES_TIMEOUT:
//                        if (ThisEvent.EventParam == wallhuggingtimer) { // timer to check for enemy every once in a while while bumping around
//                            //TODO: make new checkin timer?
//                            nextState = Engage_Destroy_Searching; // search
//                            makeTransition = TRUE;
//                            ThisEvent.EventType = ES_NO_EVENT;
//
//                        }
                        break;

                    default: // all unhandled events pass the event back up to the next level
                        break;
                }
            }
            break;

        case Redirecting:
            if (ThisEvent.EventType != ES_NO_EVENT) {
                switch (ThisEvent.EventType) {
                    case ES_ENTRY:
                        PivotRight(speed);
                        ES_Timer_InitTimer(pivotingtimer, pivotingtimervalue);
                        break;



                    case ES_EXIT:
                        ES_Timer_StopTimer(pivotingtimer);
                        //                        ThisEvent.EventType = ES_NO_EVENT;
                        break;

                    case ES_TIMEOUT:
                        if (ThisEvent.EventParam = pivotingtimer) {
                            nextState = Engage_Destroy_Searching; // search
                            makeTransition = TRUE;
                            ThisEvent.EventType = ES_NO_EVENT; // head for whatever's in the future
                        }

                        break;

                    default: // all unhandled events pass the event back up to the next level
                        break;
                }
            }
            break;


        default: // all unhandled states fall into here
            break;
    } // end switch on Current State

    if (makeTransition == TRUE) { // making a state transition, send EXIT and ENTRY
        // recursively call the current state with an exit event
        RunEngage_DestroySubHSM(EXIT_EVENT); // <- rename to your own Run function
        CurrentState = nextState;
        RunEngage_DestroySubHSM(ENTRY_EVENT); // <- rename to your own Run function
    }

    ES_Tail(); // trace call stack end
    return ThisEvent;
}
コード例 #3
0
ファイル: protocol_04.c プロジェクト: jochym/nexstar-evo
int GoToCoords(double newra, double newdec, int pmodel)
{
  char sendstr[] = { 0x50, 0x04, 0x10, 0x17, 0x00, 0x00, 0x00, 0x00 };
  char returnstr[32];
  int azcount, azcount0, azcount1, azcount2;
  int altcount, altcount0, altcount1, altcount2;
  int numread; 
  double newha, newalt, newaz;
  double newha0, newalt0, newaz0;
  double newra0, newdec0;
  double newra1, newdec1;
  double nowha0, nowra0, nowdec0;
  double encoderalt = 0.;
  double encoderaz = 0.;
     
  /* Select fast slew command if needed */
  /* Note:  may place large inertial load on the gear train */
  
  if( SLEWFAST )
  {
    sendstr[3] = 0x02;
  }
        
  newha = LSTNow() - newra;
  newha = Map12(newha);
  
  /* Convert HA and Dec to Alt and Az */
  /* Test for visibility              */
  
  EquatorialToHorizontal(newha, newdec, &newaz, &newalt);
  
  /* Check altitude limit */
  
  if (newalt < MINTARGETALT)
  {
    fprintf(stderr,"Target is below the telescope horizon\n");
    slewphase = 0;
    return(0);
  }
  
  /* Target request is valid */
  /* Find the best path to target */
    
  /* Mount coordinates for the target */
  
  newra1 = newra;
  newdec1 = newdec;
  PointingToTel(&newra0,&newdec0,newra1,newdec1,pmodel);  
  newha0 = LSTNow() - newra0;
  newha0 = Map12(newha0);
  EquatorialToHorizontal(newha0, newdec0, &newaz0, &newalt0);
  
  /* Stop all mount motion in preparation for a slew */
  
  FullStop();  

  /* Get current mount coordinates */
  
  GetTel(&nowra0, &nowdec0, RAW);
  nowha0 = LSTNow() - nowra0;
  nowha0 = Map12(nowha0);
          
  /* Prepare encoder counts for a new slew */

  /* German equatorial */

  if (telmount == GEM)
  {
    
    /* Flip signs for the southern sky */
    
    if (SiteLatitude < 0.)
    {
      newdec0 = -1.*newdec0;
      newha0 = -1.*newha0;
    }
    
    if ((newha0 >= -12.) && ( newha0 < -6.))
    { 
      slewphase = 1;
      encoderaz = newha0*15. + 180.;
      encoderalt = newdec0;
    }
    else if ((newha0 >= -6.) && ( newha0 <= 0.))
    { 
      slewphase = 1;
      encoderaz = newha0*15. + 180.;
      encoderalt = newdec0;
    }
    else if ((newha0 > 0.) && ( newha0 <= 6.))
    { 
      slewphase = 1;
      encoderaz = newha0*15.;
      encoderalt = 180. - newdec0;
    }
    else if ((newha0 > 6.) && ( newha0 <= 12.))
    { 
      slewphase = 1;
      encoderaz = newha0*15.;
      encoderalt = 180. - newdec0;
    }    
    else
    {
      fprintf(stderr,"German equatorial slew request error\n");
      return(0);      
    }

    if (newha0 == 0.)
    { 
      /* OTA looking at meridian */
      /* This is ambiguous unless we know which side of the pier it is on */
      /* Assume telescope was on the west side looking east */
      /*   and was moved to point to the meridian with the OTA west of pier */
      slewphase = 1;
      fprintf(stderr,"Warning: assuming OTA is west of pier.\n");
      encoderaz = 90.;
      encoderalt = newdec0 - 90.;
    }
    else if (newha0 == -6.)
    {
      /* OTA looking east */
      slewphase = 1;
      encoderaz = 0.;
      encoderalt = newdec0 - 90.;
    }
    else if (newha0 == 6.)
    {
      /* OTA looking west */
      slewphase = 1;
      encoderaz = 0.;
      encoderalt = 90. - newdec0;
    }    
    else if ((newha0 > -12.) && ( newha0 < -6.))
    { 
      /* OTA east of pier looking below the pole */
      slewphase = 1;
      encoderaz = newha0*15. + 90.;
      encoderalt = newdec0 - 90.;
    }
    else if ((newha0 > -6.) && ( newha0 < 0.))
    { 
      /* OTA west of pier looking east */
      slewphase = 1;
      encoderaz = newha0*15. + 90.;
      encoderalt = newdec0 - 90.;
    }
    else if ((newha0 > 0.) && ( newha0 <= 6.))
    { 
      /*OTA east of pier looking west */
      slewphase = 1;
      encoderaz = newha0*15. - 90.;
      encoderalt = 90. - newdec0;
    }
    else if ((newha0 > 6.) && ( newha0 < 12.))
    { 
      /* OTA west of pier looking below the pole */
      slewphase = 1;
      encoderaz = newha0*15. - 90.;
      encoderalt = 90. - newdec0;
    }    
    else
    {
      fprintf(stderr,"German equatorial slew request outside limits\n");
      return(0);      
    }

    /* Tests for safe slew based on encoder readings would go here */
        
    /* Test need for two-segment slew for changes of more than 90 degrees */
    
    if ((fabs(telencoderalt - encoderalt) > 90.1) || 
      (fabs(telencoderaz - encoderaz) > 90.1))
    {
      
      /* Slew request of more than 90 degrees on one axis */
      
      if ( fabs(telencoderalt) > 10. )
      {
        
        /* Telescope currently more than 10 degrees from the pole in dec */
        /* Set new target to switch position */
        
        encoderalt = switchalt;
        encoderaz = switchaz;
        slewphase = 2;
      }  
    }
            
    encoderalt = encoderalt*altcountperdeg;
    encoderaz = encoderaz*azcountperdeg;     
  }
  
  /* Equatorial fork */
  
  if (telmount == EQFORK)
  {
    slewphase = 1;
    encoderaz = newha0*15.;
    encoderalt = newdec0;

    /* Tests for safe slew based on encoder readings would go here */

    encoderalt = encoderalt*altcountperdeg;
    encoderaz = encoderaz*azcountperdeg;       
  }
  
  /* Alt-az fork */
  
  if (telmount == ALTAZ)
  {
    slewphase = 1;
    encoderaz = newaz0;
    encoderalt = newalt0;

    /* Tests for safe slew based on encoder readings would go here */

    encoderaz = encoderaz*azcountperdeg;
    encoderalt = encoderalt*altcountperdeg;
  }
        
  /* Convert encoder angle readings to encoder counter readings */

  azcount = encoderaz;
  if (azcount < 0)
  {
    azcount = 16777217 + azcount;
  }

  altcount = encoderalt;
  if (altcount < 0)
  {
    altcount = 16777217 + altcount;
  }

  /* Prepare NexStar commands                  */
  /* Parse each of the 3 bytes of the counters */
    
  azcount0  = azcount  / 65536;
  azcount   = azcount  % 65536;
  azcount1  = azcount  / 256;
  azcount2  = azcount  % 256;
  altcount0 = altcount / 65536;
  altcount  = altcount % 65536;
  altcount1 = altcount / 256;
  altcount2 = altcount % 256;
  
  /* Send command to go to new RA/Azimuth */
    
  sendstr[1] = 0x04;
  sendstr[2] = 0x10;
  sendstr[3] = 0x17;
  sendstr[4] = (unsigned short) azcount0;
  sendstr[5] = (unsigned short) azcount1;
  sendstr[6] = (unsigned short) azcount2;

  tcflush(TelPortFD,TCIOFLUSH);
  
  writen(TelPortFD,sendstr,8);
  numread=readn(TelPortFD,returnstr,1,2);
  
  /* Send command to go to new Dec/Altitude */
    
  sendstr[1] = 0x04;
  sendstr[2] = 0x11;
  sendstr[3] = 0x17;
  sendstr[4] = (unsigned short) altcount0;
  sendstr[5] = (unsigned short) altcount1;
  sendstr[6] = (unsigned short) altcount2;

  tcflush(TelPortFD,TCIOFLUSH);
    
  writen(TelPortFD,sendstr,8);
  numread=readn(TelPortFD,returnstr,1,2);
  
  tcflush(TelPortFD,TCIOFLUSH);
  
  /* A slew is in progress */

  return(1);
}
コード例 #4
0
/**
 * @Function RunLine_FollowingSubHSM(ES_Event ThisEvent)
 * @param ThisEvent - the event (type and param) to be responded.
 * @return Event - return event (type and param), in general should be ES_NO_EVENT
 * @brief This function is where you implement the whole of the heirarchical state
 *        machine, as this is called any time a new event is passed to the event
 *        queue. This function will be called recursively to implement the correct
 *        order for a state transition to be: exit current state -> enter next state
 *        using the ES_EXIT and ES_ENTRY events.
 * @note Remember to rename to something appropriate.
 *       The lower level state machines are run first, to see if the event is dealt
 *       with there rather than at the current level. ES_EXIT and ES_ENTRY events are
 *       not consumed as these need to pass pack to the higher level state machine.
 * @author J. Edward Carryer, 2011.10.23 19:25
 * @author Gabriel H Elkaim, 2011.10.23 19:25 */
ES_Event Run_AA_LineFollowing_SubHSM(ES_Event ThisEvent) {
    uint8_t makeTransition = FALSE; // use to flag transition
    AA_LineFollowing_subHSM_t nextState; // <- change type to correct enum

    ES_Tattle(); // trace call stack

    switch (CurrentState) {
        case Init_AA_LineFollowing: // If current state is initial Psedudo State
            if (ThisEvent.EventType == ES_INIT)// only respond to ES_Init
            {
                nextState = EntryLineFollowing;
                makeTransition = TRUE;
                ThisEvent.EventType = ES_NO_EVENT;
            }
            break;

        case EntryLineFollowing:
            if (ThisEvent.EventType != ES_NO_EVENT) { // An event is still active
                switch (ThisEvent.EventType) {
                    case ES_ENTRY:
                        StraightForward(speed);
                        break;

                    case ES_EXIT:
                        break;

                    case TAPE:
                        if (ThisEvent.EventParam == 0b100000) { // LL: 20, 100000
                            FullStop();
                            nextState = Adjusting_Left;
                            makeTransition = TRUE;
                            ThisEvent.EventType = ES_NO_EVENT;
                        } else if (ThisEvent.EventParam == 0b000010) { // RR: 02
                            FullStop();
                            nextState = Pivoting_Right;
                            makeTransition = TRUE;
                            ThisEvent.EventType = ES_NO_EVENT;
                        } else if ((ThisEvent.EventParam & 0b110010) == 0b110010) { // LL, L,  RR
                            FullStop();
                            nextState = Reversing_Left;
                            makeTransition = TRUE;
                            ThisEvent.EventType = ES_NO_EVENT;
                        } else if ((ThisEvent.EventParam & 0b001001) == 0b001001) { // F, B
                            FullStop();
                            nextState = Adjusting_Right;
                            makeTransition = TRUE;
                            ThisEvent.EventType = ES_NO_EVENT;
                        } else {
                            ThisEvent.EventType = ES_NO_EVENT;
                        }
                        break;
                }
            }
            break;

        case Adjusting_Left:
            if (ThisEvent.EventType != ES_NO_EVENT) { // An event is still active
                switch (ThisEvent.EventType) {
                    case ES_ENTRY:
                        TurnLeft(speed * 1);
                        break;

                    case TAPE:
                        if ((ThisEvent.EventParam & 0b000010) == 0b000010) { // RR (corner)
                            nextState = Pivoting_Right;
                            makeTransition = TRUE;
                            ThisEvent.EventType = ES_NO_EVENT;
                        } else if ((ThisEvent.EventParam & 0b001000) == 0b001000) { //F
                            FullStop();
                            nextState = Adjusting_Right; //Adjusting_Right
                            makeTransition = TRUE;
                            ThisEvent.EventType = ES_NO_EVENT;
                        } else {
                            ThisEvent.EventType = ES_NO_EVENT;
                        }
                        break;

                    case ES_EXIT:
                        break;
                }
            }
            break;

        case Adjusting_Right:
            if (ThisEvent.EventType != ES_NO_EVENT) { // An event is still active
                switch (ThisEvent.EventType) {
                    case ES_ENTRY:
                        TurnRight(speed * 1);
                        break;

                    case TAPE:
                        if ((ThisEvent.EventParam & 0b010000) == 0b010000) { // L
                            FullStop();
                            nextState = Adjusting_Left;
                            makeTransition = TRUE;
                            ThisEvent.EventType = ES_NO_EVENT;
                        } else if ((ThisEvent.EventParam & 0b100000) == 0b100000) { // LL
                            FullStop();
                            nextState = Adjusting_Left;
                            makeTransition = TRUE;
                            ThisEvent.EventType = ES_NO_EVENT;
                        } else if ((ThisEvent.EventParam & 0b000010) == 0b000010) { // RR (corner)
                            nextState = Pivoting_Right;
                            makeTransition = TRUE;
                            ThisEvent.EventType = ES_NO_EVENT;
                        } else if ((ThisEvent.EventParam & 0b000110) == 0b000110) { //R, RR (corner)
                            nextState = Pivoting_Right;
                            makeTransition = TRUE;
                            ThisEvent.EventType = ES_NO_EVENT;
                        } else {
                            ThisEvent.EventType = ES_NO_EVENT;
                        }
                        break;

                    case ES_EXIT:
                        break;
                }
            }
            break;

        case Pivoting_Right:
            if (ThisEvent.EventType != ES_NO_EVENT) { // An event is still active
                switch (ThisEvent.EventType) {
                    case ES_ENTRY:
                        ES_Timer_InitTimer(ammofindtimer, 2000);
                        PivotRight(speed);
                        break;

                    case ES_EXIT:
                        ES_Timer_StopTimer(ammofindtimer);
                        break;

                    case TAPE:

                        if ((ThisEvent.EventParam & 0b110010) == 0b110010) { // LL, L, RR
                            nextState = Reversing_Left;
                            makeTransition = TRUE;
                            ThisEvent.EventType = ES_NO_EVENT;
                        } else if ((ThisEvent.EventParam & 0b010000) == 0b010000) { // L
                            FullStop();
                            nextState = Adjusting_Left;
                            makeTransition = TRUE;
                            ThisEvent.EventType = ES_NO_EVENT;
                        } else if ((ThisEvent.EventParam & 0b100001) == 0b100001) { // LL, B
                            nextState = Adjusting_Left;
                            makeTransition = TRUE;
                            ThisEvent.EventType = ES_NO_EVENT;
                        } else if ((ThisEvent.EventParam & 0b100000) == 0b100000) { // LL
                            nextState = Adjusting_Left;
                            makeTransition = TRUE;
                            ThisEvent.EventType = ES_NO_EVENT;
                        }
                        else {
                            ThisEvent.EventType = ES_NO_EVENT;
                        }
                        break;

                    case ES_TIMEOUT:
                        if (ThisEvent.EventParam == ammofindtimer) {
                            nextState = EntryLineFollowing;
                            makeTransition = TRUE;
                            ThisEvent.EventType = ES_NO_EVENT;
                        }
                        break;
                }
            }
            break;

        case Reversing_Left:
            if (ThisEvent.EventType != ES_NO_EVENT) { // An event is still active
                switch (ThisEvent.EventType) {
                    case ES_ENTRY:
                        ES_Timer_InitTimer(turningtimer, turningtimervalue);
                        TurnLeft(-(speed));
                        break;

                    case ES_EXIT:
                        ES_Timer_StopTimer(turningtimer);
                        break;

                    case ES_TIMEOUT:
                        nextState = Adjusting_Left;
                        makeTransition = TRUE;
                        ThisEvent.EventType = ES_NO_EVENT;


                    case TAPE:
                        if ((ThisEvent.EventParam & 0b100000) == 0b100000) { // LL
                            nextState = Adjusting_Left;
                            makeTransition = TRUE;
                            ThisEvent.EventType = ES_NO_EVENT;
                        } else {
                            ThisEvent.EventType = ES_NO_EVENT;
                        }
                        break;
                }
            }
            break;

        default: // all unhandled states fall into here
            break;
    } // end switch on Current State


    if (makeTransition == TRUE) { // making a state transition, send EXIT and ENTRY
        // recursively call the current state with an exit event
        Run_AA_LineFollowing_SubHSM(EXIT_EVENT);
        CurrentState = nextState;
        Run_AA_LineFollowing_SubHSM(ENTRY_EVENT);
    }

    ES_Tail(); // trace call stack end
    return ThisEvent;
}