summaryrefslogtreecommitdiff
path: root/2005
diff options
context:
space:
mode:
authorgaillaro2005-04-05 18:30:06 +0000
committergaillaro2005-04-05 18:30:06 +0000
commit8df6328c400012812394fe5957b6837636fc74fe (patch)
treed66909635334305fe155b93c3bdece9408b06845 /2005
parent97b69507c877a4644c0caac4f61e052e188f9d8e (diff)
interfaces pour l'apprentissage du RN et pour visionner les traitements d'images à partir de plusieurs sources (file, cam, serv)
Diffstat (limited to '2005')
-rw-r--r--2005/i/robert/src/ovision/ui/Makefile.defs19
-rw-r--r--2005/i/robert/src/ovision/ui/adjust.cc351
-rw-r--r--2005/i/robert/src/ovision/ui/adjust.hh63
-rw-r--r--2005/i/robert/src/ovision/ui/comm.cc339
-rw-r--r--2005/i/robert/src/ovision/ui/comm.hh60
-rw-r--r--2005/i/robert/src/ovision/ui/live.cc180
-rw-r--r--2005/i/robert/src/ovision/ui/live.hh81
-rw-r--r--2005/i/robert/src/ovision/ui/mainui.cc51
-rw-r--r--2005/i/robert/src/ovision/ui/mainui.hh26
-rw-r--r--2005/i/robert/src/ovision/ui/testui.cc46
-rw-r--r--2005/i/robert/src/ovision/ui/testui.hh4
-rw-r--r--2005/i/robert/src/ovision/ui/ui.cc1057
-rw-r--r--2005/i/robert/src/ovision/ui/ui.hh118
13 files changed, 2395 insertions, 0 deletions
diff --git a/2005/i/robert/src/ovision/ui/Makefile.defs b/2005/i/robert/src/ovision/ui/Makefile.defs
new file mode 100644
index 0000000..3bddbf3
--- /dev/null
+++ b/2005/i/robert/src/ovision/ui/Makefile.defs
@@ -0,0 +1,19 @@
+PROGRAMS += adjust ui
+LIBS += adjust.a
+LIBSGL= -L/usr/X11R6/lib -lGL -lGLU -lglut
+LIBNCURSES=-lmenu -lncurses
+CXXFLAGS = -Wall -g
+LDFLAGS = -L/usr/pkg/lib
+
+adjust_OBJECTS = adjust.o comm.o img.o imgInterface.o image.o group.o segm.o segmLearn.o oconfig.o convertImg.o magnifier.o live.o $(data_OBJECTS) $(image_OBJECTS) $(video4linux_OBJECTS) $(utils_OBJECTS)
+liveView_OBJECTS = liveView.o live.o img.o imgInterface.o image.o group.o segm.o segmLearn.o oconfig.o convertImg.o magnifier.o $(data_OBJECTS) $(image_OBJECTS) $(video4linux_OBJECTS) $(utils_OBJECTS)
+ui_OBJECTS = ui.o mainui.o oconfig.o group.o segm.o
+
+ui: $(ui_OBJECTS:%.o=%.o)
+ $(CXX) $(LDFLAGS) $(LIBNCURSES) $^ -o $@
+
+adjust: $(adjust_OBJECTS:%.o=%.o)
+ $(CXX) $(LDFLAGS) $(LIBSGL) $^ -o $@
+
+liveView: $(liveView_OBJECTS:%.o=%.o)
+ $(CXX) $(LDFLAGS) $(LIBSGL) $^ -o $@
diff --git a/2005/i/robert/src/ovision/ui/adjust.cc b/2005/i/robert/src/ovision/ui/adjust.cc
new file mode 100644
index 0000000..0dc35f2
--- /dev/null
+++ b/2005/i/robert/src/ovision/ui/adjust.cc
@@ -0,0 +1,351 @@
+#include <GL/glut.h> // Header File For The GLUT Library
+#include <GL/gl.h> // Header File For The OpenGL32 Library
+#include <GL/glu.h> // Header File For The GLu32 Library
+#include <iostream>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+
+#include "adjust.hh"
+#include "comm.hh"
+
+using namespace std;
+
+#define IMG_WIDTH 360
+#define IMG_HEIGHT 296
+#define WIDTH 1076
+#define HEIGHT 591
+
+int window;
+Comm *comm;
+
+int point[NB_POINTS_UI][2] = {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}};
+int width=538; int height=395;
+
+int* getPpoint()
+{
+ return (int*)point;
+}
+
+
+/// Sortie du programme
+void
+leave (int numSignal)
+{
+ exit(0);
+}
+
+
+/// Sortie du programme anormal
+void
+tooLate(int numSignal)
+{
+ // Affichage d'un message d'erreur
+ cerr << "tooLate : Temps d'attente FIFO depasse\n";
+ leave(-1);
+}
+
+
+/// Lecture du fifo et execution de la commande
+void
+executeUiCmds(int numSignal)
+{
+ // Reassignement du signal handler
+ signal(SIGUSR1, executeUiCmds);
+
+ char buffer[50];
+
+ // On test si le fifo a ete initialiser
+ if (numSignal == SIGUSR2)
+ {
+ // Permet l'envoie du message d'initialisation
+ strcpy(buffer, "i\n");
+ }
+ else
+ {
+ // Timer
+ signal(ALARM, tooLate);
+ alarm(5);
+
+ // Lecture du FIFO
+ if (!read (comm->fifo, buffer, 50))
+ {
+ cerr << "ReadUicmds : Error FIFO is empty" << endl;
+ return;
+ }
+
+ alarm(0);
+ }
+
+ // Parse de la commande recue
+ comm->executeUiCmds(buffer);
+
+ // Envoyer un signal de réponse à UI
+ kill(comm->uiPid, SIGUSR1);
+}
+
+
+/// Chargement d'une texture a partir de donnees RGB
+unsigned int
+loadImage(int width, int height, unsigned char *data, unsigned int lastTex)
+{
+ GLuint tex;
+
+ if (glIsTexture(lastTex)) glDeleteTextures(1, &lastTex);
+
+
+ // Mode de chargement des donnees
+ glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
+
+ // Creer une id pour stocker l'image
+ glGenTextures(1, &tex);
+ glBindTexture(GL_TEXTURE_2D, tex);
+
+ // Stocke l'image
+ //glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
+ gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height, GL_RGB, GL_UNSIGNED_BYTE, data);
+
+ // Config des parametres
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
+
+ // Retourne l'id de l'image
+ return tex;
+}
+
+
+/// Initialisation des fonctions OpenGL
+void
+initGL(int width, int height)
+{
+ // Initialisation du mode d'affichage
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+
+ // Mode de chargement des donnees
+ glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
+ glShadeModel(GL_FLAT);
+ glEnable(GL_TEXTURE_2D);
+
+
+ // Remise a zero de la matrice de projection
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+
+ // Plan de projection en 2D
+ glOrtho(0.0, WIDTH, 0.0, HEIGHT, -1.0, 1.0);
+ glMatrixMode(GL_MODELVIEW);
+
+ glPointSize(4.0f);
+}
+
+
+
+/// Redimenssionement d'une fenetre
+void
+reSizeGLScene(int w, int h)
+{
+ // Evite div par 0
+ if (height==0) h=1;
+
+ height = h;
+ width = w;
+
+ // Initialise le point de vue
+ glViewport(0, 0, w, h);
+ glMatrixMode(GL_PROJECTION);
+
+ // Remise a zero et mode 2D
+ glLoadIdentity();
+ glOrtho(0.0, WIDTH, 0.0, HEIGHT, -1.0, 1.0);
+ glMatrixMode(GL_MODELVIEW);
+
+}
+
+
+/// Affiche une image
+/// @param texId numero de la texture a afficher
+void
+drawImage(GLuint texId)
+{
+ int wMin, wMax;
+ int hMin, hMax;
+
+ // Selection de l'image
+ glBindTexture(GL_TEXTURE_2D, comm->getTex ()[texId]);
+
+ // Calcul des coordonnees de l'image
+ wMin = BORDER+(texId%3)*(352+BORDER);
+ wMax = 352+BORDER+(texId%3)*(352+BORDER);
+ hMin = HEIGHT-288-BORDER-(int)(texId/3)*(288+BORDER);
+ hMax = HEIGHT-BORDER-(int)(texId/3)*(288+BORDER);
+
+ // Dessine un carre contenant l'image
+ glBegin(GL_QUADS);
+ glNormal3f( 0.0f, 0.0f, 1.0f);
+ glColor3f(1.0f,1.0f,1.0f);
+ glTexCoord2f(0.0f, 0.0f); glVertex3f(wMax, hMax, -1.0f);
+ glTexCoord2f(1.0f, 0.0f); glVertex3f(wMin, hMax, -1.0f);
+ glTexCoord2f(1.0f, 1.0f); glVertex3f(wMin, hMin, -1.0f);
+ glTexCoord2f(0.0f, 1.0f); glVertex3f(wMax, hMin, -1.0f);
+ glEnd();
+}
+
+
+/// Dessine les images a l'ecran
+void
+drawGLScene()
+{
+ // Efface le buffer
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
+ // Affiche toutes les images
+ for (int i=0; i<NBIMG; i++)
+ drawImage(i);
+
+
+
+ glColor3ub(0,0,255);
+ glDisable(GL_TEXTURE_2D);
+ // Dessine points de calibration de la distance
+ for (int i=0; i<NB_POINTS_UI; i++)
+ {
+ if (point[i][0] >= 0)
+/* x = (int)((double)WIDTH/width * x);
+ y = height - y;
+ y = (int)((double)HEIGHT/height * y);*/
+ glBegin(GL_POINTS);
+ glVertex3f( (float)((point[i][0] + BORDER) * (double)352 / IMG_WIDTH),
+ (float)((point[i][1] + BORDER) * (double)288 / IMG_HEIGHT),
+ -0.9f);
+ glVertex3f( (float)((point[i][0] + BORDER) * (double)352 / IMG_WIDTH),
+ (float)((point[i][1] + BORDER) * (double)288 / IMG_HEIGHT + 288 + BORDER),
+ -0.9f);
+ glEnd();
+
+ }
+ glEnable(GL_TEXTURE_2D);
+
+
+ glFlush();
+
+ // Affiche le buffer suivant
+ glutSwapBuffers();
+}
+
+
+/// Interruptions du clavier
+void
+keyPressed(unsigned char key, int x, int y)
+{
+ // Touche Echap
+ if (key == 27)
+ {
+ glutDestroyWindow(window);
+ leave(0);
+ }
+ if (key == 'r')
+ comm->reloadConfig ("rc/vision.conf");
+}
+
+/// Gestion souris
+void
+mouseFunc(int button, int state, int x, int y)
+{
+ if (state == GLUT_UP)
+ {
+ // On calcul les coordonnees de l'image
+ x = (int)((double)WIDTH/width * x);
+ y = (int)((double)HEIGHT/height * y);
+ int imgX = -1;
+ int imgY = -1;
+ if ((x < 352+BORDER) && (y < BORDER+288) && (x > BORDER) && (y > BORDER))
+ {
+ imgX = x * IMG_WIDTH / 352 - BORDER;
+ imgY = y * IMG_HEIGHT / 288 - BORDER;
+
+ }
+
+ if ((x < 352+BORDER) && (y < HEIGHT-BORDER) && (x > BORDER) && (y > 2*BORDER+288))
+ {
+ imgX = x * IMG_WIDTH / 352 - BORDER;
+ imgY = y * IMG_HEIGHT / 288 - 3 * BORDER - 288;
+ }
+
+ cout << "x " << imgX << " y " << imgY << endl;
+ int i=0;
+
+ if (imgX >= 0)
+ {
+ imgY = IMG_HEIGHT - imgY;
+
+ // Ajout de point
+ if (button == GLUT_LEFT_BUTTON)
+ {
+ while(i < NB_POINTS_UI)
+ {
+ if (point[i][0] < 0)
+ {
+ point[i][0] = imgX;
+ point[i][1] = imgY;
+ i=NB_POINTS_UI+3;
+ cout << "Point ajoute: " << imgX << ", " << imgY << endl;
+ }
+ i++;
+ }
+ if (i == NB_POINTS_UI+3) cout << "MouseFunc : 3 points sont deja selectionnes" << endl;
+ }
+
+ // Suppression de point
+ else if (button == GLUT_RIGHT_BUTTON)
+ {
+ while(i<NB_POINTS_UI)
+ {
+ if ((abs(point[i][0] - imgX) < 5) && (abs(point[i][1] - imgY) < 5))
+ {
+ point[i][0] = -1;
+ point[i][1] = -1;
+ i=NB_POINTS_UI+3;
+ }
+ i++;
+ }
+ if (i == NB_POINTS_UI+3) cout << "MouseFunc : 0 point selectionne" << endl;
+ }
+ }
+ drawGLScene();
+ }
+}
+
+/// Fonction principale
+int
+main(int argc, char **argv)
+{
+ // Initialisation de l'OpenGL
+ glutInit(&argc, argv);
+ glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
+ glutInitWindowSize(width, height);
+ glutInitWindowPosition(0, 0);
+ window = glutCreateWindow("adjust - APBteam");
+ glutDisplayFunc(&drawGLScene);
+ glutReshapeFunc(&reSizeGLScene);
+ glutKeyboardFunc(&keyPressed);
+ glutMouseFunc(&mouseFunc);
+ initGL(WIDTH, HEIGHT);
+
+ // Init de comm
+ comm = new Comm("shots/test.rgb");
+ comm->init ();
+
+ //Initialisation des signal handlers
+ signal(SIGUSR1, executeUiCmds);
+ signal(SIGUSR2, executeUiCmds);
+ signal(SIGQUIT, leave);
+
+ // Boucle principale
+ glutMainLoop();
+
+ return 1;
+}
diff --git a/2005/i/robert/src/ovision/ui/adjust.hh b/2005/i/robert/src/ovision/ui/adjust.hh
new file mode 100644
index 0000000..9a248c8
--- /dev/null
+++ b/2005/i/robert/src/ovision/ui/adjust.hh
@@ -0,0 +1,63 @@
+// robert - programme du robot 2005
+//
+// Copyright (C) 2005 Olivier Gaillard
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+#ifndef adjust_h
+#define adjust_h
+
+/// Constantes d'interruptions
+#define QUIT 3
+#define USR1 10
+#define ALARM 14
+
+
+/// Proprietes de la fenetre
+#define BORDER 5
+#define NBIMG 6
+
+/// Constantes liees au chargement des commandes
+#define NUMCOLORTOCHANGE 1
+#define COLORTOCHANGE 2
+
+#define NBCOLORTOMERGE 1
+#define NUMCOLORTOMERGE 2
+
+#define NUMCOLORTODEL 1
+
+#define NBNNOUTPUT 1
+
+#define NUMGROUP 1
+
+#define NUMCOLORTOSHOW 1
+
+#define FILENAME 1
+
+#define NBCOLORNN 1
+
+/// Affiche les images a l'ecran
+void drawGLScene();
+
+/// Chargement des textures a partir de donnees RGB
+unsigned int loadImage(int width, int height, unsigned char *data, unsigned int lastTex);
+int *getPpoint();
+
+#endif // adjust_h
diff --git a/2005/i/robert/src/ovision/ui/comm.cc b/2005/i/robert/src/ovision/ui/comm.cc
new file mode 100644
index 0000000..906ad51
--- /dev/null
+++ b/2005/i/robert/src/ovision/ui/comm.cc
@@ -0,0 +1,339 @@
+// comm.cc - Classe Comm
+// robert - Programme du robot APBteam
+// Copyright (C) 2005 Olivier Gaillard
+
+
+/// @file comm.cc Interprete les commandes envoyes par l'interface UI et les executent
+
+#include <iostream>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string>
+#include <sstream>
+
+#include "comm.hh"
+
+/// Constructeur
+/// @param *filename nom de l'image a utiliser
+Comm::Comm (const char *filename)
+ : yuvSwitch (0)
+{
+ // Copie du nom de l'image courante
+ strcpy(fname, filename);
+}
+
+void
+Comm::init ()
+{
+ // Ecriture du PID dans un fichier
+ long pid = getpid();
+ FILE *file = fopen("adjust.PID", "w+");
+ if (!file)
+ {
+ std::cerr << "Comm::Comm Error during file opening" << std::endl;
+ return;
+ }
+ fprintf(file, "%li\n", pid);
+ fclose(file);
+
+ live_ = new Live (NBIMG);
+ live_->init (fname);
+}
+
+/// Destructeur
+Comm::~Comm()
+{
+ close(fifo);
+}
+
+/// Synchronisation des poids locaux et de ceux du programme ui
+void
+Comm::sendNodes ()
+{
+ char buf[10];
+ for (int i=0; i < live_->oconfig->nnNbColor*3; i++)
+ {
+ sprintf(buf, "%u\n", live_->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 (const char *buffer)
+{
+ std::cout << "Commande reçue : " << buffer;
+ std::stringstream ss;
+ ss << buffer;
+ char cmd;
+ ss >> cmd;
+ // Detection de la commande recue
+ switch (cmd)
+ {
+ case 'i': // ouverture du fifo
+ std::cout << "Initialisation du fifo\n";
+ // Ouverture du fifo
+ fifo = open("uicmds", O_RDWR);
+ if (!fifo) {
+ std::cerr << "InitComm : Error during opening FIFO" << std::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)
+ {
+ std::cerr << "Comm::ExecuteUiCmds : PID file not found" << std::endl;
+ exit(1);
+ }
+ char buf[10];
+ fgets(buf, 10, file);
+ uiPid = atol(buf);
+ fclose(file);
+ break;
+
+ case 'c': // changement de couleur
+ int numColor;
+ ss >> numColor;
+
+ // Changement des valeurs sur les poids du NN
+ int colorToChange;
+ for (int i=0; i<3; i++)
+ {
+ ss >> colorToChange;
+ live_->segm->node_[numColor*3+i] = colorToChange;
+ }
+ // On live_->segmente l'image puis on la stocke
+ live_->segmAndGroup ();
+ std::cout << "Couleur " << numColor << " changé aux valeurs " << (int)live_->segm->node_[numColor*3] << " " << (int)live_->segm->node_[numColor*3+1] << " " << (int)live_->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_
+ ss >> nbColorToMerge;
+ if (nbColorToMerge == -1)
+ {
+ for (int i=0; i<live_->oconfig->nnNbColor; i++)
+ live_->segm->index_[i] = i;
+ }
+ // Sinon on mix les couleurs
+ else
+ {
+ numIndexColor = live_->segm->index_[nbColorToMerge];
+
+ // On inscrit les changements dans l'index_
+ int numColorToMerge;
+ for (int i=1; i<nbColorToMerge; i++)
+ {
+ ss >> numColorToMerge;
+ live_->segm->index_[numColorToMerge] = numIndexColor;
+ }
+ }
+ // On live_->segmente l'image puis on la stocke
+ live_->segmAndGroup();
+ std::cout << nbColorToMerge << " colors merged to " << numIndexColor << std::endl;
+ break;
+
+ case 's': // isole une couleur
+ int numColorToShow;
+ ss >> numColorToShow;
+ // Cas ou toutes les couleurs doivent etre affiche
+ if (numColorToShow == -1)
+ live_->segmAndGroup ();
+ // Afficher seulement une couleur
+ else
+ live_->segmAndGroup (numColorToShow);
+ break;
+
+ case 'd': // supprimer couleur
+ int numColorToDel;
+ ss >> numColorToDel;
+ // Decalage de toutes les couleurs pour supprimer une couleur
+ unsigned char *pCur;
+ pCur = &live_->oconfig->node[numColorToDel*3];
+ for(int i=numColorToDel*3; i<live_->oconfig->nnNbColor*3; i++)
+ {
+ *(pCur) = *(pCur+3);
+ pCur++;
+ }
+ live_->oconfig->nnNbColor--;
+ // On refait le NN vu qu'il y a une couleur de moins
+ live_->segm->buildNN(live_->oconfig->nnNbColor, Segm::loadFromFile);
+ live_->segm->showNodes();
+ // On live_->segmente l'image puis on la stocke
+ live_->segmAndGroup();
+ break;
+
+ case 'r': // Reload l'image
+ int nbNNOutput;
+ ss >> nbNNOutput;
+ // Reattribution du nombre de sorties d'origine
+ if (nbNNOutput != -1) live_->oconfig->nnNbColor = nbNNOutput;
+ // Recharge du fichier des poids
+ live_->oconfig->loadNNFile("rc/poids");
+ // On refait le NN vu qu'il y a une couleur de moins
+ live_->segm->buildNN(live_->oconfig->nnNbColor, Segm::loadFromFile);
+ // On live_->segmente l'image puis on la stocke
+ live_->segmAndGroup();
+ // Si l'image a ete sauve on change l'image pivot
+ if (nbNNOutput == -1)
+ live_->rootPics ();
+ break;
+
+ case 'a': // Selectionne la couleur des objets à afficher
+ {
+ int obj;
+ ss >> obj;
+ std::cout << "Changement de l'objet affiché " << obj << std::endl;
+ live_->oconfig->uiGroupToDisplay = obj;
+ live_->segmAndGroup ();
+ live_->rootPics ();
+ }
+ break;
+
+ case 'b': // Selectionne la couleur des objets
+ {
+ int col;
+ std::string obj;
+ ss >> obj >> col;
+ for (std::vector<ObjectColor>::iterator iter=live_->oconfig->groupColor.begin ();
+ iter != live_->oconfig->groupColor.end (); ++iter)
+ {
+ if (obj == iter->label)
+ {
+ iter->color = col;
+ break;
+ }
+ }
+ live_->segmAndGroup ();
+ live_->rootPics ();
+ }
+ break;
+ /*
+ case 'g': // Selection du live_->groupe
+ ss >> live_->oconfig->live_->groupColor;
+ */
+ // On live_->segmente l'image puis on la stocke
+ live_->segmAndGroup();
+ break;
+
+
+ case 'n': // Image suivante
+ std::cout << ss.str () << std::endl;
+ // Copie du nom de l'image courante
+ ss >> fname;
+ // Ouverture de l'image pilote et stockage
+ live_->img->loadRaw(fname, Image::rgb, 360, 296);
+ memcpy(live_->data[0], live_->img->tabData_, sizeof(char)*live_->img->nbPixels_*3);
+ live_->tex[0] = loadImage(live_->img->width_, live_->img->height_, live_->data[0], live_->tex[0]);
+ // Conversion en YUV et stockage
+ ConvertImg convert;
+ convert.RGBtoYUV (*live_->img);
+ // NN live_->oconfigure en RGB ou YUV ?
+ if (!live_->oconfig->inputColor == Image::rgb) live_->img->loadRaw(fname, Image::rgb, 360, 296);
+ live_->segmAndGroup();
+ // Affichage de l'image pilote
+ live_->rootPics ();
+ break;
+
+
+ case 't': // Entraine le reseau
+ live_->segm->trainNN(live_->img);
+ // On live_->segmente l'image puis on la stocke
+ live_->segmAndGroup();
+ // Synchronisation des poids avec ui
+ sendNodes();
+ break;
+
+ case 'p': // Regenere les poids du reseau
+ int nbColor;
+ ss >> nbColor;
+ // Assignation du nombre de couleurs a isoler par le reseau
+ live_->oconfig->nnNbColor = nbColor;
+ // Genere aleatoire les poids
+ live_->segm->buildNN(live_->oconfig->nnNbColor, Segm::generate);
+ // Apprentissage
+ live_->segm->trainNN(live_->img);
+ // On live_->segmente l'image puis on la stocke
+ live_->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; i<NB_POINTS_UI; i++)
+ if (pPoint[i*2] == -1)
+ {
+ cerr << "Comm::ExecuteUiCmds : Pas assez de points selectionnes\n";
+ return;
+ }
+
+ // for (int i = 0; i<NB_POINTS_UI; i++)
+ // {
+ // live_->oconfig->tabPoint[i*4+0] = pPoint[i*2];
+ // live_->oconfig->tabPoint[i*4+1] = pPoint[i*2+1];
+ // live_->oconfig->tabPoint[i*4+2] = 0;
+ // live_->oconfig->tabPoint[i*4+3] = 0;
+ // }
+
+ live_->oconfig->createDistFile("rc/dist", NB_POINTS_UI);
+ break;
+ *//*
+ case 'y':
+ yuvSwitch++;
+
+ // Conversion en YUV et stockage
+ live_->img->loadRaw(filename, Image::yuv, 360, 296);
+ if (yuvSwitch%3 == 1)
+ {
+ ConvertImg convert;
+ convert.YUVtoRGB (live_->img->;
+ }
+ else if (yuvSwitch%3 == 2)
+ {
+ ConvertImg convert;
+ convert.RGBtoYUV (live_->img->;
+ }
+ delete[] live_->img->eft[1];
+ live_->img->eft[1] = new unsigned char[live_->img->nbPixels_*3];
+ memcpy(live_->img->eft[1], live_->img->tabData_, sizeof(char)*live_->img->nbPixels_*3);
+ live_->tex[3] = loadImage(live_->img->width_, live_->img->height_, live_->img->eft[1], live_->tex[3]);
+ live_->img->loadRaw(fname, Image::yuv, 360, 296);
+ break;
+ */
+ case 'z':
+ live_->group->showZones();
+ break;
+ /*
+ case 'f':
+ {
+ ///TODO
+ char buf[20];
+ Zone *pCur = live_->group->zoneListBall;
+ write (fifo, "Groupes balles:\n", 20);
+ while(pCur) {
+ sprintf(buf, "%u %i %i %i %i\n", pCur->id, pCur->xmin, pCur->xmax, pCur->ymin, pCur->ymax);
+ write (fifo, buf, 20);
+ }
+
+ pCur = live_->group->zoneListGoal;
+ write (fifo, "Groupes poteaux:\n", 20);
+ while(pCur) {
+ sprintf(buf, "%u %i %i %i %i\n", pCur->id, pCur->xmin, pCur->xmax, pCur->ymin, pCur->ymax);
+ write (fifo, buf, 20);
+ }
+ write (fifo, "end\n", 20);
+ }
+ break;
+ */
+ }
+ drawGLScene();
+}
+
diff --git a/2005/i/robert/src/ovision/ui/comm.hh b/2005/i/robert/src/ovision/ui/comm.hh
new file mode 100644
index 0000000..3d36cae
--- /dev/null
+++ b/2005/i/robert/src/ovision/ui/comm.hh
@@ -0,0 +1,60 @@
+// robert - programme du robot 2005
+//
+// Copyright (C) 2005 Olivier Gaillard
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#ifndef comm_h
+#define comm_h
+
+#include "live.hh"
+
+/// Interprete les commandes envoyes par l'interface UI et les executent
+class Comm
+{
+ int yuvSwitch;
+ Live *live_;
+ /// nom de l'image courante
+ char fname[100];
+ public:
+ /// Constructeur
+ Comm (const char *filename);
+ /// Destructeur
+ ~Comm (void);
+ /// classe de traitement de l'image pour affichage
+ /// PID du programme ui
+ long uiPid;
+ /// id utilisé pour l'ouverture du fifo
+ int fifo;
+ /// Initialisation
+ void init ();
+ /// Recharge le fichier de conf
+ void reloadConfig (const char *filename) {live_->reloadConfig (filename);}
+ /// Execute une commande venant de l'interface
+ void executeUiCmds (const char *buffer);
+ /// Accessors
+ unsigned* getTex () {return live_->tex;}
+
+ private:
+ /// Synchronisation des poids locaux et de ceux du programme ui
+ void sendNodes();
+};
+
+
+#endif // comm_h
diff --git a/2005/i/robert/src/ovision/ui/live.cc b/2005/i/robert/src/ovision/ui/live.cc
new file mode 100644
index 0000000..21a7c3e
--- /dev/null
+++ b/2005/i/robert/src/ovision/ui/live.cc
@@ -0,0 +1,180 @@
+// comm.cc - Classe Live
+// robert - Programme du robot APBteam
+// Copyright (C) 2005 Olivier Gaillard
+
+
+/// @file live.cc Traitement de l'image dans le but d'être visualisé sur une interface
+
+#include <iostream>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string>
+#include <sstream>
+
+#include "live.hh"
+#include "image/raw_reader.hh"
+#include "data/data_input_file.hh"
+#include "video4linux/video4linux.hh"
+
+/// Constructeur
+/// @param *filename nom de l'image a utiliser
+Live::Live (const unsigned nbImg, const ImageInput imgInput)
+ : group (0), imgInput_ (imgInput)
+{
+ if (nbImg < 6) nbImg_ = 6;
+ else nbImg_ = nbImg;
+}
+
+void
+Live::init (const char *filename)
+{
+ tex = new unsigned[nbImg_];
+ data = new unsigned char*[nbImg_];
+ // Creation de oconfig
+ oconfig = new OConfig ();
+ // Création de l'image
+ img = new ImgInterface;
+ // Ouverture de l'image pilote et stockage
+ Image::PixelFormat pf = Image::rgb;
+ switch (imgInput_)
+ {
+ case file:
+ {
+ // Copie du nom de l'image courante
+ strcpy (fname, filename);
+ std::string f (fname);
+ DataInputFile *dif = new DataInputFile (f);
+ DataInput *di = reinterpret_cast<DataInput*> (dif);
+ reader_ = new RawReader (*di, 360, 296, pf);
+ }
+ break;
+ case cam:
+ {
+ Video4Linux *r;
+ r = new Video4Linux ("/dev/video", pf);
+ r->calibrate ();
+ reader_ = reinterpret_cast<ImageReader*> (r);
+ }
+ break;
+ case serv:
+ break;
+ }
+ img->load (*reader_);
+ // Allocation memoire pour les images
+ for (unsigned i=0; i<nbImg_; i++)
+ data[i] = new unsigned char[img->nbPixels_*3];
+ memcpy(data[0], img->tabData_, sizeof(char) * img->nbPixels_ * 3);
+ tex[0] = loadImage(img->width_, img->height_, data[0], tex[0]);
+ // Initialisation de la segmentation
+ segm = new SegmLearn;
+ segm->buildNN (oconfig->nnNbColor, Segm::loadFromFile);
+ mag = new Magnifier (img, segm);
+ segmAndGroup ();
+ // Affichage de l'image pilote avec la couleur d'aquisition et en RGB
+ tex[1] = loadImage (img->width_, img->height_, data[0], tex[1]);
+ /*if (img->colorMode_ != Image::rgb)
+ {
+ ConvertImg conv;
+ conv.ConvertToRGB (*img);
+ tex[3] = loadImage (img->width_, img->height_, data[0], tex[4]);
+ img->loadRaw (fname, Image::rgb, 360, 296);
+ }*/
+ rootPics ();
+}
+
+/// Mis à jour de l'image
+void
+Live::updateImg (const char *filename)
+{
+ Image::PixelFormat pf = Image::rgb;
+ switch (imgInput_)
+ {
+ case file:
+ {
+ // Copie du nom de l'image courante
+ strcpy (fname, filename);
+ std::string f (filename);
+ DataInputFile *dif = new DataInputFile (f);
+ DataInput *di = reinterpret_cast<DataInput*> (dif);
+ delete reader_;
+ reader_ = new RawReader (*di, 360, 296, pf);
+ }
+ break;
+ case cam:
+ case serv:
+ break;
+ }
+ img->load (*reader_);
+ memcpy(data[0], img->tabData_, sizeof(char) * img->nbPixels_ * 3);
+ tex[0] = loadImage(img->width_, img->height_, data[0], tex[0]);
+ segmAndGroup ();
+ rootPics ();
+}
+
+/// Fixe une image ségmentée et une image de groupe dans la partie centrale
+void
+Live::rootPics ()
+{
+ memcpy (data[1], data[2], sizeof (char)*img->nbPixels_*3);
+ memcpy (data[4], data[5], sizeof (char)*img->nbPixels_*3);
+ tex[1] = loadImage(img->width_, img->height_, data[1], tex[1]);
+ tex[4] = loadImage(img->width_, img->height_, data[4], tex[4]);
+
+}
+
+/// Destructeur
+Live::~Live()
+{
+ // Liberation de la memoire
+ delete oconfig;
+ delete segm;
+ delete group;
+ delete [] data;
+}
+
+/// Recharge le fichier de config
+void
+Live::reloadConfig (const char *filename)
+{
+ oconfig->load (filename);
+}
+
+
+/// Segmente et group les couleurs
+void
+Live::segmAndGroup(int numColorToShow)
+{
+ // Création des groupes
+ delete group;
+ group = new Group(img, segm);
+ std::vector<Zone> list;
+ if (numColorToShow >= 0)
+ {
+ group->jumpPoints(numColorToShow);
+ list = group->getZoneList ();
+ }
+ else
+ {
+ group->jumpPoints(oconfig->groupColor);
+ mag->analyse (group->getZoneList ());
+ list = mag->getItemList ((Group::ZoneType)oconfig->uiGroupToDisplay);
+ }
+ // Création de l'image des groupes
+ img->doGroupImg (list);
+ img->doImg (img->getTabSegm ());
+ memcpy (data[5], img->getTabOut (), sizeof (char)*img->nbPixels_*3);
+ // Création de l'image segmentée
+ if (numColorToShow >= 0)
+ segm->segmImg (img, numColorToShow);
+ else
+ {
+ segm->segmImg (img);
+ img->addGroupToDisplay (img->getTabSegm (), list);
+ }
+ img->doImg (img->getTabSegm ());
+ memcpy (data[2], img->getTabOut (), sizeof (char)*img->nbPixels_*3);
+ tex[2] = loadImage(img->width_, img->height_, data[2], tex[2]);
+ tex[5] = loadImage(img->width_, img->height_, data[5], tex[5]);
+}
+
diff --git a/2005/i/robert/src/ovision/ui/live.hh b/2005/i/robert/src/ovision/ui/live.hh
new file mode 100644
index 0000000..7c5301e
--- /dev/null
+++ b/2005/i/robert/src/ovision/ui/live.hh
@@ -0,0 +1,81 @@
+// robert - programme du robot 2005
+//
+// Copyright (C) 2005 Olivier Gaillard
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#ifndef live_h
+#define live_h
+
+#include "adjust.hh"
+#include "ovision/see/convertImg.hh"
+#include "ovision/see/imgInterface.hh"
+#include "ovision/see/segmLearn.hh"
+#include "ovision/see/oconfig.hh"
+#include "ovision/see/group.hh"
+#include "ovision/see/magnifier.hh"
+
+#define NB_POINTS_UI 6
+
+/// Traitement de l'image dans le but d'être visualisé sur une interface
+class Live
+{
+ unsigned nbImg_;
+ ImageReader *reader_;
+ public:
+ enum ImageInput {file, cam, serv};
+ /// Constructeur
+ Live (const unsigned nbImg, const ImageInput imgInput = file);
+ /// Destructeur
+ ~Live (void);
+
+ /// tableau des numeros de textures utilises par openGL
+ unsigned *tex;
+ /// tableau de donnees RGB stockant les images
+ unsigned char **data;
+ /// classe image
+ ImgInterface *img;
+ /// classe config
+ OConfig *oconfig;
+ /// classe segmentation
+ SegmLearn *segm;
+ /// classe group
+ Group *group;
+ /// classe magnifier
+ Magnifier *mag;
+ /// nom de l'image courante
+ char fname[100];
+
+ /// Initialisation
+ void init (const char *filename);
+ /// Recharge le fichier de config
+ void reloadConfig (const char *filename);
+ /// Segmentation et groupement des couleurs
+ void segmAndGroup(int numColorToShow = -1);
+ /// Fixe une image ségmentée et une image de groupe dans la partie centrale
+ void rootPics ();
+ /// Mis à jour de l'image
+ void updateImg (const char *filename);
+
+ private:
+ ImageInput imgInput_;
+};
+
+
+#endif // live_h
diff --git a/2005/i/robert/src/ovision/ui/mainui.cc b/2005/i/robert/src/ovision/ui/mainui.cc
new file mode 100644
index 0000000..39bd3c2
--- /dev/null
+++ b/2005/i/robert/src/ovision/ui/mainui.cc
@@ -0,0 +1,51 @@
+#include "ui.hh"
+
+#include <iostream>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+
+using namespace std;
+
+UI *ui;
+int ready;
+
+int
+GetReady()
+{
+ return ready;
+}
+
+void
+SetReady(int i)
+{
+ ready = i;
+}
+
+
+// Lecture du fifo et execution de la commande
+void
+endSleep(int numSignal)
+{
+ // Reassignement du signal handler
+ signal(SIGUSR1, endSleep);
+ ready = 1;
+}
+
+
+int
+main(int argc, char **argv)
+{
+ signal(SIGUSR1, endSleep);
+
+ if (argc > 0)
+ {
+ ui = new UI (argv[1]);
+ }
+ else ui = new UI;
+
+ ui->menu ();
+
+ delete ui;
+}
diff --git a/2005/i/robert/src/ovision/ui/mainui.hh b/2005/i/robert/src/ovision/ui/mainui.hh
new file mode 100644
index 0000000..ba855ae
--- /dev/null
+++ b/2005/i/robert/src/ovision/ui/mainui.hh
@@ -0,0 +1,26 @@
+// robert - programme du robot 2005
+//
+// Copyright (C) 2005 Olivier Gaillard
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+int GetReady();
+void SetReady(int i);
+
diff --git a/2005/i/robert/src/ovision/ui/testui.cc b/2005/i/robert/src/ovision/ui/testui.cc
new file mode 100644
index 0000000..2493256
--- /dev/null
+++ b/2005/i/robert/src/ovision/ui/testui.cc
@@ -0,0 +1,46 @@
+#include "ui.hh"
+
+#include <iostream>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+
+using namespace std;
+
+UI *ui;
+int ready;
+
+int
+GetReady()
+{
+ return ready;
+}
+
+void
+SetReady(int i)
+{
+ ready = i;
+}
+
+
+// Lecture du fifo et execution de la commande
+void
+endSleep(int numSignal)
+{
+ // Reassignement du signal handler
+ signal(SIGUSR1, endSleep);
+ ready = 1;
+}
+
+
+int
+main()
+{
+ signal(SIGUSR1, endSleep);
+
+ ui = new UI;
+ ui->Menu();
+
+ delete ui;
+}
diff --git a/2005/i/robert/src/ovision/ui/testui.hh b/2005/i/robert/src/ovision/ui/testui.hh
new file mode 100644
index 0000000..2d550cb
--- /dev/null
+++ b/2005/i/robert/src/ovision/ui/testui.hh
@@ -0,0 +1,4 @@
+
+int GetReady();
+void SetReady(int i);
+
diff --git a/2005/i/robert/src/ovision/ui/ui.cc b/2005/i/robert/src/ovision/ui/ui.cc
new file mode 100644
index 0000000..525fca2
--- /dev/null
+++ b/2005/i/robert/src/ovision/ui/ui.cc
@@ -0,0 +1,1057 @@
+// ui.cc - Classe User Interface
+// robert - Programme du robot APBteam
+// Copyright (C) 2005 Olivier Gaillard
+
+/// @file ui.cc Interface ncurses permettant de piloter adjust
+
+#include <iostream>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string>
+
+#include "ui.hh"
+#include "mainui.hh"
+
+/// Nombre d'items du menu
+#define NBITEMS 12
+
+
+
+/// Items du menu principal
+char *itemsName[NBITEMS][2] = {{"Move color", "Permet d'ajuster les niveaux d'une couleur"},
+ {"Del color", "Enleve une couleur du reseau"},
+ {"Merge colors", "Groupe plusieurs couleurs ensembles"},
+ {"Object to display", "Selectionne l'object à afficher"},
+ {"Change object color", "Selectionne l'index de la couleur d'un objet"},
+ {"Show objets found", "Affiche les balles et poteaux trouvés"},
+ {"Training", "Entraine le reseau de neurones"},
+ {"New network", "Regenere de nouveaux poids pour le reseau"},
+ {"Cancel changes", "Recharge le fichier de oconfig"},
+ {"Save changes", "Sauvegarde les changements dans le fichier"},
+ {"Quit", "Quitte le programme"},
+ {NULL, NULL}};
+
+/// Constructor
+UI::UI(const char *filename)
+{
+ oconfig = new OConfig;
+
+ // TODO verifier que le terminal est assez grand sinon écran noir
+
+
+ // Suppression de l'ancien fifo
+ system("rm -f uicmds");
+
+ // Creation du fifo
+ if (mknod("uicmds", S_IFIFO | 0666, 0) != 0)
+ {
+ std::cerr << "UI::UI : Error during fifo creation\n";
+ return;
+ }
+
+ // Ouverture du fifo
+ fifo = open("uicmds", O_RDWR);
+ if (fifo < 0)
+ {
+ std::cerr << "UI::UI : Error during fifo opening\n";
+ return;
+ }
+
+ // On choppe le pid du prog adjust situé dans le fichier adjust.PID
+ FILE *file;
+ file = fopen("adjust.PID", "r");
+ if (!file)
+ {
+ std::cerr << "UI:UI : PID file not found" << std::endl;
+ exit(1);
+ }
+ char buf[10];
+ fgets(buf, 10, file);
+ pid = atol(buf);
+ fclose(file);
+
+ curImage = 0;
+ parseFileList();
+
+ oconfig->loadNNFile();
+ savedNNColorNumber = oconfig->nnNbColor;
+
+ // Ecriture du PID dans un fichier
+ long uiPid = getpid();
+ file = fopen("ui.PID", "w+");
+ if (!file)
+ {
+ std::cerr << "UI::UI : Error during file opening" << std::endl;
+ return;
+ }
+ fprintf(file, "%li\n", uiPid);
+ fclose(file);
+
+ // Ouverture du fifo
+ kill(pid, SIGUSR2);
+
+ // Init ncurses
+ initscr();
+ start_color();
+ keypad(stdscr, TRUE);
+ cbreak();
+ noecho();
+ curs_set(0);
+
+ // Init couleurs
+ init_pair(1, COLOR_BLUE, COLOR_BLACK);
+ init_pair(2, COLOR_RED, COLOR_BLACK);
+ init_pair(3, COLOR_GREEN, COLOR_BLACK);
+ init_pair(4, COLOR_CYAN, COLOR_BLACK);
+
+ if (filename)
+ {
+ sprintf(buf, "n %s\n", filename);
+ sendSignal(buf);
+ }
+}
+
+
+/// Destructeur
+UI::~UI()
+{
+ // Libere memoire
+ unpost_menu(mainMenu);
+ free_menu(mainMenu);
+ for(int i = 0; i < NBITEMS; ++i)
+ free_item(item[i]);
+ endwin();
+
+ close(fifo);
+
+ // Ferme adjust SIGQUIT
+ kill(pid, SIGQUIT);
+
+ system("rm -f adjust.PID ui.PID");
+
+ if (fileList) delete fileList;
+}
+
+
+/// Synchronisation des poids locaux avec ceux du programme adjust
+void
+UI::updateNodes ()
+{
+ char buf[10];
+
+ // On parcours toutes les couleurs
+ for (int i=0; i < oconfig->nnNbColor*3; i++)
+ {
+ // On lis le fifo et on le copie dans le tableau node
+ read(fifo, buf, 10);
+ oconfig->node[i] = atoi(buf);
+ }
+}
+
+
+
+/// Cree la liste d'images a ouvrir
+void
+UI::parseFileList ()
+{
+ // On enleve l'ancienne liste et on en cree une nouvelle
+ char buf[100];
+ sprintf(buf, "rm -Rf imagelist ; ls %s | grep -e .jpg -e .JPG -e .png -e .PNG > imagelist", oconfig->imgPath);
+ system(buf);
+
+ FILE *file;
+ file = fopen("imagelist", "r");
+ if (!file)
+ {
+ std::cerr << "UI:ParseFileList : file not found" << std::endl;
+ std::cerr << "UI:ParseFileList : use 'ls pictures_dir > imagelist" << std::endl;
+ exit(1);
+ }
+
+ lengthFileList = 0;
+
+ while(fgets(buf, 30, file))
+ lengthFileList++;
+ rewind(file);
+
+ fileList = new char*[lengthFileList];
+ int fileCount = 0;
+ char *p;
+
+ while (fgets(buf, 30, file))
+ {
+ fileList[fileCount] = new char[30];
+ p = strtok(buf, "\t\n");
+ if (p)
+ {
+ strcpy(fileList[fileCount], p);
+ fileCount++;
+ }
+ else lengthFileList--;
+ }
+}
+
+
+/// Envoie une donnee au prog adjust
+/// @param *cmd commande a envoyer
+void
+UI::sendSignal (const char *cmd)
+{
+ // Ecrit dans le fifo
+ write(fifo, cmd, 50);
+
+ // Envoie un signal USR1 au prog adjust
+ kill(pid, SIGUSR1);
+
+ // Attente de la reponse de adjust
+ SetReady(0);
+ while (!GetReady())
+ {
+ usleep(1);
+ }
+}
+
+/// Affiche un msg dans la barre d'etat
+/// @param *str message a afficher dans la barre d'etat
+void
+UI::printStatus (const char *str)
+{
+ // Creation de la fenetre
+ WINDOW *statusWindow = newwin(3, 60, 20, 5);
+ wattron(statusWindow, A_BOLD | COLOR_PAIR(4));
+
+ // Affichage du texte
+ wprintw(statusWindow, "%s\n", str);
+ wrefresh(statusWindow);
+
+ // Liberation de la memoire
+ delwin(statusWindow);
+}
+
+
+/// menu de selection de couleur
+/// @param type choix du texte des items
+/// @param current item selectionne au depart
+int
+UI::chooseColor (const int type, const int current)
+{
+ // Choix de la couleur
+ char **colorName;
+
+ // Nombre d'item a afficher
+ if (type == NB_COULEUR)
+ oconfig->nnNbColor = 10;
+
+ // Creation des items
+ ITEM **colorItem = new ITEM*[oconfig->nnNbColor+2];
+ colorName = new char*[oconfig->nnNbColor+1];
+ for (int i=0; i<oconfig->nnNbColor; i++)
+ {
+ colorName[i] = new char[20];
+ if (type == NUM_COULEUR)
+ sprintf(colorName[i], "Couleur %i", i);
+ else if (type == NB_COULEUR)
+ sprintf(colorName[i], "%i", i);
+ colorItem[i] = new_item(colorName[i] , NULL);
+ }
+ colorName[oconfig->nnNbColor] = new char[20];
+ sprintf(colorName[oconfig->nnNbColor], "Annuler");
+ colorItem[oconfig->nnNbColor] = new_item(colorName[oconfig->nnNbColor] , NULL);
+ colorItem[oconfig->nnNbColor+1] = NULL;
+
+ // Creation de la fenetre
+ WINDOW *colorWindow = newwin(11, 15, 9, 35);
+ keypad(colorWindow, TRUE);
+
+ // Creation du menu
+ MENU *colormenu = new_menu(colorItem);
+ set_menu_win(colormenu, colorWindow);
+ set_menu_mark(colormenu, " -> ");
+ post_menu(colormenu);
+ wrefresh(colorWindow);
+
+ // Affichage d'info
+ printStatus("Utiliser ENTREE pour selectionner la couleur\n");
+
+ char buf[50];
+ int car;
+ int col=0;
+
+ if (type == NUM_COULEUR)
+ {
+ // Cree une image de la couleur selectionnee
+ sprintf(buf, "s %i\n", current);
+ sendSignal(buf);
+ }
+
+ set_current_item(colormenu, colorItem[current]);
+ col = current;
+
+ wrefresh(colorWindow);
+
+ while((car = wgetch(colorWindow)) != 10)
+ {
+ switch (car)
+ {
+ case KEY_DOWN: // Touche BAS
+ // Deplacement dans le menu
+ if (col < (int)oconfig->nnNbColor)
+ {
+ menu_driver(colormenu, REQ_DOWN_ITEM);
+ col++;
+ }
+ break;
+
+ case KEY_UP: // Touche HAUT
+ // Deplacement dans le menu
+ if (col > 0)
+ {
+ menu_driver(colormenu, REQ_UP_ITEM);
+ col--;
+ }
+ break;
+ }
+
+ if ( (type == NUM_COULEUR) && (col < oconfig->nnNbColor))
+ {
+ // Cree une image de la couleur selectionnee
+ sprintf(buf, "s %i\n", col);
+ sendSignal(buf);
+ }
+
+ wrefresh(colorWindow);
+ }
+
+ // Cas d'annulation
+ if (col == oconfig->nnNbColor)
+ {
+ col = -1;
+
+ // On reaffiche l'image normale
+ sendSignal("r -1\n");
+ }
+
+ // Liberation memoire
+ for(int i=0; i<oconfig->nnNbColor; i++)
+ free_item(colorItem[i]);
+ free_menu(colormenu);
+ delwin(colorWindow);
+ colorWindow = newwin(11, 15, 9, 35);
+ wrefresh(colorWindow);
+ delwin(colorWindow);
+ delete [] colorName;
+
+ // Retourne la valeur choisie par l'utilisateur
+ return col;
+}
+
+/// menu de selection d'objet
+int
+UI::chooseObject (const int current)
+{
+ const int nbObjects = 5;
+
+ // Creation des items
+ const char *objectName[15] = {"greenSkittle", "redSkittle", "border", "base", "gap", "undefined", "annuler"};
+ ITEM **objectItem = new ITEM*[nbObjects+2];
+ for (int i = 0; i < nbObjects+1; ++i)
+ objectItem[i] = new_item(objectName[i], NULL);
+ objectItem[nbObjects+1] = NULL;
+
+ // Creation de la fenetre
+ WINDOW *objectWindow = newwin(7, 18, 10, 45);
+ keypad(objectWindow, TRUE);
+
+ // Creation du menu
+ MENU *objectmenu = new_menu(objectItem);
+ set_menu_win(objectmenu, objectWindow);
+ set_menu_mark(objectmenu, " -> ");
+ post_menu(objectmenu);
+ wrefresh(objectWindow);
+
+ // Affichage d'info
+ printStatus("Utiliser ENTREE pour selectionner l'objet\n");
+
+ int car;
+ int obj=0;
+
+ set_current_item(objectmenu, objectItem[current]);
+ obj = current;
+
+ wrefresh(objectWindow);
+
+ while((car = wgetch(objectWindow)) != 10)
+ {
+ switch (car)
+ {
+ case KEY_DOWN: // Touche BAS
+ // Deplacement dans le menu
+ if (obj < nbObjects)
+ {
+ menu_driver(objectmenu, REQ_DOWN_ITEM);
+ obj++;
+ }
+ break;
+
+ case KEY_UP: // Touche HAUT
+ // Deplacement dans le menu
+ if (obj > 0)
+ {
+ menu_driver(objectmenu, REQ_UP_ITEM);
+ obj--;
+ }
+ break;
+ }
+
+// if ( (type == NUM_COULEUR) && (obj < oconfig->nnNbColor))
+// {
+// // Cree une image de la couleur selectionnee
+// sprintf(buf, "s %i\n", obj);
+// sendSignal(buf);
+// }
+
+ wrefresh(objectWindow);
+ }
+
+ // Cas d'annulation
+ if (obj == nbObjects)
+ obj = -1;
+
+ // Liberation memoire
+ for(int i=0; i<nbObjects; i++)
+ free_item(objectItem[i]);
+ free_menu(objectmenu);
+ delwin(objectWindow);
+ objectWindow = newwin(7, 18, 10, 45);
+ wrefresh(objectWindow);
+ delwin(objectWindow);
+
+ // Retourne la valeur choisie par l'utilisateur
+ return obj;
+}
+
+
+
+/// menu de melange de couleurs
+void
+UI::goMergeWindow ()
+{
+ ITEM **items;
+ char **mergeName;
+
+ // Creation des items
+ ITEM **mergeItem = new ITEM*[oconfig->nnNbColor+2];
+ mergeName = new char*[oconfig->nnNbColor+1];
+ for (int i=0; i<oconfig->nnNbColor; i++)
+ {
+ mergeName[i] = new char[20];
+ sprintf(mergeName[i], "Couleur %i (%i)", i, oconfig->index[i]);
+ mergeItem[i] = new_item(mergeName[i] , NULL);
+ }
+
+ // Ajout du choix unmerge a la fin du menu
+ mergeName[oconfig->nnNbColor] = new char[20];
+ strcpy(mergeName[oconfig->nnNbColor], "Unmerge all");
+ mergeItem[oconfig->nnNbColor] = new_item(mergeName[oconfig->nnNbColor], NULL);
+ mergeItem[oconfig->nnNbColor+1] = NULL;
+
+ // Creation de la fenetre
+ WINDOW *mergeWindow = newwin(10, 20, 9, 35);
+ keypad(mergeWindow, TRUE);
+
+ // Creation du menu
+ MENU *mergemenu = new_menu(mergeItem);
+ set_menu_win(mergemenu, mergeWindow);
+ set_menu_mark(mergemenu, " -> ");
+ menu_opts_off(mergemenu, O_ONEVALUE);
+ post_menu(mergemenu);
+
+ wrefresh(mergeWindow);
+
+ // Initialisation de variables
+ int c;
+ int end = 0;
+ int col = 0;
+ char buf[40];
+ char cmd[50];
+ char tmp[3];
+ int nbColorToMerge = 0;
+
+ // Cree une image de la couleur selectionnee
+ sendSignal("s 0\n");
+
+ // Affichage d'info
+ printStatus("ESPACE pour choisir les valeurs, ENTREE pour valider\n");
+
+ // Boucle du menu de selection des couleurs
+ int indexColor = -1;
+ while(!end)
+ {
+ c = wgetch(mergeWindow);
+ switch (c)
+ {
+ case ' ': // Touche ESPACE
+ // Selection d'un element
+ menu_driver(mergemenu, REQ_TOGGLE_ITEM);
+ break;
+
+ case KEY_DOWN: // Touche BAS
+ // Deplacement dans le menu
+ if (col < oconfig->nnNbColor)
+ {
+ menu_driver(mergemenu, REQ_DOWN_ITEM);
+ col++;
+ }
+ break;
+
+ case KEY_UP: // Touche HAUT
+ // Deplacement dans le menu
+ if (col > 0)
+ {
+ menu_driver(mergemenu, REQ_UP_ITEM);
+ col--;
+ }
+ break;
+
+ case 10: // Touche ENTREE
+ // Validation des elements
+ items = menu_items(mergemenu);
+
+
+ // Si l'option unmerge est choisie
+ if ( item_index(current_item(mergemenu)) == item_count(mergemenu)-1)
+ {
+ // On remet a zero la table d'index
+ for (int i=0; i<oconfig->nnNbColor; i++)
+ oconfig->index[i] = i;
+
+ // Fin de la boucle
+ end = 1;
+ nbColorToMerge++;
+ }
+ else
+ {
+ // Parcours des items du menu
+ for (int i=0; i< item_count(mergemenu)-1; i++)
+ // Si il on ete valide on les ajoute a la string
+ if (item_value(items[i]) == TRUE)
+ {
+ // Memorisation du premier index trouve pour
+ // le copier dans les autres couleurs choisies
+ if (indexColor == -1) indexColor = oconfig->index[i];
+ sprintf(tmp, " %i", i);
+ strcat(buf, tmp);
+ nbColorToMerge++;
+ oconfig->index[i]= indexColor;
+ }
+
+ // Flag de fin de boucle
+ end = 1;
+ }
+ break;
+ }
+
+ if (col != oconfig->nnNbColor)
+ {
+ // Cree une image de la couleur selectionnee
+ sprintf(cmd, "s %i\n", col);
+ sendSignal(cmd);
+ }
+ }
+
+ if (nbColorToMerge)
+ {
+ // Cas ou unmerge a ete selectionne
+ if (indexColor == -1)
+ {
+ // Envoie un signal
+ sprintf(cmd, "m %i\n", -1);
+ sendSignal(cmd);
+
+ // Affichage d'info
+ sprintf(cmd, "Les index des couleurs ont ete remises a zero");
+ printStatus(cmd);
+ }
+ else
+ {
+ // Finition de la chaine a envoye
+ strcat(buf, "\n");
+ sprintf(cmd, "m %i", nbColorToMerge);
+ strcat(cmd, buf);
+
+ // Envoie du signal
+ sendSignal(cmd);
+
+ // Affichage d'info
+ sprintf(cmd, "Les couleurs melangees sont %s", buf+1);
+ printStatus(cmd);
+ }
+ }
+ else printStatus("Pas de couleur selectionnee\n");
+ wrefresh(mergeWindow);
+
+
+ // Liberation memoire
+ for(int i=0; i<oconfig->nnNbColor; i++)
+ free_item(mergeItem[i]);
+ free_menu(mergemenu);
+ delwin(mergeWindow);
+ mergeWindow = newwin(10, 20, 9, 35);
+ wrefresh(mergeWindow);
+ delwin(mergeWindow);
+ delete [] mergeName;
+}
+
+
+
+/// menu de suppression de couleur
+void
+UI::goDelColor()
+{
+ // menu de sélection de couleur
+ int numColor = chooseColor(NUM_COULEUR);
+
+ // Annulation
+ if (numColor < 0) return;
+
+ // Envoie du signal
+ char buf[50];
+ sprintf(buf, "d %i\n", numColor);
+ sendSignal(buf);
+
+ // On supprime la couleur en local
+ unsigned char *pCur;
+ pCur = &oconfig->node[numColor*3];
+ for(int i=numColor*3; i<oconfig->nnNbColor*3; i++)
+ {
+ *(pCur) = *(pCur+3);
+ pCur++;
+ }
+
+ oconfig->nnNbColor--;
+
+ // Affichage d'info
+ sprintf(buf, "Couleur %i supprimee\n", numColor);
+ printStatus(buf);
+}
+
+
+
+/// menu de selection du group a former
+void
+UI::goSelectGroup(const int type)
+{
+ // menu de selection de couleur
+/* int tmp;
+ if (type == BALL) tmp = chooseColor(NUM_COULEUR, oconfig->groupColor);
+ else if (type == GOAL) tmp = chooseColor(NUM_COULEUR, oconfig->goalColor);
+
+
+ if (tmp != -1)
+ {
+ if (type == BALL)
+ {
+
+ oconfig->groupColor = tmp;
+
+ // Envoie d'un signal avec la valeur choisie
+ char buf[50];
+ sprintf(buf, "g %i\n", tmp);
+ sendSignal(buf);
+ }
+ else if (type == GOAL)
+ {
+ oconfig->goalColor = tmp;
+ }
+ }
+ */
+}
+
+
+
+/// menu de suppression de couleur
+void
+UI::goChangeColor ()
+{
+ unsigned char c[3];
+ int ligne=0;
+ char cmd[50];
+
+ // menu de sélection de couleur
+ int col = chooseColor(NUM_COULEUR);
+
+ // Annulation
+ if (col < 0) return;
+
+ // Affectation des composantes actuelles
+ for (int i=0; i<3; i++)
+ c[i] = oconfig->node[col*3+i];
+
+ // Création de la fenetre
+ WINDOW *colorWindow = newwin(4, 60, 12, 25);
+ keypad(colorWindow, TRUE);
+
+ // Initialisation de l'affichage
+ wprintw(colorWindow, "Couleur %i:\n", col);
+ wprintw(colorWindow, "<---------------------------------------------------->\n");
+ wprintw(colorWindow, "<---------------------------------------------------->\n");
+ wprintw(colorWindow, "<---------------------------------------------------->\n");
+
+ // Affichage du curseur sur les lignes
+ // ainsi que des valeurs des composantes de la couleur
+ wattron(colorWindow, A_BOLD | COLOR_PAIR(1));
+ mvwprintw(colorWindow, 1, 56, "%3u", c[0]);
+ mvwprintw(colorWindow, 1, c[0]/5+1, "*");
+ wattroff(colorWindow, A_BOLD | COLOR_PAIR(1));
+ mvwprintw(colorWindow, 2, 56, "%3u", c[1]);
+ mvwprintw(colorWindow, 3, 56, "%3u", c[2]);
+ mvwprintw(colorWindow, 2, c[1]/5+1, "*");
+ mvwprintw(colorWindow, 3, c[2]/5+1, "*");
+
+ wrefresh(colorWindow);
+
+ // Boucle pour la selection des valeurs
+ int car;
+ while ((car = wgetch(colorWindow)) != 10)
+ {
+ switch(car)
+ {
+ case KEY_UP: // Touche HAUT
+ if (ligne != 0)
+ {
+ // Mise a jour affichage
+ mvwprintw(colorWindow, ligne+1, 56, "%3u", c[ligne]);
+ mvwprintw(colorWindow, ligne+1, c[ligne]/5+1, "*");
+ ligne--;
+ }
+ break;
+
+ case KEY_DOWN: // Touche BAS
+ if (ligne != 2)
+ {
+ // Mise a jour affichage
+ mvwprintw(colorWindow, ligne+1, 56, "%3u", c[ligne]);
+ mvwprintw(colorWindow, ligne+1, c[ligne]/5+1, "*");
+ ligne++;
+ }
+ break;
+
+ case KEY_LEFT: // Touche gauche
+ if (c[ligne] > 0)
+ {
+ // Mise a jour affichage
+ mvwprintw(colorWindow, ligne+1, c[ligne]/5+1, "-");
+ c[ligne]--;
+ }
+ break;
+
+ case KEY_RIGHT: // Touche droite
+ if (c[ligne] < 255)
+ {
+ // Mise a jour affichage
+ mvwprintw(colorWindow, ligne+1, c[ligne]/5+1, "-");
+ c[ligne]++;
+ }
+ break;
+
+ case KEY_NPAGE : // Touche gauche
+ if (c[ligne] > 9)
+ {
+ // Mise a jour affichage
+ mvwprintw(colorWindow, ligne+1, c[ligne]/5+1, "-");
+ c[ligne]-=10;
+ }
+ break;
+
+ case KEY_PPAGE: // Touche droite
+ if (c[ligne] < 246)
+ {
+ // Mise a jour affichage
+ mvwprintw(colorWindow, ligne+1, c[ligne]/5+1, "-");
+ c[ligne]+=10;
+ }
+ break;
+ }
+
+ // Mise a jour de l'affichage des valeurs
+ wattron(colorWindow, A_BOLD | COLOR_PAIR(1));
+ mvwprintw(colorWindow, ligne+1, 56, "%3u", c[ligne]);
+ mvwprintw(colorWindow, ligne+1, c[ligne]/5+1, "*");
+ wattroff(colorWindow, A_BOLD | COLOR_PAIR(1));
+
+ wrefresh(colorWindow);
+
+ // Communication avec adjust
+ sprintf(cmd, "c %i %u %u %u\n", col, c[0], c[1], c[2]);
+ sendSignal(cmd);
+
+ // Affichage d'info
+ sprintf(cmd, "Couleur %i change en %u %u %u\n", col, c[0], c[1], c[2]);
+ printStatus(cmd);
+ }
+
+ // Affectation des nouvelles valeurs
+ for (int i=0; i<3; i++)
+ oconfig->node[col*3+i] = c[i];
+
+ // Communication avec adjust
+ sprintf(cmd, "c %i %u %u %u\n", col, c[0], c[1], c[2]);
+ sendSignal(cmd);
+
+ // Suppression de la fenetre ecran et affichage
+ delwin(colorWindow);
+ colorWindow = newwin(4, 60, 12, 25);
+ wrefresh(colorWindow);
+ delwin(colorWindow);
+}
+
+// Affiche les objets et poteaux trouvés
+void
+UI::showObjectsFound ()
+{
+ // Creation de la fenetre
+ WINDOW *winInfo = newwin(15, 60, 5, 4);
+
+ // Affichage du texte
+
+ sendSignal ("f\n");
+
+ char buf[20] = "start";
+ bool end = 1;
+ while ( end != 0 )
+ {
+ read (fifo, buf, 20);
+ end = strcmp ("end\n", buf);
+ if (end != 0) wprintw (winInfo, "%s", buf);
+ }
+
+ wrefresh(winInfo);
+
+ // Liberation de la memoire
+ delwin(winInfo);
+}
+
+void
+UI::newNN (const int nbColor)
+{
+ char buf[20];
+ if (nbColor != -1)
+ {
+ sprintf(buf, "p %i\n", nbColor);
+ sendSignal(buf);
+
+ if (oconfig->node) delete [] oconfig->node;
+ oconfig->node = new unsigned char[nbColor*3];
+
+ oconfig->nnNbColor = nbColor;
+
+ // Synchronisation des poids avec adjust
+ updateNodes ();
+
+ printStatus("Nouveau reseau de neurones charge\n");
+ }
+}
+
+/// Affiche le menu principale
+void
+UI::menu ()
+{
+ // Init items
+ item = new ITEM*[NBITEMS];
+ for (int i=0; i<NBITEMS; i++)
+ item[i] = new_item(itemsName[i][0], NULL);
+
+ // Init window
+ mainWindow = newwin(20, 75, 2, 2);
+ keypad(mainWindow, TRUE);
+
+ // Init titre
+ wattron(mainWindow, COLOR_PAIR(2));
+ wprintw(mainWindow, "Adjust - APBteam");
+ wattroff(mainWindow, COLOR_PAIR(2));
+ mvwhline(mainWindow,1,0,ACS_HLINE, 16);
+
+ // Init menus
+ mainMenu = new_menu(item);
+ set_menu_mark(mainMenu, " -> ");
+ set_menu_win(mainMenu, mainWindow);
+ set_menu_sub(mainMenu, derwin(mainWindow, 13, 65, 3, 1));
+ set_menu_format(mainMenu, NBITEMS, 1);
+ post_menu(mainMenu);
+
+ // Actualisation de la fenetre
+ wrefresh(mainWindow);
+
+ int c;
+ int select=0;
+ int end=0;
+
+ // Affichage de l'aide de l'item
+ wattron(mainWindow,COLOR_PAIR(3));
+ mvwprintw(mainWindow, 3+select, 25, itemsName[select][1]);
+
+ char buf[50];
+
+ // Boucle du menu principal
+ while(!end)
+ {
+ c = wgetch(mainWindow);
+ switch(c)
+ {
+ case KEY_DOWN: // Touche flèche BAS
+ // On se déplace vers le bas
+ menu_driver(mainMenu, REQ_DOWN_ITEM);
+ if (select!=NBITEMS-2)
+ {
+ // Efface la ligne d'aide de l'item courant
+ mvwprintw(mainWindow,3+select, 25, "\t\t\t\t\t\t\t");
+ select++;
+ }
+ break;
+
+ case KEY_UP: // Touche flèche HAUT
+ // On se déplace vers le haut
+ menu_driver(mainMenu, REQ_UP_ITEM);
+ if (select!=0)
+ {
+ // Efface la ligne d'aide de l'item courant
+ mvwprintw(mainWindow,3+select, 25, "\t\t\t\t\t\t\t");
+ select--;
+ }
+ break;
+
+ case 10: // Touche ENTER
+ switch(select)
+ {
+ case NBITEMS-2: // Quitte le programme
+ end=1;
+ break;
+
+ case 0: // Change les valeurs des poids du NN pour une couleur
+ goChangeColor();
+ break;
+
+ case 1: // Supprime une couleur
+ goDelColor();
+ break;
+
+ case 2: // Melange 2 couleurs
+ goMergeWindow();
+ break;
+
+ case 3: // Selectionne la couleur des objets à afficher
+ {
+ int obj;
+ obj = chooseObject(0);
+ if (obj >= 0)
+ {
+ sprintf(buf, "a %i\n", obj);
+ sendSignal(buf);
+ }
+ }
+ break;
+
+ case 4: // Selectionne la couleur des objets
+ {
+ int obj, col;
+ obj = chooseObject(0);
+ if (obj >= 0)
+ {
+ col = chooseColor (NUM_COULEUR, 0);
+ if (col >= 0)
+ {
+ std::string name = Group::translateToColorName (obj);
+ sprintf(buf, "b %s %i\n", name.c_str (), col);
+ sendSignal(buf);
+ }
+ }
+ }
+ break;
+
+
+ case 5: // Affiche les objets trouvés
+ showObjectsFound ();
+ wrefresh (mainWindow);
+ break;
+
+ case 6: // Entraine le NN
+ sprintf(buf, "t\n");
+ sendSignal(buf);
+
+ // Synchronisation des poids avec adjust
+ updateNodes ();
+
+ printStatus ("Réseau de neurones entrainé\n");
+ break;
+
+ case 7: // Regeneration de poids
+ int nbColor;
+ nbColor = chooseColor (NB_COULEUR, oconfig->nnNbColor);
+ newNN (nbColor);
+ break;
+
+ case 8:// Annuler les changements
+ // Reload du fichier de poids initial
+ oconfig->loadNNFile();
+
+ // Envoie du nombre de couleur initial du NN et reload de l'image
+ sprintf(buf, "r %i", savedNNColorNumber);
+ sendSignal(buf);
+ oconfig->nnNbColor = savedNNColorNumber;
+
+ printStatus("Les changements ont été annulés\n");
+ break;
+
+ case 9: // Sauver les changements
+ // Sauvegarde des poids dans le fichier poids
+ oconfig->createNNFile("rc/poids", oconfig->nnNbColor);
+
+ // Reload du NN et de l'image a partir des nouveaux poids
+ sprintf(buf, "r -1");
+ sendSignal(buf);
+
+ printStatus ("Les changements ont été sauvés\n");
+ break;
+ } // END switch touche ENTER
+
+ break;
+
+ // Sortie du programme
+ case 27: // ECHAP
+ end=true;
+ break;
+
+ // Changement d'image
+ case ' ':
+ // Image suivante
+ curImage++;
+ if (curImage >= lengthFileList) curImage = 0;
+
+ // Envoie de la commande pour le chargement de la nouvelle image
+ sprintf (buf, "n %s%s\n", oconfig->imgPath, fileList[curImage]);
+ sendSignal (buf);
+ break;
+
+ case 'g':
+ showObjectsFound ();
+ wgetch (mainWindow);
+ break;
+
+ case 'n':
+ newNN (oconfig->nnNbColor);
+ break;
+ }
+
+ // On affiche le texte d'aide de l'item correspondant
+ mvwprintw (mainWindow, 3+select, 25, itemsName[select][1]);
+ wrefresh (mainWindow);
+ }
+
+ delwin (mainWindow);
+}
+
+
diff --git a/2005/i/robert/src/ovision/ui/ui.hh b/2005/i/robert/src/ovision/ui/ui.hh
new file mode 100644
index 0000000..049ac6d
--- /dev/null
+++ b/2005/i/robert/src/ovision/ui/ui.hh
@@ -0,0 +1,118 @@
+// robert - programme du robot 2005
+//
+// Copyright (C) 2005 Olivier Gaillard
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#ifndef UI_h
+#define UI_h
+
+// Realisé a l'aide du "NCURSES Programming HOWTO"
+
+
+#include <menu.h>
+#include "ovision/see/oconfig.hh"
+#include "ovision/see/group.hh"
+
+
+#define NUM_COULEUR 1
+#define NB_COULEUR 2
+
+
+/// Interface ncurses permettant de piloter adjust
+class UI {
+
+ /// Variable utilisees pour ncurses
+ ITEM **item;
+ MENU *mainMenu;
+ WINDOW *mainWindow;
+
+ /// Id du fifo
+ int fifo;
+
+ /// PID du prog
+ long pid;
+
+ /// Sauvegarde la valeur de sorties du NN
+ int savedNNColorNumber;
+
+ /// liste des images
+ char **fileList;
+
+ /// id de l'image actuel
+ int curImage;
+
+ /// taille de la liste
+ int lengthFileList;
+
+ OConfig *oconfig;
+
+
+ public:
+ /// Constructeurs.
+ UI (const char *filename = "");
+
+ /// Destructeur.
+ ~UI (void);
+
+ /// Affiche le menu principale
+ void menu ();
+
+ /// reponse du programme adjust
+ int uiReady;
+
+ protected:
+ /// Cree la liste d'images a ouvrir
+ void parseFileList();
+
+ /// Menu de selection de couleur
+ int chooseColor (const int type, const int current = 0);
+
+ /// Affiche un msg dans la barre d'etat
+ void printStatus (const char *str);
+
+ /// Menu de suppression de couleur
+ void goDelColor ();
+
+ /// menu de selection d'objet
+ int chooseObject (const int current);
+
+ /// Menu de selection du group a former
+ void goSelectGroup (const int type);
+
+ /// Menu de melange de couleurs
+ void goMergeWindow ();
+
+ /// Menu de changements des composantes d'un poid du NN
+ void goChangeColor ();
+
+ /// Synchronisation des poids locaux et de ceux du programme adjust
+ void updateNodes ();
+
+ /// Envoie une donnee au prog adjust
+ void sendSignal (const char *buf);
+
+ // Affiche les objets et poteaux trouvés
+ void showObjectsFound ();
+
+ void newNN (const int nbColor);
+};
+
+
+#endif // UI_h