diff --git a/GuiNuMo-server/Makefile b/GuiNuMo-server/Makefile index 99a7751..8b6416f 100644 --- a/GuiNuMo-server/Makefile +++ b/GuiNuMo-server/Makefile @@ -3,31 +3,25 @@ GXXFLAGS=-Wall -O2 LD=g++ LDFLAGS=-Wall -lm -O2 +HEADER= + all: test -clientinfo.o: clientinfo.cc clientinfo.hh point.hh - $(GXX) $(GXXFLAGS) clientinfo.cc -c -o clientinfo.o +% : %.o + $(LD) $(LDFLAGS) -o $@ $^ +%.o : %.cc $(HEADER) + $(GXX) $(GXXFLAGS) -c $< -server.o: server.cc server.hh clientinfo.hh referencepoint.hh accesspoint.hh point.hh measurement.hh - $(GXX) $(GXXFLAGS) server.cc -c -o server.o +clientinfo.o : clientinfo.hh point.hh +server.o : server.hh clientinfo.hh referencepoint.hh accesspoint.hh point.hh measurement.hh area.hh +referencepoint.o : referencepoint.hh measurement.hh point.hh +accesspoint.o : accesspoint.hh point.hh +point.o : point.hh +measurement.o : measurement.hh +area.o : area.hh point.hh +test.o : point.hh measurement.hh accesspoint.hh referencepoint.hh clientinfo.hh server.hh -referencepoint.o: referencepoint.cc referencepoint.hh measurement.hh point.hh - $(GXX) $(GXXFLAGS) referencepoint.cc -c -o referencepoint.o - -accesspoint.o: accesspoint.cc accesspoint.hh point.hh - $(GXX) $(GXXFLAGS) accesspoint.cc -c -o accesspoint.o - -point.o: point.cc point.hh - $(GXX) $(GXXFLAGS) point.cc -c -o point.o - -measurement.o: measurement.cc measurement.hh - $(GXX) $(GXXFLAGS) measurement.cc -c -o measurement.o - -test.o: test.cc point.hh measurement.hh accesspoint.hh referencepoint.hh clientinfo.hh server.hh - $(GXX) $(GXXFLAGS) test.cc -c -o test.o - -test: test.o point.o measurement.o accesspoint.o referencepoint.o clientinfo.o server.o - $(LD) $(LDFLAGS) -o test test.o point.o measurement.o accesspoint.o referencepoint.o clientinfo.o server.o +test : point.o measurement.o accesspoint.o referencepoint.o clientinfo.o server.o area.o clean: @rm -fv *~ *.o diff --git a/GuiNuMo-server/area.cc b/GuiNuMo-server/area.cc index 77d7e48..b099e88 100644 --- a/GuiNuMo-server/area.cc +++ b/GuiNuMo-server/area.cc @@ -1,17 +1,20 @@ #include "area.hh" -Area::Area(string an, float x1, float x2, float y1, float y2, float z1, float z2) + +Area::Area(const string &_name, const float &_x1, const float &_x2, const float &_y1, const float &_y2, const float &_z1, const float &_z2) { - area_name = an; - x_min = x1; - x_max = x2; - y_min = y1; - y_max = y2; - z_min = z1; - z_max = z2; + area_name = _name ; + x_min = _x1 ; + x_max = _x2 ; + y_min = _y1 ; + y_max = _y2 ; + z_min = _z1 ; + z_max = _z2 ; } + + Area::Area(const Area &a) { area_name = a.area_name; @@ -23,14 +26,25 @@ Area::Area(const Area &a) z_max = a.z_max; } -bool Area::containsPoint(Point p)const + + +bool Area::containsPoint(const Point &p)const { - if((p.getX() >= x_min) \ - && (p.getX() <= x_max) \ - && (p.getY() >= y_min) \ - && (p.getY() <= y_max) \ - && (p.getZ() >= z_min) \ + if((p.getX() >= x_min) + && (p.getX() <= x_max) + && (p.getY() >= y_min) + && (p.getY() <= y_max) + && (p.getZ() >= z_min) && (p.getZ() <= z_max)) return true; + return false; } + + + +ostream &operator<<(ostream &os, const Area &a) +{ + os << a.area_name << ';' << a.x_min << ';' << a.x_max << ';' << a.y_min << ';' << a.y_max << ';' << a.z_min << ';' << a.z_max ; + return os ; +} diff --git a/GuiNuMo-server/area.hh b/GuiNuMo-server/area.hh index 918792b..613e8f4 100644 --- a/GuiNuMo-server/area.hh +++ b/GuiNuMo-server/area.hh @@ -3,6 +3,7 @@ #include #include +#include "point.hh" using namespace std; using std::string; @@ -19,24 +20,29 @@ protected: float z_max; public: - Area(string an = "None", float x1 = 0, float x2 = 0, float y1 = 0, float y2 = 0, float z1 = 0, float z2 = 0); - Area(const Area &a); + Area(const string &_name = "No name", const float &_x1 = 0, const float &_x2 = 0, const float &_y1 = 0, const float &_y2 = 0, const float &_z1 = 0, const float &_z2 = 0) ; + Area(const Area &a) ; ~Area() {}; - bool containsPoint(Point p)const; - string getLabel()const { return label; }; - float getXmin()const { return x_min; }; - float getXmax()const { return x_max; }; - float getYmin()const { return y_min; }; - float getYmax()const { return y_max; }; - float getZmin()const { return z_min; }; - float getZmax()const { return z_max; }; - void setLabel(string l) { label = l; }; - void setXmin(float v) { x_min = v; }; - void setXmax(float v) { x_max = v; }; - void setYmin(float v) { y_min = v; }; - void setYmax(float v) { y_max = v; }; - void setZmin(float v) { z_min = v; }; - void setZmax(float v) { z_max = v; }; + + bool containsPoint(const Point &p)const ; + + string getName()const { return area_name ; } ; + float getXmin()const { return x_min; } ; + float getXmax()const { return x_max; } ; + float getYmin()const { return y_min; } ; + float getYmax()const { return y_max; } ; + float getZmin()const { return z_min; } ; + float getZmax()const { return z_max; } ; + + void setName(const string &_name) { area_name = _name ; } ; + void setXmin(const float &v) { x_min = v; } ; + void setXmax(const float &v) { x_max = v; } ; + void setYmin(const float &v) { y_min = v; } ; + void setYmax(const float &v) { y_max = v; } ; + void setZmin(const float &v) { z_min = v; } ; + void setZmax(const float &v) { z_max = v; } ; + + friend ostream &operator<<(ostream &os, const Area &a) ; }; -#endif +#endif // _AREA_HH_ diff --git a/GuiNuMo-server/cfg/distances.csv b/GuiNuMo-server/cfg/distances.csv index 19e32fd..89bd280 100644 --- a/GuiNuMo-server/cfg/distances.csv +++ b/GuiNuMo-server/cfg/distances.csv @@ -1,6 +1,7 @@ # Pour chaque pièce on prend le point (0;3) du référentiel pièce. # X;Y;Z;D1;X1;Y1;Z1;D2;X2;Y2;Z2;…;Dn;Xn;Yn;Zn # Le point (X;Y;Z) est en visibilité du point (Xn;Yn;Zn). Dn est un entier dont la valeur est égale à 1 si le lien est bidirectionnel, et à 0 s'il est unidirectionnel (auquel cas le lien sera enregistré comme allant uniquement de (X;Y;Z) à (Xn;Yn;Zn)). +# Pour chaque point, on enregistre seulement les points en visibilité directe les plus proche dans chaque direction ; autrement dit, si trois points A, B et C sont alignés, ou du moins suffisamment alignés pour qu'en se positionnant sur A et en regardant vers B on voit aussi C, alors on enregistre le lien de A vers B et le lien de B vers C, mais pas celui de A vers C. # 1100 3.00;5.48;3.00;1;7.50;7.00;3.00 @@ -19,3 +20,6 @@ # 1050 4.00;28.00;3.00;1;7.50;28.00;3.00 + +# CouloirN1 +7.50;7.00;3.00;1;8.00;14.00;3.00;1;7.50;22.00;3.00;1;7.50;28.00;3.00 diff --git a/GuiNuMo-server/cfg/topo.csv b/GuiNuMo-server/cfg/topo.csv index 2314398..70ee70e 100644 --- a/GuiNuMo-server/cfg/topo.csv +++ b/GuiNuMo-server/cfg/topo.csv @@ -1,12 +1,14 @@ -1100;1.00;7.28;6.05;3.70;3.00 -0190;1.00;10.88;6.05;7.28;3.00 -0180;1.00;14.48;6.05;10.88;3.00 -1070;1.00;18.12;6.05;14.48;3.00 -1060;1.00;25.32;6.05;18.12;3.00 -1050;1.00;31.40;6.05;25.32;3.00 -CouloirN1;5.00;3.70;6.05;0.50;3.00 -CouloirN1;6.05;29.50;8.20;0.50;3.00 -CouloirN1;8.20;16.50;10.00;10.88;3.00 -WC;8.20;9.00;10.00;0.50;3.00 -1105;8.20;10.88;10.00;9.00;3.00 -1095;8.20;29.30;10.00;24.80;3.00 +# nom_pièce;X1;Y1;X2;Y2;Z1;Z2 + +1100;1.00;7.28;6.05;3.70;3.00;6.00 +0190;1.00;10.88;6.05;7.28;3.00;6.00 +0180;1.00;14.48;6.05;10.88;3.00;6.00 +1070;1.00;18.12;6.05;14.48;3.00;6.00 +1060;1.00;25.32;6.05;18.12;3.00;6.00 +1050;1.00;31.40;6.05;25.32;3.00;6.00 +CouloirN1;5.00;3.70;6.05;0.50;3.00;6.00 +CouloirN1;6.05;29.50;8.20;0.50;3.00;6.00 +CouloirN1;8.20;16.50;10.00;10.88;3.00;6.00 +WC;8.20;9.00;10.00;0.50;3.00;6.00 +1105;8.20;10.88;10.00;9.00;3.00;6.00 +1095;8.20;29.30;10.00;24.80;3.00;6.00 diff --git a/GuiNuMo-server/point.cc b/GuiNuMo-server/point.cc index 86ca5dd..73e078e 100644 --- a/GuiNuMo-server/point.cc +++ b/GuiNuMo-server/point.cc @@ -1,5 +1,7 @@ #include "point.hh" + + Point Point::operator=(const Point &p) { if(this == &p) @@ -10,6 +12,8 @@ Point Point::operator=(const Point &p) return *this; } + + bool Point::operator==(const Point &p)const { if((x == p.x) && (y == p.y) && (z == p.z)) @@ -17,6 +21,8 @@ bool Point::operator==(const Point &p)const return false; } + + bool Point::operator!=(const Point &p)const { if((x == p.x) && (y == p.y) && (z == p.z)) @@ -24,6 +30,25 @@ bool Point::operator!=(const Point &p)const return true; } + + +bool Point::operator<(const Point &p)const +{ + if (x + y + z < p.x + p.y + p.z) + return true ; + + return false ; +} + + + +bool Point::operator>(const Point &p)const +{ + return p < *this ; +} + + + ostream &operator<<(ostream &os, const Point &p) { os << "(" << p.x << ";" << p.y << ";" << p.z << ")"; diff --git a/GuiNuMo-server/point.hh b/GuiNuMo-server/point.hh index 6e33b0e..f3cbe18 100644 --- a/GuiNuMo-server/point.hh +++ b/GuiNuMo-server/point.hh @@ -16,6 +16,7 @@ protected: public: Point(const float &_x = 0, const float &_y = 0, const float &_z = 0) { x = _x; y = _y; z = _z; } ; Point(const Point &p) { x = p.x; y = p.y; z = p.z; } ; + Point(const float c[3]) { x = c[0] ; y = c[1] ; z = c[2] ; } ; ~Point() {}; float getX()const { return x; }; float getY()const { return y; }; @@ -29,6 +30,8 @@ public: Point operator=(const Point &p); bool operator==(const Point &p)const; bool operator!=(const Point &p)const; + bool operator<(const Point &p)const ; + bool operator>(const Point &p)const ; friend ostream &operator<<(ostream & os, const Point &p); }; diff --git a/GuiNuMo-server/server.cc b/GuiNuMo-server/server.cc index 7873ee2..89b392d 100644 --- a/GuiNuMo-server/server.cc +++ b/GuiNuMo-server/server.cc @@ -10,6 +10,17 @@ /******* Misc. very usefull functions *******/ +/* Retourne la position du Point "p" dans le tableau "tab" de taille "size", ou -1 en cas d'échec. */ +inline int point_tab_idx(const Point *tab, unsigned int &size, const Point &p) +{ + for (unsigned int i = 0 ; i < size ; i++) + if (tab[i] == p) + return i ; + + return -1 ; +} + + /* Explodes a string into substrings based on separator sep. Returns a string vector. */ inline vector explode(const string &input, const char &sep) @@ -212,8 +223,10 @@ Server::Server(const string &ip_addr, const int &listen_port) /* Bind */ bind(sockListen, (struct sockaddr *)&server_addr, sizeof(server_addr)); - makeReferencePointListFromFile(DEFAULT_REF_POINT_FILE); - makeApListFromFile(DEFAULT_AP_FILE); + makeReferencePointListFromFile(DEFAULT_REF_POINT_FILE) ; // Initialisation de "reference_point_list". + makeApListFromFile(DEFAULT_AP_FILE) ; // Initialisation de "access_point_list". + makeTopologyFromFile(DEFAULT_TOPOLOGY_FILE) ; // Initialisation de "area_list". + makeWaypointDistancesFromFile(DEFAULT_DISTANCE_FILE) ; // Initialisation de "waypoint_indexes" et "waypoint_matrix". } @@ -832,6 +845,195 @@ void Server::makeApListFromFile(const string &filename) +void Server::makeTopologyFromFile(const string &filename) +{ + ifstream input_file ; + char buffer[BUFFER_LENGTH] ; + vector infos ; + + input_file.open(filename.c_str()) ; + if (input_file.fail()) + { + cerr << "Error opening input file « " << filename << " » !" << endl ; + return ; + } + +#ifdef DEBUG + cout << "Lecture du fichier « " << filename << " »..." << endl ; +#endif // DEBUG + + while (!input_file.eof()) + { + input_file.getline(buffer, BUFFER_LENGTH) ; + + if ((input_file.rdstate() & ifstream::eofbit) == 0) + { + /* Traitement basique des commentaires */ + if (buffer[0] == '\0' // Ligne vide + || buffer[0] == '#') // ou ligne commençant par # + continue ; // ignorer cette ligne. + + infos = explode(buffer, ';') ; +#ifdef DEBUG + cout << "Pièce : " << buffer ; +#endif // DEBUG + area_list.insert(make_pair(infos[0], Area(infos[0], string2float(infos[1]), string2float(infos[2]), string2float(infos[3]), string2float(infos[4]), string2float(infos[5]), string2float(infos[6])))) ; +#ifdef DEBUG + cout << " ajoutée." << endl ; +#endif // DEBUG + + infos.clear() ; + } + } + +#ifdef DEBUG + cout << "--> Liste des pièces (" << area_list.size() << ") :" << endl ; + for (multimap::iterator it = area_list.begin() ; it != area_list.end() ; it++) + cout << it->first << " : " << it->second << endl ; + cout << endl ; +#endif // DEBUG + + input_file.close() ; +} + + + +void Server::makeWaypointDistancesFromFile(const string &filename) +{ + ifstream input_file ; + char buffer[BUFFER_LENGTH] ; + vector infos ; + map > point_list ; + Point p_cur, p_tmp ; + + input_file.open(filename.c_str()); + if (input_file.fail()) + { + cerr << "Error opening input file « " << filename << " » !" << endl ; + return ; + } + +#ifdef DEBUG + cout << "Lecture du fichier « " << filename << " »..." << endl ; +#endif // DEBUG + + while (!input_file.eof()) + { + input_file.getline(buffer, BUFFER_LENGTH) ; + + if ((input_file.rdstate() & ifstream::eofbit) == 0) + { + /* Traitement basique des commentaires */ + if (buffer[0] == '\0' // Ligne vide + || buffer[0] == '#') // ou ligne commençant par # + continue ; // ignorer cette ligne. + + infos = explode(buffer, ';') ; +#ifdef DEBUG + cout << "Lien : " << buffer ; fflush(stdout); +#endif // DEBUG + + p_cur = Point(string2float(infos[0]), string2float(infos[1]), string2float(infos[2])) ; // On récupère le point courant (le premier de la ligne) + for (unsigned int i = 3 ; i < infos.size() ; i++) // Récupération et ajout des autres points + { + char direction = string2int(infos[i++]) ; + float coord[3] ; + unsigned int j ; + + for (j = 0 ; j < 3 && i < infos.size() ; i++, j++) + coord[j] = string2float(infos[i]) ; + + if (j == 3) // Si on est allé jusqu'au bout + { + p_tmp = Point(coord) ; + point_list[p_cur].push_back(p_tmp) ; + if (direction != 0) // Si le lien est bidirectionnel + point_list[p_tmp].push_back(p_cur) ; + } + } + + infos.clear() ; + +#ifdef DEBUG + cout << " traité." << endl ; fflush(stdout); +#endif // DEBUG + } + } + + input_file.close() ; // Lecture du fichier terminée + + + /* Construction de la matrice */ + unsigned int nb_pts = point_list.size() ; // Nombre de points + waypoint_indexes = new Point[nb_pts] ; // Tableau contenant tous les points (attribut du serveur) + waypoint_matrix = new float*[nb_pts] ; // Matrice des distances entre les points (attribut du serveur) + int cur_idx = 0, tmp_idx = -1 ; // Itérateurs sur les indices des tableaux + +#ifdef DEBUG + cout << "--> Liste des points de référence (" << nb_pts << ") :" << endl ; fflush(stdout); +#endif // DEBUG + + for (map >::iterator it = point_list.begin() ; it != point_list.end() ; it++) // Pour chaque point enregistré dans le hash + { +#ifdef DEBUG + cout << it->first << " :" ; +#endif // DEBUG + + if ((tmp_idx = point_tab_idx(waypoint_indexes, nb_pts, it->first)) == -1) // Si le point n'existe pas encore dans la matrice, on le crée : + { + waypoint_indexes[cur_idx] = it->first ; + waypoint_matrix[cur_idx] = new float[nb_pts] ; + for (unsigned int k = 0 ; k < nb_pts ; k++) // Initialisation des distances à -1 + waypoint_matrix[cur_idx][k] = -1 ; + tmp_idx = cur_idx++ ; + } + + for (unsigned int k = 0 ; k < it->second.size() ; k++) // Pour chaque point associé au point courant, + { +#ifdef DEBUG + cout << " / " << it->second[k] ; +#endif // DEBUG + + int tmp_idx_2 = point_tab_idx(waypoint_indexes, nb_pts, it->second[k]) ; // Recherche du point associé. + + if (tmp_idx_2 == -1) // Si le point associé n'existe pas encore dans la matrice, on le crée : + { + waypoint_indexes[cur_idx] = it->second[k] ; + waypoint_matrix[cur_idx] = new float[nb_pts] ; + for (unsigned int k = 0 ; k < nb_pts ; k++) // Initialisation des distances à -1 + waypoint_matrix[cur_idx][k] = -1 ; + tmp_idx_2 = cur_idx++ ; + } + + waypoint_matrix[tmp_idx][tmp_idx_2] = waypoint_indexes[tmp_idx].distance(it->second[k]) ; // it->second[k] n'existe pas forcément ! + } + +#ifdef DEBUG + cout << " /" << endl ; +#endif // DEBUG + } + + +#ifdef DEBUG + /* Affichage de la matrice */ + cout << "--> Matrice des distances :\n\t\t|" ; + for (unsigned int k = 0 ; k < nb_pts ; k++) + cout << ' ' << waypoint_indexes[k] << "\t|" ; + cout << endl ; + for (unsigned int k = 0 ; k < nb_pts ; k++) + { + cout << waypoint_indexes[k] << "\t|" ; + for (unsigned int l = 0 ; l < nb_pts ; l++) + cout << '\t' << waypoint_matrix[k][l] << "\t|" ; + cout << endl ; + } + + cout << endl ; +#endif // DEBUG +} + + + /* FONCTION POUR RÉTRO-COMPATIBILITÉ * Affiche la liste des points de référence (reference_point_list). */ void Server::printReferencePointList() diff --git a/GuiNuMo-server/server.hh b/GuiNuMo-server/server.hh index 3feb1a7..1e45007 100644 --- a/GuiNuMo-server/server.hh +++ b/GuiNuMo-server/server.hh @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -18,6 +19,7 @@ #include "accesspoint.hh" #include "point.hh" #include "measurement.hh" +#include "area.hh" using namespace std; using std::string; @@ -26,6 +28,8 @@ using std::string; #define DEFAULT_REF_POINT_FILE "csv/agreg/toutes.csv" // Fichier des points de référence #define DEFAULT_AP_FILE "cfg/minipc.cfg" // Fichier de configuration des AP #define DEFAULT_TRACKING_FILE "csv/agreg/divagation.csv" // Fichier de prérégrination +#define DEFAULT_TOPOLOGY_FILE "cfg/topo.csv" +#define DEFAULT_DISTANCE_FILE "cfg/distances.csv" #define DEFAULT_IP "127.0.0.1" #define DEFAULT_LISTEN_PORT 7777 #define LIGHT_SPEED 300000000 @@ -42,9 +46,12 @@ using std::string; class Server { protected: - vector client_list; - vector reference_point_list; - vector access_point_list; + vector client_list ; // Liste des clients connus + vector reference_point_list ; // Liste des points de référence (calibration) + vector access_point_list ; // Liste des AP connus + multimap area_list ; // Liste des zones homogènes (pièces) + Point *waypoint_indexes ; // Liste des points de parcours + float **waypoint_matrix ; // Matrice des distances entre les points de parcours struct sockaddr_in server_addr; int sockListen; int sockSend; @@ -82,8 +89,9 @@ public: void makeReferencePointListFromFile(const string &filename); void makePointListFromFile(vector &dest_point_list, const string &filename) ; void makePointListFromFile(vector &dest_point_list, const string &filename, const bool uniq_point) ; - void makeApListFromFile(const string &filename); + void makeTopologyFromFile(const string &filename) ; + void makeWaypointDistancesFromFile(const string &filename) ; void printReferencePointList(); void printPointList(vector &point_list) ; @@ -100,4 +108,4 @@ public: void radar_exp(); }; -#endif +#endif // _SERVER_HH_ diff --git a/GuiNuMo-server/test.cc b/GuiNuMo-server/test.cc index 4b3011b..5aaccfc 100644 --- a/GuiNuMo-server/test.cc +++ b/GuiNuMo-server/test.cc @@ -21,5 +21,8 @@ int main(int argc, char ** argv) // my_server.radar_exp(); my_server.fastViterbiLike(VITERBI_N, VITERBI_K, 0) ; + cout << argv[0] << " : fin." << endl ; + fflush(stdout) ; + return 0; }