GuiNuMo : plein de modifs (gestion topologie)

server.{hh,cc} :
* Changé le comportement des fonctions pointIndex() et pointExists() :
  pointIndex() renvoie -1 si le point n'est pas trouvé, et pointExists()
  effectue un appel à pointIndex(). Passage de toutes ces fonctions en
  inline.
* Déplacement des fonctions point_tab_idx() et point_vector_idx() dans
  la classe Server, en tant que variantes de pointIndex().
* Utilisation, pour les bibliothèques C, des en-têtes C++ (e.g <cmath>)
  plutôt que les en-têtes C (e.g <math.h>).
* Correction des fonctions areaConnection() qui utilisaient la mauvaise
  liste de points.
* Diverses corrections mineures.
* Modification de la fonction makeWaypointListFromFile() afin de prendre
  en compte la topologie dans le calcul des distances.
* Ajout de la fonction inTheSameArea(), qui permet de savoir si deux
  points appartiennent à la même zone.
* Ajout de la fonction checkTopology() qui effectues quelques
  vérifications sur la topologie du bâtiment déclarée dans les fichiers
  de configuration.

area.cc :
* Modification du constructeur de manière à ce qu'il accepte tous les
  formats possibles de définitions des zones (4 ordres possibles pour
  les coordonnées).

point.{hh,cc} :
* Modification de l'operator< pour que la comparaison ne soit pas
  ambigüe (posait problème dans les set).
* Modification des autres opérateurs, ajout des opérateurs <= et >=.

cfg/ :
* waypoints.csv : ajout des points de passage du rez-de-chaussée et des
  escaliers.
* topo.csv : ajout des zones du rez-de-chaussée et des escaliers.

Makefile :
* Suppression d'options inutiles.
* Suppression de l'option d'optimisation, qui causait une boucle infinie
  bizarre : cf. Server::makeWaypointListFromFile().

git-svn-id: https://pif.pu-pm.univ-fcomte.fr/svn/loc@48 785a6c6c-259e-4ff1-8b91-dc31627914f0
This commit is contained in:
Matteo Cypriani 2008-07-03 13:04:30 +00:00
parent 085b348670
commit 5b1286c6ba
8 changed files with 533 additions and 115 deletions

View File

@ -1,7 +1,8 @@
GXX=g++
GXXFLAGS=-g -Wall -pedantic -O2
DEBUG=-g
GXXFLAGS=$(DEBUG) -Wall -pedantic
LD=g++
LDFLAGS=-g -Wall -pedantic -lm -O2
LDFLAGS=-lm
HEADER=guinumo.hh

View File

@ -5,12 +5,53 @@
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 = _name ;
x_min = _x1 ;
x_max = _x2 ;
y_min = _y1 ;
y_max = _y2 ;
z_min = _z1 ;
z_max = _z2 ;
if (_x1 < _x2 && _y1 > _y2) // Le premier point de la pièce est en haut à gauche
{
x_min = _x1 ;
x_max = _x2 ;
y_min = _y2 ; // on inverse les Y
y_max = _y1 ;
}
else if (_x1 > _x2 && _y1 < _y2) // Le premier point de la pièce est en bas à droite
{
x_min = _x2 ; // on inverse les X
x_max = _x1 ;
y_min = _y1 ;
y_max = _y2 ;
}
else if (_x1 > _x2 && _z1 > _z2) // Le premier point de la pièce est en haut à droite
{
x_min = _x2 ; // on inverse les X
x_max = _x1 ;
z_min = _z2 ; // on inverse les Y
z_max = _z1 ;
}
else // Le premier point de la pièce est en bas à gauche ou autres cas (par ex. coordonnées nulles)
{
x_min = _x1 ;
x_max = _x2 ;
y_min = _y1 ;
y_max = _y2 ;
}
if (_z1 < _z2)
{
z_min = _z1 ;
z_max = _z2 ;
}
else
{
z_min = _z2 ;
z_max = _z1 ;
}
#ifdef DEBUG_2
cout << "Area créée ("<< area_name << ',' << x_min << ',' << y_min << ',' << x_max << ',' << y_max << ',' << z_min << ',' << z_max << ")" << endl ;
#endif // DEBUG_2
}

View File

@ -2,6 +2,37 @@
# Chaque ligne définit une zone, de la forme :
# Nom de la pièce;X1;Y1;X2;Y2;Z1;Z2
### Rez-de-chaussée ###
#
0140;1.00;7.28;6.05;3.70;0.00;2.99
0130;1.00;10.88;6.05;7.28;0.00;2.99
0120;1.00;14.48;6.05;10.88;0.00;2.99
0110;1.00;18.12;6.05;14.48;0.00;2.99
0100;1.00;21.66;6.05;18.12;0.00;2.99
0090;1.00;25.32;6.05;21.66;0.00;2.99
0080;1.00;29.00;6.05;25.32;0.00;2.99
0070;1.00;32.00;6.05;29.00;0.00;2.99
WC N0;8.20;5.30;10.00;0.50;0.00;2.99
0085;8.20;9.00;10.00;5.30;0.00;2.99
0075;8.20;10.88;10.00;9.00;0.00;2.99
Palier N0;5.00;3.70;8.20;0.50;0.00;2.99
Couloir N0 A;6.05;30.00;8.20;3.70;0.00;2.99
Couloir N0 B;8.20;16.50;10.00;10.88;0.00;2.99
Couloir N0 C;8.20;24.80;10.00;22.60;0.00;2.99
### Escaliers N0 / N1 ###
#
# TODO : affiner la hauteur, etc.
Escalier N0-N1 A;8.20;22.60;10.00;16.50;0.00;6.00
Escalier N0-N1 B1;2.50;2.00;5.00;0.50;0.00;6.00
Escalier N0-N1 B palier;1.00;3.70;2.50;0.50;1.50;6.00
Escalier N0-N1 B2;2.50;3.70;5.00;2.00;1.50;6.00
### Premier étage ###
#
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
@ -14,3 +45,4 @@ WC N1;8.20;9.00;10.00;0.50;3.00;6.00
Palier N1;5.00;3.70;8.20;0.50;3.00;6.00
Couloir N1 A;6.05;29.50;8.20;3.70;3.00;6.00
Couloir N1 B;8.20;16.50;10.00;10.88;3.00;6.00
Couloir N1 C;8.20;24.80;10.00;22.60;3.00;6.00

1 # Liste des zones homogènes du bâtiment (pièces).
2 # Chaque ligne définit une zone, de la forme :
3 # Nom de la pièce;X1;Y1;X2;Y2;Z1;Z2
4 1100;1.00;7.28;6.05;3.70;3.00;6.00 ### Rez-de-chaussée ###
5 #
6 0140;1.00;7.28;6.05;3.70;0.00;2.99
7 0130;1.00;10.88;6.05;7.28;0.00;2.99
8 0120;1.00;14.48;6.05;10.88;0.00;2.99
9 0110;1.00;18.12;6.05;14.48;0.00;2.99
10 0100;1.00;21.66;6.05;18.12;0.00;2.99
11 0090;1.00;25.32;6.05;21.66;0.00;2.99
12 0080;1.00;29.00;6.05;25.32;0.00;2.99
13 0070;1.00;32.00;6.05;29.00;0.00;2.99
14 WC N0;8.20;5.30;10.00;0.50;0.00;2.99
15 0085;8.20;9.00;10.00;5.30;0.00;2.99
16 0075;8.20;10.88;10.00;9.00;0.00;2.99
17 Palier N0;5.00;3.70;8.20;0.50;0.00;2.99
18 Couloir N0 A;6.05;30.00;8.20;3.70;0.00;2.99
19 Couloir N0 B;8.20;16.50;10.00;10.88;0.00;2.99
20 Couloir N0 C;8.20;24.80;10.00;22.60;0.00;2.99
21 ### Escaliers N0 / N1 ###
22 #
23 # TODO : affiner la hauteur, etc.
24 Escalier N0-N1 A;8.20;22.60;10.00;16.50;0.00;6.00
25 Escalier N0-N1 B1;2.50;2.00;5.00;0.50;0.00;6.00
26 Escalier N0-N1 B palier;1.00;3.70;2.50;0.50;1.50;6.00
27 Escalier N0-N1 B2;2.50;3.70;5.00;2.00;1.50;6.00
28 ### Premier étage ###
29 #
30 1100;1.00;7.28;6.05;3.70;3.00;6.00
31 0190;1.00;10.88;6.05;7.28;3.00;6.00
32 0180;1.00;14.48;6.05;10.88;3.00;6.00
33 1070;1.00;18.12;6.05;14.48;3.00;6.00
34 1060;1.00;25.32;6.05;18.12;3.00;6.00
35 1050;1.00;31.40;6.05;25.32;3.00;6.00
36 0190;1.00;10.88;6.05;7.28;3.00;6.00 WC N1;8.20;9.00;10.00;0.50;3.00;6.00
37 0180;1.00;14.48;6.05;10.88;3.00;6.00 1105;8.20;10.88;10.00;9.00;3.00;6.00
38 1070;1.00;18.12;6.05;14.48;3.00;6.00 1095;8.20;29.30;10.00;24.80;3.00;6.00
45
46
47
48

View File

@ -2,6 +2,83 @@
# Chaque ligne définit les trois coordonnées d'un point, de la forme :
# X;Y;Z
# Note : pour les zones appartenant à la même pièce non-convexe (ex : Couloir N0 A et Couloir N0 B), on définit un point tous les 1,50 m.
# Idem pour les portes très larges.
### Rez-de-chaussée ###
# 0140
6.05;6.50;0.00
# 0130
6.05;7.50;0.00
# 0120
6.05;13.50;0.00
# 0130 / 0120
3.00;10.88;0.00
# 0110
6.05;14.50;0.00
# 0100
6.05;21.00;0.00
# 0090
6.05;22.25;0.00
# 0080
6.05;28.50;0.00
# 0070
6.05;29.50;0.00
# WC N0
8.20;5.00;0.00
# 0085
8.20;8.50;0.00
# 0075
8.20;9.50;0.00
# Couloir N0 A / B
8.20;11.50;0.00
8.20;13.00;0.00
8.20;14.50;0.00
8.20;16.00;0.00
# Couloir N0 A / C
8.20;23.70;0.00
# Palier N0
7.50;3.70;0.00
### Escaliers N0 / N1 ###
# Couloir N0 C / Escalier NO-N1 A
8.95;22.60;0.00
# Escalier NO-N1 A / Couloir N1 B
8.95;16.50;3.00
# Palier NO / Escalier N0-N1 B1
5.00;1.25;0.00
# Escalier N0-N1 B1 / Escalier N0-N1 B palier
2.50;1.25;1.50
# Escalier N0-N1 B palier / Escalier N0-N1 B2
2.50;2.75;1.50
# Escalier N0-N1 B2 / Palier N1
5.00;2.75;3.00
### Premier étage ###
# 1100
6.05;6.50;3.00
@ -11,6 +88,9 @@
# 0180
6.05;13.50;3.00
# 0190 / 0180
3.00;10.88;3.00
# 1070
6.05;14.50;3.00
@ -35,5 +115,8 @@
8.20;14.50;3.00
8.20;16.00;3.00
# Couloir N1 A / C
8.20;23.70;3.00
# Palier N1
7.50;3.70;3.00

1 # Liste des points de passage.
2 # Chaque ligne définit les trois coordonnées d'un point, de la forme :
3 # X;Y;Z
4 # 1100 # Note : pour les zones appartenant à la même pièce non-convexe (ex : Couloir N0 A et Couloir N0 B), on définit un point tous les 1,50 m.
5 # Idem pour les portes très larges.
6 ### Rez-de-chaussée ###
7 # 0140
8 6.05;6.50;0.00
9 # 0130
10 6.05;7.50;0.00
11 # 0120
12 6.05;13.50;0.00
13 # 0130 / 0120
14 3.00;10.88;0.00
15 # 0110
16 6.05;14.50;0.00
17 # 0100
18 6.05;21.00;0.00
19 # 0090
20 6.05;22.25;0.00
21 # 0080
22 6.05;28.50;0.00
23 # 0070
24 6.05;29.50;0.00
25 # WC N0
26 8.20;5.00;0.00
27 # 0085
28 8.20;8.50;0.00
29 # 0075
30 8.20;9.50;0.00
31 # Couloir N0 A / B
32 8.20;11.50;0.00
33 8.20;13.00;0.00
34 8.20;14.50;0.00
35 8.20;16.00;0.00
36 # Couloir N0 A / C
37 8.20;23.70;0.00
38 # Palier N0
39 7.50;3.70;0.00
40 ### Escaliers N0 / N1 ###
41 # Couloir N0 C / Escalier NO-N1 A
42 8.95;22.60;0.00
43 # Escalier NO-N1 A / Couloir N1 B
44 8.95;16.50;3.00
45 # Palier NO / Escalier N0-N1 B1
46 5.00;1.25;0.00
47 # Escalier N0-N1 B1 / Escalier N0-N1 B palier
48 2.50;1.25;1.50
49 # Escalier N0-N1 B palier / Escalier N0-N1 B2
50 2.50;2.75;1.50
51 # Escalier N0-N1 B2 / Palier N1
52 5.00;2.75;3.00
53 ### Premier étage ###
54 # 1100
55 6.05;6.50;3.00
56 # 0190
57 6.05;7.50;3.00
58 # 0180
59 6.05;13.50;3.00
60 # 0190 / 0180
61 3.00;10.88;3.00
62 # 1070
63 6.05;14.50;3.00
64 # 1060
65 6.05;21.00;3.00
66 # 1050
67 6.05;27.75;3.00
68 # WC N1
69 8.20;5.00;3.00
70 # 1105
71 8.20;9.50;3.00
72 # 1095
73 8.20;26.00;3.00
74 # Couloir N1 A / B
75 8.20;11.50;3.00
76 8.20;13.00;3.00
77 8.20;14.50;3.00
78 8.20;16.00;3.00
79 # Couloir N1 A / C
80 8.20;23.70;3.00
81 # Palier N1
82 6.05;6.50;3.00 7.50;3.70;3.00
83
84
88
89
90
91
92
93
94
95
96
115
116
117
118
119
120
121
122

View File

@ -14,27 +14,19 @@ Point Point::operator=(const Point &p)
bool Point::operator==(const Point &p)const
bool Point::operator<(const Point &p) const
{
if((x == p.x) && (y == p.y) && (z == p.z))
return true;
return false;
}
if (x < p.x)
return true ;
if (x > p.x)
return false ;
if (y < p.y)
return true ;
if (y > p.y)
return false ;
bool Point::operator!=(const Point &p)const
{
if((x == p.x) && (y == p.y) && (z == p.z))
return false;
return true;
}
bool Point::operator<(const Point &p)const
{
if (x + y + z < p.x + p.y + p.z)
if (z < p.z)
return true ;
return false ;
@ -42,13 +34,6 @@ bool Point::operator<(const Point &p)const
bool Point::operator>(const Point &p)const
{
return p < *this ;
}
ostream &operator<<(ostream &os, const Point &p)
{
os << "(" << p.x << ";" << p.y << ";" << p.z << ")";

View File

@ -27,11 +27,14 @@ public:
float squareDistance(const Point &p)const { return ((x-p.x)*(x-p.x))+((y-p.y)*(y-p.y))+((z-p.z)*(z-p.z)); };
float squareDistance(const float &mx, const float &my, const float &mz)const { return ((x-mx)*(x-mx))+((y-my)*(y-my))+((z-mz)*(z-mz)); };
float distance(const Point &p)const { return sqrt(((x-p.x)*(x-p.x))+((y-p.y)*(y-p.y))+((z-p.z)*(z-p.z))); };
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 ;
Point operator=(const Point &p) ;
bool operator==(const Point &p) const {return ((x == p.x) && (y == p.y) && (z == p.z)) ;} ;
bool operator!=(const Point &p) const {return !(*this == p) ;} ;
bool operator<(const Point &p) const ;
bool operator>(const Point &p) const {return (p < *this) ;} ;
bool operator<=(const Point &p) const {return (*this < p || *this == p) ;} ;
bool operator>=(const Point &p) const {return (p <= *this) ;} ;
friend ostream &operator<<(ostream & os, const Point &p);
};

View File

@ -5,26 +5,23 @@
/******* 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 ;
/* Tronque le float "f" à "n" décimales et le retourne */
inline float round_float(float f, int n)
{
n = pow(10, n) ;
float f_dec = modff(f, &f) ;
f_dec = floor(f_dec * n) / n ;
return f + f_dec ;
}
/* Retourne la position du Point "p" dans le vector "v", ou -1 en cas d'échec. */
inline int point_vector_idx(const vector<Point> &v, const Point &p)
/* Tronque le float "f" à 2 décimales et le retourne */
inline float round_float_2(float f)
{
for (unsigned int i = 0 ; i < v.size() ; i++)
if (v[i] == p)
return i ;
return -1 ;
return round_float(f, 2) ;
}
@ -234,11 +231,15 @@ 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) ; // Initialisation de "reference_point_list".
makeApListFromFile(DEFAULT_AP_FILE) ; // Initialisation de "access_point_list".
makeTopologyFromFile(DEFAULT_TOPOLOGY_FILE) ; // Initialisation de "area_list".
makeWaypointListFromFile(DEFAULT_WAYPOINT_FILE) ; // Initialisation de "waypoint_list" et "waypoint_matrix".
makeReferencePointListFromFile(DEFAULT_REF_POINT_FILE) ; // Initialisation de "reference_point_list".
if (! checkTopology()) // Vérifications.
exit 1 ; // Si problème, on quitte.
makeReferencePointDistances() ; // Initialisation de "reference_point_matrix".
makeApListFromFile(DEFAULT_AP_FILE) ; // Initialisation de "access_point_list".
#ifdef DEBUG_T
cout << "//<-- Server::Server()" << endl ; fflush(stdout) ;
@ -305,6 +306,57 @@ map<string, Area> Server::inWhichAreas(const Point &p)
/* Retourne true si les points "p1" et "p2" sont dans la même zone (ou ont au moins une zone en commun s'ils appartiennent à plusieurs zones).
*/
bool Server::inTheSameArea(const Point &p1, const Point &p2)
{
#ifdef DEBUG_T
cout << "//--> Server::inTheSameArea()" << endl ; fflush(stdout) ;
#endif // DEBUG_T
map<string, Area> // Liste des zones comportant les points p1 et p2 :
zones1(inWhichAreas(p1)),
zones2(inWhichAreas(p2)) ;
#ifdef DEBUG_2
cout << " zones1 (" << zones1.size() << ") : [" ;
for (map<string, Area>::iterator it1 = zones1.begin() ; it1 != zones1.end() ; it1++)
cout << it1->first << ',' ;
cout << "\b]" ;
cout << " zones2 (" << zones2.size() << ") : [" ;
for (map<string, Area>::iterator it1 = zones2.begin() ; it1 != zones2.end() ; it1++)
cout << it1->first << ',' ;
cout << "\b]" ;
#endif // DEBUG_2
if (zones1.size() == 0 || zones2.size() == 0) // Si aucune zone ne contient p1 ou p2,
{
#ifdef DEBUG_T
cout << "//<-- Server::inTheSameArea()" << endl ; fflush(stdout) ;
#endif // DEBUG_T
return false ; // on quitte.
}
for (map<string, Area>::iterator it1 = zones1.begin() ; it1 != zones1.end() ; it1++) // Parcours des zones :
for (map<string, Area>::iterator it2 = zones2.begin() ; it2 != zones2.end() ; it2++)
if (it1->second == it2->second) // Si les deux zones sont identiques,
{
#ifdef DEBUG_T
cout << "//<-- Server::inTheSameArea()" << endl ; fflush(stdout) ;
#endif // DEBUG_T
return true ; // p1 et p2 sont dans la même zone.
}
#ifdef DEBUG_T
cout << "//<-- Server::inTheSameArea()" << endl ; fflush(stdout) ;
#endif // DEBUG_T
return false ;
}
/* Cherche les points de passage communs aux zones "z1" et "z2".
* Retourne un vector<Point> contenant la liste de ces points.
*/
@ -316,11 +368,11 @@ vector<Point> Server::areaConnection(const Area &z1, const Area &z2)
vector<Point> points ;
for (unsigned int i = 0 ; i < reference_point_list.size() ; i++)
for (unsigned int i = 0 ; i < waypoint_list.size() ; i++)
{
map<string, Area> areas(inWhichAreas(reference_point_list[i])) ;
map<string, Area> areas(inWhichAreas(waypoint_list[i])) ;
if (areas.find(z1.getName()) != areas.end() && areas.find(z2.getName()) != areas.end())
points.push_back(reference_point_list[i]) ;
points.push_back(waypoint_list[i]) ;
}
#ifdef DEBUG_T
@ -343,11 +395,11 @@ vector<Point> Server::areaConnection(const Area &z)
vector<Point> points ;
for (unsigned int i = 0 ; i < reference_point_list.size() ; i++)
for (unsigned int i = 0 ; i < waypoint_list.size() ; i++)
{
map<string, Area> areas(inWhichAreas(reference_point_list[i])) ;
map<string, Area> areas(inWhichAreas(waypoint_list[i])) ;
if (areas.find(z.getName()) != areas.end())
points.push_back(reference_point_list[i]) ;
points.push_back(waypoint_list[i]) ;
}
#ifdef DEBUG_T
@ -373,6 +425,10 @@ float Server::distanceTopology(const Point &p1, const Point &p2)
if (zones1.size() == 0 || zones2.size() == 0) // Si aucune zone ne contient p1 ou p2,
{
#ifdef DEBUG_2
cout << "Aucune zone ne contient " << p1 << " (" << zones1.size() << " zones) ou " << p2 << " (" << zones2.size() << " zones)." << endl ;
#endif // DEBUG_2
#ifdef DEBUG_T
cout << "//<-- Server::distanceTopology()" << endl ; fflush(stdout) ;
#endif // DEBUG_T
@ -387,8 +443,13 @@ float Server::distanceTopology(const Point &p1, const Point &p2)
/* *** Cas de la même zone *** */
if (z1 == z2) // Si les points sont dans la même zone,
{
#ifdef DEBUG_2
cout << p1 << " et " << p2 << " sont dans la même zone." << endl ;
#endif // DEBUG_2
#ifdef DEBUG_T
cout << "//<-- Server::distanceTopology()" << endl ; fflush(stdout) ;
#endif // DEBUG_T
@ -397,9 +458,15 @@ float Server::distanceTopology(const Point &p1, const Point &p2)
}
/* *** Cas de deux zones voisines *** */
/* *** Cas de deux zones voisines (connectées directement) *** */
if ((connection = areaConnection(z1, z2)).size() != 0) // Si les points sont dans deux zones voisines,
{ // la distance entre eux est la distance euclidienne de chacun jusqu'au plus proche point de passage entre les deux zones.
#ifdef DEBUG_2
cout << p1 << " et " << p2 << " sont dans deux zones voisines." << endl ;
#endif // DEBUG_2
float dist = p1.distance(connection[0]) + p2.distance(connection[0]) ;
for (unsigned int i = 1 ; i < connection.size() ; i++) // Recherche du point de passage offrant la plus courte distance
{
@ -417,6 +484,11 @@ float Server::distanceTopology(const Point &p1, const Point &p2)
/* *** Les points sont dans des zones non-voisines *** */
#ifdef DEBUG_2
cout << p1 << " et " << p2 << " sont dans des zones non-voisines." << endl ;
#endif // DEBUG_2
vector<Point> // Liste des points de passage appartenant respectivement à z1 et à z2.
wp_z1(areaConnection(z1)),
wp_z2(areaConnection(z2)) ;
@ -436,10 +508,13 @@ float Server::distanceTopology(const Point &p1, const Point &p2)
unsigned int i1, i2 ;
for (i1 = 0 ; i1 < wp_z1.size() ; i1++) // Recherche des premiers indices valides (où il existe un chemin entre les points de passage)
{
wp_z1_idx = point_vector_idx(waypoint_list, wp_z1[i1]) ;
wp_z1_idx = pointIndex(waypoint_list, wp_z1[i1]) ;
for (i2 = 0 ; i2 < wp_z2.size() ; i2++)
{
wp_z2_idx = point_vector_idx(waypoint_list, wp_z2[i2]) ;
wp_z2_idx = pointIndex(waypoint_list, wp_z2[i2]) ;
if (wp_z2_idx < 0)
continue ;
if (waypoint_matrix[wp_z1_idx][wp_z2_idx] != -1) // Si c'est bon,
break ; // on arrête le parcours.
}
@ -461,7 +536,7 @@ float Server::distanceTopology(const Point &p1, const Point &p2)
for (unsigned int j = i2 + 1 ; j < wp_z2.size() ; j++) // Fin du parcours :
{
wp_z2_idx = point_vector_idx(waypoint_list, wp_z2[j]) ;
wp_z2_idx = pointIndex(waypoint_list, wp_z2[j]) ;
if (waypoint_matrix[wp_z1_idx][wp_z2_idx] == -1)
continue ;
tmp_dist = p1.distance(wp_z1[i1]) + waypoint_matrix[wp_z1_idx][wp_z2_idx] + p2.distance(wp_z2[j]) ;
@ -474,8 +549,8 @@ float Server::distanceTopology(const Point &p1, const Point &p2)
for (unsigned int j = 0 ; j < wp_z2.size() ; j++)
{
// Indice des points de passage wp_z1[i] et wp_z2[j] dans la liste des points de passage :
wp_z1_idx = point_vector_idx(waypoint_list, wp_z1[i]) ;
wp_z2_idx = point_vector_idx(waypoint_list, wp_z2[j]) ;
wp_z1_idx = pointIndex(waypoint_list, wp_z1[i]) ;
wp_z2_idx = pointIndex(waypoint_list, wp_z2[j]) ;
if (waypoint_matrix[wp_z1_idx][wp_z2_idx] == -1) // S'il n'existe aucun chemin entre les deux points de passage
continue ;
@ -505,7 +580,7 @@ float Server::distanceTopology(const Point &p1, const Point &p2)
/* FONCTION POUR RÉTRO-COMPATIBILITÉ.
* Recherche un point de coordonnées (x;y;z) dans la liste reference_point_list, retourne true s'il existe, false sinon. */
bool Server::pointExists(const float &x, const float &y, const float &z)const
inline bool Server::pointExists(const float &x, const float &y, const float &z) const
{
#ifdef DEBUG_T
cout << "//--> Server::pointExists(&float, &float, &float)" << endl ; fflush(stdout) ;
@ -524,7 +599,7 @@ bool Server::pointExists(const float &x, const float &y, const float &z)const
/* FONCTION POUR RÉTRO-COMPATIBILITÉ.
* Recherche un Point dans la liste reference_point_list, retourne true s'il existe, false sinon. */
bool Server::pointExists(const Point &p)const
inline bool Server::pointExists(const Point &p) const
{
#ifdef DEBUG_T
cout << "//--> Server::pointExists(&Point)" << endl ; fflush(stdout) ;
@ -542,7 +617,7 @@ bool Server::pointExists(const Point &p)const
/* Recherche un point de coordonnées (x;y;z) dans la liste "point_list", retourne true s'il existe, false sinon. */
bool Server::pointExists(const vector<ReferencePoint> &point_list, const float &x, const float &y, const float &z) const
inline bool Server::pointExists(const vector<ReferencePoint> &point_list, const float &x, const float &y, const float &z) const
{
#ifdef DEBUG_T
cout << "//--> Server::pointExists(&vector<ReferencePoint>, &float, &float, &float)" << endl ; fflush(stdout) ;
@ -560,34 +635,24 @@ bool Server::pointExists(const vector<ReferencePoint> &point_list, const float &
/* Recherche un Point dans la liste "point_list", retourne true s'il existe, false sinon. */
bool Server::pointExists(const vector<ReferencePoint> &point_list, const Point &p) const
inline bool Server::pointExists(const vector<ReferencePoint> &point_list, const Point &p) const
{
#ifdef DEBUG_T
cout << "//--> Server::pointExists(&vector<ReferencePoint>, &Point)" << endl ; fflush(stdout) ;
#endif // DEBUG_T
unsigned int i;
for (i = 0 ; i < point_list.size() ; i++)
if (p == point_list[i].getCoordinates())
{
#ifdef DEBUG_T
cout << "//<-- Server::pointExists(&vector<ReferencePoint>, &Point)" << endl ; fflush(stdout) ;
#endif // DEBUG_T
return true;
}
bool ret = (pointIndex(point_list, p) != -1) ;
#ifdef DEBUG_T
cout << "//<-- Server::pointExists(&vector<ReferencePoint>, &Point)" << endl ; fflush(stdout) ;
#endif // DEBUG_T
return false;
return ret ;
}
/* Do not forget to call pointExists() before this one */
unsigned int Server::pointIndex(const float &x, const float &y, const float &z)const
inline int Server::pointIndex(const float &x, const float &y, const float &z) const
{
#ifdef DEBUG_T
cout << "//--> Server::pointIndex(&float, &float, &float)" << endl ; fflush(stdout) ;
@ -604,8 +669,7 @@ unsigned int Server::pointIndex(const float &x, const float &y, const float &z)c
/* Do not forget to call pointExists() before this one */
unsigned int Server::pointIndex(const Point &p)const
inline int Server::pointIndex(const Point &p) const
{
#ifdef DEBUG_T
cout << "//--> Server::pointIndex(&Point)" << endl ; fflush(stdout) ;
@ -622,7 +686,7 @@ unsigned int Server::pointIndex(const Point &p)const
unsigned int Server::pointIndex(const vector<ReferencePoint> &point_list, const float &x, const float &y, const float &z) const
inline int Server::pointIndex(const vector<ReferencePoint> &point_list, const float &x, const float &y, const float &z) const
{
#ifdef DEBUG_T
cout << "//--> Server::pointIndex(&vector<ReferencePoint>, &float, &float, &float)" << endl ; fflush(stdout) ;
@ -639,7 +703,7 @@ unsigned int Server::pointIndex(const vector<ReferencePoint> &point_list, const
unsigned int Server::pointIndex(const vector<ReferencePoint> &point_list, const Point &p) const
inline int Server::pointIndex(const vector<ReferencePoint> &point_list, const Point &p) const
{
#ifdef DEBUG_T
cout << "//--> Server::pointIndex(&vector<ReferencePoint>, &Point)" << endl ; fflush(stdout) ;
@ -647,8 +711,8 @@ unsigned int Server::pointIndex(const vector<ReferencePoint> &point_list, const
unsigned int i;
for (i = 0 ; i < reference_point_list.size() ; i++)
if (p == reference_point_list[i].getCoordinates())
for (i = 0 ; i < point_list.size() ; i++)
if (p == point_list[i].getCoordinates())
{
#ifdef DEBUG_T
cout << "//<-- Server::pointIndex(&vector<ReferencePoint>, &Point)" << endl ; fflush(stdout) ;
@ -660,7 +724,44 @@ unsigned int Server::pointIndex(const vector<ReferencePoint> &point_list, const
cout << "//<-- Server::pointIndex(&vector<ReferencePoint>, &Point)" << endl ; fflush(stdout) ;
#endif // DEBUG_T
return 0; // Should never happen
return -1 ; // Point non trouvé
}
/* Retourne la position du Point "p" dans le tableau à une dimension "point_tab" de taille "size", ou -1 en cas d'échec. */
inline int Server::pointIndex(const Point *point_tab, unsigned int &size, const Point &p) const
{
for (unsigned int i = 0 ; i < size ; i++)
if (point_tab[i] == p)
return i ;
return -1 ;
}
/* Retourne la position du Point "p" dans le vector "point_list", ou -1 en cas d'échec. */
inline int Server::pointIndex(const vector<Point> &point_list, const Point &p) const
{
#ifdef DEBUG_T
cout << "//--> Server::pointIndex(&vector<Point>, &Point)" << endl ; fflush(stdout) ;
#endif // DEBUG_T
for (unsigned int i = 0 ; i < point_list.size() ; i++)
if (point_list[i] == p)
{
#ifdef DEBUG_T
cout << "//<-- Server::pointIndex(&vector<Point>, &Point)" << endl ; fflush(stdout) ;
#endif // DEBUG_T
return i ;
}
#ifdef DEBUG_T
cout << "//<-- Server::pointIndex(&vector<Point>, &Point)" << endl ; fflush(stdout) ;
#endif // DEBUG_T
return -1 ;
}
@ -1131,12 +1232,12 @@ Point Server::interlink(const vector<Measurement> &m, const int &client_idx)cons
dist_vect.clear();
centres.clear();
/* Return position */
return ret;
#ifdef DEBUG_T
cout << "//<-- Server::interlink()" << endl ; fflush(stdout) ;
#endif // DEBUG_T
/* Return position */
return ret;
}
@ -1403,7 +1504,7 @@ void Server::makeTopologyFromFile(const string &filename)
cerr << "Erreur ! Déclaration multiple de la zone « " << infos[0] << " »." << endl ; // on le signale ;
else // sinon on l'ajoute :
{
area_list[infos[0]] = Area(infos[0], string2float(infos[1]), string2float(infos[2]), string2float(infos[3]), string2float(infos[4]), string2float(infos[5]), string2float(infos[6])) ;
area_list[infos[0]] = Area(infos[0], string2float(infos[1]), string2float(infos[3]), string2float(infos[2]), string2float(infos[4]), string2float(infos[5]), string2float(infos[6])) ;
#ifdef DEBUG
cout << " ajoutée." << endl ;
#endif // DEBUG
@ -1438,11 +1539,13 @@ void Server::makeWaypointListFromFile(const string &filename)
cout << "//--> Server::makeWaypointListFromFile()" << endl ; fflush(stdout) ;
#endif // DEBUG_T
/* *** Lecture du fichier *** */
ifstream input_file ;
char buffer[BUFFER_LENGTH] ;
vector<string> infos ;
set<Point> point_list ;
// Point p_cur, p_tmp ;
input_file.open(filename.c_str());
if (input_file.fail())
@ -1471,16 +1574,16 @@ void Server::makeWaypointListFromFile(const string &filename)
infos = explode(buffer, ';') ;
#ifdef DEBUG
cout << "Point de passage : " << buffer ; fflush(stdout);
cout << "Point de passage : " << buffer << ' ' ; fflush(stdout);
#endif // DEBUG
/* Ajout du point lu */
Point tmp_pt(string2float(infos[0]), string2float(infos[1]), string2float(infos[2])) ;
if (! point_list.insert(tmp_pt).second)
cerr << "Point " << tmp_pt << " dupliqué !" << endl ;
else
cerr << "Point " << tmp_pt << " non ajouté ! Peut-être est-il dupliqué ?" << endl ;
#ifdef DEBUG
cout << " traité." << endl ; fflush(stdout);
else
cout << "traité." << endl ; fflush(stdout);
#endif // DEBUG
infos.clear() ;
@ -1490,7 +1593,8 @@ void Server::makeWaypointListFromFile(const string &filename)
input_file.close() ; // Lecture du fichier terminée
/* Construction de la matrice */
/* *** Construction de la matrice des distances *** */
unsigned int nb_pts = point_list.size() ; // Nombre de points
unsigned int cur_idx = 0 ; // Itérateur sur l'indice de la matrice.
waypoint_list.reserve(nb_pts) ; // Vector contenant tous les points (attribut du serveur)
@ -1502,19 +1606,19 @@ void Server::makeWaypointListFromFile(const string &filename)
waypoint_matrix[i][k] = -1 ;
}
#ifdef DEBUG
cout << "--> Liste des points de passage (" << nb_pts << ") :" << endl ; fflush(stdout);
#endif // DEBUG
/* Calcul des distances */
/* Initialisation (voisinage de premier ordre de chaque point */
for (set<Point>::iterator it = point_list.begin() ; it != point_list.end() ; it++, cur_idx++) // Pour chaque point enregistré
{
#ifdef DEBUG
cout << *it << " :" ;
#endif // DEBUG
waypoint_list[cur_idx] = *it ; // Ajout du point dans waypoint_list // FIXME : utiliser plutôt push_back() ?
waypoint_list.push_back(*it) ; // Ajout du point dans waypoint_list
waypoint_matrix[cur_idx][cur_idx] = 0 ; // La distance du point à lui-même est nulle
for (unsigned int k = 0 ; k < cur_idx ; k++) // Pour chacun des point précédent
@ -1522,9 +1626,12 @@ void Server::makeWaypointListFromFile(const string &filename)
#ifdef DEBUG
cout << " / " << waypoint_list[k] ;
#endif // DEBUG
float dist = it->distance(waypoint_list[k]) ; // On calcule la distance
waypoint_matrix[cur_idx][k] = dist ; // et on l'insère dans le tableau,
waypoint_matrix[k][cur_idx] = dist ; // dans les deux sens.
if (inTheSameArea(waypoint_list[cur_idx], waypoint_list[k])) // Si le point est dans la même zone,
{
float dist = it->distance(waypoint_list[k]) ; // on calcule la distance
waypoint_matrix[cur_idx][k] = dist ; // et on l'insère dans le tableau,
waypoint_matrix[k][cur_idx] = dist ; // dans les deux sens.
}
}
#ifdef DEBUG
@ -1532,9 +1639,54 @@ void Server::makeWaypointListFromFile(const string &filename)
#endif // DEBUG
}
#ifdef DEBUG_2
/* Premier affichage de la matrice */
cout << "--> Matrice des distances entre points de passage (après initialisation) :\n\t\t|" ;
for (unsigned int k = 0 ; k < nb_pts ; k++)
cout << ' ' << waypoint_list[k] << "\t|" ;
cout << endl ;
for (unsigned int k = 0 ; k < nb_pts ; k++)
{
cout << waypoint_list[k] << "\t|" ;
for (unsigned int l = 0 ; l < nb_pts ; l++)
cout << '\t' << waypoint_matrix[k][l] << "\t|" ;
cout << endl ;
}
cout << endl ;
#endif // DEBUG_2
/* Itérations suivantes */
bool comput_done = true ;
while (comput_done)
{
comput_done = false ;
for (unsigned int i = 0 ; i < nb_pts ; i++)
for (unsigned int j = 0 ; j < nb_pts ; j++)
if (waypoint_matrix[i][j] > 0)
for (unsigned int k = 0 ; k < nb_pts ; k++)
if (waypoint_matrix[j][k] > 0)
{
/* /!\
* NE PAS OPTIMISER (g++ -O0) !
* Avec l'option d'optimisation de GCC (-O1, -O2 ou -O3), le test :
* (tmp_dist < round_float_2(waypoint_matrix[i][k]) || waypoint_matrix[i][k] == -1)
* est vrai, même si les deux comparaisons sont fausses.
* Cela semble provenir de la variable tmp_dist.
*/
float tmp_dist = round_float_2(waypoint_matrix[j][k] + waypoint_matrix[i][j]) ;
if (tmp_dist < round_float_2(waypoint_matrix[i][k]) || waypoint_matrix[i][k] == -1)
{
waypoint_matrix[i][k] = tmp_dist ;
comput_done = true ;
}
}
}
#ifdef DEBUG
/* Affichage de la matrice */
/* Deuxième affichage de la matrice */
cout << "--> Matrice des distances entre points de passage :\n\t\t|" ;
for (unsigned int k = 0 ; k < nb_pts ; k++)
cout << ' ' << waypoint_list[k] << "\t|" ;
@ -1546,7 +1698,6 @@ void Server::makeWaypointListFromFile(const string &filename)
cout << '\t' << waypoint_matrix[k][l] << "\t|" ;
cout << endl ;
}
cout << endl ;
#endif // DEBUG
@ -1558,6 +1709,123 @@ void Server::makeWaypointListFromFile(const string &filename)
/* Vérifie la cohérence de la topologie décrite dans les fichiers de configuration.
* Retourne false si un problème est détecté, true sinon.
* /!\ La liste des *points de passage*, leur *matrice de distances*, ainsi que la liste des *points de référence*, DOIVENT ÊTRE INITIALISÉES avant l'appel à cette fonction. Il faut donc appeler makeWaypointListFromFile() et makeReferencePointListFromFile() avant checkTopology().
*/
bool Server::checkTopology()
{
#ifdef DEBUG_T
cout << "//--> Server::checkTopology()" << endl ; fflush(stdout) ;
#endif // DEBUG_T
bool ret = true ;
/* *** Recherche de points de passage n'appartenant à aucune zone *** */
for (unsigned int i = 0 ; i < waypoint_list.size() ; i++)
{
map<string, Area> areas(inWhichAreas(waypoint_list[i])) ;
if (areas.empty())
{
#ifdef DEBUG
cout << "Le point de passage " << waypoint_list[i] << " n'appartient à aucune zone !" << endl ;
#endif // DEBUG
ret = false ;
}
#ifdef DEBUG_2
else
{
cout << "Le point de passage " << waypoint_list[i] << " appartient aux zones suivantes :" << endl ;
for (map<string, Area>::iterator it = areas.begin() ; it != areas.end() ; it++)
cout << '\t' << it->first << endl ;
}
#endif // DEBUG_2
}
/* *** Recherche de points de référence n'appartenant à aucune zone *** */
for (unsigned int i = 0 ; i < reference_point_list.size() ; i++)
{
map<string, Area> areas(inWhichAreas((Point) reference_point_list[i])) ;
if (areas.empty())
{
#ifdef DEBUG
cout << "Le point de référence " << (Point) reference_point_list[i] << " n'appartient à aucune zone !" << endl ;
#endif // DEBUG
ret = false ; // À modifier si on veut permettre aux points de référence de n'appartenir à aucune zone.
}
#ifdef DEBUG_2
else
{
cout << "Le point de référence " << (Point) reference_point_list[i] << " appartient aux zones suivantes :" << endl ;
for (map<string, Area>::iterator it = areas.begin() ; it != areas.end() ; it++)
cout << '\t' << it->first << endl ;
}
#endif // DEBUG_2
}
/* *** Recherche des pièces non connectées (et liste des connexions entre pièces) *** */
set<string> connected_areas ; // Liste des zones connectées à au moins une autre zone (on n'enregistre que le nom des zones, dupliquer toutes les zones étant inutile).
for (map<string, Area>::iterator it1 = area_list.begin() ; it1 != area_list.end() ; it1++)
for (map<string, Area>::iterator it2 = area_list.begin() ; it2 != area_list.end() ; it2++)
{
if (it1 == it2)
continue ;
vector<Point> connect(areaConnection(it1->second, it2->second)) ;
if (!connect.empty())
{
connected_areas.insert(it1->first) ; // Ajout de la zone à la liste des zones connectées.
#ifdef DEBUG
cout << "Les zones « " << it1->first << " » et « " << it2->first << " » sont connectées par les points suivants :" << endl ;
for (unsigned int i = 0 ; i < connect.size() ; i++)
cout << '\t' << connect[i] << endl ;
#endif // DEBUG
}
#ifdef DEBUG_2
else
cout << "Les zones « " << it1->first << " » et « " << it2->first << " » ne sont pas connectées." << endl ;
#endif // DEBUG_2
}
if (connected_areas.size() != area_list.size())
{
#ifdef DEBUG
map<string, Area> orphan_areas(area_list) ; // Liste des zones orphelines (non-connectées). Copie de la liste des zones (on devrait utiliser un set ne contenant que les noms, comme pour "connected_areas", mais c'est plus compliqué à coder alors on ne va pas s'embêter, surtout pour un affichage de débogage).
for (set<string>::iterator it = connected_areas.begin() ; it != connected_areas.end() ; it++)
orphan_areas.erase(*it) ; // On supprime chaque zone connectée de la liste des zones orphelines.
cout << "Les zones suivantes ne sont connectées à aucune autre :" << endl ;
for (map<string, Area>::iterator it = orphan_areas.begin() ; it != orphan_areas.end() ; it++)
cout << '\t' << it->first << endl ;
#endif // DEBUG
ret = false ;
}
#ifdef DEBUG_T
cout << "//<-- Server::checkTopology()" << endl ; fflush(stdout) ;
#endif // DEBUG_T
return ret ;
}
/* Calcule la distance entre tous les points de référence en tenant compte de la topologie (initialise reference_point_matrix).
* /!\ La liste des *points de passage*, leur *matrice de distances*, ainsi que la liste des *points de référence*, DOIVENT ÊTRE INITIALISÉES avant l'appel à cette fonction. Il faut donc appeler makeWaypointListFromFile() et makeReferencePointListFromFile() avant makeReferencePointDistances().
*/

View File

@ -12,9 +12,9 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <math.h>
#include <stdio.h>
#include <cstring>
#include <cmath>
#include <cstdio>
#include "guinumo.hh"
#include "clientinfo.hh"
@ -75,6 +75,7 @@ public:
ClientInfo& createClient() ;
map<string, Area> inWhichAreas(const Point &p) ;
bool inTheSameArea(const Point &p1, const Point &p2) ;
vector<Point> areaConnection(const Area &z1, const Area &z2) ;
vector<Point> areaConnection(const Area &z) ;
float distanceTopology(const Point &p1, const Point &p2) ;
@ -84,10 +85,12 @@ public:
bool pointExists(const vector<ReferencePoint> &point_list, const float &x, const float &y, const float &z) const ;
bool pointExists(const vector<ReferencePoint> &point_list, const Point &p) const ;
unsigned int pointIndex(const float &x, const float &y, const float &z)const;
unsigned int pointIndex(const Point &p)const;
unsigned int pointIndex(const vector<ReferencePoint> &point_list, const float &x, const float &y, const float &z) const ;
unsigned int pointIndex(const vector<ReferencePoint> &point_list, const Point &p) const ;
int pointIndex(const float &x, const float &y, const float &z) const;
int pointIndex(const Point &p) const;
int pointIndex(const vector<ReferencePoint> &point_list, const float &x, const float &y, const float &z) const ;
int pointIndex(const vector<ReferencePoint> &point_list, const Point &p) const ;
int pointIndex(const Point *tab, unsigned int &size, const Point &p) const ;
int pointIndex(const vector<Point> &point_list, const Point &p) const ;
bool apExists(const string &ap_addr)const;
unsigned int apIndex(const string &ap_addr)const;
@ -111,6 +114,8 @@ public:
void makeWaypointListFromFile(const string &filename) ;
void makeReferencePointDistances() ;
bool checkTopology() ;
void printReferencePointList();
void printPointList(vector<ReferencePoint> &point_list) ;
void printAccessPointList();