CRAC Team / Pixy2-HA
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pixy2.cpp Source File

pixy2.cpp

00001 #include "pixy2.h"
00002 
00003 PIXY2::PIXY2(PinName tx, PinName rx, int debit)
00004 {
00005     _Pixy2 = new Serial (tx, rx, debit);
00006     _Pixy2->attach (callback(this,&PIXY2::pixy2_getByte));
00007     etat = idle;
00008     Pixy2_buffer = (Byte*) malloc (0x100);
00009 }
00010 
00011 PIXY2::~PIXY2()
00012 {
00013     free (Pixy2_buffer);
00014 }
00015 
00016 /* Le programme utilise l'interruption de la liaison série pour recevoir le message et avancer la machine d'état pour permettre au programme de ne pas être bloquant en réception.
00017    Lorsqu'on appelle une fonction, elle retourne le code -2 pour signifier que le message de réponse de la caméra n'est pas completement reçu...
00018    Les étapes de fonctionnement sont les suivantes :
00019    
00020    * idle : La caméra n'a pas été solicité => on envoi le message de requête.
00021    * messageSent : La requête a été transmise, mais la réponse n'est pas encore arrivée.
00022    * receivingHeader : Le mot de synchro a été reçu, le reste de l'entête est en cours de réception.
00023    * receivingData : L'entête a été intégralement reçu (et traité) et on est en train de recevoir la payload.
00024    * dataReceived : La réponse a été intégralement reçue et est disponible pour le traitement (et la libération).
00025    
00026    On utilise plusieurs pointeurs : 
00027    * wPointer est le pointeur d'écriture des octets reçus dans le buffer de réception
00028    * hPointer est le pointeur de l'entête du message
00029    * dPointer est le pointeur de la zone de données
00030    
00031    On rajoute une variable : dataSize, qui définit la quantité de données à recevoir (issue de l'entête)
00032    
00033    **** COMMENT CA MARCHE ****
00034    
00035    Au début wPointer = 0. Quand wPointer est supérieur à 1 (donc qu'on a reçu au moins 2 octets), on regarde si on a reçu le code de début de trame 0xC1AF
00036    Si ce n'est pas le cas, on continue de recevoir les octets et on les stock jusqu'à trouver le code de début de trame.
00037    Quand on trouve le code, on enregistre le point de départ (c'est hPointer) comme étant la position actuelle du wPointer-1.
00038    A partir de ça, on attend de recevoir les 4 premiers octets de l'entête :
00039    * start of frame (hPointer et hPointer + 1)
00040    * identification du type (hPointer + 2)
00041    * taille des données (hPointer + 3)
00042    Et ensuite si on a une trame avec un checksum (normal) :
00043    * le checksum (hPointer + 4 et hPointer + 5)
00044    * les données (hPointer + 6 et +)
00045    Et si on a une trame sans checksum (pas normal) :
00046    * les données (hPointer + 4 et +)
00047    
00048    On continue alors de recevoir des octets jusqu'à ce que wPointer soit égal à dPointer + dataSize - 1
00049    par exemple si la data fait 4 octets et une trame avec checksum, on reçoit tant que wPointer est inférieur à 9 (6 + 4 - 1)
00050    ou pour la même quantité de données mais avec une trame sans checksum 7 (4 + 4 - 1)...
00051 */
00052 
00053 void PIXY2::pixy2_getByte ()    // Interruption de la pixy2
00054 {
00055     T_Word                  *buffer;
00056     
00057     Pixy2_buffer[wPointer] = _Pixy2->getc();                                        // On stocke l'octet reçu dans la première case dispo du buffer de réception
00058     
00059     switch (etat) {
00060         case messageSent :                                                          // Si on a envoyé une requete => on attend un entête
00061             if (wPointer > 0) {                                                     // On attend d'avoir reçu 2 octets
00062                 buffer = (T_Word*) &Pixy2_buffer[wPointer-1];                       // On pointe la structure sur les 2 derniers octets reçus
00063                 if ((buffer->mot == PIXY2_CSSYNC) || (buffer->mot == PIXY2_SYNC)) { // Si c'est un mot d'entête
00064                     etat = receivingHeader;                                         // On passe à l'état réception de l'entête
00065                     hPointer = wPointer - 1;                                        // On initialise le pointeur de l'entête
00066                     if (buffer->mot == PIXY2_SYNC) {
00067                         frameContainChecksum = 0;                                   // Si c'est un entête sans checksum, on mémorise qu'il n'y a pas de checksum à vérifier
00068                         dPointer = hPointer + 4;
00069                     } else {
00070                         frameContainChecksum = 1;                                   // Sinon, on mémorise qu'il y a un checksum à vérifier
00071                         dPointer = hPointer + 6;
00072                     }
00073                 }                                                                   // Si on n'a pas de mot d'entête on attend d'en trouver un...
00074             }
00075             break;
00076 
00077         case receivingHeader :                                                      // Si on est en train de recevoir un entête (entre le SYNC et... La fin de l'entête)
00078             if ((frameContainChecksum && ((wPointer - hPointer) == (PIXY2_CSHEADERSIZE - 1))) || (!frameContainChecksum && ((wPointer - hPointer) == (PIXY2_NCSHEADERSIZE - 1)))) {
00079                                                                                     // Si on a reçu 6 octets pour une trame avec checksum ou 4 pour une trame sans checksum, c'est à dire un entête complet
00080                 etat = receivingData;                                               // On dit que l'on va de recevoir des données
00081                 dataSize = Pixy2_buffer[hPointer + 3];                              // On enregistre la taille de la payload
00082             }
00083             break;
00084 
00085         case receivingData :                                                        // Si on est en train de recevoir des données.
00086             if (wPointer == ((dataSize - 1) + dPointer)) etat = dataReceived;       // Quand on a reçu toutes les données promises on dit que c'est OK
00087             break;
00088 
00089         default : // On ne traite volontairement ici pas tous les cas, en particulier idle et dataReceived. C'est à la fonction de le faire ! Le reste est lié à des réceptions de données.
00090             break;
00091     }
00092     wPointer++;                                                                     // on pointe la case suivante du buffer de réception
00093 
00094 }
00095 
00096 T_pixy2ErrorCode PIXY2::pixy2_sndGetVersion (void){
00097     T_pixy2SendBuffer   msg;
00098     int                 i = 0, dataSize = 0;
00099     msg.frame.header.pixSync = PIXY2_SYNC;
00100     msg.frame.header.pixType = PIXY2_ASK_VERS;
00101     msg.frame.header.pixLength = dataSize;
00102     do {
00103         while(!_Pixy2->writable());
00104         _Pixy2->putc(msg.data[i]);
00105         i++;
00106     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00107     return PIXY2_OK;
00108 }
00109 
00110 T_pixy2ErrorCode PIXY2::pixy2_sndGetResolution (void){
00111     T_pixy2SendBuffer   msg;
00112     int                 i = 0, dataSize = 1;
00113     msg.frame.header.pixSync = PIXY2_SYNC;
00114     msg.frame.header.pixType = PIXY2_ASK_RESOL;
00115     msg.frame.header.pixLength = dataSize;
00116     msg.frame.data[0] = 0;
00117     do {
00118         while(!_Pixy2->writable());
00119         _Pixy2->putc(msg.data[i]);
00120         i++;
00121     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00122     return PIXY2_OK;
00123 }
00124 
00125 T_pixy2ErrorCode PIXY2::pixy2_sndSetCameraBrightness (Byte brightness){
00126     T_pixy2SendBuffer   msg;
00127     int                 i = 0, dataSize = 1;
00128     msg.frame.header.pixSync = PIXY2_SYNC;
00129     msg.frame.header.pixType = PIXY2_SET_BRIGHT;
00130     msg.frame.header.pixLength = dataSize;
00131     msg.frame.data[0] = brightness;
00132     do {
00133         while(!_Pixy2->writable());
00134         _Pixy2->putc(msg.data[i]);
00135         i++;
00136     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00137     return PIXY2_OK;
00138 }
00139 
00140 T_pixy2ErrorCode PIXY2::pixy2_sndSetServo (Word s0, Word s1){
00141     T_pixy2SendBuffer   msg;
00142     int                 i = 0, dataSize = 4;
00143     T_Word              tmp;
00144     msg.frame.header.pixSync = PIXY2_SYNC;
00145     msg.frame.header.pixType = PIXY2_SET_SERVOS;
00146     msg.frame.header.pixLength = dataSize;
00147     tmp.mot = s0;
00148     msg.frame.data[0] = tmp.octet[0];
00149     msg.frame.data[1] = tmp.octet[1];
00150     tmp.mot = s1;
00151     msg.frame.data[2] = tmp.octet[0];
00152     msg.frame.data[3] = tmp.octet[1];
00153     do {
00154         while(!_Pixy2->writable());
00155         _Pixy2->putc(msg.data[i]);
00156         i++;
00157     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00158     return PIXY2_OK;
00159 }
00160 
00161 T_pixy2ErrorCode PIXY2::pixy2_sndSetLED (Byte red, Byte green, Byte blue){
00162     T_pixy2SendBuffer   msg;
00163     int                 i = 0, dataSize = 3;
00164     msg.frame.header.pixSync = PIXY2_SYNC;
00165     msg.frame.header.pixType = PIXY2_SET_LED;
00166     msg.frame.header.pixLength = dataSize;
00167     msg.frame.data[0] = red;
00168     msg.frame.data[1] = green;
00169     msg.frame.data[2] = blue;
00170     do {
00171         while(!_Pixy2->writable());
00172         _Pixy2->putc(msg.data[i]);
00173         i++;
00174     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00175     return PIXY2_OK;
00176 }
00177 
00178 T_pixy2ErrorCode PIXY2::pixy2_sndSetLamp (Byte upper, Byte lower){
00179     T_pixy2SendBuffer   msg;
00180     int                 i = 0, dataSize = 2;
00181     msg.frame.header.pixSync = PIXY2_SYNC;
00182     msg.frame.header.pixType = PIXY2_SET_LED;
00183     msg.frame.header.pixLength = dataSize;
00184     msg.frame.data[0] = upper;
00185     msg.frame.data[1] = lower;
00186     do {
00187         while(!_Pixy2->writable());
00188         _Pixy2->putc(msg.data[i]);
00189         i++;
00190     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00191     return PIXY2_OK;
00192 }
00193 
00194 T_pixy2ErrorCode PIXY2::pixy2_sndGetFPS (void){
00195     T_pixy2SendBuffer   msg;
00196     int                 i = 0, dataSize = 0;
00197     msg.frame.header.pixSync = PIXY2_SYNC;
00198     msg.frame.header.pixType = PIXY2_ASK_FPS;
00199     msg.frame.header.pixLength = dataSize;
00200     do {
00201         while(!_Pixy2->writable());
00202         _Pixy2->putc(msg.data[i]);
00203         i++;
00204     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00205     return PIXY2_OK;
00206 }
00207 
00208 T_pixy2ErrorCode PIXY2::pixy2_sndGetBlocks (Byte sigmap, Byte maxBloc){
00209     T_pixy2SendBuffer   msg;
00210     int                 i = 0, dataSize = 2;
00211     msg.frame.header.pixSync = PIXY2_SYNC;
00212     msg.frame.header.pixType = PIXY2_ASK_BLOC;
00213     msg.frame.header.pixLength = dataSize;
00214     msg.frame.data[0] = sigmap;
00215     msg.frame.data[1] = maxBloc;
00216     do {
00217         while(!_Pixy2->writable());
00218         _Pixy2->putc(msg.data[i]);
00219         i++;
00220     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00221     return PIXY2_OK;
00222 }
00223 
00224 T_pixy2ErrorCode PIXY2::pixy2_sndGetLineFeature (Byte type, Byte feature){
00225     T_pixy2SendBuffer   msg;
00226     int                 i = 0, dataSize = 2;
00227     msg.frame.header.pixSync = PIXY2_SYNC;
00228     msg.frame.header.pixType = PIXY2_ASK_LINE;
00229     msg.frame.header.pixLength = dataSize;
00230     msg.frame.data[0] = type;
00231     msg.frame.data[1] = feature;
00232     do {
00233         while(!_Pixy2->writable());
00234         _Pixy2->putc(msg.data[i]);
00235         i++;
00236     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00237     return PIXY2_OK;
00238 }
00239 
00240 T_pixy2ErrorCode PIXY2::pixy2_sndSetMode (Byte mode){
00241     T_pixy2SendBuffer   msg;
00242     int                 i = 0, dataSize = 1;
00243     msg.frame.header.pixSync = PIXY2_SYNC;
00244     msg.frame.header.pixType = PIXY2_SET_MODE;
00245     msg.frame.header.pixLength = dataSize;
00246     msg.frame.data[0] = mode;
00247     do {
00248         while(!_Pixy2->writable());
00249         _Pixy2->putc(msg.data[i]);
00250         i++;
00251     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00252     return PIXY2_OK;
00253 }
00254 
00255 T_pixy2ErrorCode PIXY2::pixy2_sndSetNextTurn (Word angle){
00256     T_pixy2SendBuffer   msg;
00257     int                 i = 0, dataSize = 2;
00258     T_Word              tmp;
00259     tmp.mot = angle;
00260     msg.frame.header.pixSync = PIXY2_SYNC;
00261     msg.frame.header.pixType = PIXY2_SET_TURN;
00262     msg.frame.header.pixLength = dataSize;
00263     tmp.mot = angle;
00264     msg.frame.data[0] = tmp.octet[0];
00265     msg.frame.data[1] = tmp.octet[1];
00266     do {
00267         while(!_Pixy2->writable());
00268         _Pixy2->putc(msg.data[i]);
00269         i++;
00270     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00271     return PIXY2_OK;
00272 }
00273 
00274 T_pixy2ErrorCode PIXY2::pixy2_sndSetDefaultTurn (Word angle){
00275     T_pixy2SendBuffer   msg;
00276     int                 i = 0, dataSize = 2;
00277     T_Word              tmp;
00278     tmp.mot = angle;
00279     msg.frame.header.pixSync = PIXY2_SYNC;
00280     msg.frame.header.pixType = PIXY2_SET_DEFTURN;
00281     msg.frame.header.pixLength = dataSize;
00282     tmp.mot = angle;
00283     msg.frame.data[0] = tmp.octet[0];
00284     msg.frame.data[1] = tmp.octet[1];
00285     do {
00286         while(!_Pixy2->writable());
00287         _Pixy2->putc(msg.data[i]);
00288         i++;
00289     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00290     return PIXY2_OK;
00291 }
00292 
00293 T_pixy2ErrorCode PIXY2::pixy2_sndSetVector (Byte vectorIndex){
00294     T_pixy2SendBuffer   msg;
00295     int                 i = 0, dataSize = 1;
00296     msg.frame.header.pixSync = PIXY2_SYNC;
00297     msg.frame.header.pixType = PIXY2_SET_VECTOR;
00298     msg.frame.header.pixLength = dataSize;
00299     msg.frame.data[0] = vectorIndex;
00300     do {
00301         while(!_Pixy2->writable());
00302         _Pixy2->putc(msg.data[i]);
00303         i++;
00304     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00305     return PIXY2_OK;
00306 }
00307 
00308 T_pixy2ErrorCode PIXY2::pixy2_sndReverseVector (void){
00309     T_pixy2SendBuffer   msg;
00310     int                 i = 0, dataSize = 0;
00311     msg.frame.header.pixSync = PIXY2_SYNC;
00312     msg.frame.header.pixType = PIXY2_SET_REVERSE;
00313     msg.frame.header.pixLength = dataSize;
00314     do {
00315         while(!_Pixy2->writable());
00316         _Pixy2->putc(msg.data[i]);
00317         i++;
00318     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00319     return PIXY2_OK;
00320 }
00321 
00322 T_pixy2ErrorCode PIXY2::pixy2_sndGetRGB (Word x, Word y, Byte saturate){
00323     T_pixy2SendBuffer   msg;
00324     int                 i = 0, dataSize = 3;
00325     msg.frame.header.pixSync = PIXY2_SYNC;
00326     msg.frame.header.pixType = PIXY2_ASK_VIDEO;
00327     msg.frame.header.pixLength = dataSize;
00328     msg.frame.data[0] = x;
00329     msg.frame.data[1] = y;
00330     msg.frame.data[2] = saturate;
00331     do {
00332         while(!_Pixy2->writable());
00333         _Pixy2->putc(msg.data[i]);
00334         i++;
00335     } while (i<(PIXY2_NCSHEADERSIZE+dataSize));
00336     return PIXY2_OK;
00337 }
00338 
00339 /*  La fonction est bloquante à l'envoi (pas vraiment le choix), mais elle est non bloquante en réception. On essayera de faire une fonction non bloquante en envoi avec write, mais c'est pas la priorité.
00340 Le principe c'est de stocker dans un buffer circulaire les données au fur et à mesure qu'elle sont reçues et de traiter uniquement en castant les infos. Pour cela, il faut recevoir et stocker. */
00341 
00342 T_pixy2ErrorCode PIXY2::pixy2_getVersion (T_pixy2Version *version){
00343 
00344     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00345     T_pixy2ErrorCode    cr = PIXY2_OK;
00346     
00347     switch (etat) {
00348         case idle :                                                                 // Si la caméra est inactive
00349             wPointer = 0;                                                           // On remonte en haut du buffer
00350             cr = PIXY2::pixy2_sndGetVersion();                                      // On envoie la trame de demande de la version
00351             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00352             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00353             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00354             break;
00355             
00356         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00357             if (frameContainChecksum) {                                             // Si la trame contient un checksum
00358                 if ( !pixy2_validateChecksum (&Pixy2_buffer[hPointer]) ) {          // On lance la validation du checksum
00359                     return PIXY2_BAD_CHECKSUM;                                      // Si le checksum est faux on retourne une erreur
00360                 }
00361             }
00362             if (msg->pixType == PIXY2_REP_VERS) {                                   // On vérifie que la trame est du type convenable (REPONSE VERSION)
00363                 version = (T_pixy2Version*) &Pixy2_buffer[dPointer];                // On mappe le pointeur de structure sur le buffer de réception.
00364             } else {                                                                // Si ce n'est pas le bon type
00365                 if (msg->pixType == PIXY2_REP_ERROR) {                              // Cela pourrait être une trame d'erreur
00366                     cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];              // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00367                 } else cr = PIXY2_TYPE_ERROR;                                       // Si le type ne correspond à rien de normal on signale une erreur de type.
00368             }
00369             etat = idle;                                                            // On annoce que la pixy est libre
00370             break;
00371 
00372         default :                                                                   // Dans tous les autres cas
00373             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00374             break;
00375     }
00376     return cr;
00377 }
00378 
00379 T_pixy2ErrorCode PIXY2::pixy2_getResolution (T_pixy2Resolution *resolution){
00380 
00381     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00382     T_pixy2ErrorCode    cr = PIXY2_OK;
00383     
00384     switch (etat) {
00385         case idle :                                                                 // Si la caméra est inactive
00386             wPointer = 0;                                                           // On remonte en haut du buffer
00387             cr = PIXY2::pixy2_sndGetResolution();                                   // On envoie la trame de demande de la résolution
00388             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00389             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00390             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00391             break;
00392             
00393         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00394             if (frameContainChecksum) {                                             // Si la trame contient un checksum
00395                 if ( !pixy2_validateChecksum (&Pixy2_buffer[hPointer]) ) {          // On lance la validation du checksum
00396                     return PIXY2_BAD_CHECKSUM;                                      // Si le checksum est faux on retourne une erreur
00397                 }
00398             }
00399             if (msg->pixType == PIXY2_REP_RESOL) {                                  // On vérifie que la trame est du type convenable (REPONSE RESOLUTION)
00400                 resolution = (T_pixy2Resolution*) &Pixy2_buffer[dPointer];          // On mappe le pointeur de structure sur le buffer de réception.
00401             } else {                                                                // Si ce n'est pas le bon type
00402                 if (msg->pixType == PIXY2_REP_ERROR) {                              // Cela pourrait être une trame d'erreur
00403                     cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];              // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00404                 } else cr = PIXY2_TYPE_ERROR;                                       // Si le type ne correspond à rien de normal on signale une erreur de type.
00405             }
00406             etat = idle;                                                            // On annoce que la pixy est libre
00407             break;
00408 
00409         default :                                                                   // Dans tous les autres cas
00410             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00411             break;
00412     }
00413     return cr;
00414 }
00415 
00416 T_pixy2ErrorCode PIXY2::pixy2_setCameraBrightness (Byte brightness){
00417 
00418     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00419     T_pixy2ErrorCode    cr = PIXY2_OK;
00420     
00421     switch (etat) {
00422         case idle :                                                                 // Si la caméra est inactive
00423             wPointer = 0;                                                           // On remonte en haut du buffer
00424             cr = PIXY2::pixy2_sndSetCameraBrightness (brightness);                  // On envoie la trame de règlage de la luminosité
00425             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00426             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00427             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00428             break;
00429             
00430         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00431             if (frameContainChecksum) {                                             // Si la trame contient un checksum
00432                 if ( !pixy2_validateChecksum (&Pixy2_buffer[hPointer]) ) {          // On lance la validation du checksum
00433                     return PIXY2_BAD_CHECKSUM;                                      // Si le checksum est faux on retourne une erreur
00434                 }
00435             }
00436             if ((msg->pixType == PIXY2_REP_ACK) || (msg->pixType == PIXY2_REP_ERROR)) {
00437                                                                                     // On vérifie que la trame est du type convenable (ACK ou ERREUR)
00438                 cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];                  // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00439             } else cr = PIXY2_TYPE_ERROR;                                           // Si le type ne correspond à rien de normal on signale une erreur de type.
00440             etat = idle;                                                            // On annoce que la pixy est libre
00441             break;
00442 
00443         default :                                                                   // Dans tous les autres cas
00444             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00445             break;
00446     }
00447     return cr;
00448 }
00449 
00450 T_pixy2ErrorCode PIXY2::pixy2_setServos (Word s0, Word s1){
00451 
00452     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00453     T_pixy2ErrorCode    cr = PIXY2_OK;
00454     
00455     switch (etat) {
00456         case idle :                                                                 // Si la caméra est inactive
00457             wPointer = 0;                                                           // On remonte en haut du buffer
00458             cr = PIXY2::pixy2_sndSetServo (s0, s1);                                 // On envoie la trame de règlage des servos moteurs
00459             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00460             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00461             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00462             break;
00463             
00464         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00465             if (frameContainChecksum) {                                             // Si la trame contient un checksum
00466                 if ( !pixy2_validateChecksum (&Pixy2_buffer[hPointer]) ) {          // On lance la validation du checksum
00467                     return PIXY2_BAD_CHECKSUM;                                      // Si le checksum est faux on retourne une erreur
00468                 }
00469             }
00470             if ((msg->pixType == PIXY2_REP_ACK) || (msg->pixType == PIXY2_REP_ERROR)) {
00471                                                                                     // On vérifie que la trame est du type convenable (ACK ou ERREUR)
00472                 cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];                  // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00473             } else cr = PIXY2_TYPE_ERROR;                                           // Si le type ne correspond à rien de normal on signale une erreur de type.
00474             etat = idle;                                                            // On annoce que la pixy est libre
00475             break;
00476 
00477         default :                                                                   // Dans tous les autres cas
00478             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00479             break;
00480     }
00481     return cr;
00482 }
00483 
00484 T_pixy2ErrorCode PIXY2::pixy2_setLED (Byte red, Byte green, Byte blue){
00485 
00486     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00487     T_pixy2ErrorCode    cr = PIXY2_OK;
00488     
00489     switch (etat) {
00490         case idle :                                                                 // Si la caméra est inactive
00491             wPointer = 0;                                                           // On remonte en haut du buffer
00492             cr = PIXY2::pixy2_sndSetLED (red, green, blue);                         // On envoie la trame de règlage des composantes de la LED RGB
00493             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00494             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00495             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00496             break;
00497             
00498         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00499             if (frameContainChecksum) {                                             // Si la trame contient un checksum
00500                 if ( !pixy2_validateChecksum (&Pixy2_buffer[hPointer]) ) {          // On lance la validation du checksum
00501                     return PIXY2_BAD_CHECKSUM;                                      // Si le checksum est faux on retourne une erreur
00502                 }
00503             }
00504             if ((msg->pixType == PIXY2_REP_ACK) || (msg->pixType == PIXY2_REP_ERROR)) {
00505                                                                                     // On vérifie que la trame est du type convenable (ACK ou ERREUR)
00506                 cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];                  // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00507             } else cr = PIXY2_TYPE_ERROR;                                           // Si le type ne correspond à rien de normal on signale une erreur de type.
00508             etat = idle;                                                            // On annoce que la pixy est libre
00509             break;
00510 
00511         default :                                                                   // Dans tous les autres cas
00512             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00513             break;
00514     }
00515     return cr;
00516 }
00517 
00518 T_pixy2ErrorCode PIXY2::pixy2_setLamp (Byte upper, Byte lower){
00519 
00520     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00521     T_pixy2ErrorCode    cr = PIXY2_OK;
00522     
00523     switch (etat) {
00524         case idle :                                                                 // Si la caméra est inactive
00525             wPointer = 0;                                                           // On remonte en haut du buffer
00526             cr = PIXY2::pixy2_sndSetLamp (upper, lower);                            // On envoie la trame de règlage d'allumage des lumières de contraste
00527             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00528             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00529             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00530             break;
00531             
00532         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00533             if (frameContainChecksum) {                                             // Si la trame contient un checksum
00534                 if ( !pixy2_validateChecksum (&Pixy2_buffer[hPointer]) ) {          // On lance la validation du checksum
00535                     return PIXY2_BAD_CHECKSUM;                                      // Si le checksum est faux on retourne une erreur
00536                 }
00537             }
00538             if ((msg->pixType == PIXY2_REP_ACK) || (msg->pixType == PIXY2_REP_ERROR)) {
00539                                                                                     // On vérifie que la trame est du type convenable (ACK ou ERREUR)
00540                 cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];                  // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00541             } else cr = PIXY2_TYPE_ERROR;                                           // Si le type ne correspond à rien de normal on signale une erreur de type.
00542             etat = idle;                                                            // On annoce que la pixy est libre
00543             break;
00544 
00545         default :                                                                   // Dans tous les autres cas
00546             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00547             break;
00548     }
00549     return cr;
00550 }
00551 
00552 T_pixy2ErrorCode PIXY2::pixy2_getFPS (T_pixy2ReturnCode *framerate){
00553 
00554     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00555     T_pixy2ErrorCode    cr = PIXY2_OK;
00556     
00557     switch (etat) {
00558         case idle :                                                                 // Si la caméra est inactive
00559             wPointer = 0;                                                           // On remonte en haut du buffer
00560             cr = PIXY2::pixy2_sndGetFPS();                                          // On envoie la trame de demande du Framerate
00561             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00562             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00563             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00564             break;
00565             
00566         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00567             if (frameContainChecksum) {                                             // Si la trame contient un checksum
00568                 if ( !pixy2_validateChecksum (&Pixy2_buffer[hPointer]) ) {          // On lance la validation du checksum
00569                     return PIXY2_BAD_CHECKSUM;                                      // Si le checksum est faux on retourne une erreur
00570                 }
00571             }
00572             if (msg->pixType == PIXY2_REP_FPS) {                                    // On vérifie que la trame est du type convenable (REPONSE FPS)
00573                 framerate = (T_pixy2ReturnCode*) &Pixy2_buffer[dPointer];           // On mappe le pointeur de structure sur le buffer de réception.
00574             } else {                                                                // Si ce n'est pas le bon type
00575                 if (msg->pixType == PIXY2_REP_ERROR) {                              // Cela pourrait être une trame d'erreur
00576                     cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];              // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00577                 } else cr = PIXY2_TYPE_ERROR;                                       // Si le type ne correspond à rien de normal on signale une erreur de type.
00578             }
00579             etat = idle;                                                            // On annoce que la pixy est libre
00580             break;
00581 
00582         default :                                                                   // Dans tous les autres cas
00583             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00584             break;
00585     }
00586     return cr;
00587 }
00588 
00589 T_pixy2ErrorCode PIXY2::pixy2_getBlocks (Byte sigmap, Byte maxBloc){
00590 
00591     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00592     T_pixy2ErrorCode    cr = PIXY2_OK;
00593     
00594     switch (etat) {
00595         case idle :                                                                 // Si la caméra est inactive
00596             wPointer = 0;                                                           // On remonte en haut du buffer
00597             cr = PIXY2::pixy2_sndGetBlocks(sigmap, maxBloc);                        // On envoie la trame de demande de blocs de couleur
00598             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00599             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00600             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00601             break;
00602             
00603         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00604             if (frameContainChecksum) {                                             // Si la trame contient un checksum
00605                 if ( !pixy2_validateChecksum (&Pixy2_buffer[hPointer]) ) {          // On lance la validation du checksum
00606                     return PIXY2_BAD_CHECKSUM;                                      // Si le checksum est faux on retourne une erreur
00607                 }
00608             }
00609             if (msg->pixType == PIXY2_REP_BLOC) {                                   // On vérifie que la trame est du type convenable (REPONSE BLOCS)
00610                 Pixy2_blocks = (T_pixy2Bloc*) &Pixy2_buffer[dPointer];              // On mappe le pointeur de structure sur le buffer de réception.
00611                 Pixy2_numBlocks = dataSize / sizeof(T_pixy2Bloc);                   // On indique le nombre de blocs reçus
00612             } else {                                                                // Si ce n'est pas le bon type
00613                 if (msg->pixType == PIXY2_REP_ERROR) {                              // Cela pourrait être une trame d'erreur
00614                     cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];              // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00615                 } else cr = PIXY2_TYPE_ERROR;                                       // Si le type ne correspond à rien de normal on signale une erreur de type.
00616             }
00617             etat = idle;                                                            // On annoce que la pixy est libre
00618             break;
00619 
00620         default :                                                                   // Dans tous les autres cas
00621             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00622             break;
00623     }
00624     return cr;
00625 }
00626 
00627 T_pixy2ErrorCode PIXY2::pixy2_getFeatures (){
00628 
00629     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00630     T_pixy2ErrorCode    cr = PIXY2_OK;
00631     T_pixy2LineFeature* lineFeature;
00632     int                 fPointer;
00633 
00634     if (frameContainChecksum) {                                                     // Si la trame contient un checksum
00635         if ( !pixy2_validateChecksum (&Pixy2_buffer[hPointer]) ) {                  // On lance la validation du checksum
00636             return PIXY2_BAD_CHECKSUM;                                              // Si le checksum est faux on retourne une erreur
00637         }
00638     }
00639     if (msg->pixType == PIXY2_REP_LINE) {                                           // On vérifie que la trame est du type convenable (REPONSE LIGNE)
00640         fPointer = dPointer;                                                        // On pointe sur la premiere feature
00641         do {
00642             lineFeature = (T_pixy2LineFeature*) &Pixy2_buffer[fPointer];            // On mappe le pointeur de structure sur le buffer de réception des features.
00643             if (lineFeature->fType == PIXY2_VECTOR) {                               // On regarde si le type est vecteur
00644                 Pixy2_numVectors = lineFeature->fLength / sizeof(T_pixy2Vector);
00645                                                                                     // Si oui, on compte combien il y a de vecteurs
00646                 Pixy2_vectors = (T_pixy2Vector*) &Pixy2_buffer[fPointer];           // On mappe le résultat
00647                 fPointer += lineFeature->fLength;                                   // On déplace le pointeur de données et on recommence
00648                 cr |= PIXY2_VECTOR;
00649             }
00650 
00651             if (lineFeature->fType == PIXY2_BARCODE) {                              // On regarde si le type est codebarre
00652                 Pixy2_numBarcodes = lineFeature->fLength / sizeof(T_pixy2BarCode);
00653                                                                                     // Si oui, on compte combien il y a de codebarre
00654                 Pixy2_barcodes = (T_pixy2BarCode*) &Pixy2_buffer[fPointer];         // On mappe le résultat
00655                 fPointer += lineFeature->fLength;                                   // On déplace le pointeur de données et on recommence
00656                 cr |= PIXY2_BARCODE;
00657             }
00658             if (lineFeature->fType == PIXY2_INTERSECTION) {                         // On regarde si le type est intersection
00659                 Pixy2_numIntersections = lineFeature->fLength / sizeof(T_pixy2Intersection);
00660                                                                                     // Si oui, on compte combien il y a d'intersections
00661                 Pixy2_intersections = (T_pixy2Intersection*) &Pixy2_buffer[fPointer];
00662                                                                                     // On mappe le résultat sur l'entête de l'intersection
00663                 fPointer += lineFeature->fLength;                                   // On déplace le pointeur de données et on recommence
00664                 cr |= PIXY2_INTERSECTION;
00665             }
00666         } while(fPointer < ((dataSize - 1) + dPointer));                            // Tant qu'il y a des données à traiter
00667     } else {                                                                        // Si ce n'est pas le bon type
00668         if (msg->pixType == PIXY2_REP_ERROR) {                                      // Cela pourrait être une trame d'erreur
00669             cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];                      // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00670         } else cr = PIXY2_TYPE_ERROR;                                               // Si le type ne correspond à rien de normal on signale une erreur de type.
00671     }
00672     etat = idle;                                                                    // On annoce que la pixy est libre
00673     return cr;
00674 }
00675 
00676 
00677 T_pixy2ErrorCode PIXY2::pixy2_getMainFeature (Byte features){
00678 
00679     T_pixy2ErrorCode    cr = PIXY2_OK;
00680     
00681     switch (etat) {
00682         case idle :                                                                 // Si la caméra est inactive
00683             wPointer = 0;                                                           // On remonte en haut du buffer
00684             cr = PIXY2::pixy2_sndGetLineFeature(0, features);                       // On envoie la trame de demande de suivi de ligne
00685             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00686             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00687             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00688             break;
00689             
00690         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00691             cr = PIXY2::pixy2_getFeatures();                                        // On appelle la fonction de traitement.
00692             break;
00693 
00694         default :                                                                   // Dans tous les autres cas
00695             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00696             break;
00697     }
00698     return cr;
00699 }
00700 
00701 T_pixy2ErrorCode PIXY2::pixy2_getAllFeature (Byte features){
00702     T_pixy2ErrorCode    cr = PIXY2_OK;
00703 
00704     switch (etat) {
00705         case idle :                                                                 // Si la caméra est inactive
00706             wPointer = 0;                                                           // On remonte en haut du buffer
00707             cr = PIXY2::pixy2_sndGetLineFeature(1, features);                       // On envoie la trame de demande de suivi de ligne
00708             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00709             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00710             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00711             break;
00712 
00713         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00714             cr = PIXY2::pixy2_getFeatures();                                        // On appelle la fonction de traitement.
00715             break;
00716 
00717         default :                                                                   // Dans tous les autres cas
00718             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00719             break;
00720     }
00721     return cr;
00722 }
00723 
00724 T_pixy2ErrorCode PIXY2::pixy2_setMode (Byte mode)
00725 {
00726     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00727     T_pixy2ErrorCode    cr = PIXY2_OK;
00728 
00729     switch (etat) {
00730         case idle :                                                                 // Si la caméra est inactive
00731             wPointer = 0;                                                           // On remonte en haut du buffer
00732             cr = PIXY2::pixy2_sndSetMode (mode);                                    // On envoie la trame de règlage du mode de fonctionnement du suivi de ligne
00733             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00734             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00735             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00736             break;
00737 
00738         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00739             if (frameContainChecksum) {                                             // Si la trame contient un checksum
00740                 if ( !pixy2_validateChecksum (&Pixy2_buffer[hPointer]) ) {          // On lance la validation du checksum
00741                     return PIXY2_BAD_CHECKSUM;                                      // Si le checksum est faux on retourne une erreur
00742                 }
00743             }
00744             if ((msg->pixType == PIXY2_REP_ACK) || (msg->pixType == PIXY2_REP_ERROR)) {
00745                                                                                     // On vérifie que la trame est du type convenable (ACK ou ERREUR)
00746                 cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];                  // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00747             } else cr = PIXY2_TYPE_ERROR;                                           // Si le type ne correspond à rien de normal on signale une erreur de type.
00748             etat = idle;                                                            // On annoce que la pixy est libre
00749             break;
00750 
00751         default :                                                                   // Dans tous les autres cas
00752             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00753             break;
00754     }
00755     return cr;
00756 }
00757 
00758 T_pixy2ErrorCode PIXY2::pixy2_setNextTurn (sWord angle)
00759 {
00760     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00761     T_pixy2ErrorCode    cr = PIXY2_OK;
00762 
00763     switch (etat) {
00764         case idle :                                                                 // Si la caméra est inactive
00765             wPointer = 0;                                                           // On remonte en haut du buffer
00766             cr = PIXY2::pixy2_sndSetNextTurn (angle);                               // On envoie la trame de choix de l'angle du prochain virage
00767             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00768             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00769             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00770             break;
00771 
00772         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00773             if (frameContainChecksum) {                                             // Si la trame contient un checksum
00774                 if ( !pixy2_validateChecksum (&Pixy2_buffer[hPointer]) ) {          // On lance la validation du checksum
00775                     return PIXY2_BAD_CHECKSUM;                                      // Si le checksum est faux on retourne une erreur
00776                 }
00777             }
00778             if ((msg->pixType == PIXY2_REP_ACK) || (msg->pixType == PIXY2_REP_ERROR)) {
00779                                                                                     // On vérifie que la trame est du type convenable (ACK ou ERREUR)
00780                 cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];                  // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00781             } else cr = PIXY2_TYPE_ERROR;                                           // Si le type ne correspond à rien de normal on signale une erreur de type.
00782             etat = idle;                                                            // On annoce que la pixy est libre
00783             break;
00784 
00785         default :                                                                   // Dans tous les autres cas
00786             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00787             break;
00788     }
00789     return cr;
00790 }
00791 
00792 T_pixy2ErrorCode PIXY2::pixy2_setDefaultTurn (sWord angle)
00793 {
00794     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00795     T_pixy2ErrorCode    cr = PIXY2_OK;
00796 
00797     switch (etat) {
00798         case idle :                                                                 // Si la caméra est inactive
00799             wPointer = 0;                                                           // On remonte en haut du buffer
00800             cr = PIXY2::pixy2_sndSetDefaultTurn (angle);                            // On envoie la trame de choix de l'angle par défaut des virages
00801             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00802             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00803             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00804             break;
00805 
00806         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00807             if (frameContainChecksum) {                                             // Si la trame contient un checksum
00808                 if ( !pixy2_validateChecksum (&Pixy2_buffer[hPointer]) ) {          // On lance la validation du checksum
00809                     return PIXY2_BAD_CHECKSUM;                                      // Si le checksum est faux on retourne une erreur
00810                 }
00811             }
00812             if ((msg->pixType == PIXY2_REP_ACK) || (msg->pixType == PIXY2_REP_ERROR)) {
00813                                                                                     // On vérifie que la trame est du type convenable (ACK ou ERREUR)
00814                 cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];                  // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00815             } else cr = PIXY2_TYPE_ERROR;                                           // Si le type ne correspond à rien de normal on signale une erreur de type.
00816             etat = idle;                                                            // On annoce que la pixy est libre
00817             break;
00818 
00819         default :                                                                   // Dans tous les autres cas
00820             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00821             break;
00822     }
00823     return cr;
00824 }
00825 
00826 T_pixy2ErrorCode PIXY2::pixy2_setVector (Byte vectorIndex)
00827 {
00828     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00829     T_pixy2ErrorCode    cr = PIXY2_OK;
00830 
00831     switch (etat) {
00832         case idle :                                                                 // Si la caméra est inactive
00833             wPointer = 0;                                                           // On remonte en haut du buffer
00834             cr = PIXY2::pixy2_sndSetVector (vectorIndex);                           // On envoie la trame de choix du vecteur à suivre
00835             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00836             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00837             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00838             break;
00839 
00840         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00841             if (frameContainChecksum) {                                             // Si la trame contient un checksum
00842                 if ( !pixy2_validateChecksum (&Pixy2_buffer[hPointer]) ) {          // On lance la validation du checksum
00843                     return PIXY2_BAD_CHECKSUM;                                      // Si le checksum est faux on retourne une erreur
00844                 }
00845             }
00846             if ((msg->pixType == PIXY2_REP_ACK) || (msg->pixType == PIXY2_REP_ERROR)) {
00847                                                                                     // On vérifie que la trame est du type convenable (ACK ou ERREUR)
00848                 cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];                  // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00849             } else cr = PIXY2_TYPE_ERROR;                                           // Si le type ne correspond à rien de normal on signale une erreur de type.
00850             etat = idle;                                                            // On annoce que la pixy est libre
00851             break;
00852 
00853         default :                                                                   // Dans tous les autres cas
00854             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00855             break;
00856     }
00857     return cr;
00858 }
00859 
00860 
00861 T_pixy2ErrorCode PIXY2::pixy2_ReverseVector (void)
00862 {
00863     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00864     T_pixy2ErrorCode    cr = PIXY2_OK;
00865 
00866     switch (etat) {
00867         case idle :                                                                 // Si la caméra est inactive
00868             wPointer = 0;                                                           // On remonte en haut du buffer
00869             cr = PIXY2::pixy2_sndReverseVector ();                                  // On envoie la trame d'inversion de l'image (haut en bas et bas en haut)
00870             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00871             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00872             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00873             break;
00874 
00875         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00876             if (frameContainChecksum) {                                             // Si la trame contient un checksum
00877                 if ( !pixy2_validateChecksum (&Pixy2_buffer[hPointer]) ) {          // On lance la validation du checksum
00878                     return PIXY2_BAD_CHECKSUM;                                      // Si le checksum est faux on retourne une erreur
00879                 }
00880             }
00881             if ((msg->pixType == PIXY2_REP_ACK) || (msg->pixType == PIXY2_REP_ERROR)) {
00882                                                                                     // On vérifie que la trame est du type convenable (ACK ou ERREUR)
00883                 cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];                  // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00884             } else cr = PIXY2_TYPE_ERROR;                                           // Si le type ne correspond à rien de normal on signale une erreur de type.
00885             etat = idle;                                                            // On annoce que la pixy est libre
00886             break;
00887 
00888         default :                                                                   // Dans tous les autres cas
00889             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00890             break;
00891     }
00892     return cr;
00893 }
00894 
00895 T_pixy2ErrorCode PIXY2::pixy2_getRGB (Word x, Word y, Byte saturate, T_pixy2Pixel *pixel){
00896 
00897     T_pixy2RcvHeader    *msg = (T_pixy2RcvHeader*) &Pixy2_buffer[hPointer];
00898     T_pixy2ErrorCode    cr = PIXY2_OK;
00899     
00900     switch (etat) {
00901         case idle :                                                                 // Si la caméra est inactive
00902             wPointer = 0;                                                           // On remonte en haut du buffer
00903             cr = PIXY2::pixy2_sndGetRGB(x, y, saturate);                            // On envoie la trame de demande de la couleur (RGB) d'un carée de pixel
00904             if (cr!= PIXY2_OK) return cr;                                           // S'il y a une erreur lors de l'envoi on ejecte !
00905             etat = messageSent;                                                     // On passe à l'attente du message de réponse
00906             cr = PIXY2_BUSY;                                                        // On signale à l'utilisateur que la caméra est maintenant occupée
00907             break;
00908             
00909         case dataReceived :                                                         // Quand on a reçu l'intégralité du message
00910             if (frameContainChecksum) {                                             // Si la trame contient un checksum
00911                 if ( !pixy2_validateChecksum (&Pixy2_buffer[hPointer]) ) {          // On lance la validation du checksum
00912                     return PIXY2_BAD_CHECKSUM;                                      // Si le checksum est faux on retourne une erreur
00913                 }
00914             }
00915             if (msg->pixType == PIXY2_REP_ACK) {                                    // On vérifie que la trame est du type convenable (REPONSE ACK)
00916                 pixel = (T_pixy2Pixel*) &Pixy2_buffer[dPointer];                    // On mappe le pointeur de structure sur le buffer de réception.
00917             } else {                                                                // Si ce n'est pas le bon type
00918                 if (msg->pixType == PIXY2_REP_ERROR) {                              // Cela pourrait être une trame d'erreur
00919                     cr = *(T_pixy2ErrorCode*) &Pixy2_buffer[dPointer];              // Si c'est le cas, on copie le code d'erreur reçu dans la variable de retour
00920                 } else cr = PIXY2_TYPE_ERROR;                                       // Si le type ne correspond à rien de normal on signale une erreur de type.
00921             }
00922             etat = idle;                                                            // On annoce que la pixy est libre
00923             break;
00924 
00925         default :                                                                   // Dans tous les autres cas
00926             cr = PIXY2_BUSY;                                                        // On signale que la caméra est occupée.
00927             break;
00928     }
00929     return cr;
00930 }
00931 
00932 
00933 
00934 T_pixy2ErrorCode PIXY2::pixy2_validateChecksum (Byte* tab){
00935     Word    i, sum = 0;
00936     T_Word  *tmp;
00937     
00938     for (i=0; i<*(tab+3);i++)   sum = sum + *(tab + PIXY2_CSHEADERSIZE + i);
00939     tmp = (T_Word*) (tab+4);
00940     if (tmp->mot == sum) return PIXY2_OK;
00941     else return PIXY2_BAD_CHECKSUM;
00942 }