homologation gros robot et test avec les ack de la carte a tout faire

Fork of CRAC-Strat_2017_HOMOLOGATION_PETIT_ROBOT 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_BALISE,CHECK_POMPES,CHECK_ACTIONNEURS};
00029 unsigned short id_alive[NOMBRE_CARTES]= {ALIVE_MOTEUR,ALIVE_BALISE,ALIVE_POMPES,ALIVE_ACTIONNEURS};
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             telemetreDistance = 0;
00226         break;
00227         case ETAT_GAME_INIT:
00228             //On charge la liste des instructions
00229             loadAllInstruction();//Mise en cache de toute les instructions
00230             
00231             gameEtat = ETAT_GAME_WAIT_FOR_JACK;
00232             SendRawId(ECRAN_ACK_START_MATCH);
00233             tactile_printf("Attente du JACK.");
00234             setAsservissementEtat(1);//On réactive l'asservissement
00235             jack.mode(PullDown); // désactivation de la résistance interne du jack
00236             jack.fall(&jack_ISR); // création de l'interrupt attachée au changement d'état (front descendant) sur le jack
00237          
00238 #ifdef ROBOT_BIG //le gros robot n'a pas de recalage bordure pour ce placer au début, on lui envoit donc ça position
00239             localData2 = POSITION_DEBUT_T;
00240             localData3 = POSITION_DEBUT_Y;
00241             if(InversStrat == 1) {
00242                 localData2 = -localData2;//Inversion theta
00243                 localData3 = 3000 - POSITION_DEBUT_Y;//Inversion du Y
00244             }
00245             SetOdometrie(ODOMETRIE_BIG_POSITION, POSITION_DEBUT_X,localData3,localData2);
00246 #endif 
00247 #ifdef ROBOT_SMALL
00248             SetOdometrie(ODOMETRIE_SMALL_POSITION, POSITION_DEBUT_X,POSITION_DEBUT_Y,POSITION_DEBUT_T);
00249 #endif
00250         break;
00251         case ETAT_GAME_WAIT_FOR_JACK:
00252             //On attend le jack
00253         break;
00254         case ETAT_GAME_START:
00255             gameEtat = ETAT_GAME_LOAD_NEXT_INSTRUCTION;
00256             
00257             if (ModeDemo == 0){
00258                 chronoEnd.attach(&chronometre_ISR,90);//On lance le chrono de 90s
00259                 gameTimer.start();
00260             } 
00261             gameTimer.reset();
00262             jack.fall(NULL);//On désactive l'interruption du jack
00263             SendRawId(GLOBAL_START);
00264             tactile_printf("Start");//Pas vraiment util mais bon
00265         break;
00266         case ETAT_GAME_LOAD_NEXT_INSTRUCTION:
00267             /*
00268             Chargement de l'instruction suivante ou arret du robot si il n'y a plus d'instruction
00269             */
00270             //printf("load next instruction\n");
00271             
00272             if(actual_instruction >= nb_instructions || actual_instruction == 255) {
00273                 gameEtat = ETAT_END;
00274                 //Il n'y a plus d'instruction, fin du jeu
00275             } else {
00276                 instruction = strat_instructions[actual_instruction];
00277                 //On effectue le traitement de l'instruction 
00278                 gameEtat = ETAT_GAME_PROCESS_INSTRUCTION;
00279             }
00280             screenChecktry = 0;
00281         break;
00282         case ETAT_GAME_PROCESS_INSTRUCTION:
00283             /*
00284             Traitement de l'instruction, envoie de la trame CAN
00285             */
00286             //debug_Instruction(instruction);
00287             switch(instruction.order)
00288             {
00289                 case MV_COURBURE://C'est un rayon de courbure
00290                     waitingAckID = ASSERVISSEMENT_COURBURE;
00291                     waitingAckFrom = ACKNOWLEDGE_MOTEUR;
00292                     if(instruction.nextActionType == ENCHAINEMENT) {
00293                         MV_enchainement++;
00294                         localData5 = 1;
00295                     } else {
00296                         if(MV_enchainement > 0) {
00297                             localData5 = 2;
00298                             MV_enchainement = 0;
00299                         } else {
00300                             localData5 = 0;
00301                         }
00302                     }
00303                     localData1 = ((instruction.direction == LEFT)?1:-1);
00304                     if(InversStrat == 1)
00305                     {
00306                         localData1 = -localData1;//Inversion de la direction
00307                     }
00308                     
00309                     BendRadius(instruction.arg1, instruction.arg3, localData1, localData5);
00310                 break;
00311                 case MV_LINE://Ligne droite
00312                     waitingAckID = ASSERVISSEMENT_RECALAGE;
00313                     waitingAckFrom = ACKNOWLEDGE_MOTEUR;
00314                     if(instruction.nextActionType == ENCHAINEMENT) {
00315                         MV_enchainement++;
00316                         localData5 = 1;
00317                     } else {
00318                         if(MV_enchainement > 0) {//Utilisé en cas d'enchainement, 
00319                             localData5 = 2;
00320                             MV_enchainement = 0;
00321                         } else {
00322                             localData5 = 0;
00323                         }
00324                     }
00325                     #ifdef ROBOT_BIG
00326                     if(InversStrat == 1) {
00327                             /*if (instruction.direction == FORWARD) instruction.direction = BACKWARD;
00328                             else instruction.direction = FORWARD;*/
00329                             instruction.direction = ((instruction.direction == FORWARD)?BACKWARD:FORWARD);
00330                         }
00331                     #endif    
00332                     localData2 = (((instruction.direction == FORWARD)?1:-1)*instruction.arg1);
00333                     GoStraight(localData2, 0, 0, localData5);
00334                     
00335                 break;
00336                 case MV_TURN: //Rotation sur place
00337                     if(instruction.direction == RELATIVE) {
00338                         localData2 = instruction.arg3;
00339                     } else {//C'est un rotation absolu, il faut la convertir en relative
00340                         localData2 = instruction.arg3;
00341                         
00342                         if(InversStrat == 1) {
00343                             localData2 = -localData2;
00344                         }
00345                         
00346                         localData2 = (localData2 - theta_robot)%3600;
00347                         if(localData2 > 1800) {
00348                             localData2 = localData2-3600;
00349                         }
00350                         
00351                     }
00352                     
00353                     Rotate(localData2);
00354                     waitingAckID = ASSERVISSEMENT_ROTATION;
00355                     waitingAckFrom = ACKNOWLEDGE_MOTEUR;
00356                 break;
00357                 case MV_XYT:
00358                     if(instruction.direction == BACKWARD) {
00359                         localData1 = -1;
00360                     } else {
00361                         localData1 = 1;
00362                     }
00363                     
00364                     if(InversStrat == 1) {
00365                         localData2 = -instruction.arg3;
00366                         localData3 = 3000 - instruction.arg2;//Inversion du Y
00367                     } else {
00368                         localData3 = instruction.arg2;
00369                         localData2 = instruction.arg3;
00370                     }
00371                     GoToPosition(instruction.arg1,localData3,localData2,localData1);
00372                     waitingAckID = ASSERVISSEMENT_XYT;
00373                     waitingAckFrom = ACKNOWLEDGE_MOTEUR;
00374                 break;
00375                 case MV_RECALAGE:
00376                     waitingAckID = ASSERVISSEMENT_RECALAGE;
00377                     waitingAckFrom = ACKNOWLEDGE_MOTEUR;
00378                     instruction.nextActionType = WAIT;
00379                     localData2 = (((instruction.direction == FORWARD)?1:-1)*3000);//On indique une distance de 3000 pour etre sur que le robot va ce recaler
00380                     
00381                     if(instruction.precision == RECALAGE_Y) {
00382                         localData5 = 2;
00383                         if(InversStrat == 1) {
00384                             localData3 = 3000 - instruction.arg1;//Inversion du Y
00385                         } else {
00386                             localData3 = instruction.arg1;
00387                         }
00388                     } else {
00389                         localData5 = 1;
00390                         localData3 = instruction.arg1;
00391                     }
00392                     
00393                     GoStraight(localData2, localData5, localData3, 0);
00394                 break;
00395                 case ACTION:
00396                     int tempo = 0;
00397                     waitingAckID= SERVO_AX12_ACTION;
00398                     waitingAckFrom = ACKNOWLEDGE_AX12;
00399                     tempo = doAction(instruction.arg1,instruction.arg2,instruction.arg3);
00400                     if(tempo == 1){
00401                         //L'action est spécifique
00402                         if((waitingAckFrom == 0 && waitingAckID == 0) || instruction.nextActionType == ENCHAINEMENT) {
00403                             
00404                             actual_instruction = instruction.nextLineOK;//On indique que l'on va charger l'instruction suivante
00405                             gameEtat = ETAT_GAME_LOAD_NEXT_INSTRUCTION;
00406                         } else {
00407                             gameEtat = ETAT_GAME_WAIT_ACK;
00408                         }
00409                         #ifdef ROBOT_SMALL
00410                             actual_instruction = instruction.nextLineOK;//On indique que l'on va charger l'instruction suivante
00411                             gameEtat = ETAT_GAME_LOAD_NEXT_INSTRUCTION;
00412                         #endif
00413                         return;
00414                        
00415                     } else if (tempo == 2) {
00416                     #ifdef ROBOT_SMALL 
00417                         // on est dans le cas de l'avance selon le telemetre
00418                         waitingAckID = ASSERVISSEMENT_RECALAGE;
00419                         waitingAckFrom = ACKNOWLEDGE_MOTEUR;
00420                         
00421                         localData2 = (((instruction.direction == FORWARD)?1:-1)*instruction.arg1);
00422                         GoStraight(telemetreDistance, 0, 0, 0);
00423                         // on reset la distance du telemetre à 0
00424                         telemetreDistance = 5000;
00425                     #endif
00426                     }else{
00427                         //C'est un AX12 qu'il faut bouger
00428                         //AX12_setGoal(instruction.arg1,instruction.arg3/10,instruction.arg2);
00429                         //AX12_enchainement++;
00430                                                 
00431                     }
00432                 break;
00433                 default:
00434                     //Instruction inconnue, on l'ignore
00435                 break;
00436             }    
00437             
00438             
00439             
00440             if(instruction.nextActionType == JUMP || instruction.nextActionType == WAIT) {
00441                 gameEtat = ETAT_GAME_WAIT_ACK;//Il faut attendre que la carte est bien reçu l'acknowledge
00442                 screenChecktry++;//On incrèment le conteur de tentative de 1
00443                 cartesCheker.reset();//On reset le timeOut
00444                 cartesCheker.start();
00445                 if(AX12_enchainement > 0) {
00446                     //AX12_processChange();//Il faut lancer le déplacement des AX12
00447                     //AX12_enchainement = 0;
00448                 }
00449             } else {//C'est un enchainement
00450                 if(instruction.order == MV_LINE){
00451                       gameEtat =  ETAT_GAME_WAIT_ACK;
00452                     
00453                 }else{
00454                     actual_instruction = instruction.nextLineOK;//On indique que l'on va charger l'instruction suivante
00455                     gameEtat = ETAT_GAME_LOAD_NEXT_INSTRUCTION;//C'est un enchainement, on charge directement l'instruction suivante
00456                 }
00457             }
00458             
00459         break;
00460         case ETAT_GAME_WAIT_ACK:
00461             /*
00462             Attente de l'ack de l'instruction
00463             */
00464             if(waitingAckID == 0 && waitingAckFrom == 0) {//Les ack ont été reset, c'est bon on continu
00465             //if(true) {
00466                 cartesCheker.stop();
00467                 if(instruction.nextActionType == JUMP) {
00468                     if(instruction.jumpAction == JUMP_POSITION) {
00469                         gameEtat = ETAT_GAME_JUMP_POSITION;
00470                     } else {//Pour eviter les erreurs, on dit que c'est par défaut un jump time
00471                         gameEtat = ETAT_GAME_JUMP_TIME;
00472                         cartesCheker.reset();//On reset le timeOut
00473                         cartesCheker.start();  
00474                     }
00475                 } else if(instruction.nextActionType == WAIT) {
00476                     gameEtat = ETAT_GAME_WAIT_END_INSTRUCTION;
00477                      switch(instruction.order)
00478                     {
00479                         case MV_COURBURE:
00480                             waitingAckID = ASSERVISSEMENT_COURBURE;
00481                             waitingAckFrom = INSTRUCTION_END_MOTEUR;
00482                         break;
00483                         case MV_LINE:
00484                             waitingAckID = ASSERVISSEMENT_RECALAGE;
00485                             waitingAckFrom = INSTRUCTION_END_MOTEUR;
00486                         break;
00487                         case MV_TURN:
00488                             waitingAckID = ASSERVISSEMENT_ROTATION;
00489                             waitingAckFrom = INSTRUCTION_END_MOTEUR;
00490                         break;
00491                         case MV_XYT:
00492                             waitingAckID = ASSERVISSEMENT_XYT;
00493                             waitingAckFrom = INSTRUCTION_END_MOTEUR;
00494                         break;
00495                         case MV_RECALAGE:
00496                             waitingAckID = ASSERVISSEMENT_RECALAGE;
00497                             waitingAckFrom = INSTRUCTION_END_MOTEUR;
00498                         break;
00499                         case ACTION:
00500                             
00501                             if (modeTelemetre == 0){
00502                                 if (telemetreDistance == 0){
00503                                     waitingAckID = SERVO_AX12_ACTION;// instruction.arg1;  
00504                                     waitingAckFrom = INSTRUCTION_END_AX12; //SERVO_AX12_DONE;
00505                                 }else if(telemetreDistance == 5000){
00506                                     // on est dans le cas ou l'on fait une ligne suivant la distance du telemetre
00507                                     waitingAckID = ASSERVISSEMENT_RECALAGE;
00508                                     waitingAckFrom = INSTRUCTION_END_MOTEUR;
00509                                     telemetreDistance = 0;
00510                                 }
00511                             }else{ // si on attend la reponse du telemetre  
00512                                 //modeTelemetre = 1; 
00513                                 waitingAckID = OBJET_SUR_TABLE;
00514                                 waitingAckFrom = 0; 
00515                             }
00516                         break;
00517                         default:
00518                         break;
00519                     }   
00520                 } else {
00521                     gameEtat = ETAT_GAME_LOAD_NEXT_INSTRUCTION;
00522                     actual_instruction = instruction.nextLineOK;//On indique que l'on va charger l'instruction suivante
00523                 }
00524             } else if(cartesCheker.read_ms () > 50){
00525                 cartesCheker.stop();
00526                 if(screenChecktry >=2) {//La carte n'a pas reçus l'information, on passe à l'instruction d'erreur
00527                     actual_instruction = instruction.nextLineError;
00528                     gameEtat = ETAT_GAME_LOAD_NEXT_INSTRUCTION;
00529                 } else {
00530                     gameEtat = ETAT_GAME_PROCESS_INSTRUCTION;//On retourne dans l'etat d'envois de l'instruction
00531                 }
00532             }
00533         break;
00534         
00535         case ETAT_GAME_JUMP_TIME:
00536             if(cartesCheker.read_ms () >= instruction.JumpTimeOrX) {
00537                 cartesCheker.stop();//On arrete le timer
00538                 actual_instruction = instruction.nextLineOK;//On indique que l'on va charger l'instruction suivante
00539                 gameEtat = ETAT_GAME_LOAD_NEXT_INSTRUCTION;//On charge l'instruction suivante
00540             }
00541         break;
00542         
00543         case ETAT_GAME_JUMP_CONFIG:
00544             signed int depasX = 1, depasY = 1;  // servent à indiquer le sens de dépassement des coordonnées
00545                                                 //  1 si l'instruction est plus grande que la position du robot
00546                                                 // -1 si l'instruction est plus petite que la position du robot
00547                                                 //  0 si l'instruction et position du robot sont proche de moins de 1cm
00548             if (abs(x_robot-instruction.JumpTimeOrX)<10){
00549                     depasX = 0;
00550             }else if(x_robot > instruction.JumpTimeOrX){
00551                     depasX = -1;
00552             }
00553             
00554             if(abs(y_robot-instruction.JumpY)<10){
00555                     depasY = 0;
00556             }else if(y_robot > instruction.JumpY){
00557                     depasY = -1;
00558             }
00559                 
00560             gameEtat = ETAT_GAME_JUMP_POSITION;
00561         break;
00562         case ETAT_GAME_JUMP_POSITION:
00563             bool Xok = false, Yok = false;
00564              
00565                 if (depasX == 0){
00566                     Xok = true;    
00567                 }else if ((instruction.JumpTimeOrX - x_robot)*depasX < -5){
00568                     Xok = true;
00569                 }
00570                 
00571                 if (depasY == 0){
00572                     Yok = true;    
00573                 }else if ((instruction.JumpY - y_robot)*depasY < -5){
00574                     Yok = true;
00575                 }
00576                 
00577                 // on teste si les deux coordonnées ont été dépassées, si oui on lance l'instruction suivante
00578                 if (Xok && Yok){
00579                         actual_instruction = instruction.nextLineOK;//On indique que l'on va charger l'instruction suivante
00580                         gameEtat = ETAT_GAME_LOAD_NEXT_INSTRUCTION;//On charge l'instruction suivante
00581                     }
00582                 
00583         break;
00584         case ETAT_GAME_WAIT_END_INSTRUCTION:
00585             if(waitingAckID == 0 && waitingAckFrom ==0) {//On attend que la carte nous indique que l'instruction est terminée
00586                 actual_instruction = instruction.nextLineOK;//On indique que l'on va charger l'instruction suivante
00587                 gameEtat = ETAT_GAME_LOAD_NEXT_INSTRUCTION;//On charge l'instruction suivante
00588             }
00589         break;
00590         
00591         
00592         case ETAT_WARNING_TIMEOUT://Attente de la trame fin de danger ou du timeout de 2s
00593             if(timeoutWarning.read_ms() >= BALISE_TIMEOUT)//ça fait plus de 2s, il faut changer de stratégie
00594             {
00595                 gameEtat = ETAT_WARNING_SWITCH_STRATEGIE;
00596             }
00597         break;
00598         case ETAT_WARING_END_BALISE_WAIT://Attente d'une seconde apres la fin d'un End Balise pour etre sur que c'est bon
00599             if(timeoutWarningWaitEnd.read_ms() >= 1000) {//c'est bon, on repart
00600                 //actual_instruction = instruction.nextLineError;
00601                 gameEtat = ETAT_WARNING_END_LAST_INSTRUCTION;
00602             }
00603         break;
00604         case ETAT_WARNING_END_LAST_INSTRUCTION://trouver le meilleur moyen de reprendre l'instruction en cours
00605 #ifdef ROBOT_BIG
00606             actual_instruction = instruction.nextLineError;//  2 //Modification directe... c'est pas bien mais ça marchait pour le match 5
00607             gameEtat = ETAT_GAME_LOAD_NEXT_INSTRUCTION;
00608 #else       
00609             actual_instruction = instruction.nextLineError;
00610             gameEtat = ETAT_GAME_LOAD_NEXT_INSTRUCTION; 
00611 #endif      
00612             gameEtat = ETAT_END;
00613         break;
00614         case ETAT_WARNING_SWITCH_STRATEGIE://Si à la fin du timeout il y a toujours un robot, passer à l'instruction d'erreur
00615             actual_instruction = instruction.nextLineError;
00616             gameEtat = ETAT_GAME_LOAD_NEXT_INSTRUCTION;
00617             ingnorBaliseOnce = 1;
00618         break;
00619             
00620             
00621             
00622         case ETAT_END: 
00623             if (ModeDemo){
00624                 gameEtat = ETAT_CHECK_CARTE_SCREEN;
00625                 ModeDemo = 1;
00626             } else {
00627                 gameEtat = ETAT_END_LOOP;
00628             }
00629         break;
00630         case ETAT_END_LOOP:
00631             //Rien, on tourne en rond
00632             
00633         break;
00634         default:
00635             
00636         break;
00637     }       
00638 }           
00639             
00640 /****************************************************************************************/
00641 /* FUNCTION NAME: canProcessRx                                                          */
00642 /* DESCRIPTION  : Fonction de traitement des messages CAN                               */
00643 /****************************************************************************************/
00644 void canProcessRx(void)
00645 {           
00646     static signed char FIFO_occupation=0,FIFO_max_occupation=0;
00647     CANMessage msgTx=CANMessage();
00648     FIFO_occupation=FIFO_ecriture-FIFO_lecture;
00649     if(FIFO_occupation<0)
00650         FIFO_occupation=FIFO_occupation+SIZE_FIFO;
00651     if(FIFO_max_occupation<FIFO_occupation)
00652         FIFO_max_occupation=FIFO_occupation;
00653     if(FIFO_occupation!=0) {
00654         
00655         switch(msgRxBuffer[FIFO_lecture].id) {
00656             case DEBUG_FAKE_JAKE://Permet de lancer le match à distance
00657             case GLOBAL_JACK:
00658                 if(gameEtat == ETAT_GAME_WAIT_FOR_JACK) {
00659                     gameEtat = ETAT_GAME_START;
00660                     SendRawId(ACKNOWLEDGE_JACK);
00661                 }
00662             break;
00663             
00664             case ALIVE_BALISE:
00665             case ALIVE_MOTEUR:
00666             case ALIVE_IHM:
00667             case ALIVE_ACTIONNEURS:
00668             case ALIVE_POMPES:
00669             case ALIVE_AX12:
00670             case ECRAN_ALL_CHECK:
00671                 if(waitingAckFrom == msgRxBuffer[FIFO_lecture].id) {
00672                     waitingAckFrom = 0;//C'est la bonne carte qui indique qu'elle est en ligne
00673                 }
00674             break; 
00675             
00676             case ACKNOWLEDGE_BALISE:
00677             case ACKNOWLEDGE_MOTEUR:
00678             case ACKNOWLEDGE_IHM:
00679             case ACKNOWLEDGE_TELEMETRE:
00680             case ACKNOWLEDGE_AX12:
00681             case INSTRUCTION_END_BALISE:
00682             case INSTRUCTION_END_MOTEUR:
00683             case INSTRUCTION_END_IHM:
00684             case INSTRUCTION_END_AX12:
00685                 
00686                 if(waitingAckFrom == msgRxBuffer[FIFO_lecture].id && ((unsigned short)msgRxBuffer[FIFO_lecture].data[0]|((unsigned short)(msgRxBuffer[FIFO_lecture].data[1])<<8) == waitingAckID)) {
00687                     waitingAckFrom = 0;
00688                     waitingAckID = 0;
00689                 }
00690             break;
00691 #ifdef ROBOT_BIG
00692             case ODOMETRIE_BIG_POSITION:
00693 #else
00694             case ODOMETRIE_SMALL_POSITION:
00695 #endif
00696                 x_robot=msgRxBuffer[FIFO_lecture].data[0]|((unsigned short)(msgRxBuffer[FIFO_lecture].data[1])<<8);
00697                 y_robot=msgRxBuffer[FIFO_lecture].data[2]|((unsigned short)(msgRxBuffer[FIFO_lecture].data[3])<<8);
00698                 theta_robot=msgRxBuffer[FIFO_lecture].data[4]|((signed short)(msgRxBuffer[FIFO_lecture].data[5])<<8);
00699             break;
00700             
00701             case ECRAN_START_MATCH:
00702                 if(gameEtat == ETAT_CONFIG) {
00703                     gameEtat = ETAT_GAME_INIT;
00704                 }
00705             break;
00706             case SERVO_AX12_SETGOAL:
00707                 //SendAck(0x114, SERVO_AX12_SETGOAL);
00708                 //if(AX12_isLocal(msgRxBuffer[FIFO_lecture].data[0]))
00709                     //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));
00710                   
00711             break;
00712             
00713             case SERVO_AX12_PROCESS:
00714                 SendAck(0x114, SERVO_AX12_PROCESS);
00715                 //AX12_processChange(1);
00716             break;
00717             
00718             case SERVO_AX12_DONE:
00719                 SendRawId(POMPE_PWM);
00720                 /*//SendAck(0x114, SERVO_AX12_DONE);
00721                 AX12_notifyCANEnd(((unsigned short)(msgRxBuffer[FIFO_lecture].data[0])));
00722                 
00723                 gameEtat = ETAT_GAME_LOAD_NEXT_INSTRUCTION;
00724                 waitingAckFrom = 0;
00725                 waitingAckID = 0;*/
00726                 
00727             break;
00728             case ECRAN_CHOICE_COLOR://Choix de la couleur
00729                 if(gameEtat == ETAT_CONFIG) {//C'est bon on a le droit de modifier les config
00730                     if(msgRxBuffer[FIFO_lecture].data[0] == 0)
00731                         InversStrat = 0;//Pas d'inversion de la couleur
00732                     else
00733                         InversStrat = 1;//Inversion de la couleur
00734                         
00735                     msgTx.id=ECRAN_ACK_COLOR; // tx ack de la couleur
00736                     msgTx.len=1;
00737                     msgTx.format=CANStandard;
00738                     msgTx.type=CANData;
00739                     // couleur sur 1 octet
00740                     msgTx.data[0]=msgRxBuffer[FIFO_lecture].data[0];
00741                     can1.write(msgTx);
00742                     
00743                 }
00744             break;
00745             
00746             case ECRAN_CHOICE_STRAT://Choix du fichier de stratégie à utiliser
00747                 if(gameEtat == ETAT_CONFIG) {//C'est bon on a le droit de modifier les config
00748                     msgTx.id=ECRAN_ACK_STRAT; // tx ack de la couleur
00749                     msgTx.len=1;
00750                     msgTx.format=CANStandard;
00751                     msgTx.type=CANData;
00752                     if(SelectStrategy(msgRxBuffer[FIFO_lecture].data[0])) {
00753                         // id de la stratégie sur 1 octet
00754                         if (msgRxBuffer[FIFO_lecture].data[0] < 0x10){  // Si la strat est une strat de match, on desactive le mode demo
00755                                 ModeDemo = 0;
00756                         } else {                                        // sinon, on active le mode demo, utile pour la fin de la demo
00757                                 ModeDemo = 1;
00758                         }
00759                         
00760                         msgTx.data[0]=msgRxBuffer[FIFO_lecture].data[0];
00761                     } else {
00762                         //erreur sur 1 octet
00763                         msgTx.data[0]=0;
00764                     }
00765                     can1.write(msgTx);
00766                     wait_ms(10);
00767                     setAsservissementEtat(0);//Désactivation de l'asservissement pour repositionner le robot dans le zone de départ
00768                     tactile_printf("Strat %d, Asser desactive",msgTx.data[0]);
00769                 }
00770             break;
00771             case BALISE_DANGER :
00772                 SendAck(ACKNOWLEDGE_BALISE, BALISE_END_DANGER);
00773             break;
00774             
00775             case BALISE_STOP:
00776                 SendAck(ACKNOWLEDGE_BALISE, BALISE_STOP);
00777                 //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, 
00778                     if(needToStop() != 0 && ingnorBaliseOnce ==0) {
00779                         if(gameEtat > ETAT_GAME_START && gameEtat != ETAT_WARNING_TIMEOUT)
00780                         {
00781                             SendRawId(ASSERVISSEMENT_STOP);
00782                             while(1);  // while(1) pour se stop avec la balise
00783                             gameEtat = ETAT_WARNING_TIMEOUT;
00784                             if(gameEtat != ETAT_WARING_END_BALISE_WAIT) {
00785                                 timeoutWarning.reset();
00786                                 timeoutWarning.start();//Reset du timer utiliser par le timeout
00787                             }
00788                         }
00789                     }
00790                 //}
00791                 ingnorBaliseOnce = 0;
00792             break;
00793             
00794             case BALISE_END_DANGER:
00795                 SendAck(ACKNOWLEDGE_BALISE, BALISE_END_DANGER);
00796                 if(gameEtat == ETAT_WARNING_TIMEOUT) {
00797                     timeoutWarningWaitEnd.reset();
00798                     timeoutWarningWaitEnd.start();
00799                     gameEtat = ETAT_WARING_END_BALISE_WAIT;
00800                 }
00801             break;
00802             
00803             case ECRAN_CHOICE_START_ACTION:
00804                 if(gameEtat == ETAT_CONFIG) {//C'est bon on a le droit de modifier les config
00805                     if(msgRxBuffer[FIFO_lecture].data[0] == 1) {
00806                         runRobotTest();
00807                     } else {
00808                         initRobotActionneur();
00809                     }
00810                     wait_ms(500);
00811                     SendRawId(ECRAN_ACK_CHOICE_START_ACTION);
00812                 }
00813             break;
00814             
00815             case OBJET_SUR_TABLE:
00816                 if (msgRxBuffer[FIFO_lecture].data[1] == 0xff){
00817                         
00818                         gameEtat = ETAT_WARNING_END_LAST_INSTRUCTION;
00819                     }
00820                 else{
00821                         
00822                         waitingAckFrom = 0;
00823                         waitingAckID = 0; 
00824                         
00825                         strat_instructions[actual_instruction+1].arg1 = returnX(strat_instructions[actual_instruction].arg2);
00826                         strat_instructions[actual_instruction+1].arg2 = returnY(strat_instructions[actual_instruction].arg2);
00827                     }
00828                 modeTelemetre = 0;
00829             break;
00830         }        
00831         
00832         FIFO_lecture=(FIFO_lecture+1)%SIZE_FIFO;
00833     }
00834 }