code petit robot pour homologation

Fork of CRAC-Strat_2017_V2 by CRAC Team

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Strategie.cpp Source File

Strategie.cpp

00001  #include "Strategie.h"
00002 
00003 E_stratGameEtat     gameEtat  = ETAT_CHECK_CARTE_SCREEN;
00004 E_stratGameEtat     lastEtat  = ETAT_CHECK_CARTE_SCREEN;
00005 unsigned char screenChecktry = 0;
00006 Timer cartesCheker;//Le timer pour le timeout de la vérification des cartes
00007 Timer fakeJack;
00008 Timer gameTimer;
00009 Timer debugetatTimer;
00010 Timer timeoutWarning;
00011 Timer timeoutWarningWaitEnd;
00012 Timeout chronoEnd;//permet d'envoyer la trame CAN pour la fin 
00013 
00014 unsigned short waitingAckID = 0;//L'id du ack attendu
00015 unsigned short waitingAckFrom = 0;//La provenance du ack attendu
00016 char modeTelemetre; // Si à 1, indique que l'on attend une reponse du telemetre 
00017 //unsigned short telemetreDistance = 0;
00018 signed char FIFO_lecture=0;//Position du fifo de lecture des messages CAN
00019 
00020 signed short x_robot,y_robot,theta_robot;//La position du robot
00021 
00022 signed short start_move_x,start_move_y,start_move_theta;//La position du robot lors du début d'un mouvement, utilisé pour reprendre le mouvement apres stop balise
00023 
00024 #ifdef ROBOT_BIG
00025 //unsigned short id_check[NOMBRE_CARTES]= {CHECK_BALISE,CHECK_MOTEUR,CHECK_ACTIONNEURS,CHECK_AX12,CHECK_POMPES};
00026 //unsigned short id_alive[NOMBRE_CARTES]= {ALIVE_BALISE,ALIVE_MOTEUR,ALIVE_ACTIONNEURS,ALIVE_AX12,ALIVE_POMPES};
00027 
00028 unsigned short id_check[NOMBRE_CARTES]= {CHECK_MOTEUR,CHECK_MOTEUR};
00029 unsigned short id_alive[NOMBRE_CARTES]= {ALIVE_MOTEUR,ALIVE_MOTEUR};
00030 
00031 InterruptIn jack(p25); //  entrée analogique en interruption pour le jack
00032 #else
00033 //unsigned short id_check[NOMBRE_CARTES]= {CHECK_BALISE,CHECK_MOTEUR,CHECK_ACTIONNEURS};
00034 //unsigned short id_alive[NOMBRE_CARTES]= {ALIVE_BALISE,ALIVE_MOTEUR,ALIVE_ACTIONNEURS};
00035 
00036 unsigned short id_check[NOMBRE_CARTES]= {CHECK_MOTEUR};
00037 unsigned short id_alive[NOMBRE_CARTES]= {ALIVE_MOTEUR};
00038 
00039 InterruptIn jack(p25); //  entrée analogique en interruption pour le jack
00040 #endif
00041 unsigned char checkCurrent = 0;
00042 unsigned char countAliveCard = 0; 
00043 
00044 unsigned char InversStrat = 1;//Si à 1, indique que l'on part de l'autre cote de la table(inversion des Y)
00045 
00046 unsigned char ModeDemo = 0; // Si à 1, indique que l'on est dans le mode demo
00047 
00048 unsigned char countRobotNear = 0;//Le nombre de robot à proximité
00049 
00050 unsigned char ingnorBaliseOnce = 0;
00051 
00052 
00053 /****************************************************************************************/
00054 /* FUNCTION NAME: chronometre_ISR                                                       */
00055 /* DESCRIPTION  : Interruption à la fin des 90s du match                                */
00056 /****************************************************************************************/
00057 void chronometre_ISR (void)
00058 {
00059     SendRawId(ASSERVISSEMENT_STOP);//On stope les moteurs
00060     SendRawId(GLOBAL_GAME_END);//Indication fin de match
00061     gameTimer.stop();//Arret du timer
00062 
00063 #ifdef ROBOT_BIG
00064     wait_ms(2000);
00065     doFunnyAction();
00066 #endif
00067     
00068     while(1);//On bloque la programme dans l'interruption
00069 }
00070 
00071 /****************************************************************************************/
00072 /* FUNCTION NAME: jack_ISR                                                              */
00073 /* DESCRIPTION  : Interruption en changement d'état sur le Jack                         */
00074 /****************************************************************************************/
00075 void jack_ISR (void)
00076 {
00077     if(gameEtat == ETAT_GAME_WAIT_FOR_JACK) {
00078         led4=1;
00079         gameEtat = ETAT_GAME_START;//On débute le match
00080     }
00081 }
00082 
00083 /****************************************************************************************/
00084 /* FUNCTION NAME: automate_process                                                      */
00085 /* DESCRIPTION  : Automate de gestion de la stratégie du robot                          */
00086 /****************************************************************************************/
00087 void automate_process(void)
00088 {
00089     static struct S_Instruction instruction;
00090     static unsigned char AX12_enchainement = 0;
00091     static unsigned char MV_enchainement = 0;
00092     signed char localData1 = 0;
00093     signed short localData2 = 0;
00094     unsigned short localData3 = 0;
00095     //signed short localData4 = 0;
00096     unsigned char localData5 = 0;
00097     
00098     if(gameTimer.read_ms() >= 89000) {//Fin du match (On autorise 2s pour déposer des éléments
00099         gameTimer.stop();
00100         gameTimer.reset();
00101         gameEtat = ETAT_END;//Fin du temps
00102     }
00103     
00104     if(lastEtat != gameEtat || debugetatTimer.read_ms() >= 1000) {
00105         lastEtat = gameEtat;
00106         debugetatTimer.reset();
00107         sendStratEtat((unsigned char)gameEtat, (unsigned char)actual_instruction);
00108     }
00109     
00110     switch(gameEtat)
00111     {
00112         case ETAT_CHECK_CARTE_SCREEN:
00113             /*
00114             Verification de l'état de la carte ecran
00115             */
00116             waitingAckFrom = ALIVE_IHM;//On indique que l'on attend un ack de la carte IHM
00117             SendRawId(CHECK_IHM);//On demande à la carte IHM d'insiquer ça présence
00118             
00119             screenChecktry++;//On incrèment le conteur de tentative de 1
00120             cartesCheker.reset();//On reset le timeOut
00121             cartesCheker.start();//On lance le timer pour le timeout
00122             gameEtat = ETAT_CHECK_CARTE_SCREEN_WAIT_ACK;
00123             
00124             //gameEtat = ETAT_GAME_START;
00125             
00126         break;
00127         case ETAT_CHECK_CARTE_SCREEN_WAIT_ACK:
00128             /*
00129             Attente du ALIVE de la carte écran.
00130             
00131             Si la carte ne répond pas apres 10ms, on retoune dans l'etat ETAT_CHECK_CARTE_SCREEN
00132             maximum 3 tentatives
00133             Si pas de réponse, clignotement de toutes les leds possible
00134             */
00135             if(waitingAckFrom == 0) {//C'est bon la carte est en ligne
00136                 cartesCheker.stop();
00137                 screenChecktry = 0;
00138                 gameEtat = ETAT_CHECK_CARTES;
00139             } else if(cartesCheker.read_ms () > 100) {
00140                 cartesCheker.stop();
00141                 if(screenChecktry >=3) {
00142                     errorLoop();//Erreur La carte IHM n'est pas en ligne
00143                 } else {
00144                     gameEtat = ETAT_CHECK_CARTE_SCREEN;
00145                 }
00146             }
00147         break;
00148         case ETAT_CHECK_CARTES:
00149             /*
00150             Il faut faire une boucle pour verifier toutes les cartes les une apres les autres
00151             */
00152             waitingAckFrom = id_alive[checkCurrent];//On indique que l'on attend un ack de la carte IHM
00153             SendRawId(id_check[checkCurrent]);//On demande à la carte d'indiquer ça présence
00154             
00155             screenChecktry++;//On incrèment le conteur de tentative de 1
00156             cartesCheker.reset();//On reset le timeOut
00157             cartesCheker.start();//On lance le timer pour le timeout
00158             gameEtat = ETAT_CHECK_CARTES_WAIT_ACK;
00159             
00160             
00161             
00162             
00163         break;
00164         case ETAT_CHECK_CARTES_WAIT_ACK:
00165             /*
00166             On attend l'ack de la carte en cours de vérification
00167             */
00168             //printf("cartesCheker = %d waitingAckFrom = %d\n",cartesCheker.read_ms(), waitingAckFrom);
00169             if(waitingAckFrom == 0) {//C'est bon la carte est en ligne
00170                 cartesCheker.stop();
00171                 screenChecktry = 0;
00172                 countAliveCard++;
00173                 checkCurrent++;
00174                 if(checkCurrent >= NOMBRE_CARTES) {
00175                     //printf("all card check, missing %d cards\n",(NOMBRE_CARTES-countAliveCard));
00176                     if(countAliveCard >= NOMBRE_CARTES) {
00177                         gameEtat = ETAT_CONFIG;
00178                         SendRawId(ECRAN_ALL_CHECK);//On dit à l'IHM que toutes les cartes sont en ligne
00179                         tactile_printf("Selection couleur et strategie");
00180                     } else {
00181                         gameEtat = ETAT_WAIT_FORCE;//Passage en attente de forçage du lancement
00182                         waitingAckFrom = ECRAN_ALL_CHECK;
00183                     }
00184                 } else {
00185                     gameEtat = ETAT_CHECK_CARTES;
00186                 }
00187             } else if(cartesCheker.read_ms () > 100) {
00188                 cartesCheker.stop();
00189                 if(screenChecktry >=3) {
00190                     //printf("missing card %d\n",id_check[checkCurrent]);
00191                     screenChecktry = 0;
00192                     checkCurrent++;
00193                     
00194                     if(checkCurrent >= NOMBRE_CARTES) {
00195                         if(countAliveCard == NOMBRE_CARTES) {
00196                             gameEtat = ETAT_CONFIG;
00197                             SendRawId(ECRAN_ALL_CHECK);//On dit à l'IHM que toutes les cartes sont en ligne
00198                         } else {
00199                             gameEtat = ETAT_WAIT_FORCE;//Passage en attente de forçage du lancement
00200                             waitingAckFrom = ECRAN_ALL_CHECK;
00201                         }
00202                     } else {
00203                         gameEtat = ETAT_CHECK_CARTES;
00204                     }
00205                 } else {
00206                     gameEtat = ETAT_CHECK_CARTES;
00207                 }
00208             }
00209         break;
00210         case ETAT_WAIT_FORCE:
00211             /*
00212             Attente du forçage de la part de la carte IHM
00213             */
00214             if(waitingAckFrom == 0) {
00215                 gameEtat = ETAT_CONFIG;
00216             }
00217         break;
00218         case ETAT_CONFIG:
00219             /*
00220             Attente de l'odre de choix de mode,
00221             Il est possible de modifier la couleur et l'id de la stratégie
00222             Il est aussi possible d'envoyer les ordres de debug
00223             */
00224             modeTelemetre = 0;
00225         break;
00226         case ETAT_GAME_INIT:
00227             //On charge la liste des instructions
00228             loadAllInstruction();//Mise en cache de toute les instructions
00229             
00230             gameEtat = ETAT_GAME_WAIT_FOR_JACK;
00231             SendRawId(ECRAN_ACK_START_MATCH);
00232             tactile_printf("Attente du JACK.");
00233             setAsservissementEtat(1);//On réactive l'asservissement
00234             jack.mode(PullDown); // désactivation de la résistance interne du jack
00235             jack.fall(&jack_ISR); // création de l'interrupt attachée au changement d'état (front descendant) sur le jack
00236          
00237 #ifdef ROBOT_BIG //le gros robot n'a pas de recalage bordure pour ce placer au début, on lui envoit donc ça position
00238             localData2 = POSITION_DEBUT_T;
00239             localData3 = POSITION_DEBUT_Y;
00240             if(InversStrat == 1) {
00241                 localData2 = -localData2;//Inversion theta
00242                 localData3 = 3000 - POSITION_DEBUT_Y;//Inversion du Y
00243             }
00244             SetOdometrie(ODOMETRIE_BIG_POSITION, POSITION_DEBUT_X,localData3,localData2);
00245 #endif 
00246 #ifdef ROBOT_SMALL
00247             SetOdometrie(ODOMETRIE_SMALL_POSITION, POSITION_DEBUT_X,POSITION_DEBUT_Y,POSITION_DEBUT_T);
00248 #endif
00249         break;
00250         case ETAT_GAME_WAIT_FOR_JACK:
00251             //On attend le jack
00252         break;
00253         case ETAT_GAME_START:
00254             gameEtat = ETAT_GAME_LOAD_NEXT_INSTRUCTION;
00255             
00256             if (ModeDemo == 0){
00257                 chronoEnd.attach(&chronometre_ISR,90);//On lance le chrono de 90s
00258                 gameTimer.start();
00259             } 
00260             gameTimer.reset();
00261             jack.fall(NULL);//On désactive l'interruption du jack
00262             SendRawId(GLOBAL_START);
00263             tactile_printf("Start");//Pas vraiment util mais bon
00264         break;
00265         case ETAT_GAME_LOAD_NEXT_INSTRUCTION:
00266             /*
00267             Chargement de l'instruction suivante ou arret du robot si il n'y a plus d'instruction
00268             */
00269             //printf("load next instruction\n");
00270             
00271             if(actual_instruction >= nb_instructions || actual_instruction == 255) {
00272                 gameEtat = ETAT_END;
00273                 //Il n'y a plus d'instruction, fin du jeu
00274             } else {
00275                 instruction = strat_instructions[actual_instruction];
00276                 //On effectue le traitement de l'instruction 
00277                 gameEtat = ETAT_GAME_PROCESS_INSTRUCTION;
00278             }
00279             screenChecktry = 0;
00280         break;
00281         case ETAT_GAME_PROCESS_INSTRUCTION:
00282             /*
00283             Traitement de l'instruction, envoie de la trame CAN
00284             */
00285             //debug_Instruction(instruction);
00286             switch(instruction.order)
00287             {
00288                 case MV_COURBURE://C'est un rayon de courbure
00289                     waitingAckID = ASSERVISSEMENT_COURBURE;
00290                     waitingAckFrom = ACKNOWLEDGE_MOTEUR;
00291                     if(instruction.nextActionType == ENCHAINEMENT) {
00292                         MV_enchainement++;
00293                         localData5 = 1;
00294                     } else {
00295                         if(MV_enchainement > 0) {
00296                             localData5 = 2;
00297                             MV_enchainement = 0;
00298                         } else {
00299                             localData5 = 0;
00300                         }
00301                     }
00302                     localData1 = ((instruction.direction == LEFT)?1:-1);
00303                     if(InversStrat == 1)
00304                     {
00305                         localData1 = -localData1;//Inversion de la direction
00306                     }
00307                     
00308                     BendRadius(instruction.arg1, instruction.arg3, localData1, localData5);
00309                 break;
00310                 case MV_LINE://Ligne droite
00311                     waitingAckID = ASSERVISSEMENT_RECALAGE;
00312                     waitingAckFrom = ACKNOWLEDGE_MOTEUR;
00313                     if(instruction.nextActionType == ENCHAINEMENT) {
00314                         MV_enchainement++;
00315                         localData5 = 1;
00316                     } else {
00317                         if(MV_enchainement > 0) {//Utilisé en cas d'enchainement, 
00318                             localData5 = 2;
00319                             MV_enchainement = 0;
00320                         } else {
00321                             localData5 = 0;
00322                         }
00323                     }
00324                     #ifdef ROBOT_BIG
00325                     if(InversStrat == 1) {
00326                             /*if (instruction.direction == FORWARD) instruction.direction = BACKWARD;
00327                             else instruction.direction = FORWARD;*/
00328                             instruction.direction = ((instruction.direction == FORWARD)?BACKWARD:FORWARD);
00329                         }
00330                     #endif    
00331                     localData2 = (((instruction.direction == FORWARD)?1:-1)*instruction.arg1);
00332                     GoStraight(localData2, 0, 0, localData5);
00333                     
00334                 break;
00335                 case MV_TURN: //Rotation sur place
00336                     if(instruction.direction == RELATIVE) {
00337                         localData2 = instruction.arg3;
00338                     } else {//C'est un rotation absolu, il faut la convertir en relative
00339                         localData2 = instruction.arg3;
00340                         
00341                         if(InversStrat == 1) {
00342                             localData2 = -localData2;
00343                         }
00344                         
00345                         localData2 = (localData2 - theta_robot)%3600;
00346                         if(localData2 > 1800) {
00347                             localData2 = localData2-3600;
00348                         }
00349                         
00350                     }
00351                     
00352                     Rotate(localData2);
00353                     waitingAckID = ASSERVISSEMENT_ROTATION;
00354                     waitingAckFrom = ACKNOWLEDGE_MOTEUR;
00355                 break;
00356                 case MV_XYT:
00357                     if(instruction.direction == BACKWARD) {
00358                         localData1 = -1;
00359                     } else {
00360                         localData1 = 1;
00361                     }
00362                     
00363                     if(InversStrat == 1) {
00364                         localData2 = -instruction.arg3;
00365                         localData3 = 3000 - instruction.arg2;//Inversion du Y
00366                     } else {
00367                         localData3 = instruction.arg2;
00368                         localData2 = instruction.arg3;
00369                     }
00370                     GoToPosition(instruction.arg1,localData3,localData2,localData1);
00371                     waitingAckID = ASSERVISSEMENT_XYT;
00372                     waitingAckFrom = ACKNOWLEDGE_MOTEUR;
00373                 break;
00374                 case MV_RECALAGE:
00375                     waitingAckID = ASSERVISSEMENT_RECALAGE;
00376                     waitingAckFrom = ACKNOWLEDGE_MOTEUR;
00377                     instruction.nextActionType = WAIT;
00378                     localData2 = (((instruction.direction == FORWARD)?1:-1)*3000);//On indique une distance de 3000 pour etre sur que le robot va ce recaler
00379                     
00380                     if(instruction.precision == RECALAGE_Y) {
00381                         localData5 = 2;
00382                         if(InversStrat == 1) {
00383                             localData3 = 3000 - instruction.arg1;//Inversion du Y
00384                         } else {
00385                             localData3 = instruction.arg1;
00386                         }
00387                     } else {
00388                         localData5 = 1;
00389                         localData3 = instruction.arg1;
00390                     }
00391                     
00392                     GoStraight(localData2, localData5, localData3, 0);
00393                 break;
00394                 case ACTION:
00395                     int tempo = 0;
00396                     waitingAckID= SERVO_AX12_ACTION;
00397                     waitingAckFrom = ACKNOWLEDGE_AX12;
00398                     tempo = doAction(instruction.arg1,instruction.arg2,instruction.arg3);
00399                     if(tempo == 1){
00400                         //L'action est spécifique
00401                         if((waitingAckFrom == 0 && waitingAckID == 0) || instruction.nextActionType == ENCHAINEMENT) {
00402                             
00403                             actual_instruction = instruction.nextLineOK;//On indique que l'on va charger l'instruction suivante
00404                             gameEtat = ETAT_GAME_LOAD_NEXT_INSTRUCTION;
00405                         } else {
00406                             gameEtat = ETAT_GAME_WAIT_ACK;
00407                         }
00408                         #ifdef ROBOT_SMALL
00409                             actual_instruction = instruction.nextLineOK;//On indique que l'on va charger l'instruction suivante
00410                             gameEtat = ETAT_GAME_LOAD_NEXT_INSTRUCTION;
00411                         #endif
00412                         return;
00413                      #ifdef ROBOT_SMALL   
00414                     } else if (tempo == 2) {
00415                         // on est dans le cas de l'avance selon le telemetre
00416                         waitingAckID = ASSERVISSEMENT_RECALAGE;
00417                         waitingAckFrom = ACKNOWLEDGE_MOTEUR;
00418                         
00419                         localData2 = (((instruction.direction == FORWARD)?1:-1)*instruction.arg1);
00420                         GoStraight(telemetreDistance, 0, 0, 0);
00421                         // on reset la distance du telemetre à 0
00422                         telemetreDistance = 5000;
00423                         #endif
00424                     }else{
00425                         //C'est un AX12 qu'il faut bouger
00426                         //AX12_setGoal(instruction.arg1,instruction.arg3/10,instruction.arg2);
00427                         //AX12_enchainement++;
00428                                                 
00429                     }
00430                 break;
00431                 default:
00432                     //Instruction inconnue, on l'ignore
00433                 break;
00434             }    
00435             
00436             
00437             
00438             if(instruction.nextActionType == JUMP || instruction.nextActionType == WAIT) {
00439                 gameEtat = ETAT_GAME_WAIT_ACK;//Il faut attendre que la carte est bien reçu l'acknowledge
00440                 screenChecktry++;//On incrèment le conteur de tentative de 1
00441                 cartesCheker.reset();//On reset le timeOut
00442                 cartesCheker.start();
00443                 if(AX12_enchainement > 0) {
00444                     //AX12_processChange();//Il faut lancer le déplacement des AX12
00445                     //AX12_enchainement = 0;
00446                 }
00447             } else {//C'est un enchainement
00448                 if(instruction.order == MV_LINE){
00449                       gameEtat =  ETAT_GAME_WAIT_ACK;
00450                     
00451                 }else{
00452                     actual_instruction = instruction.nextLineOK;//On indique que l'on va charger l'instruction suivante
00453                     gameEtat = ETAT_GAME_LOAD_NEXT_INSTRUCTION;//C'est un enchainement, on charge directement l'instruction suivante
00454                 }
00455             }
00456             
00457         break;
00458         case ETAT_GAME_WAIT_ACK:
00459             /*
00460             Attente de l'ack de l'instruction
00461             */
00462             if(waitingAckID == 0 && waitingAckFrom == 0) {//Les ack ont été reset, c'est bon on continu
00463             //if(true) {
00464                 cartesCheker.stop();
00465                 if(instruction.nextActionType == JUMP) {
00466                     if(instruction.jumpAction == JUMP_POSITION) {
00467                         gameEtat = ETAT_GAME_JUMP_POSITION;
00468                     } else {//Pour eviter les erreurs, on dit que c'est par défaut un jump time
00469                         gameEtat = ETAT_GAME_JUMP_TIME;
00470                         cartesCheker.reset();//On reset le timeOut
00471                         cartesCheker.start();  
00472                     }
00473                 } else if(instruction.nextActionType == WAIT) {
00474                     gameEtat = ETAT_GAME_WAIT_END_INSTRUCTION;
00475                      switch(instruction.order)
00476                     {
00477                         case MV_COURBURE:
00478                             waitingAckID = ASSERVISSEMENT_COURBURE;
00479                             waitingAckFrom = INSTRUCTION_END_MOTEUR;
00480                         break;
00481                         case MV_LINE:
00482                             waitingAckID = ASSERVISSEMENT_RECALAGE;
00483                             waitingAckFrom = INSTRUCTION_END_MOTEUR;
00484                         break;
00485                         case MV_TURN:
00486                             waitingAckID = ASSERVISSEMENT_ROTATION;
00487                             waitingAckFrom = INSTRUCTION_END_MOTEUR;
00488                         break;
00489                         case MV_XYT:
00490                             waitingAckID = ASSERVISSEMENT_XYT;
00491                             waitingAckFrom = INSTRUCTION_END_MOTEUR;
00492                         break;
00493                         case MV_RECALAGE:
00494                             waitingAckID = ASSERVISSEMENT_RECALAGE;
00495                             waitingAckFrom = INSTRUCTION_END_MOTEUR;
00496                         break;
00497                         case ACTION:
00498                             
00499                             if (modeTelemetre == 0){
00500                                 if (telemetreDistance == 0){
00501                                     waitingAckID = SERVO_AX12_ACTION;// instruction.arg1;  
00502                                     waitingAckFrom = INSTRUCTION_END_AX12; //SERVO_AX12_DONE;
00503                                 }else if(telemetreDistance == 5000){
00504                                     // on est dans le cas ou l'on fait une ligne suivant la distance du telemetre
00505                                     waitingAckID = ASSERVISSEMENT_RECALAGE;
00506                                     waitingAckFrom = INSTRUCTION_END_MOTEUR;
00507                                     telemetreDistance = 0;
00508                                 }
00509                             }else{ // si on attend la reponse du telemetre  
00510                                 //modeTelemetre = 1; 
00511                                 waitingAckID = OBJET_SUR_TABLE;
00512                                 waitingAckFrom = 0; 
00513                             }
00514                         break;
00515                         default:
00516                         break;
00517                     }   
00518                 } else {
00519                     gameEtat = ETAT_GAME_LOAD_NEXT_INSTRUCTION;
00520                     actual_instruction = instruction.nextLineOK;//On indique que l'on va charger l'instruction suivante
00521                 }
00522             } else if(cartesCheker.read_ms () > 50){
00523                 cartesCheker.stop();
00524                 if(screenChecktry >=2) {//La carte n'a pas reçus l'information, on passe à l'instruction d'erreur
00525                     actual_instruction = instruction.nextLineError;
00526                     gameEtat = ETAT_GAME_LOAD_NEXT_INSTRUCTION;
00527                 } else {
00528                     gameEtat = ETAT_GAME_PROCESS_INSTRUCTION;//On retourne dans l'etat d'envois de l'instruction
00529                 }
00530             }
00531         break;
00532         
00533         case ETAT_GAME_JUMP_TIME:
00534             if(cartesCheker.read_ms () >= instruction.JumpTimeOrX) {
00535                 cartesCheker.stop();//On arrete le timer
00536                 actual_instruction = instruction.nextLineOK;//On indique que l'on va charger l'instruction suivante
00537                 gameEtat = ETAT_GAME_LOAD_NEXT_INSTRUCTION;//On charge l'instruction suivante
00538             }
00539         break;
00540         
00541         case ETAT_GAME_JUMP_CONFIG:
00542             signed int depasX = 1, depasY = 1;  // servent à indiquer le sens de dépassement des coordonnées
00543                                                 //  1 si l'instruction est plus grande que la position du robot
00544                                                 // -1 si l'instruction est plus petite que la position du robot
00545                                                 //  0 si l'instruction et position du robot sont proche de moins de 1cm
00546             if (abs(x_robot-instruction.JumpTimeOrX)<10){
00547                     depasX = 0;
00548             }else if(x_robot > instruction.JumpTimeOrX){
00549                     depasX = -1;
00550             }
00551             
00552             if(abs(y_robot-instruction.JumpY)<10){
00553                     depasY = 0;
00554             }else if(y_robot > instruction.JumpY){
00555                     depasY = -1;
00556             }
00557                 
00558             gameEtat = ETAT_GAME_JUMP_POSITION;
00559         break;
00560         case ETAT_GAME_JUMP_POSITION:
00561             bool Xok = false, Yok = false;
00562              
00563                 if (depasX == 0){
00564                     Xok = true;    
00565                 }else if ((instruction.JumpTimeOrX - x_robot)*depasX < -5){
00566                     Xok = true;
00567                 }
00568                 
00569                 if (depasY == 0){
00570                     Yok = true;    
00571                 }else if ((instruction.JumpY - y_robot)*depasY < -5){
00572                     Yok = true;
00573                 }
00574                 
00575                 // on teste si les deux coordonnées ont été dépassées, si oui on lance l'instruction suivante
00576                 if (Xok && Yok){
00577                         actual_instruction = instruction.nextLineOK;//On indique que l'on va charger l'instruction suivante
00578                         gameEtat = ETAT_GAME_LOAD_NEXT_INSTRUCTION;//On charge l'instruction suivante
00579                     }
00580                 
00581         break;
00582         case ETAT_GAME_WAIT_END_INSTRUCTION:
00583             if(waitingAckID == 0 && waitingAckFrom ==0) {//On attend que la carte nous indique que l'instruction est terminée
00584                 actual_instruction = instruction.nextLineOK;//On indique que l'on va charger l'instruction suivante
00585                 gameEtat = ETAT_GAME_LOAD_NEXT_INSTRUCTION;//On charge l'instruction suivante
00586             }
00587         break;
00588         
00589         
00590         case ETAT_WARNING_TIMEOUT://Attente de la trame fin de danger ou du timeout de 2s
00591             if(timeoutWarning.read_ms() >= BALISE_TIMEOUT)//ça fait plus de 2s, il faut changer de stratégie
00592             {
00593                 gameEtat = ETAT_WARNING_SWITCH_STRATEGIE;
00594             }
00595         break;
00596         case ETAT_WARING_END_BALISE_WAIT://Attente d'une seconde apres la fin d'un End Balise pour etre sur que c'est bon
00597             if(timeoutWarningWaitEnd.read_ms() >= 1000) {//c'est bon, on repart
00598                 //actual_instruction = instruction.nextLineError;
00599                 gameEtat = ETAT_WARNING_END_LAST_INSTRUCTION;
00600             }
00601         break;
00602         case ETAT_WARNING_END_LAST_INSTRUCTION://trouver le meilleur moyen de reprendre l'instruction en cours
00603 #ifdef ROBOT_BIG
00604             actual_instruction = instruction.nextLineError;//  2 //Modification directe... c'est pas bien mais ça marchait pour le match 5
00605             gameEtat = ETAT_GAME_LOAD_NEXT_INSTRUCTION;
00606 #else       
00607             actual_instruction = instruction.nextLineError;
00608             gameEtat = ETAT_GAME_LOAD_NEXT_INSTRUCTION; 
00609 #endif      
00610             gameEtat = ETAT_END;
00611         break;
00612         case ETAT_WARNING_SWITCH_STRATEGIE://Si à la fin du timeout il y a toujours un robot, passer à l'instruction d'erreur
00613             actual_instruction = instruction.nextLineError;
00614             gameEtat = ETAT_GAME_LOAD_NEXT_INSTRUCTION;
00615             ingnorBaliseOnce = 1;
00616         break;
00617             
00618             
00619             
00620         case ETAT_END: 
00621             if (ModeDemo){
00622                 gameEtat = ETAT_CHECK_CARTE_SCREEN;
00623                 ModeDemo = 1;
00624             } else {
00625                 gameEtat = ETAT_END_LOOP;
00626             }
00627         break;
00628         case ETAT_END_LOOP:
00629             //Rien, on tourne en rond
00630             
00631         break;
00632         default:
00633             
00634         break;
00635     }       
00636 }           
00637             
00638 /****************************************************************************************/
00639 /* FUNCTION NAME: canProcessRx                                                          */
00640 /* DESCRIPTION  : Fonction de traitement des messages CAN                               */
00641 /****************************************************************************************/
00642 void canProcessRx(void)
00643 {           
00644     static signed char FIFO_occupation=0,FIFO_max_occupation=0;
00645     CANMessage msgTx=CANMessage();
00646     FIFO_occupation=FIFO_ecriture-FIFO_lecture;
00647     if(FIFO_occupation<0)
00648         FIFO_occupation=FIFO_occupation+SIZE_FIFO;
00649     if(FIFO_max_occupation<FIFO_occupation)
00650         FIFO_max_occupation=FIFO_occupation;
00651     if(FIFO_occupation!=0) {
00652         
00653         switch(msgRxBuffer[FIFO_lecture].id) {
00654             case DEBUG_FAKE_JAKE://Permet de lancer le match à distance
00655                 if(gameEtat == ETAT_GAME_WAIT_FOR_JACK) {
00656                     gameEtat = ETAT_GAME_START;
00657                 }
00658             break;
00659             
00660             case ALIVE_BALISE:
00661             case ALIVE_MOTEUR:
00662             case ALIVE_IHM:
00663             case ALIVE_ACTIONNEURS:
00664             case ALIVE_POMPES:
00665             case ALIVE_AX12:
00666             case ECRAN_ALL_CHECK:
00667                 if(waitingAckFrom == msgRxBuffer[FIFO_lecture].id) {
00668                     waitingAckFrom = 0;//C'est la bonne carte qui indique qu'elle est en ligne
00669                 }
00670             break; 
00671             
00672             case ACKNOWLEDGE_BALISE:
00673             case ACKNOWLEDGE_MOTEUR:
00674             case ACKNOWLEDGE_IHM:
00675             case ACKNOWLEDGE_TELEMETRE:
00676             case ACKNOWLEDGE_AX12:
00677             case INSTRUCTION_END_BALISE:
00678             case INSTRUCTION_END_MOTEUR:
00679             case INSTRUCTION_END_IHM:
00680             case INSTRUCTION_END_AX12:
00681                 
00682                 if(waitingAckFrom == msgRxBuffer[FIFO_lecture].id && ((unsigned short)msgRxBuffer[FIFO_lecture].data[0]|((unsigned short)(msgRxBuffer[FIFO_lecture].data[1])<<8) == waitingAckID)) {
00683                     waitingAckFrom = 0;
00684                     waitingAckID = 0;
00685                 }
00686             break;
00687 #ifdef ROBOT_BIG
00688             case ODOMETRIE_BIG_POSITION:
00689 #else
00690             case ODOMETRIE_SMALL_POSITION:
00691 #endif
00692                 x_robot=msgRxBuffer[FIFO_lecture].data[0]|((unsigned short)(msgRxBuffer[FIFO_lecture].data[1])<<8);
00693                 y_robot=msgRxBuffer[FIFO_lecture].data[2]|((unsigned short)(msgRxBuffer[FIFO_lecture].data[3])<<8);
00694                 theta_robot=msgRxBuffer[FIFO_lecture].data[4]|((signed short)(msgRxBuffer[FIFO_lecture].data[5])<<8);
00695             break;
00696             
00697             case ECRAN_START_MATCH:
00698                 if(gameEtat == ETAT_CONFIG) {
00699                     gameEtat = ETAT_GAME_INIT;
00700                 }
00701             break;
00702             case SERVO_AX12_SETGOAL:
00703                 //SendAck(0x114, SERVO_AX12_SETGOAL);
00704                 //if(AX12_isLocal(msgRxBuffer[FIFO_lecture].data[0]))
00705                     //AX12_setGoal(msgRxBuffer[FIFO_lecture].data[0], msgRxBuffer[FIFO_lecture].data[1]|((unsigned short)(msgRxBuffer[FIFO_lecture].data[2])<<8), msgRxBuffer[FIFO_lecture].data[3]|((unsigned short)(msgRxBuffer[FIFO_lecture].data[4])<<8));
00706                   
00707             break;
00708             
00709             case SERVO_AX12_PROCESS:
00710                 SendAck(0x114, SERVO_AX12_PROCESS);
00711                 //AX12_processChange(1);
00712             break;
00713             
00714             case SERVO_AX12_DONE:
00715                 SendRawId(POMPE_PWM);
00716                 /*//SendAck(0x114, SERVO_AX12_DONE);
00717                 AX12_notifyCANEnd(((unsigned short)(msgRxBuffer[FIFO_lecture].data[0])));
00718                 
00719                 gameEtat = ETAT_GAME_LOAD_NEXT_INSTRUCTION;
00720                 waitingAckFrom = 0;
00721                 waitingAckID = 0;*/
00722                 
00723             break;
00724             case ECRAN_CHOICE_COLOR://Choix de la couleur
00725                 if(gameEtat == ETAT_CONFIG) {//C'est bon on a le droit de modifier les config
00726                     if(msgRxBuffer[FIFO_lecture].data[0] == 0)
00727                         InversStrat = 0;//Pas d'inversion de la couleur
00728                     else
00729                         InversStrat = 1;//Inversion de la couleur
00730                         
00731                     msgTx.id=ECRAN_ACK_COLOR; // tx ack de la couleur
00732                     msgTx.len=1;
00733                     msgTx.format=CANStandard;
00734                     msgTx.type=CANData;
00735                     // couleur sur 1 octet
00736                     msgTx.data[0]=msgRxBuffer[FIFO_lecture].data[0];
00737                     can1.write(msgTx);
00738                     
00739                 }
00740             break;
00741             
00742             case ECRAN_CHOICE_STRAT://Choix du fichier de stratégie à utiliser
00743                 if(gameEtat == ETAT_CONFIG) {//C'est bon on a le droit de modifier les config
00744                     msgTx.id=ECRAN_ACK_STRAT; // tx ack de la couleur
00745                     msgTx.len=1;
00746                     msgTx.format=CANStandard;
00747                     msgTx.type=CANData;
00748                     if(SelectStrategy(msgRxBuffer[FIFO_lecture].data[0])) {
00749                         // id de la stratégie sur 1 octet
00750                         if (msgRxBuffer[FIFO_lecture].data[0] < 0x10){  // Si la strat est une strat de match, on desactive le mode demo
00751                                 ModeDemo = 0;
00752                         } else {                                        // sinon, on active le mode demo, utile pour la fin de la demo
00753                                 ModeDemo = 1;
00754                         }
00755                         
00756                         msgTx.data[0]=msgRxBuffer[FIFO_lecture].data[0];
00757                     } else {
00758                         //erreur sur 1 octet
00759                         msgTx.data[0]=0;
00760                     }
00761                     can1.write(msgTx);
00762                     wait_ms(10);
00763                     setAsservissementEtat(0);//Désactivation de l'asservissement pour repositionner le robot dans le zone de départ
00764                     tactile_printf("Strat %d, Asser desactive",msgTx.data[0]);
00765                 }
00766             break;
00767             case BALISE_DANGER :
00768                 SendAck(ACKNOWLEDGE_BALISE, BALISE_END_DANGER);
00769             break;
00770             
00771             case BALISE_STOP:
00772                 SendAck(ACKNOWLEDGE_BALISE, BALISE_STOP);
00773                 //if (instruction[actual_instruction].order != MV_TURN){ //J'ai rajouté cette ligne mais il faut tester avec et sans pour voir le comportement du robot, 
00774                     if(needToStop() != 0 && ingnorBaliseOnce ==0) {
00775                         if(gameEtat > ETAT_GAME_START && gameEtat != ETAT_WARNING_TIMEOUT)
00776                         {
00777                             SendRawId(ASSERVISSEMENT_STOP);
00778                             //while(1);
00779                             gameEtat = ETAT_WARNING_TIMEOUT;
00780                             if(gameEtat != ETAT_WARING_END_BALISE_WAIT) {
00781                                 timeoutWarning.reset();
00782                                 timeoutWarning.start();//Reset du timer utiliser par le timeout
00783                             }
00784                         }
00785                     }
00786                 //}
00787                 ingnorBaliseOnce = 0;
00788             break;
00789             
00790             case BALISE_END_DANGER:
00791                 SendAck(ACKNOWLEDGE_BALISE, BALISE_END_DANGER);
00792                 if(gameEtat == ETAT_WARNING_TIMEOUT) {
00793                     timeoutWarningWaitEnd.reset();
00794                     timeoutWarningWaitEnd.start();
00795                     gameEtat = ETAT_WARING_END_BALISE_WAIT;
00796                 }
00797             break;
00798             
00799             case ECRAN_CHOICE_START_ACTION:
00800                 if(gameEtat == ETAT_CONFIG) {//C'est bon on a le droit de modifier les config
00801                     if(msgRxBuffer[FIFO_lecture].data[0] == 1) {
00802                         runRobotTest();
00803                     } else {
00804                         initRobotActionneur();
00805                     }
00806                     wait_ms(500);
00807                     SendRawId(ECRAN_ACK_CHOICE_START_ACTION);
00808                 }
00809             break;
00810             
00811             case OBJET_SUR_TABLE:
00812                 if (msgRxBuffer[FIFO_lecture].data[1] == 0xff){
00813                         
00814                         gameEtat = ETAT_WARNING_END_LAST_INSTRUCTION;
00815                     }
00816                 else{
00817                         
00818                         waitingAckFrom = 0;
00819                         waitingAckID = 0; 
00820                         
00821                         strat_instructions[actual_instruction+1].arg1 = returnX(strat_instructions[actual_instruction].arg2);
00822                         strat_instructions[actual_instruction+1].arg2 = returnY(strat_instructions[actual_instruction].arg2);
00823                     }
00824                 modeTelemetre = 0;
00825             break;
00826         }        
00827         
00828         FIFO_lecture=(FIFO_lecture+1)%SIZE_FIFO;
00829     }
00830 }