2008-04-11 10:11:29 +02:00
# include "server.hh"
2008-04-30 11:36:55 +02:00
# define TEST
# define DEBUG // Décommenter pour avoir de l'affichage en plus.
2008-05-26 15:15:33 +02:00
//#define DEBUG_2 // Décommenter pour avoir encore plus d'affichage.
2008-04-30 11:36:55 +02:00
/******* Misc. very usefull functions *******/
2008-05-29 10:48:05 +02:00
/* 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 ;
}
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
/* Explodes a string into substrings based on separator sep. Returns a string vector. */
2008-04-30 11:36:55 +02:00
inline vector < string > explode ( const string & input , const char & sep )
2008-04-11 10:11:29 +02:00
{
vector < string > vs ;
string tmp ;
unsigned int i ;
2008-04-15 12:19:15 +02:00
for ( i = 0 ; i < input . size ( ) ; i + + )
if ( input [ i ] = = sep )
2008-04-11 10:11:29 +02:00
{
vs . push_back ( tmp ) ;
tmp . clear ( ) ;
}
else
{
tmp . push_back ( input [ i ] ) ;
}
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
//Last entry, did not encounter a separator.
vs . push_back ( tmp ) ;
tmp . clear ( ) ;
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
return vs ;
}
2008-04-30 11:36:55 +02:00
2008-04-11 10:11:29 +02:00
/* Function to convert a string to an integer */
2008-04-30 11:36:55 +02:00
inline int string2int ( const string & nb )
2008-04-11 10:11:29 +02:00
{
istringstream iss ( nb ) ;
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
int tmp ;
2008-04-15 12:19:15 +02:00
iss > > tmp ;
2008-04-11 10:11:29 +02:00
return tmp ;
}
2008-04-30 11:36:55 +02:00
2008-04-11 10:11:29 +02:00
/* Function to convert a string to an unsigned integer */
2008-04-30 11:36:55 +02:00
inline unsigned int string2uint ( const string & nb )
2008-04-11 10:11:29 +02:00
{
istringstream iss ( nb ) ;
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
unsigned int tmp ;
2008-04-15 12:19:15 +02:00
iss > > tmp ;
2008-04-11 10:11:29 +02:00
return tmp ;
}
2008-04-30 11:36:55 +02:00
2008-04-11 10:11:29 +02:00
/* Function to convert a string to a float */
2008-04-30 11:36:55 +02:00
inline float string2float ( const string & nb )
2008-04-11 10:11:29 +02:00
{
istringstream iss ( nb ) ;
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
float tmp ;
2008-04-15 12:19:15 +02:00
iss > > tmp ;
2008-04-11 10:11:29 +02:00
return tmp ;
}
2008-04-30 11:36:55 +02:00
2008-04-11 10:11:29 +02:00
/* Function extracts ints from string */
inline vector < int > extractValues ( string buff )
{
unsigned int ptr = 0 ;
vector < int > ret ;
string tmp_field ;
2008-04-15 12:19:15 +02:00
if ( buff [ buff . size ( ) - 1 ] ! = ' ; ' )
2008-04-11 10:11:29 +02:00
buff . push_back ( ' ; ' ) ;
2008-04-15 12:19:15 +02:00
while ( ptr < buff . size ( ) )
2008-04-11 10:11:29 +02:00
{
2008-04-15 12:19:15 +02:00
if ( buff [ ptr ] ! = ' ; ' )
2008-04-11 10:11:29 +02:00
tmp_field . push_back ( buff [ ptr ] ) ;
else
{
ret . push_back ( string2int ( tmp_field ) ) ;
tmp_field . clear ( ) ;
}
ptr + + ;
}
return ret ;
}
2008-04-30 11:36:55 +02:00
inline vector < string > extractReferencePointInfoFromBuffer ( const string & buffer_in )
2008-04-11 10:11:29 +02:00
{
unsigned int i = 0 ;
string tmp_field ;
vector < string > ret ;
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
/* Extract coordinates */
/* x */
2008-04-15 12:19:15 +02:00
while ( buffer_in [ i ] ! = ' ; ' )
2008-04-11 10:11:29 +02:00
{
tmp_field . push_back ( buffer_in [ i ] ) ;
i + + ;
}
ret . push_back ( tmp_field ) ;
tmp_field . clear ( ) ;
2008-04-30 11:36:55 +02:00
i + + ; // go after the ';'
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
/* y */
2008-04-15 12:19:15 +02:00
while ( buffer_in [ i ] ! = ' ; ' )
2008-04-11 10:11:29 +02:00
{
tmp_field . push_back ( buffer_in [ i ] ) ;
i + + ;
}
ret . push_back ( tmp_field ) ;
tmp_field . clear ( ) ;
i + + ;
2008-04-15 12:19:15 +02:00
2008-04-30 11:36:55 +02:00
# ifndef FRED_CSV_FORMAT // Dans le format Fred, on n'a pas de coordonnée Z.
/* z */
while ( buffer_in [ i ] ! = ' ; ' )
{
tmp_field . push_back ( buffer_in [ i ] ) ;
i + + ;
}
ret . push_back ( tmp_field ) ;
tmp_field . clear ( ) ;
i + + ;
2008-05-07 10:59:06 +02:00
# endif // FRED_CSV_FORMAT
2008-04-30 11:36:55 +02:00
2008-04-11 10:11:29 +02:00
/* Extract direction (not used now) */
2008-04-15 12:19:15 +02:00
while ( buffer_in [ i ] ! = ' ; ' )
2008-04-11 10:11:29 +02:00
{
tmp_field . push_back ( buffer_in [ i ] ) ;
i + + ;
}
ret . push_back ( tmp_field ) ;
tmp_field . clear ( ) ;
i + + ;
2008-04-15 12:19:15 +02:00
2008-04-30 11:36:55 +02:00
# ifdef FRED_CSV_FORMAT
2008-04-11 10:11:29 +02:00
/* Extract mac address */
2008-04-15 12:19:15 +02:00
while ( buffer_in [ i ] ! = ' ; ' )
2008-04-11 10:11:29 +02:00
{
tmp_field . push_back ( buffer_in [ i ] ) ;
i + + ;
}
ret . push_back ( tmp_field ) ;
tmp_field . clear ( ) ;
i + + ;
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
/* Extract scan list */
2008-04-15 12:19:15 +02:00
while ( i < buffer_in . size ( ) )
2008-04-11 10:11:29 +02:00
{
tmp_field . push_back ( buffer_in [ i ] ) ;
i + + ;
}
ret . push_back ( tmp_field ) ;
tmp_field . clear ( ) ;
2008-05-07 10:59:06 +02:00
# else // FRED_CSV_FORMAT
2008-04-30 11:36:55 +02:00
while ( i < = buffer_in . size ( ) )
{
if ( ( buffer_in [ i ] = = ' ; ' | | i = = buffer_in . size ( ) ) & & ! tmp_field . empty ( ) ) // Si on est sur un séparateur et que la valeur lue n'est pas vide,
{
# ifdef DEBUG_2
cout < < " Ajout de la valeur lue : " < < tmp_field < < endl ;
2008-05-07 10:59:06 +02:00
# endif // DEBUG_2
2008-04-30 11:36:55 +02:00
ret . push_back ( tmp_field ) ; // on met la valeur lue dans les valeurs de retour.
tmp_field . clear ( ) ;
}
else // Si on n'est pas sur un séparateur,
tmp_field . push_back ( buffer_in [ i ] ) ; // on ajoute le caractère courant à la suite de la valeur lue.
i + + ;
}
2008-05-07 10:59:06 +02:00
# endif // FRED_CSV_FORMAT
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
/* Return the vector with each data */
return ret ;
}
2008-04-30 11:36:55 +02:00
2008-04-11 10:11:29 +02:00
/* ***************************************************************** */
2008-04-30 11:36:55 +02:00
2008-04-15 12:19:15 +02:00
//Server::Server(string ip_addr, int listen_port, int send_port) // FIXME : paramètre send_port inutilisé
2008-04-30 11:36:55 +02:00
Server : : Server ( const string & ip_addr , const int & listen_port )
2008-04-11 10:11:29 +02:00
{
/* Open socket */
sockListen = socket ( PF_INET , SOCK_DGRAM , 0 ) ;
sockSend = socket ( PF_INET , SOCK_DGRAM , 0 ) ;
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
/* Set addr */
server_addr . sin_family = AF_INET ;
server_addr . sin_port = htons ( listen_port ) ;
server_addr . sin_addr . s_addr = inet_addr ( ip_addr . c_str ( ) ) ;
memset ( server_addr . sin_zero , ' \0 ' , sizeof ( server_addr . sin_zero ) ) ;
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
/* Bind */
bind ( sockListen , ( struct sockaddr * ) & server_addr , sizeof ( server_addr ) ) ;
2008-04-30 11:36:55 +02:00
2008-05-29 10:48:05 +02:00
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".
2008-04-11 10:11:29 +02:00
}
2008-04-30 11:36:55 +02:00
2008-04-11 10:11:29 +02:00
Server : : ~ Server ( )
{
client_list . clear ( ) ;
reference_point_list . clear ( ) ;
access_point_list . clear ( ) ;
close ( sockListen ) ;
close ( sockSend ) ;
}
2008-04-30 11:36:55 +02:00
void Server : : send_to_client ( const int & cl )
2008-04-11 10:11:29 +02:00
{
/* Do not forget to implement later: usefull for a demo */
}
2008-04-30 11:36:55 +02:00
2008-04-11 10:11:29 +02:00
int Server : : receive_data ( )
{
/* Do not forget to implement later: usefull for a demo */
return 0 ;
}
2008-04-30 11:36:55 +02:00
2008-05-07 10:59:06 +02:00
/* 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 . */
2008-04-30 11:36:55 +02:00
bool Server : : pointExists ( const float & x , const float & y , const float & z ) const
2008-04-11 10:11:29 +02:00
{
2008-05-07 10:59:06 +02:00
return pointExists ( reference_point_list , Point ( x , y , z ) ) ;
}
/* 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
{
return pointExists ( reference_point_list , p ) ;
}
/* 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
{
return pointExists ( point_list , Point ( x , y , z ) ) ;
}
/* 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
{
2008-04-11 10:11:29 +02:00
unsigned int i ;
2008-04-15 12:19:15 +02:00
2008-05-07 10:59:06 +02:00
for ( i = 0 ; i < point_list . size ( ) ; i + + )
if ( p = = point_list [ i ] . getCoordinates ( ) )
2008-04-11 10:11:29 +02:00
return true ;
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
return false ;
}
2008-04-30 11:36:55 +02:00
2008-04-11 10:11:29 +02:00
/* Do not forget to call pointExists() before this one */
2008-04-30 11:36:55 +02:00
unsigned int Server : : pointIndex ( const float & x , const float & y , const float & z ) const
2008-04-11 10:11:29 +02:00
{
2008-05-07 10:59:06 +02:00
return pointIndex ( reference_point_list , Point ( x , y , z ) ) ;
}
2008-04-15 12:19:15 +02:00
2008-05-07 10:59:06 +02:00
/* Do not forget to call pointExists() before this one */
unsigned int Server : : pointIndex ( const Point & p ) const
{
return pointIndex ( reference_point_list , p ) ;
2008-04-11 10:11:29 +02:00
}
2008-04-30 11:36:55 +02:00
2008-05-07 10:59:06 +02:00
unsigned int Server : : pointIndex ( const vector < ReferencePoint > & point_list , const float & x , const float & y , const float & z ) const
{
return pointIndex ( point_list , Point ( x , y , z ) ) ;
}
unsigned int Server : : pointIndex ( const vector < ReferencePoint > & point_list , const Point & p ) const
2008-04-11 10:11:29 +02:00
{
unsigned int i ;
2008-04-15 12:19:15 +02:00
for ( i = 0 ; i < reference_point_list . size ( ) ; i + + )
if ( p = = reference_point_list [ i ] . getCoordinates ( ) )
2008-05-07 10:59:06 +02:00
return i ;
2008-04-15 12:19:15 +02:00
2008-05-07 10:59:06 +02:00
return 0 ; // Should never happen
2008-04-11 10:11:29 +02:00
}
2008-04-30 11:36:55 +02:00
bool Server : : apExists ( const string & ap_addr ) const
2008-04-11 10:11:29 +02:00
{
unsigned int i ;
2008-04-15 12:19:15 +02:00
for ( i = 0 ; i < access_point_list . size ( ) ; i + + )
if ( access_point_list [ i ] . getApAddr ( ) = = ap_addr )
2008-04-11 10:11:29 +02:00
return true ;
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
return false ;
}
2008-04-30 11:36:55 +02:00
unsigned int Server : : apIndex ( const string & ap_addr ) const
2008-04-11 10:11:29 +02:00
{
unsigned int i ;
2008-04-15 12:19:15 +02:00
for ( i = 0 ; i < access_point_list . size ( ) ; i + + )
if ( access_point_list [ i ] . getApAddr ( ) = = ap_addr )
2008-04-11 10:11:29 +02:00
return i ;
2008-04-15 12:19:15 +02:00
return 0 ; // Should never happen
2008-04-11 10:11:29 +02:00
}
2008-04-30 11:36:55 +02:00
/* Selects the "k" closest points from the measurement "m", in the SS space.
* Returns an empty vector if no points are found , which should never happen .
*/
vector < Point > Server : : getkClosestInSs ( const vector < Measurement > & m , const unsigned int & k ) const
{
return getkClosestInSs ( m , k , NULL ) ;
}
/* Selects the "k" closest points from the measurement "m", in the SS space.
* If " point_ignored " is not NULL , the Point " *point_ignored " is ignored .
* Returns an empty vector if no points are found , which should never happen .
*/
vector < Point > Server : : getkClosestInSs ( const vector < Measurement > & m , const unsigned int & k , const Point * point_ignored ) const
2008-04-11 10:11:29 +02:00
{
unsigned int i , j , min_idx ;
vector < float > distances_vector ;
vector < Point > points_vector ;
Point tmp_pt ;
float tmp_distance = 0 , dist_max = 10000000 , tmp_min ;
2008-04-15 12:19:15 +02:00
for ( i = 0 ; i < reference_point_list . size ( ) ; i + + )
2008-04-30 11:36:55 +02:00
if ( point_ignored = = NULL | | ( reference_point_list [ i ] . getCoordinates ( ) ! = * point_ignored ) )
2008-04-11 10:11:29 +02:00
{
tmp_distance = reference_point_list [ i ] . getSsSquareDistance ( m ) ;
2008-05-07 14:25:51 +02:00
# ifdef DEBUG_2
cout < < tmp_distance < < " " ;
# endif // DEBUG_2
2008-04-11 10:11:29 +02:00
/* if not k points, add it */
if ( distances_vector . size ( ) < k )
{
distances_vector . push_back ( tmp_distance ) ;
points_vector . push_back ( reference_point_list [ i ] . getCoordinates ( ) ) ;
2008-05-05 13:59:55 +02:00
dist_max = ( dist_max < tmp_distance ) ? tmp_distance : dist_max ;
2008-04-11 10:11:29 +02:00
}
else
{
/* if tmp_dst < dist_max, should add it and remove previous greatest dist. */
if ( dist_max > tmp_distance )
{
/* remove old max */
2008-04-15 12:19:15 +02:00
for ( j = 0 ; j < distances_vector . size ( ) ; j + + )
if ( distances_vector [ j ] = = dist_max )
2008-04-11 10:11:29 +02:00
{
2008-05-07 14:25:51 +02:00
distances_vector [ j ] = tmp_distance ;
2008-05-07 13:59:54 +02:00
points_vector [ j ] = reference_point_list [ i ] . getCoordinates ( ) ;
2008-04-11 10:11:29 +02:00
break ;
}
2008-05-07 14:15:42 +02:00
/* Now seek the new max. distance */
dist_max = distances_vector [ 0 ] ;
for ( j = 1 ; j < distances_vector . size ( ) ; j + + )
if ( distances_vector [ j ] > dist_max )
dist_max = distances_vector [ j ] ;
2008-04-11 10:11:29 +02:00
}
/* Else nothing needs to be done */
}
}
2008-05-07 14:25:51 +02:00
# ifdef DEBUG_2
cout < < endl ;
# endif // DEBUG_2
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
/* Sorts the vector */
2008-04-15 12:19:15 +02:00
for ( i = 0 ; i < distances_vector . size ( ) - 1 ; i + + )
2008-04-11 10:11:29 +02:00
{
tmp_min = distances_vector [ i ] ;
min_idx = i ;
2008-04-15 12:19:15 +02:00
for ( j = i + 1 ; j < distances_vector . size ( ) ; j + + )
if ( tmp_min > distances_vector [ j ] )
2008-04-11 10:11:29 +02:00
{
tmp_min = distances_vector [ j ] ;
min_idx = j ;
}
2008-04-15 12:19:15 +02:00
if ( min_idx ! = i )
2008-04-11 10:11:29 +02:00
{
/* Swap points */
tmp_pt = points_vector [ i ] ;
points_vector [ i ] = points_vector [ min_idx ] ;
points_vector [ min_idx ] = tmp_pt ;
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
/* Swap distances */
distances_vector [ min_idx ] = distances_vector [ i ] ;
distances_vector [ i ] = tmp_min ;
}
}
2008-04-15 12:19:15 +02:00
2008-05-05 13:59:55 +02:00
# ifdef DEBUG
cout < < " getkClosestInSs() : Points sélectionnés : " < < endl ;
if ( distances_vector . size ( ) ! = points_vector . size ( ) )
cout < < " Erreur ! distances_vector.size()= " < < distances_vector . size ( ) < < " != points_vector.size()= " < < points_vector . size ( ) < < endl ;
else
for ( i = 0 ; i < distances_vector . size ( ) - 1 ; i + + )
cout < < distances_vector [ i ] < < " : " < < points_vector [ i ] < < endl ;
2008-05-07 10:59:06 +02:00
# endif // DEBUG
2008-05-05 13:59:55 +02:00
2008-04-11 10:11:29 +02:00
return points_vector ;
}
2008-04-30 11:36:55 +02:00
Point Server : : getkWeightedInSs ( const vector < Measurement > & m , const unsigned int & k ) const
{
return getkWeightedInSs ( m , k , NULL ) ;
}
/* If "point_ignored" is not NULL, the Point "*point_ignored" is ignored.
*/
Point Server : : getkWeightedInSs ( const vector < Measurement > & m , const unsigned int & k , const Point * point_ignored ) const
2008-04-11 10:11:29 +02:00
{
unsigned int i , j ;
vector < float > distances_vector ;
vector < Point > points_vector ;
float tmp_distance = 0 , dist_max = 10000000 ;
Point ret ;
float total = 0 , x = 0 , y = 0 , z = 0 ;
2008-04-15 12:19:15 +02:00
for ( i = 0 ; i < reference_point_list . size ( ) ; i + + )
2008-04-30 11:36:55 +02:00
if ( point_ignored = = NULL | | ( reference_point_list [ i ] . getCoordinates ( ) ! = * point_ignored ) )
2008-04-11 10:11:29 +02:00
{
tmp_distance = reference_point_list [ i ] . getSsSquareDistance ( m ) ;
/* if not k points, add it */
2008-04-15 12:19:15 +02:00
if ( distances_vector . size ( ) < k )
2008-04-11 10:11:29 +02:00
{
distances_vector . push_back ( tmp_distance ) ;
points_vector . push_back ( reference_point_list [ i ] . getCoordinates ( ) ) ;
2008-04-15 12:19:15 +02:00
dist_max = ( dist_max > tmp_distance ) ? tmp_distance : dist_max ;
2008-04-11 10:11:29 +02:00
}
else
{
/* if tmp_dst < dist_max, should add it and remove previous greatest dist. */
2008-04-15 12:19:15 +02:00
if ( dist_max > tmp_distance )
2008-04-11 10:11:29 +02:00
{
/* remove old max */
2008-04-15 12:19:15 +02:00
for ( j = 0 ; j < distances_vector . size ( ) ; j + + )
2008-04-11 10:11:29 +02:00
if ( distances_vector [ j ] = = dist_max )
{
dist_max = tmp_distance ;
distances_vector . erase ( distances_vector . begin ( ) + j ) ;
points_vector . erase ( points_vector . begin ( ) + j ) ;
distances_vector . push_back ( tmp_distance ) ;
points_vector . push_back ( reference_point_list [ i ] . getCoordinates ( ) ) ;
break ;
}
}
/* Else nothing needs to be done */
}
}
2008-04-15 12:19:15 +02:00
for ( i = 0 ; i < distances_vector . size ( ) ; i + + )
2008-04-11 10:11:29 +02:00
total + = distances_vector [ i ] ;
2008-04-15 12:19:15 +02:00
for ( i = 0 ; i < distances_vector . size ( ) ; i + + )
2008-04-11 10:11:29 +02:00
{
x + = points_vector [ i ] . getX ( ) * distances_vector [ i ] / total ;
y + = points_vector [ i ] . getY ( ) * distances_vector [ i ] / total ;
z + = points_vector [ i ] . getZ ( ) * distances_vector [ i ] / total ;
}
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
ret . setX ( x ) ;
ret . setY ( y ) ;
ret . setZ ( z ) ;
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
return ret ;
}
2008-04-30 11:36:55 +02:00
Point Server : : kPointsAverage ( const vector < Point > & vp ) const
2008-04-11 10:11:29 +02:00
{
unsigned int i ;
float x = 0 , y = 0 , z = 0 ;
Point p ;
2008-04-15 12:19:15 +02:00
for ( i = 0 ; i < vp . size ( ) ; i + + )
2008-04-11 10:11:29 +02:00
{
x + = vp [ i ] . getX ( ) ;
y + = vp [ i ] . getY ( ) ;
z + = vp [ i ] . getZ ( ) ;
}
p . setX ( x / ( float ) vp . size ( ) ) ;
p . setY ( y / ( float ) vp . size ( ) ) ;
p . setZ ( z / ( float ) vp . size ( ) ) ;
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
return p ;
}
2008-04-30 11:36:55 +02:00
Point Server : : fbcm ( const vector < Measurement > & m , const int & client_idx ) const
2008-04-11 10:11:29 +02:00
{
Point ret ( 0 , 0 , 0 ) ;
vector < string > addr ;
vector < float > dist_vect ;
vector < Point > centres ;
unsigned int i , ap_idx ;
float constant_term , minmax_res , minmax_max ;
float x = MINMAX_X_START , y = MINMAX_Y_START ;
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
i = 0 ;
//cout << "FBCM: ";
2008-04-15 12:19:15 +02:00
for ( i = 0 ; i < m . size ( ) ; i + + )
if ( apExists ( m [ i ] . getMacAddr ( ) ) )
2008-04-11 10:11:29 +02:00
{
ap_idx = apIndex ( m [ i ] . getMacAddr ( ) ) ;
//cout << "AP idx: " << ap_idx << " ";
centres . push_back ( access_point_list [ ap_idx ] . getCoordinates ( ) ) ;
addr . push_back ( m [ i ] . getMacAddr ( ) ) ;
constant_term = access_point_list [ ap_idx ] . getOutputPower ( ) + access_point_list [ ap_idx ] . getAntennaGain ( ) + 2 ;
2008-04-15 12:19:15 +02:00
constant_term + = 20 * log10 ( ( 300000000.0 / ( float ) access_point_list [ ap_idx ] . getFrequency ( ) ) / ( 4 * M_PI ) ) ;
2008-04-11 10:11:29 +02:00
//end of expr. should be: client_list[client_idx].getAntennaGain() instead of 2.
2008-04-15 12:19:15 +02:00
//cout << "20log(" << (300000000.0 / (float) access_point_list[ap_idx].getFrequency()) / (4*M_PI) << ") = ";
2008-04-11 10:11:29 +02:00
//cout << constant_term << " ";
dist_vect . push_back ( pow ( 10 , ( constant_term - m [ i ] . getAverage ( ) ) / ( 10 * access_point_list [ ap_idx ] . getFriisIndex ( ) ) ) ) ;
//cout << endl;
}
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
/* Then: min-max */
minmax_res = 1000000 ;
2008-04-15 12:19:15 +02:00
for ( x = MINMAX_X_START ; x < MINMAX_X_STOP ; x + = MINMAX_STEP )
for ( y = MINMAX_Y_START ; y < MINMAX_Y_STOP ; y + = MINMAX_STEP )
2008-04-11 10:11:29 +02:00
{
minmax_max = 0 ;
2008-04-15 12:19:15 +02:00
for ( i = 0 ; i < centres . size ( ) ; i + + )
if ( ( centres [ i ] . squareDistance ( x , y , 3 ) - ( dist_vect [ i ] * dist_vect [ i ] ) ) > minmax_max )
minmax_max = centres [ i ] . squareDistance ( x , y , 3 ) - ( dist_vect [ i ] * dist_vect [ i ] ) ;
if ( minmax_max < minmax_res )
2008-04-11 10:11:29 +02:00
{
ret . setX ( x ) ;
ret . setY ( y ) ;
minmax_res = minmax_max ;
}
}
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
/* Clear all vectors */
addr . clear ( ) ;
dist_vect . clear ( ) ;
centres . clear ( ) ;
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
/* Return position */
return ret ;
}
2008-04-30 11:36:55 +02:00
Point Server : : interlink ( const vector < Measurement > & m , const int & client_idx ) const
2008-04-11 10:11:29 +02:00
{
Point ret ( 0 , 0 , 0 ) ;
vector < string > addr ;
vector < float > dist_vect ;
vector < Point > centres ;
unsigned int i , ap_idx ;
float constant_term , minmax_res , minmax_max ;
float x = MINMAX_X_START , y = MINMAX_Y_START ;
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
i = 0 ;
2008-04-15 12:19:15 +02:00
for ( i = 0 ; i < m . size ( ) ; i + + )
if ( apExists ( m [ i ] . getMacAddr ( ) ) )
2008-04-11 10:11:29 +02:00
{
ap_idx = apIndex ( m [ i ] . getMacAddr ( ) ) ;
centres . push_back ( access_point_list [ ap_idx ] . getCoordinates ( ) ) ;
addr . push_back ( m [ i ] . getMacAddr ( ) ) ;
constant_term = access_point_list [ ap_idx ] . getOutputPower ( ) + access_point_list [ ap_idx ] . getAntennaGain ( ) ;
2008-04-15 12:19:15 +02:00
constant_term + = 20 * log10 ( ( 300000000.0 / ( float ) access_point_list [ ap_idx ] . getFrequency ( ) ) / ( 4 * M_PI ) ) + 2 ;
2008-04-11 10:11:29 +02:00
//end of expr. should be: client_list[client_idx].getAntennaGain() instead of 2.
dist_vect . push_back ( pow ( 10 , ( constant_term - m [ i ] . getAverage ( ) ) / 35 ) ) ;
2008-04-15 12:19:15 +02:00
}
2008-04-11 10:11:29 +02:00
/* Then: min-max */
minmax_res = 1000000 ;
2008-04-15 12:19:15 +02:00
for ( x = MINMAX_X_START ; x < MINMAX_X_STOP ; x + = MINMAX_STEP )
for ( y = MINMAX_Y_START ; y < MINMAX_Y_STOP ; y + = MINMAX_STEP )
2008-04-11 10:11:29 +02:00
{
minmax_max = 0 ;
2008-04-15 12:19:15 +02:00
for ( i = 0 ; i < centres . size ( ) ; i + + )
if ( ( centres [ i ] . squareDistance ( x , y , 3 ) - ( dist_vect [ i ] * dist_vect [ i ] ) ) > minmax_max )
minmax_max = centres [ i ] . squareDistance ( x , y , 3 ) - ( dist_vect [ i ] * dist_vect [ i ] ) ;
if ( minmax_max < minmax_res )
2008-04-11 10:11:29 +02:00
{
ret . setX ( x ) ;
ret . setY ( y ) ;
minmax_res = minmax_max ;
}
}
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
/* Clear all vectors */
addr . clear ( ) ;
dist_vect . clear ( ) ;
centres . clear ( ) ;
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
/* Return position */
return ret ;
}
2008-04-30 11:36:55 +02:00
2008-05-05 13:59:55 +02:00
/* FONCTION POUR RÉTRO-COMPATIBILITÉ.
* Crée la liste des points de référence dans la liste reference_point_list . */
2008-04-30 11:36:55 +02:00
void Server : : makeReferencePointListFromFile ( const string & filename )
2008-04-11 10:11:29 +02:00
{
2008-05-07 10:59:06 +02:00
makePointListFromFile ( reference_point_list , filename , true ) ;
2008-05-05 13:59:55 +02:00
}
void Server : : makePointListFromFile ( vector < ReferencePoint > & dest_point_list , const string & filename )
2008-05-07 10:59:06 +02:00
{
makePointListFromFile ( dest_point_list , filename , true ) ;
}
/* Lit le fichier de mesures (CSV) nommé "filename", et place les informations dans la liste "dest_point_list".
* Si " uniq_point " est vrai , on vérifiera l ' existence d ' un point avant tout ajout d ' information , de manière à ne pas créer de doublon : si le point existe déjà , les informations lui seront ajoutées , sinon un nouveau point sera créé dans la liste .
* Si " uniq_point " est faux , un nouveau point sera créé pour chaque ligne du fichier .
*/
void Server : : makePointListFromFile ( vector < ReferencePoint > & dest_point_list , const string & filename , const bool uniq_point )
2008-05-05 13:59:55 +02:00
{
ifstream input_file ; // Flux d'entrée du fichier.
char buffer [ BUFFER_LENGTH ] ; // Buffer lu dans le fichier.
string cpp_buffer ; // Buffer au format string.
2008-04-11 10:11:29 +02:00
ReferencePoint rp ;
Point tmp_point ;
2008-05-05 13:59:55 +02:00
float x , y , z ; // Coordonnées des points.
2008-05-07 10:59:06 +02:00
unsigned int pt_idx = 0 ; // Position du point lu dans la liste.
2008-05-05 13:59:55 +02:00
vector < string > infos ; // Liste des informations lues dans une ligne du fichier.
2008-04-15 12:19:15 +02:00
input_file . open ( filename . c_str ( ) ) ;
2008-04-30 11:36:55 +02:00
2008-04-15 12:19:15 +02:00
if ( input_file . fail ( ) )
{
cerr < < " Error opening input file « " < < filename < < " » ! " < < endl ;
return ;
}
2008-04-30 11:36:55 +02:00
# ifdef DEBUG
cout < < " Lecture du fichier « " < < filename < < " »... " ;
int nlines = 0 ;
int npoints = 0 ;
2008-05-07 10:59:06 +02:00
# endif // DEBUG
2008-04-30 11:36:55 +02:00
2008-04-15 12:19:15 +02:00
while ( ! input_file . eof ( ) )
2008-04-11 10:11:29 +02:00
{
2008-04-30 11:36:55 +02:00
# ifdef DEBUG
if ( nlines % 100 = = 0 )
printf ( " \n %5d " , nlines ) ;
cout < < ' . ' ;
nlines + + ;
2008-05-07 10:59:06 +02:00
# endif // DEBUG
2008-04-30 11:36:55 +02:00
2008-04-11 10:11:29 +02:00
input_file . getline ( buffer , BUFFER_LENGTH ) ;
2008-04-30 11:36:55 +02:00
2008-04-15 12:19:15 +02:00
if ( ( input_file . rdstate ( ) & ifstream : : eofbit ) = = 0 )
2008-04-11 10:11:29 +02:00
{
/* Extract fields */
cpp_buffer = buffer ;
2008-04-30 11:36:55 +02:00
if ( cpp_buffer . size ( ) = = 0 ) // Ignorer une ligne vide
continue ;
2008-05-07 10:59:06 +02:00
2008-04-11 10:11:29 +02:00
infos = extractReferencePointInfoFromBuffer ( cpp_buffer ) ;
x = string2float ( infos [ 0 ] ) ;
y = string2float ( infos [ 1 ] ) ;
2008-04-30 11:36:55 +02:00
# ifdef FRED_CSV_FORMAT
z = DEFAULT_Z ;
2008-05-07 10:59:06 +02:00
# else // FRED_CSV_FORMAT
2008-04-30 11:36:55 +02:00
z = string2float ( infos [ 2 ] ) ;
2008-05-07 10:59:06 +02:00
# endif // FRED_CSV_FORMAT
2008-04-30 11:36:55 +02:00
2008-04-11 10:11:29 +02:00
/* Set point coordinates */
tmp_point . setX ( x ) ;
tmp_point . setY ( y ) ;
2008-04-30 11:36:55 +02:00
tmp_point . setZ ( z ) ;
2008-04-11 10:11:29 +02:00
/* Use C++ string format */
2008-05-07 10:59:06 +02:00
if ( ! uniq_point | | ! pointExists ( dest_point_list , tmp_point ) ) // Si on ne veut pas de points unique, ou que le point n'existe pas encore,
2008-04-11 10:11:29 +02:00
{
rp . setCoordinates ( tmp_point ) ;
2008-05-07 10:59:06 +02:00
dest_point_list . push_back ( rp ) ; // on le crée.
pt_idx = dest_point_list . size ( ) - 1 ; // Le point que l'on vient d'ajouter est le dernier du vector.
2008-05-05 13:59:55 +02:00
# ifdef DEBUG
2008-04-30 11:36:55 +02:00
npoints + + ;
2008-05-07 10:59:06 +02:00
# endif // DEBUG
2008-05-05 13:59:55 +02:00
# ifdef DEBUG_2
2008-04-30 11:36:55 +02:00
cout < < tmp_point < < " : ajouté. " < < endl ;
2008-05-07 10:59:06 +02:00
# endif // DEBUG_2
2008-04-30 11:36:55 +02:00
}
2008-05-07 10:59:06 +02:00
else // Le point existe déjà :
2008-04-30 11:36:55 +02:00
{
2008-05-07 10:59:06 +02:00
# ifdef DEBUG_2
2008-04-30 11:36:55 +02:00
cout < < tmp_point < < " : existe déjà. " < < endl ;
2008-05-07 10:59:06 +02:00
# endif // DEBUG_2
pt_idx = pointIndex ( dest_point_list , tmp_point ) ; // On recherche le point auquel on veut ajouter les informations.
2008-04-11 10:11:29 +02:00
}
2008-04-30 11:36:55 +02:00
# ifdef FRED_CSV_FORMAT
vector < int > measures_vector = extractValues ( infos [ 4 ] ) ;
2008-05-05 13:59:55 +02:00
for ( unsigned int i = 0 ; i < measures_vector . size ( ) ; i + + )
dest_point_list [ pt_idx ] . addMeasurement ( infos [ 3 ] , measures_vector [ i ] ) ;
2008-04-30 11:36:55 +02:00
measures_vector . clear ( ) ;
2008-05-07 10:59:06 +02:00
# else // FRED_CSV_FORMAT
2008-05-05 13:59:55 +02:00
for ( unsigned int i = 4 ; i < infos . size ( ) ; i + + )
2008-04-30 11:36:55 +02:00
{
# ifdef DEBUG_2
cout < < " Lecture de la valeur : " < < infos [ i ] < < " ... " ;
2008-05-07 10:59:06 +02:00
# endif // DEBUG_2
2008-04-30 11:36:55 +02:00
if ( i + 1 < infos . size ( ) )
{
2008-05-05 13:59:55 +02:00
dest_point_list [ pt_idx ] . addMeasurement ( infos [ i ] , string2int ( infos [ i + 1 ] ) ) ;
2008-04-30 11:36:55 +02:00
# ifdef DEBUG_2
cout < < " Mesure ajoutée : AP = " < < infos [ i ] < < " | SS = " < < string2int ( infos [ i + 1 ] ) < < endl ;
2008-05-07 10:59:06 +02:00
# endif // DEBUG_2
2008-04-30 11:36:55 +02:00
i + + ;
}
}
2008-05-07 10:59:06 +02:00
# endif // FRED_CSV_FORMAT
2008-04-11 10:11:29 +02:00
}
}
2008-04-15 12:19:15 +02:00
2008-04-30 11:36:55 +02:00
# ifdef DEBUG
cout < < ' \n ' < < nlines < < " lignes lues, " < < npoints < < " points différents ajoutés. \n " < < endl ;
2008-05-07 10:59:06 +02:00
# endif // DEBUG
2008-04-30 11:36:55 +02:00
2008-04-11 10:11:29 +02:00
input_file . close ( ) ;
2008-04-30 11:36:55 +02:00
infos . clear ( ) ;
2008-04-11 10:11:29 +02:00
}
2008-04-30 11:36:55 +02:00
void Server : : makeApListFromFile ( const string & filename )
2008-04-11 10:11:29 +02:00
{
ifstream input_file ;
char buffer [ BUFFER_LENGTH ] ;
vector < string > ap_infos ;
AccessPoint tmp_ap ;
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
input_file . open ( filename . c_str ( ) ) ;
2008-04-15 12:19:15 +02:00
if ( input_file . fail ( ) )
{
cerr < < " Error opening input file « " < < filename < < " » ! " < < endl ;
return ;
}
2008-04-30 11:36:55 +02:00
# ifdef DEBUG
cout < < " Lecture du fichier « " < < filename < < " »... " < < endl ;
2008-05-07 10:59:06 +02:00
# endif // DEBUG
2008-04-30 11:36:55 +02:00
2008-04-15 12:19:15 +02:00
while ( ! input_file . eof ( ) )
2008-04-11 10:11:29 +02:00
{
input_file . getline ( buffer , BUFFER_LENGTH ) ;
2008-04-30 11:36:55 +02:00
2008-04-15 12:19:15 +02:00
if ( ( input_file . rdstate ( ) & ifstream : : eofbit ) = = 0 )
2008-04-11 10:11:29 +02:00
{
2008-04-30 11:36:55 +02:00
/* Traitement basique des commentaires */
if ( buffer [ 0 ] = = ' \0 ' // Ligne vide
| | buffer [ 0 ] = = ' # ' ) // ou ligne commençant par #
continue ; // ignorer cette ligne.
2008-04-11 10:11:29 +02:00
ap_infos = explode ( buffer , ' ; ' ) ;
2008-04-30 11:36:55 +02:00
# ifdef DEBUG
cout < < " AP : " < < buffer ;
2008-05-07 10:59:06 +02:00
# endif // DEBUG
2008-04-11 10:11:29 +02:00
tmp_ap . setApAddr ( ap_infos [ 0 ] ) ;
tmp_ap . setCoordinates ( string2float ( ap_infos [ 1 ] ) , string2float ( ap_infos [ 2 ] ) , string2float ( ap_infos [ 3 ] ) ) ;
tmp_ap . setFrequency ( string2uint ( ap_infos [ 4 ] ) ) ;
tmp_ap . setAntennaGain ( string2float ( ap_infos [ 5 ] ) ) ;
tmp_ap . setOutputPower ( string2float ( ap_infos [ 6 ] ) ) ;
access_point_list . push_back ( tmp_ap ) ;
ap_infos . clear ( ) ;
2008-04-30 11:36:55 +02:00
# ifdef DEBUG
cout < < " ajouté. " < < endl ;
2008-05-07 10:59:06 +02:00
# endif // DEBUG
2008-04-11 10:11:29 +02:00
}
}
2008-04-15 12:19:15 +02:00
2008-04-30 11:36:55 +02:00
# ifdef DEBUG
cout < < endl ;
2008-05-07 10:59:06 +02:00
# endif // DEBUG
2008-04-30 11:36:55 +02:00
2008-04-11 10:11:29 +02:00
input_file . close ( ) ;
}
2008-04-30 11:36:55 +02:00
2008-05-29 10:48:05 +02:00
void Server : : makeTopologyFromFile ( const string & filename )
{
ifstream input_file ;
char buffer [ BUFFER_LENGTH ] ;
vector < string > 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 < string , Area > : : 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 < string > infos ;
map < Point , vector < Point > > 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 < Point , vector < Point > > : : 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
}
2008-05-05 13:59:55 +02:00
/* FONCTION POUR RÉTRO-COMPATIBILITÉ
* Affiche la liste des points de référence ( reference_point_list ) . */
2008-04-11 10:11:29 +02:00
void Server : : printReferencePointList ( )
{
2008-05-05 13:59:55 +02:00
printPointList ( reference_point_list ) ;
}
2008-04-15 12:19:15 +02:00
2008-05-05 13:59:55 +02:00
/* Affiche une liste de points (point_list). */
void Server : : printPointList ( vector < ReferencePoint > & point_list )
{
for ( unsigned int i = 0 ; i < point_list . size ( ) ; i + + )
cout < < point_list [ i ] < < endl ;
2008-04-11 10:11:29 +02:00
}
2008-04-30 11:36:55 +02:00
2008-04-11 10:11:29 +02:00
void Server : : printAccessPointList ( )
{
2008-05-05 13:59:55 +02:00
for ( unsigned int i = 0 ; i < access_point_list . size ( ) ; i + + )
2008-04-11 10:11:29 +02:00
cout < < access_point_list [ i ] < < endl ;
}
2008-04-30 11:36:55 +02:00
2008-04-11 10:11:29 +02:00
void Server : : computeFriisFromRefList ( )
{
vector < float > friis_idx_list ;
Point pt_coords , ap_coords ;
float ap_power , ap_gain , calib_gain = 2 , const_term , mes_power , friis_sum ;
unsigned int ap_freq ;
string ap_mac ;
2008-04-15 12:19:15 +02:00
2008-05-05 13:59:55 +02:00
for ( unsigned int i = 0 ; i < access_point_list . size ( ) ; i + + )
2008-04-11 10:11:29 +02:00
{
ap_power = access_point_list [ i ] . getOutputPower ( ) ;
ap_coords = access_point_list [ i ] . getCoordinates ( ) ;
ap_freq = access_point_list [ i ] . getFrequency ( ) ;
ap_gain = access_point_list [ i ] . getAntennaGain ( ) ;
ap_mac = access_point_list [ i ] . getApAddr ( ) ;
/* Compute main general term, independant from scans */
const_term = calib_gain + ap_gain ;
const_term - = 20 * log10 ( 4 * M_PI ) ;
const_term + = 20 * log10 ( 300000000.0 / ap_freq ) + ap_power ;
/* Compute an index for each ref point. List stored in friis_idx_list */
2008-05-05 13:59:55 +02:00
for ( unsigned int j = 0 ; j < reference_point_list . size ( ) ; j + + )
2008-04-11 10:11:29 +02:00
{
pt_coords = reference_point_list [ j ] . getCoordinates ( ) ;
2008-04-15 12:19:15 +02:00
if ( reference_point_list [ i ] . getPowerForAp ( ap_mac , & mes_power ) )
friis_idx_list . push_back ( ( const_term - mes_power ) / ( 10 * log10 ( ap_coords . distance ( pt_coords ) ) ) ) ;
2008-04-11 10:11:29 +02:00
}
2008-05-05 13:59:55 +02:00
2008-04-11 10:11:29 +02:00
/* Now, compute avg value */
friis_sum = 0 ;
2008-05-05 13:59:55 +02:00
for ( unsigned int j = 0 ; j < friis_idx_list . size ( ) ; j + + )
2008-04-11 10:11:29 +02:00
friis_sum + = friis_idx_list [ j ] ;
access_point_list [ i ] . setFriisIndex ( friis_sum / friis_idx_list . size ( ) ) ;
2008-05-05 13:59:55 +02:00
2008-04-11 10:11:29 +02:00
cout < < access_point_list [ i ] . getApAddr ( ) < < " -> " < < ( friis_sum / friis_idx_list . size ( ) ) < < endl ;
2008-05-05 13:59:55 +02:00
2008-04-11 10:11:29 +02:00
friis_idx_list . clear ( ) ;
}
}
2008-04-15 12:19:15 +02:00
2008-04-30 11:36:55 +02:00
2008-04-11 10:11:29 +02:00
/*
2008-04-30 11:36:55 +02:00
* Computes new cumulative distances for each running viterbi instance ,
2008-04-11 10:11:29 +02:00
* Returns the solution ( type : Point ) of the last ended viterbi .
* Distances are grouped by line corresponding to an instance .
2008-04-30 11:36:55 +02:00
* " K " MUST be the same as last . size ( ) and current . size ( ) !
2008-04-11 10:11:29 +02:00
*/
2008-04-30 11:36:55 +02:00
void Server : : fastViterbiLike ( const unsigned short & N , const unsigned short & K , const unsigned int & id_client )
2008-04-11 10:11:29 +02:00
{
2008-04-30 11:36:55 +02:00
# ifdef TEST
ClientInfo cl ;
float * * V = cl . get_viterbi_V ( ) ;
vector < Point >
& E_current = cl . getRef_viterbi_Ecurrent ( ) ,
& E_previous = cl . getRef_viterbi_Eprevious ( ) ;
2008-05-05 13:59:55 +02:00
vector < ReferencePoint > peregrination_point_list ;
2008-05-07 10:59:06 +02:00
makePointListFromFile ( peregrination_point_list , DEFAULT_TRACKING_FILE , false ) ;
# else // TEST
2008-04-30 11:36:55 +02:00
float * * V = client_list [ id_client ] . get_viterbi_V ( ) ;
vector < Point >
& E_current = client_list [ id_client ] . getRef_viterbi_Ecurrent ( ) ,
& E_previous = client_list [ id_client ] . getRef_viterbi_Eprevious ( ) ;
2008-05-07 10:59:06 +02:00
# endif // TEST
2008-04-30 11:36:55 +02:00
int i = 1 ; // Nombre d'ensembles d'historique qu'on a déjà passés
2008-05-26 15:15:33 +02:00
unsigned int V0_min_k = 0 ; // Indice du point sélectionné à chaque itération
2008-04-30 11:36:55 +02:00
if ( N < 2 )
2008-04-11 10:11:29 +02:00
{
2008-04-30 11:36:55 +02:00
cerr < < " fastViterbiLike() : N ne peut être inférieur à 2 ! " < < endl ;
return ;
2008-04-11 10:11:29 +02:00
}
2008-05-07 10:59:06 +02:00
# ifdef DEBUG
2008-05-26 15:15:33 +02:00
cout < < reference_point_list . size ( ) < < " points de référence " ;
# ifdef TEST
cout < < " , " < < peregrination_point_list . size ( ) < < " points de pérégrination. " < < endl ;
# else // TEST
cout < < ' . ' < < endl ;
# endif // TEST
# endif // DEBUG
# ifdef DEBUG_2
2008-05-07 10:59:06 +02:00
cout < < " ***** Liste pts référence : ***** " < < endl ;
printReferencePointList ( ) ;
2008-05-26 15:15:33 +02:00
# ifdef TEST
2008-05-07 10:59:06 +02:00
cout < < " ***** Liste pérégrination : ***** " < < endl ;
printPointList ( peregrination_point_list ) ;
2008-05-26 15:15:33 +02:00
# endif // TEST
2008-05-07 10:59:06 +02:00
cout < < " ********************************* " < < endl ;
2008-05-26 15:15:33 +02:00
# endif // DEBUG_2
2008-05-05 13:59:55 +02:00
2008-05-26 15:15:33 +02:00
# ifdef TEST
unsigned int pt = 0 ;
2008-05-05 13:59:55 +02:00
while ( pt < peregrination_point_list . size ( ) )
2008-05-07 10:59:06 +02:00
# else // TEST
2008-04-30 11:36:55 +02:00
while ( true )
2008-05-07 10:59:06 +02:00
# endif // TEST
2008-04-30 11:36:55 +02:00
{
vector < Measurement > vm ;
# ifdef TEST
/* Get point measurements */
2008-05-05 13:59:55 +02:00
//vm.clear();
vm = peregrination_point_list [ pt ] . getMeasurementList ( ) ;
2008-05-07 10:59:06 +02:00
# endif // TEST
2008-04-11 10:11:29 +02:00
2008-04-30 11:36:55 +02:00
E_previous = E_current ;
2008-05-05 13:59:55 +02:00
E_current = getkClosestInSs ( vm , K ) ; // Création de l'ensemble des K points les plus proches dans l'espace des puissances.
# ifdef DEBUG
cout < < " Point courant : " < < peregrination_point_list [ pt ] ;
2008-05-07 10:59:06 +02:00
# endif // DEBUG
2008-04-11 10:11:29 +02:00
2008-04-30 11:36:55 +02:00
if ( i > 1 ) // Si on n'est plus à la première itération
{
/* Recalcul des plus courtes distances */
for ( int n = N - 1 - i ; n < N - 2 ; n + + ) // Pour chaque historique existant (sauf le dernier),
for ( int k = 0 ; k < K ; k + + ) // pour chaque point de l'historique,
{ // on met à jour le chemin minimum entre l'historique précédent et le point :
V [ n ] [ k ] = V [ n + 1 ] [ 0 ] + E_previous [ 0 ] . distance ( E_current [ k ] ) ;
for ( int l = 1 ; l < K ; l + + )
{
float f = V [ n + 1 ] [ l ] + E_previous [ l ] . distance ( E_current [ k ] ) ;
if ( f < V [ n ] [ k ] )
V [ n ] [ k ] = f ;
}
}
/* Traitement du dernier historique */
for ( int k = 0 ; k < K ; k + + ) // Pour chaque point,
{ // on récupère le chemin minimum entre l'historique précédent et le point :
V [ N - 2 ] [ k ] = E_previous [ 0 ] . distance ( E_current [ k ] ) ;
for ( int l = 1 ; l < K ; l + + )
{
float f = E_previous [ l ] . distance ( E_current [ k ] ) ;
if ( f < V [ N - 2 ] [ k ] )
V [ N - 2 ] [ k ] = f ;
}
}
2008-05-26 15:15:33 +02:00
/* Choix du point à renvoyer */
V0_min_k = 0 ; // Indice du point correspondant au V0 minimal. Si le tableau n'est pas plein, la plus petite valeur a l'indice 0 (car getkClosestInSs() renvoit un résultat trié).
2008-04-30 11:36:55 +02:00
if ( N - 1 - i = = 0 )
{
2008-05-26 15:15:33 +02:00
# ifdef DEBUG
2008-04-30 11:36:55 +02:00
float V0_min = V [ 0 ] [ 0 ] ;
2008-05-26 15:15:33 +02:00
cout < < " V[0][0]= " < < V [ 0 ] [ 0 ] < < " ; V0_min= " < < V0_min < < " ; V0_min_k= " < < V0_min_k < < " -- " ;
# endif // DEBUG
2008-04-30 11:36:55 +02:00
for ( int k = 1 ; k < K ; k + + )
{
if ( V [ 0 ] [ k ] < V0_min )
2008-05-26 15:15:33 +02:00
{
V0_min_k = k ;
# ifdef DEBUG
V0_min = V [ 0 ] [ k ] ;
# endif // DEBUG
}
# ifdef DEBUG
cout < < " V[0][ " < < k < < " ]= " < < V [ 0 ] [ k ] < < " ; V0_min= " < < V0_min < < " ; V0_min_k= " < < V0_min_k < < " -- " ;
# endif // DEBUG
2008-04-30 11:36:55 +02:00
}
2008-05-26 15:15:33 +02:00
# ifdef DEBUG
cout < < " V0_min = " < < V0_min < < " ; V0_min_k= " < < V0_min_k < < endl ;
# endif // DEBUG
2008-04-30 11:36:55 +02:00
}
}
2008-04-11 10:11:29 +02:00
2008-05-05 13:59:55 +02:00
# ifdef DEBUG
2008-04-30 11:36:55 +02:00
// cout << "(N=" << N << ") - 1 - (i=" << i << ") = " << N-1-i << endl ;
2008-05-05 13:59:55 +02:00
cout < < " V : " < < endl ;
2008-04-30 11:36:55 +02:00
for ( int n = 0 ; n < N - 1 ; n + + )
{
for ( int k = 0 ; k < K ; k + + )
cout < < " [ " < < V [ n ] [ k ] < < " ] " ;
cout < < endl ;
}
2008-05-26 15:15:33 +02:00
cout < < " Point sélectionné : " < < E_current [ V0_min_k ] < < endl ;
cout < < " -------------------------- " < < endl ;
2008-05-07 10:59:06 +02:00
# endif // DEBUG
2008-04-30 11:36:55 +02:00
if ( i < N - 1 )
i + + ;
# ifdef TEST
pt + + ;
2008-05-07 10:59:06 +02:00
# endif // TEST
2008-04-30 11:36:55 +02:00
}
2008-04-11 10:11:29 +02:00
}
2008-04-30 11:36:55 +02:00
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
/* For experimentation purpose only */
void Server : : radar_exp ( )
{
ofstream logfile ;
vector < Point > solutions ;
Point solution , solution_kw , ref_coords ;
unsigned int i ;
vector < Measurement > vm ;
2008-04-30 11:36:55 +02:00
// computeFriisFromRefList();
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
/* Open a log file */
2008-04-15 12:19:15 +02:00
logfile . open ( DEFAULT_LOGFILE ) ;
if ( logfile . fail ( ) )
{
cerr < < " Error opening output file « " < < logfile < < " » ! " < < endl ;
return ;
}
2008-04-11 10:11:29 +02:00
/* Column names */
logfile < < " Coordinates \t 2-kss \t (Error) \t 3-kss \t (Error) \t 4-kss \t (Error) \t 5-kss \t (Error) \t nss \t (Error) \t Interlink \t (Error) \t FBCM \t (Error) " < < endl ;
2008-04-15 12:19:15 +02:00
cout < < reference_point_list . size ( ) < < " reference points. " < < endl ;
for ( i = 0 ; i < reference_point_list . size ( ) ; i + + )
2008-04-11 10:11:29 +02:00
{
/* Get point measurements */
vm . clear ( ) ;
vm = reference_point_list [ i ] . getMeasurementList ( ) ;
ref_coords = reference_point_list [ i ] . getCoordinates ( ) ;
/* Print point coordinates */
logfile < < ref_coords < < " \t " ;
/* From 2 to 5 K-weighted-SS */
2008-04-30 11:36:55 +02:00
solution = getkWeightedInSs ( vm , 2 , & ref_coords ) ;
2008-04-11 10:11:29 +02:00
logfile < < solution < < " \t " < < solution . distance ( ref_coords ) < < " \t " ;
2008-04-30 11:36:55 +02:00
solution = getkWeightedInSs ( vm , 3 , & ref_coords ) ;
2008-04-11 10:11:29 +02:00
logfile < < solution < < " \t " < < solution . distance ( ref_coords ) < < " \t " ;
2008-04-30 11:36:55 +02:00
solution = getkWeightedInSs ( vm , 4 , & ref_coords ) ;
2008-04-11 10:11:29 +02:00
logfile < < solution < < " \t " < < solution . distance ( ref_coords ) < < " \t " ;
2008-04-30 11:36:55 +02:00
solution = getkWeightedInSs ( vm , 5 , & ref_coords ) ;
2008-04-11 10:11:29 +02:00
logfile < < solution < < " \t " < < solution . distance ( ref_coords ) < < " \t " ;
2008-04-15 12:19:15 +02:00
2008-04-11 10:11:29 +02:00
/* Nearest in SS */
2008-04-30 11:36:55 +02:00
solutions = getkClosestInSs ( vm , 1 , & ref_coords ) ;
2008-04-11 10:11:29 +02:00
logfile < < solutions [ 0 ] < < " \t " < < solutions [ 0 ] . distance ( ref_coords ) < < " \t " ;
/* Interlink Networks */
solution = interlink ( vm , 0 ) ;
logfile < < solution < < " \t " < < solution . distance ( ref_coords ) < < " \t " ;
/* FBCM */
solution = fbcm ( vm , 0 ) ;
logfile < < solution < < " \t " < < solution . distance ( ref_coords ) < < endl ;
solutions . clear ( ) ;
}
logfile . close ( ) ;
}