// comm.cc - Classe Comm // nono - Programme du robot Efrei Robotique I1-I2 2004 // Copyright (C) 2004 Olivier Gaillard /// @file comm.cc Interprete les commandes envoyes par l'interface UI et les executent #include #include #include using namespace std; #include "comm.h" #include "adjust.h" #include "ovision/convertImg.h" /// Constructeur /// @param *filename nom de l'image a utiliser Comm::Comm(char *filename) { // Copie du nom de l'image courante strcpy(fname, filename); // Ecriture du PID dans un fichier long pid = getpid(); FILE *file = fopen("adjust.PID", "w+"); if (!file) { cerr << "InitComm : Error during file opening" << endl; return; } fprintf(file, "%li\n", pid); fclose(file); // Creation de oconfig oconfig = new OConfig("rc/vision.conf"); int *pPoint = GetPpoint(); for (int i=0; i<3; i++) { pPoint[i*2] = oconfig->tabPoint[i*4]; pPoint[i*2+1] = oconfig->tabPoint[i*4+1]; } // Ouverture de l'image pilote et stockage img.LoadRGB(filename, 0, 360, 296); imgLeft[0] = new unsigned char[img.nbPixels*3]; memcpy(imgLeft[0], img.tabData, sizeof(char) * img.nbPixels * 3); //if (img.yuv) img.RGBtoYUV(); tex[0] = LoadImage(img.width, img.height, imgLeft[0], tex[0]); // Conversion en YUV et stockage img.LoadRGB(filename, 0, 360, 296); //if (!img.yuv) img.YUVtoRGB(); tex[3] = LoadImage(img.width, img.height, img.tabData, tex[3]); // NN oconfigure en RGB ou YUV ? //if (oconfig->colorMode == RGB) img.Load(filename, 0, 360, 296); // Allocation memoire pour les images for (int i=0; i<2; i++) data[i] = new unsigned char[img.nbPixels*3]; // Initialisation de la segmentation segm = new SegmLearn (&img); segm->BuildNN(oconfig->nn_NbCouleurs, LOAD_FROM_FILE); group = new Group(&img, segm); SegmAndGroup(); // Affichage de l'image pilote en RGB et YUV tex[1] = LoadImage(img.width, img.height, data[0], tex[1]); tex[4] = LoadImage(img.width, img.height, data[1], tex[4]); yuvSwitch = 0; imgLeft[1] = NULL; } /// Destructeur Comm::~Comm() { // Liberation de la memoire delete oconfig; delete segm; delete group; delete [] data; close(fifo); } /// Recharge le fichier de config void Comm::ReloadConfig (char *filename) { oconfig->Load (filename); } /// Segmente et group les couleurs void Comm::SegmAndGroup() { segm->Segm(); // Creation des groupes if (group) delete group; group = new Group(&img, segm); group->JumpPoints(oconfig->groupColor, oconfig->goalColor); group->ShowZones (); group->TabOut(); group->TabOut(GOAL, false); // img.WriteSegm ("out.rgb", group->tabOut); img.DoImg(group->tabOut, data[1]); // Creation de l'image segmentee img.AddGroupToDisplay (segm->tabSegm, group); img.DoImg(segm->tabSegm , data[0]); tex[2] = LoadImage(img.width, img.height, data[0], tex[2]); tex[5] = LoadImage(img.width, img.height, data[1], tex[5]); } /// Synchronisation des poids locaux et de ceux du programme ui void Comm::SendNodes() { char buf[10]; for (int i=0; i < oconfig->nn_NbCouleurs*3; i++) { sprintf(buf, "%u\n", segm->node[i]); write(fifo, buf, 10); } } /// Execute une commande venant de l'interface ui /// @param *buffer ligne de commande a analyser void Comm::ExecuteUiCmds(char *buffer) { const int NBARG = 20; // Division du string char *cut[NBARG]={NULL}; cut[0] = strtok(buffer, " \t\n"); int i = 0; while ((cut[i] != NULL) && (i<(NBARG-1))) { i++; cut[i] = strtok( NULL, " \t\n"); } // Detection de la commande recue switch (buffer[0]) { case 'i': // ouverture du fifo cout << "Initialisation du fifo\n"; // Ouverture du fifo fifo = open("uicmds", O_RDWR); if (!fifo) { cerr << "InitComm : Error during opening FIFO" << endl; exit(1); } // On choppe le pid du prog ui situé dans le fichier uiPid.PID FILE *file; file = fopen("ui.PID", "r"); if (!file) { cerr << "Comm::ExecuteUiCmds : PID file not found" << endl; exit(1); } char buf[10]; fgets(buf, 10, file); uiPid = atol(buf); fclose(file); break; case 'c': // changement de couleur int numColor; numColor = atoi(cut[NUMCOLORTOCHANGE]); // Changement des valeurs sur les poids du NN for (int i=0; i<3; i++) segm->node[numColor*3+i] = atoi(cut[COLORTOCHANGE+i]); // On segmente l'image puis on la stocke SegmAndGroup(); printf("Couleur %i changé aux valeurs : %u %u %u\n", numColor, segm->node[numColor*3], segm->node[numColor*3+1], segm->node[numColor*3+2]); break; case 'm': // mélanger couleurs int nbColorToMerge, numIndexColor; // Si on recoit une commande de remise a zero de l'index if (atoi(cut[NBCOLORTOMERGE]) == -1) { for (int i=0; inn_NbCouleurs; i++) segm->index[i] = i; } // Sinon on mix les couleurs else { nbColorToMerge = atoi(cut[NBCOLORTOMERGE]); numIndexColor = segm->index[atoi(cut[NUMCOLORTOMERGE])]; // On inscrit les changements dans l'index for (int i=1; iindex[atoi(cut[NUMCOLORTOMERGE+i])] = numIndexColor; } // On segmente l'image puis on la stocke SegmAndGroup(); cout << nbColorToMerge << " colors merged to " << numIndexColor << endl; break; case 's': // isole une couleur int numColorToShow; numColorToShow = atoi(cut[NUMCOLORTOSHOW]); // Cas ou toutes les couleurs doivent etre affiche if (numColorToShow == -1) SegmAndGroup(); // Afficher seulement une couleur else { segm->Segm(numColorToShow); // Creation de l'image segmentee img.DoImg(segm->tabSegm , data[0]); // Creation des groupes group = new Group(&img, segm); group->JumpPoints(oconfig->groupColor); group->TabOut(); img.DoImg(group->tabOut, data[1]); tex[2] = LoadImage(img.width, img.height, data[0], tex[2]); tex[5] = LoadImage(img.width, img.height, data[1], tex[5]); } break; case 'd': // supprimer couleur int numColorToDel; numColorToDel = atoi(cut[NUMCOLORTODEL]); // Decalage de toutes les couleurs pour supprimer une couleur unsigned char *pCur; pCur = &oconfig->node[numColorToDel*3]; for(int i=numColorToDel*3; inn_NbCouleurs*3; i++) { *(pCur) = *(pCur+3); pCur++; } oconfig->nn_NbCouleurs--; // On refait le NN vu qu'il y a une couleur de moins segm->BuildNN(oconfig->nn_NbCouleurs, LOAD_FROM_FILE); segm->ShowNodes(); // On segmente l'image puis on la stocke SegmAndGroup(); break; case 'r': // Reload l'image int nbNNOutput; nbNNOutput = atoi(cut[NBNNOUTPUT]); // Reattribution du nombre de sorties d'origine if (nbNNOutput != -1) oconfig->nn_NbCouleurs = nbNNOutput; // Recharge du fichier des poids oconfig->LoadNNFile("rc/poids"); // On refait le NN vu qu'il y a une couleur de moins segm->BuildNN(oconfig->nn_NbCouleurs, LOAD_FROM_FILE); // On segmente l'image puis on la stocke SegmAndGroup(); // Si l'image a ete sauve on change l'image pivot if (nbNNOutput == -1) { tex[1] = LoadImage(img.width, img.height, data[0], tex[1]); tex[4] = LoadImage(img.width, img.height, data[1], tex[4]); } break; case 'g': // Selection du groupe oconfig->groupColor = atoi(cut[NUMGROUP]); // On segmente l'image puis on la stocke SegmAndGroup(); break; case 'n': // Image suivante char *filename; filename = cut[FILENAME]; cout << filename << endl; // Copie du nom de l'image courante strcpy(fname, filename); // Ouverture de l'image pilote et stockage img.LoadRGB(filename, 0, 360, 296); // Allocation memoire pour les images for (int i=0; i<2; i++) { if (data[i]) delete data[i]; data[i] = new unsigned char[img.nbPixels*3]; } delete[] imgLeft[0]; imgLeft[0] = new unsigned char[img.nbPixels*3]; memcpy(imgLeft[0], img.tabData, sizeof(char)*img.nbPixels*3); tex[0] = LoadImage(img.width, img.height, imgLeft[0], tex[0]); // Conversion en YUV et stockage ConvertImg convert; convert.RGBtoYUV (img); tex[3] = LoadImage(img.width, img.height, img.tabData, tex[3]); // NN oconfigure en RGB ou YUV ? if (!oconfig->colorMode == RGB) img.LoadRGB(filename, 0, 360, 296); SegmAndGroup(); // Affichage de l'image pilote en RGB et YUV tex[1] = LoadImage(img.width, img.height, data[0], tex[1]); tex[4] = LoadImage(img.width, img.height, data[1], tex[4]); break; case 't': // Entraine le reseau segm->TrainNN(); // On segmente l'image puis on la stocke SegmAndGroup(); // Synchronisation des poids avec ui SendNodes(); break; case 'p': // Regenere les poids du reseau int nbColor; nbColor = atoi(cut[NBCOLORNN]); // Assignation du nombre de couleurs a isoler par le reseau oconfig->nn_NbCouleurs = nbColor; // Genere aleatoire les poids segm->BuildNN(oconfig->nn_NbCouleurs, GENERATE); // Apprentissage segm->TrainNN(); // On segmente l'image puis on la stocke SegmAndGroup(); // Synchronisation des poids avec ui SendNodes(); break; case 'v': // Envoie les points pour le calcul de la distance int *pPoint; pPoint = GetPpoint(); for (int i=0; itabPoint[i*4+0] = pPoint[i*2]; oconfig->tabPoint[i*4+1] = pPoint[i*2+1]; oconfig->tabPoint[i*4+2] = 0; oconfig->tabPoint[i*4+3] = 0; } oconfig->CreateDistFile("rc/dist", NB_POINTS_UI); break; case 'y': yuvSwitch++; cout << img.yuv << endl; // Conversion en YUV et stockage img.LoadRGB(fname, 0, 360, 296); if (yuvSwitch%3 == 1) { ConvertImg convert; convert.YUVtoRGB (img); } else if (yuvSwitch%3 == 2) { ConvertImg convert; convert.RGBtoYUV (img); } delete[] imgLeft[1]; imgLeft[1] = new unsigned char[img.nbPixels*3]; memcpy(imgLeft[1], img.tabData, sizeof(char)*img.nbPixels*3); tex[3] = LoadImage(img.width, img.height, imgLeft[1], tex[3]); img.LoadRGB(fname, 0, 360, 296); break; case 'z': group->ShowZones(); break; case 'f': { char buf[20]; ZONE *pCur = group->zoneListBall; write (fifo, "Groupes balles:\n", 20); while(pCur) { sprintf(buf, "%u %i %i %i %i\n", pCur->idColor, pCur->xmin, pCur->xmax, pCur->ymin, pCur->ymax); write (fifo, buf, 20); pCur = pCur->next; } pCur = group->zoneListGoal; write (fifo, "Groupes poteaux:\n", 20); while(pCur) { sprintf(buf, "%u %i %i %i %i\n", pCur->idColor, pCur->xmin, pCur->xmax, pCur->ymin, pCur->ymax); write (fifo, buf, 20); pCur = pCur->next; } write (fifo, "end\n", 20); } break; } DrawGLScene(); }