[Positioning] Directory reorganization
Move "new" source files in src/. Update Doxyfile and Makefile. Delete old useless files: - libowlps-positioning.* - positioning.* - server.* - treatment.*
This commit is contained in:
parent
7264080536
commit
c559b827ee
|
@ -568,7 +568,7 @@ WARN_LOGFILE =
|
|||
# directories like "/usr/src/myproject". Separate the files or directories
|
||||
# with spaces.
|
||||
|
||||
INPUT =
|
||||
INPUT = src
|
||||
|
||||
# This tag can be used to specify the character encoding of the source files
|
||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
|
||||
|
@ -597,7 +597,7 @@ RECURSIVE = NO
|
|||
# excluded from the INPUT source files. This way you can easily exclude a
|
||||
# subdirectory from a directory tree whose root is specified with the INPUT tag.
|
||||
|
||||
EXCLUDE = libowlps-positioning.hh libowlps-positioning.cc owlps-positioning.hh owlps-positioning.cc positioning.hh positioning.cc server.hh server.cc treatment.hh treatment.cc
|
||||
EXCLUDE =
|
||||
|
||||
# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
|
||||
# directories that are symbolic links (a Unix filesystem feature) are excluded
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
.PHONY : all test doc clean purge install uninstall style check
|
||||
.PHONY : all test doc prepare clean purge install uninstall style check
|
||||
|
||||
SRC_DIR = src
|
||||
OBJ_DIR = obj
|
||||
TESTS_DIR = tests
|
||||
DOXYGEN_DIR = doc
|
||||
DOXYFILE = Doxyfile
|
||||
|
@ -11,7 +13,9 @@ INSTALL_DIR = $(PREFIX)/bin
|
|||
# System tools
|
||||
RM = rm -fv
|
||||
RM_RECURSIVE = \rm -fr
|
||||
RM_RECURSIVE_VERBOSE = rm -frv
|
||||
CP = cp -v
|
||||
MKDIR = mkdir -pv
|
||||
|
||||
# Other tools
|
||||
STYLE = astyle --style=gnu --formatted
|
||||
|
@ -21,14 +25,18 @@ DOXYGEN = doxygen
|
|||
# Compilation tools and flags
|
||||
GXX = g++-4.4
|
||||
#DEBUG = -g
|
||||
TESTSGXXFLAGS = -I$(TESTS_DIR) -I.
|
||||
TESTSGXXFLAGS = -I$(TESTS_DIR) -I$(SRC_DIR) -I.
|
||||
GXXFLAGS = $(DEBUG) -Wall -Wextra
|
||||
LD = $(GXX)
|
||||
LDFLAGS = -lm -lrt -lboost_program_options
|
||||
|
||||
# Targets
|
||||
TARGET = owlps-positioning
|
||||
OBJ = posutil.o \
|
||||
OBJ_TARGET = $(OBJ_DIR)/$(TARGET).o
|
||||
SOURCE_TARGET = $(SRC_DIR)/$(TARGET).cc
|
||||
|
||||
OBJ_LIST = \
|
||||
posutil.o \
|
||||
stock.o \
|
||||
timestamp.o \
|
||||
direction.o \
|
||||
|
@ -48,54 +56,91 @@ OBJ = posutil.o \
|
|||
input.o \
|
||||
inputcsv.o \
|
||||
inputlogcsv.o
|
||||
OBJ_NOTEST = posexcept.o \
|
||||
inputmedium.o
|
||||
INTERFACES = inputlogmedium.hh
|
||||
OBJ_NOTEST_LIST = \
|
||||
posexcept.o \
|
||||
inputmedium.o
|
||||
INTERFACES_LIST = inputlogmedium.hh
|
||||
|
||||
OBJ = $(OBJ_LIST:%=$(OBJ_DIR)/%)
|
||||
OBJ_NOTEST = $(OBJ_NOTEST_LIST:%=$(OBJ_DIR)/%)
|
||||
INTERFACES = $(INTERFACES_LIST:%=$(SRC_DIR)/%)
|
||||
SOURCE = \
|
||||
$(OBJ:$(OBJ_DIR)/%.o=$(SRC_DIR)/%.hh) \
|
||||
$(OBJ:$(OBJ_DIR)/%.o=$(SRC_DIR)/%.cc) \
|
||||
$(OBJ_NOTEST:$(OBJ_DIR)/%.o=$(SRC_DIR)/%.hh) \
|
||||
$(OBJ_NOTEST:$(OBJ_DIR)/%.o=$(SRC_DIR)/%.cc) \
|
||||
$(INTERFACES)
|
||||
|
||||
TESTS_XX = $(TESTS_DIR)/tests.cc
|
||||
TESTS_OBJ = $(TESTS_DIR)/tests.o
|
||||
TESTS_TARGET = $(TESTS_DIR)/tests
|
||||
TESTUTIL_OBJ = $(TESTS_DIR)/testutil.o
|
||||
TESTSETUP_OBJ = $(TESTS_DIR)/testsetup.o
|
||||
SOURCE_TESTS = $(OBJ:%.o=$(TESTS_DIR)/%_test.hh)
|
||||
SOURCE_TESTS = $(OBJ:$(OBJ_DIR)/%.o=$(TESTS_DIR)/%_test.hh)
|
||||
OBJ_TESTS = $(TESTUTIL_OBJ) $(TESTSETUP_OBJ)
|
||||
INCLUDES_TESTS = $(TESTS_DIR)/valuetraits.hh
|
||||
|
||||
all: $(TARGET)
|
||||
all: prepare $(TARGET)
|
||||
|
||||
# Generic targets
|
||||
$(TESTS_DIR)/%.o: $(TESTS_DIR)/%.cc $(TESTS_DIR)/%.hh
|
||||
$(GXX) $(GXXFLAGS) $(TESTSGXXFLAGS) -o $@ -c $<
|
||||
|
||||
%.o: %.cc %.hh
|
||||
$(GXX) $(GXXFLAGS) -c $<
|
||||
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cc $(SRC_DIR)/%.hh
|
||||
$(GXX) $(GXXFLAGS) -o $@ -c $<
|
||||
|
||||
%: %.o
|
||||
%: $(OBJ_DIR)/%.o
|
||||
$(LD) $(LDFLAGS) -o $@ $^
|
||||
|
||||
# Dependencies
|
||||
userinterface.o: configuration.o
|
||||
referencepoint.o: point3d.o
|
||||
waypoint.o: point3d.o building.o
|
||||
area.o: building.o point3d.o
|
||||
wifidevice.o: posutil.o
|
||||
accesspoint.o: wifidevice.o point3d.o
|
||||
mobile.o: wifidevice.o
|
||||
measurement.o: accesspoint.o
|
||||
request.o: timestamp.o measurement.o
|
||||
calibrationrequest.o: request.o referencepoint.o direction.o
|
||||
inputcsv.o: inputmedium.o request.o calibrationrequest.o stock.o
|
||||
inputlogcsv.o: inputlogmedium.hh request.o
|
||||
input.o: posexcept.o
|
||||
userinterface.o: \
|
||||
$(OBJ_DIR)/configuration.o
|
||||
referencepoint.o: \
|
||||
$(OBJ_DIR)/point3d.o
|
||||
waypoint.o: \
|
||||
$(OBJ_DIR)/point3d.o \
|
||||
$(OBJ_DIR)/building.o
|
||||
area.o: \
|
||||
$(OBJ_DIR)/building.o \
|
||||
$(OBJ_DIR)/point3d.o
|
||||
wifidevice.o: \
|
||||
$(OBJ_DIR)/posutil.o
|
||||
accesspoint.o: \
|
||||
$(OBJ_DIR)/wifidevice.o \
|
||||
$(OBJ_DIR)/point3d.o
|
||||
mobile.o: \
|
||||
$(OBJ_DIR)/wifidevice.o
|
||||
measurement.o: \
|
||||
$(OBJ_DIR)/accesspoint.o
|
||||
request.o: \
|
||||
$(OBJ_DIR)/timestamp.o \
|
||||
$(OBJ_DIR)/measurement.o
|
||||
calibrationrequest.o: \
|
||||
$(OBJ_DIR)/request.o \
|
||||
$(OBJ_DIR)/referencepoint.o \
|
||||
$(OBJ_DIR)/direction.o
|
||||
inputcsv.o: \
|
||||
$(OBJ_DIR)/inputmedium.o \
|
||||
$(OBJ_DIR)/request.o \
|
||||
$(OBJ_DIR)/calibrationrequest.o \
|
||||
$(OBJ_DIR)/stock.o
|
||||
inputlogcsv.o: \
|
||||
$(OBJ_DIR)/inputlogmedium.hh \
|
||||
$(OBJ_DIR)/request.o
|
||||
input.o: \
|
||||
$(OBJ_DIR)/posexcept.o
|
||||
|
||||
# Specific targets
|
||||
$(TARGET): $(OBJ) $(OBJ_NOTEST)
|
||||
$(TARGET): $(OBJ) $(OBJ_NOTEST) $(OBJ_TARGET)
|
||||
|
||||
$(TESTS_XX): $(SOURCE_TESTS)
|
||||
$(OBJ_TARGET): $(SOURCE_TARGET)
|
||||
$(GXX) $(GXXFLAGS) -o $@ -c $<
|
||||
|
||||
$(TESTS_XX): $(SOURCE_TESTS) $(OBJ)
|
||||
$(TESTS_DIR)/cxxtestgen.pl --error-printer \
|
||||
--include=$(TESTS_DIR)/valuetraits.hh \
|
||||
--include=$(TESTUTIL_OBJ:.o=.hh) \
|
||||
-o $@ $^
|
||||
-o $@ $(SOURCE_TESTS)
|
||||
|
||||
$(TESTS_OBJ): $(TESTS_XX) $(INCLUDES_TESTS)
|
||||
$(GXX) $(GXXFLAGS) $(TESTSGXXFLAGS) -o $@ -c $<
|
||||
|
@ -103,16 +148,19 @@ $(TESTS_OBJ): $(TESTS_XX) $(INCLUDES_TESTS)
|
|||
$(TESTS_TARGET): $(TESTS_OBJ) $(OBJ_TESTS) $(OBJ) $(OBJ_NOTEST)
|
||||
$(LD) $(LDFLAGS) -o $@ $^
|
||||
|
||||
test: $(TESTS_TARGET)
|
||||
test: prepare $(TESTS_TARGET)
|
||||
@$(TESTS_TARGET)
|
||||
|
||||
doc:
|
||||
@$(DOXYGEN) $(DOXYFILE)
|
||||
|
||||
prepare:
|
||||
@$(MKDIR) $(OBJ_DIR)
|
||||
|
||||
clean:
|
||||
@$(RM) *~ *.o *.gch *.orig
|
||||
@$(RM) $(TESTS_XX) $(TESTS_DIR)/*~ $(TESTS_DIR)/*.o \
|
||||
$(TESTS_DIR)/*.orig
|
||||
@$(RM) *~ */*~ *.orig */*.orig
|
||||
@$(RM_RECURSIVE_VERBOSE) $(OBJ_DIR)
|
||||
@$(RM) $(TESTS_XX) $(TESTS_DIR)/*.o
|
||||
|
||||
purge: clean
|
||||
@$(RM) $(TARGET)
|
||||
|
@ -129,16 +177,11 @@ uninstall:
|
|||
|
||||
style:
|
||||
@$(STYLE) \
|
||||
$(OBJ:.o=.hh) \
|
||||
$(OBJ:.o=.cc) \
|
||||
$(OBJ_NOTEST:.o=.hh) \
|
||||
$(OBJ_NOTEST:.o=.cc) \
|
||||
$(INTERFACES) \
|
||||
$(SOURCE) \
|
||||
$(TESTS_DIR)/*.hh \
|
||||
$(TESTS_DIR)/*.cc
|
||||
|
||||
check:
|
||||
@$(CPPCHECK) \
|
||||
$(OBJ:.o=.hh) $(OBJ:.o=.cc) \
|
||||
$(OBJ_NOTEST:.o=.hh) $(OBJ_NOTEST:.o=.cc) \
|
||||
$(INTERFACES) $(TARGET).cc
|
||||
$(SOURCE) \
|
||||
$(TARGET).cc
|
||||
|
|
|
@ -5,13 +5,6 @@
|
|||
- PosUtil
|
||||
° Déplacer les #define des canaux Wi-Fi dans le .cc
|
||||
|
||||
- Réorganisation du dépôt ?
|
||||
owlps-positioning/src
|
||||
owlps-positioning/include
|
||||
owlps-positioning/tests/src
|
||||
owlps-positioning/tests/include
|
||||
owlps-positioning/doc (générée par doxygen)
|
||||
|
||||
- Revoir le diagramme UML
|
||||
° Associations : devraient êtres représentées par des attributs
|
||||
pointeurs.
|
||||
|
|
|
@ -1,110 +0,0 @@
|
|||
#include "libowlps-positioning.hh"
|
||||
|
||||
|
||||
/* Tronque le float "f" à "n" décimales et le retourne */
|
||||
float round_float(float f, int n)
|
||||
{
|
||||
n = (int) pow((double) 10, (double) n) ;
|
||||
float f_dec = modff(f, &f) ;
|
||||
f_dec = floor(f_dec * n) / n ;
|
||||
|
||||
return f + f_dec ;
|
||||
}
|
||||
|
||||
|
||||
/* Explodes a string into substrings based on separator sep. Returns a string vector. */
|
||||
vector<string> explode(const string &input, const char &sep)
|
||||
{
|
||||
vector<string> vs;
|
||||
string tmp;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0 ; i < input.size() ; i++)
|
||||
if (input[i] == sep)
|
||||
{
|
||||
vs.push_back(tmp);
|
||||
tmp.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp.push_back(input[i]);
|
||||
}
|
||||
|
||||
vs.push_back(tmp);
|
||||
tmp.clear();
|
||||
|
||||
return vs;
|
||||
}
|
||||
|
||||
|
||||
/* Le Format Fred n'est pas utilisé */
|
||||
vector<string> extractReferencePointInfoFromBuffer(const string &buffer_in)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
string tmp_field;
|
||||
vector<string> ret;
|
||||
|
||||
/* Extract coordinates */
|
||||
/* x */
|
||||
while (buffer_in[i] != ';')
|
||||
{
|
||||
tmp_field.push_back(buffer_in[i]);
|
||||
i++;
|
||||
}
|
||||
ret.push_back(tmp_field);
|
||||
tmp_field.clear();
|
||||
i++; // go after the ';'
|
||||
|
||||
/* y */
|
||||
while (buffer_in[i] != ';')
|
||||
{
|
||||
tmp_field.push_back(buffer_in[i]);
|
||||
i++;
|
||||
}
|
||||
ret.push_back(tmp_field);
|
||||
tmp_field.clear();
|
||||
i++;
|
||||
|
||||
/* z */
|
||||
while (buffer_in[i] != ';')
|
||||
{
|
||||
tmp_field.push_back(buffer_in[i]);
|
||||
i++;
|
||||
}
|
||||
ret.push_back(tmp_field);
|
||||
tmp_field.clear();
|
||||
i++;
|
||||
|
||||
/* Extract direction (not used now) */
|
||||
while (buffer_in[i] != ';')
|
||||
{
|
||||
tmp_field.push_back(buffer_in[i]);
|
||||
i++;
|
||||
}
|
||||
ret.push_back(tmp_field);
|
||||
tmp_field.clear();
|
||||
i++;
|
||||
|
||||
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,
|
||||
{
|
||||
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++ ;
|
||||
}
|
||||
|
||||
/* Return the vector with each data */
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint64_t timeval_to_ms(const struct timeval &d)
|
||||
{
|
||||
return d.tv_sec * 1000 + d.tv_usec / 1000 ;
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
#ifndef _LIBOWLPS_POSITINING_HH_
|
||||
#define _LIBOWLPS_POSITINING_HH_
|
||||
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include <ctime>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <postgresql/libpq-fe.h>
|
||||
|
||||
|
||||
#define DEFAULT_AP_FILE "csv/minipc.cfg"
|
||||
#define DEFAULT_PT_FILE "csv/toutes.csv"
|
||||
#define DEFAULT_TOPO_FILE "csv/topo.csv"
|
||||
#define DEFAULT_WAYPOINT_FILE "csv/waypoints.csv"
|
||||
|
||||
#define DEFAULT_CONFIG_FILE "owlps-positioning.cfg"
|
||||
|
||||
#define DEFAULT_BDD_HOST "127.0.0.1"
|
||||
#define DEFAULT_BDD_NAME "owlps_db"
|
||||
#define DEFAULT_BDD_USER "owlps"
|
||||
#define DEFAULT_BDD_PASS "owlps"
|
||||
|
||||
#define LIGHT_SPEED 300000000
|
||||
#define MINMAX_STEP 0.5
|
||||
#define MINMAX_X_START 0.5
|
||||
#define MINMAX_Y_START 0.5
|
||||
#define MINMAX_Z_START 0
|
||||
#define MINMAX_X_STOP 10
|
||||
#define MINMAX_Y_STOP 31.5
|
||||
#define MINMAX_Z_STOP 6
|
||||
|
||||
typedef struct _couple_info
|
||||
{
|
||||
unsigned char ap_mac_addr_bytes[6]; // Adresse MAC de l'AP
|
||||
int antenna_signal_dbm; // Puissance du signal reçu par l'AP
|
||||
} couple_info;
|
||||
|
||||
typedef struct _request
|
||||
{
|
||||
unsigned char mobile_mac_addr_bytes[6]; //Adresse MAC du mobile
|
||||
struct timeval request_time; // Date sur le client
|
||||
int nb_couples; // Nombre couples (MAC AP;Puissance)
|
||||
} request;
|
||||
|
||||
//using namespace std ;
|
||||
|
||||
float round_float(float f, int n);
|
||||
vector<string> explode(const string &input, const char &sep);
|
||||
vector<string> extractReferencePointInfoFromBuffer(const string &buffer_in);
|
||||
uint64_t timeval_to_ms(const struct timeval &d);
|
||||
|
||||
#endif
|
|
@ -1,736 +0,0 @@
|
|||
#include "positioning.hh"
|
||||
|
||||
template <class T>
|
||||
inline T from_string(const string &s)
|
||||
{
|
||||
|
||||
T t;
|
||||
istringstream iss(s);
|
||||
|
||||
iss >> t;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
void Positioning::makeReferencePointListFromFile(const string &filename, const bool uniq_point)
|
||||
{
|
||||
|
||||
ifstream input_file ; // Flux d'entrée du fichier.
|
||||
string cpp_buffer ; // Buffer au format string.
|
||||
ReferencePoint rp;
|
||||
Point tmp_point;
|
||||
float x, y, z ; // Coordonnées des points.
|
||||
unsigned int pt_idx = 0 ; // Position du point lu dans la liste.
|
||||
int direction;
|
||||
vector<string> infos ; // Liste des informations lues dans une ligne du fichier.
|
||||
|
||||
input_file.open(filename.c_str()) ;
|
||||
if (input_file.fail())
|
||||
{
|
||||
cerr << "Error opening input file « " << filename << " » !" << endl ;
|
||||
return ;
|
||||
}
|
||||
|
||||
while (!input_file.eof())
|
||||
{
|
||||
getline(input_file, cpp_buffer);
|
||||
|
||||
if ((input_file.rdstate() & ifstream::eofbit) == 0)
|
||||
{
|
||||
if (cpp_buffer.size() == 0) // Ignorer une ligne vide
|
||||
continue ;
|
||||
|
||||
infos = extractReferencePointInfoFromBuffer(cpp_buffer);
|
||||
x = from_string<float>(infos[0]);
|
||||
y = from_string<float>(infos[1]);
|
||||
z = from_string<float>(infos[2]);
|
||||
|
||||
tmp_point.setX(x);
|
||||
tmp_point.setY(y);
|
||||
tmp_point.setZ(z);
|
||||
direction = from_string<int>(infos[3]);
|
||||
|
||||
if (!uniq_point || !pointExists(reference_point_list, tmp_point)) // Si on ne veut pas de points unique, ou que le point n'existe pas encore,
|
||||
{
|
||||
rp.setCoordinates(tmp_point);
|
||||
reference_point_list.push_back(rp); // on le crée.
|
||||
pt_idx = reference_point_list.size() - 1; // Le point que l'on vient d'ajouter est le dernier du vector.
|
||||
}
|
||||
else // Le point existe déjà :
|
||||
{
|
||||
pt_idx = pointIndex(reference_point_list, tmp_point) ; // On recherche le point auquel on veut ajouter les informations.
|
||||
}
|
||||
|
||||
for (unsigned int i = 4; i < infos.size(); i++)
|
||||
{
|
||||
if (i+1 < infos.size())
|
||||
{
|
||||
reference_point_list[pt_idx].addMeasurement(infos[i], from_string<int>(infos[i+1]));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
input_file.close();
|
||||
infos.clear() ;
|
||||
}
|
||||
|
||||
void Positioning::makeApListFromFile(const string &filename)
|
||||
{
|
||||
|
||||
ifstream input_file;
|
||||
string buffer;
|
||||
vector<string> ap_infos;
|
||||
AccessPoint tmp_ap;
|
||||
|
||||
input_file.open(filename.c_str());
|
||||
if (input_file.fail())
|
||||
{
|
||||
cerr << "Error opening input file « " << filename << " » !" << endl ;
|
||||
return ;
|
||||
}
|
||||
|
||||
while (!input_file.eof())
|
||||
{
|
||||
getline(input_file, buffer);
|
||||
|
||||
if ((input_file.rdstate() & ifstream::eofbit) == 0)
|
||||
{
|
||||
if (buffer[0] == '\0' || buffer[0] == '#') // ligne vide ou ligne commençant par #
|
||||
continue;
|
||||
|
||||
ap_infos = explode(buffer, ';');
|
||||
tmp_ap.setApAddr(ap_infos[0]);
|
||||
tmp_ap.setCoordinates(from_string<float>(ap_infos[1]), from_string<float>(ap_infos[2]), from_string<float>(ap_infos[3]));
|
||||
tmp_ap.setFrequency(from_string<unsigned int>(ap_infos[4]));
|
||||
tmp_ap.setAntennaGain(from_string<float>(ap_infos[5]));
|
||||
tmp_ap.setOutputPower(from_string<float>(ap_infos[6]));
|
||||
access_point_list.push_back(tmp_ap);
|
||||
ap_infos.clear();
|
||||
}
|
||||
}
|
||||
|
||||
input_file.close();
|
||||
}
|
||||
|
||||
void Positioning::makeTopologyFromFile(const string &filename)
|
||||
{
|
||||
|
||||
ifstream input_file;
|
||||
string buffer;
|
||||
vector<string> infos;
|
||||
|
||||
input_file.open(filename.c_str()) ;
|
||||
if (input_file.fail())
|
||||
{
|
||||
cerr << "Error opening input file « " << filename << " » !" << endl ;
|
||||
return ;
|
||||
}
|
||||
|
||||
while (!input_file.eof())
|
||||
{
|
||||
getline(input_file, buffer) ;
|
||||
|
||||
if ((input_file.rdstate() & ifstream::eofbit) == 0)
|
||||
{
|
||||
/* Traitement basique des commentaires */
|
||||
if (buffer[0] == '\0' || buffer[0] == '#') // ligne vide ou ligne commençant par #
|
||||
continue ; // ignorer cette ligne.
|
||||
|
||||
infos = explode(buffer, ';') ;
|
||||
if (area_list.find(infos[0]) != area_list.end()) // Si la pièce existe déjà,
|
||||
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], from_string<float>(infos[1]), from_string<float>(infos[3]),
|
||||
from_string<float>(infos[2]), from_string<float>(infos[4]),
|
||||
from_string<float>(infos[5]), from_string<float>(infos[6])) ;
|
||||
|
||||
infos.clear() ;
|
||||
}
|
||||
}
|
||||
|
||||
input_file.close() ;
|
||||
|
||||
}
|
||||
|
||||
void Positioning::makeWaypointListFromFile(const string &filename)
|
||||
{
|
||||
|
||||
ifstream input_file ;
|
||||
string buffer;
|
||||
vector<string> infos ;
|
||||
set<Point> point_list ;
|
||||
|
||||
input_file.open(filename.c_str());
|
||||
if (input_file.fail())
|
||||
{
|
||||
cerr << "Error opening input file « " << filename << " » !" << endl ;
|
||||
return ;
|
||||
}
|
||||
|
||||
while (!input_file.eof())
|
||||
{
|
||||
getline(input_file, buffer);
|
||||
|
||||
if ((input_file.rdstate() & ifstream::eofbit) == 0)
|
||||
{
|
||||
if (buffer[0] == '\0' || buffer[0] == '#') // ligne vide ou ligne commençant par #
|
||||
continue;
|
||||
|
||||
infos = explode(buffer, ';') ;
|
||||
|
||||
Point tmp_pt(from_string<float>(infos[0]), from_string<float>(infos[1]), from_string<float>(infos[2])) ;
|
||||
if (! point_list.insert(tmp_pt).second)
|
||||
cerr << "Point " << tmp_pt << " non ajouté ! Peut-être est-il dupliqué ?" << endl ;
|
||||
|
||||
infos.clear() ;
|
||||
}
|
||||
}
|
||||
input_file.close(); // Lecture du fichier terminée
|
||||
|
||||
makeWaypointMatrix(point_list);
|
||||
}
|
||||
|
||||
void Positioning::makeReferencePointListFromDb(PGconn *conn, const bool uniq)
|
||||
{
|
||||
|
||||
PGresult *res;
|
||||
Point tmp_point;
|
||||
ReferencePoint rp;
|
||||
|
||||
ostringstream oss;
|
||||
string buf;
|
||||
|
||||
buf = "SELECT * FROM ref_point;";
|
||||
|
||||
res = PQexec(conn, buf.c_str());
|
||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||
{
|
||||
cerr << "Commande incorrecte: " << PQerrorMessage(conn);
|
||||
}
|
||||
else
|
||||
{
|
||||
int nbRes = PQntuples(res);
|
||||
for (int i = 0; i < nbRes; i++)
|
||||
{
|
||||
tmp_point.setX(from_string<float>(PQgetvalue(res, i, 1)));
|
||||
tmp_point.setY(from_string<float>(PQgetvalue(res, i, 2)));
|
||||
tmp_point.setZ(from_string<float>(PQgetvalue(res, i, 3)));
|
||||
|
||||
if (!uniq || !pointExists(reference_point_list, tmp_point)) // Si on ne veut pas de points unique, ou que le point n'existe pas encore,
|
||||
{
|
||||
rp.setCoordinates(tmp_point);
|
||||
reference_point_list.push_back(rp); // on le crée.
|
||||
}
|
||||
}
|
||||
PQclear(res);
|
||||
|
||||
for (unsigned int i = 0; i < reference_point_list.size(); i++)
|
||||
{
|
||||
|
||||
tmp_point = reference_point_list[i].getCoordinates();
|
||||
|
||||
oss << "SELECT ap.ap_addr, n.power ";
|
||||
oss << "FROM ap, ref_packet n, ref_request r, ref_point p ";
|
||||
oss << "WHERE ap.id_ap = n.id_ap ";
|
||||
oss << "AND n.id_ref_request = r.id_ref_request ";
|
||||
oss << "AND r.id_ref_point = p.id_ref_point ";
|
||||
oss << "AND p.x = " << tmp_point.getX() << " ";
|
||||
oss << "AND p.y = " << tmp_point.getY() << " ";
|
||||
oss << "AND p.z = " << tmp_point.getZ() << ";";
|
||||
|
||||
buf = oss.str();
|
||||
oss.str("");
|
||||
|
||||
res = PQexec(conn, buf.c_str());
|
||||
|
||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||
{
|
||||
cerr << "Commande incorrecte: " << PQerrorMessage(conn);
|
||||
}
|
||||
else
|
||||
{
|
||||
nbRes = PQntuples(res);
|
||||
for (int j = 0; j < nbRes; j++)
|
||||
reference_point_list[i].addMeasurement(PQgetvalue(res, j, 0), from_string<int>(PQgetvalue(res, j, 1)));
|
||||
}
|
||||
|
||||
PQclear(res);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Positioning::makeApListFromDb(PGconn *conn)
|
||||
{
|
||||
|
||||
PGresult *res;
|
||||
AccessPoint tmp_ap;
|
||||
string buf;
|
||||
|
||||
buf = "SELECT * FROM ap;";
|
||||
|
||||
res = PQexec(conn, buf.c_str());
|
||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||
{
|
||||
cerr << "Commande incorrecte: " << PQerrorMessage(conn);
|
||||
}
|
||||
else
|
||||
{
|
||||
int nbRes = PQntuples(res);
|
||||
for (int i = 0; i < nbRes; i++)
|
||||
{
|
||||
tmp_ap.setApAddr(PQgetvalue(res, i, 1));
|
||||
tmp_ap.setCoordinates(from_string<float>(PQgetvalue(res, i, 2)), from_string<float>(PQgetvalue(res, i, 3)), from_string<float>(PQgetvalue(res, i, 4)));
|
||||
tmp_ap.setFriisIndex(from_string<float>(PQgetvalue(res, i, 5)));
|
||||
tmp_ap.setOutputPower(from_string<float>(PQgetvalue(res, i, 8)));
|
||||
tmp_ap.setAntennaGain(from_string<float>(PQgetvalue(res, i, 7)));
|
||||
tmp_ap.setFrequency(from_string<unsigned int>(PQgetvalue(res, i, 6)));
|
||||
access_point_list.push_back(tmp_ap);
|
||||
}
|
||||
}
|
||||
|
||||
PQclear(res);
|
||||
}
|
||||
|
||||
void Positioning::makeTopologyFromDb(PGconn *conn)
|
||||
{
|
||||
|
||||
PGresult *res;
|
||||
string buf;
|
||||
|
||||
buf = "SELECT * FROM area;";
|
||||
|
||||
res = PQexec(conn, buf.c_str());
|
||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||
{
|
||||
cerr << "Commande incorrecte: " << PQerrorMessage(conn);
|
||||
}
|
||||
else
|
||||
{
|
||||
int nbRes = PQntuples(res);
|
||||
for (int i = 0; i < nbRes; i++)
|
||||
{
|
||||
if (area_list.find(PQgetvalue(res, i, 1)) != area_list.end()) // Si la pièce existe déjà,
|
||||
cerr << "Erreur ! Déclaration multiple de la zone « " << PQgetvalue(res, i, 1) << " »." << endl ; // on le signale ;
|
||||
else
|
||||
area_list[PQgetvalue(res, i, 1)] = Area(PQgetvalue(res, i, 1), from_string<float>(PQgetvalue(res, i, 2)), from_string<float>(PQgetvalue(res, i, 5)),
|
||||
from_string<float>(PQgetvalue(res, i, 3)), from_string<float>(PQgetvalue(res, i, 6)),
|
||||
from_string<float>(PQgetvalue(res, i, 4)), from_string<float>(PQgetvalue(res, i, 7)));
|
||||
}
|
||||
}
|
||||
PQclear(res);
|
||||
}
|
||||
|
||||
void Positioning::makeWaypointListFromDb(PGconn *conn)
|
||||
{
|
||||
|
||||
PGresult *res;
|
||||
string buf;
|
||||
set<Point> point_list ;
|
||||
|
||||
buf = "SELECT * FROM waypoint;";
|
||||
|
||||
res = PQexec(conn, buf.c_str());
|
||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||
{
|
||||
cerr << "Commande incorrecte: " << PQerrorMessage(conn);
|
||||
}
|
||||
else
|
||||
{
|
||||
int nbRes = PQntuples(res);
|
||||
for (int i = 0; i < nbRes; i++)
|
||||
{
|
||||
Point tmp_pt(from_string<float>(PQgetvalue(res, i, 0)), from_string<float>(PQgetvalue(res, i, 1)), from_string<float>(PQgetvalue(res, i, 2)));
|
||||
if (! point_list.insert(tmp_pt).second)
|
||||
cerr << "Point " << tmp_pt << " non ajouté ! Peut-être est-il dupliqué ?" << endl ;
|
||||
}
|
||||
makeWaypointMatrix(point_list);
|
||||
}
|
||||
|
||||
PQclear(res);
|
||||
}
|
||||
|
||||
void Positioning::makeWaypointMatrix(set<Point> point_list)
|
||||
{
|
||||
|
||||
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)
|
||||
waypoint_matrix = new float*[nb_pts] ; // Matrice (carrée) des distances entre les points de passage (attribut du serveur)
|
||||
|
||||
for (unsigned int i = 0 ; i < nb_pts ; i++) // Initialisation de la matrice :
|
||||
{
|
||||
waypoint_matrix[i] = new float[nb_pts] ;
|
||||
for (unsigned int k = 0 ; k < nb_pts ; k++) // Initialisation des distances à -1
|
||||
waypoint_matrix[i][k] = -1 ;
|
||||
}
|
||||
|
||||
for (set<Point>::iterator it = point_list.begin() ; it != point_list.end() ; it++, cur_idx++) // Pour chaque point enregistré
|
||||
{
|
||||
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
|
||||
{
|
||||
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.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
float tmp_dist = round_float((waypoint_matrix[j][k] + waypoint_matrix[i][j]), 2);
|
||||
if (tmp_dist < round_float(waypoint_matrix[i][k], 2) || waypoint_matrix[i][k] == -1)
|
||||
{
|
||||
waypoint_matrix[i][k] = tmp_dist ;
|
||||
comput_done = true ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
map<string, Area> Positioning::inWhichAreas(const Point &p)
|
||||
{
|
||||
|
||||
map<string, Area> areas ;
|
||||
|
||||
for (map<string, Area>::iterator it = area_list.begin() ; it != area_list.end() ; it++)
|
||||
if (it->second.containsPoint(p))
|
||||
areas.insert(make_pair(it->first, it->second)) ;
|
||||
|
||||
return areas;
|
||||
|
||||
}
|
||||
|
||||
bool Positioning::inTheSameArea(const Point &p1, const Point &p2)
|
||||
{
|
||||
|
||||
// Liste des zones comportant les points p1 et p2 :
|
||||
map<string, Area> zones1(inWhichAreas(p1));
|
||||
map<string, Area> zones2(inWhichAreas(p2));
|
||||
|
||||
if (zones1.size() == 0 || zones2.size() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false ;
|
||||
}
|
||||
|
||||
float Positioning::distanceTopology(const Point &p1, const Point &p2)
|
||||
{
|
||||
|
||||
map<string, Area> zones1(inWhichAreas(p1));
|
||||
map<string, Area> zones2(inWhichAreas(p2));
|
||||
|
||||
if (zones1.size() == 0 || zones2.size() == 0) // Si aucune zone ne contient p1 ou p2,
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
Area z1(zones1.begin() -> second); // Première zone d'appartenance du point p1. // FIXME : vérifier toutes les zones
|
||||
Area z2(zones2.begin() -> second);
|
||||
vector<Point> connection;
|
||||
|
||||
|
||||
/* *** Cas de la même zone *** */
|
||||
if (z1 == z2) // Si les points sont dans la même zone,
|
||||
{
|
||||
return p1.distance(p2) ; // la distance entre eux est la distance euclidienne.
|
||||
}
|
||||
|
||||
|
||||
/* *** 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.
|
||||
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
|
||||
{
|
||||
float tmp_dist = p1.distance(connection[i]) + p2.distance(connection[i]) ;
|
||||
if (tmp_dist < dist)
|
||||
dist = tmp_dist ;
|
||||
}
|
||||
|
||||
return dist ;
|
||||
}
|
||||
|
||||
|
||||
/* *** Les points sont dans des zones non-voisines *** */
|
||||
// Liste des points de passage appartenant respectivement à z1 et à z2.
|
||||
vector<Point> wp_z1(areaConnection(z1));
|
||||
vector<Point> wp_z2(areaConnection(z2));
|
||||
|
||||
// Indices des points de passage dans la liste :
|
||||
int wp_z1_idx;
|
||||
int wp_z2_idx = -1 ; // z2 ne peut pas être utilisé non initialisé, contrairement à ce que dit GCC, car dans le cas où il n'est pas initialisé on quitte la fonction avant de l'utiliser (cf. "return -1" un peu plus bas);
|
||||
|
||||
if (wp_z1.size() == 0 || wp_z2.size() == 0) // Si l'une des deux zones ne comporte aucun point de passage,
|
||||
{
|
||||
return -1 ; // on quitte (ceci ne devrait jamais se produire).
|
||||
}
|
||||
|
||||
/* Première itération (voir explication de l'algorithme plus bas) */
|
||||
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 = pointIndex(waypoint_list, wp_z1[i1]) ;
|
||||
for (i2 = 0 ; i2 < wp_z2.size() ; 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.
|
||||
}
|
||||
if (waypoint_matrix[wp_z1_idx][wp_z2_idx] != -1) // Si c'est bon,
|
||||
break ; // on arrête le parcours.
|
||||
}
|
||||
|
||||
if (i1 >= wp_z1.size()) // Si on a parcouru tout le tableau sans trouver de chemin,
|
||||
{
|
||||
return -1 ; // on quitte.
|
||||
}
|
||||
|
||||
float dist = p1.distance(wp_z1[i1]) + waypoint_matrix[wp_z1_idx][wp_z2_idx] + p2.distance(wp_z2[i2]);
|
||||
float tmp_dist ;
|
||||
|
||||
for (unsigned int j = i2 + 1 ; j < wp_z2.size() ; j++) // Fin du parcours :
|
||||
{
|
||||
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]) ;
|
||||
if (tmp_dist < dist)
|
||||
dist = tmp_dist ;
|
||||
}
|
||||
|
||||
/* Itérations suivantes */
|
||||
for (unsigned int i = i1 + 1 ; i < wp_z1.size() ; i++)
|
||||
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 = 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 ;
|
||||
|
||||
tmp_dist = p1.distance(wp_z1[i]) + waypoint_matrix[wp_z1_idx][wp_z2_idx] + p2.distance(wp_z2[j]) ;
|
||||
if (tmp_dist < dist)
|
||||
dist = tmp_dist ;
|
||||
}
|
||||
|
||||
return dist ;
|
||||
}
|
||||
|
||||
vector<Point> Positioning::areaConnection(const Area &z1, const Area &z2)
|
||||
{
|
||||
vector<Point> points ;
|
||||
|
||||
for (unsigned int i = 0 ; i < waypoint_list.size() ; 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(waypoint_list[i]) ;
|
||||
}
|
||||
|
||||
return points ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
vector<Point> Positioning::areaConnection(const Area &z)
|
||||
{
|
||||
vector<Point> points ;
|
||||
|
||||
for (unsigned int i = 0 ; i < waypoint_list.size() ; i++)
|
||||
{
|
||||
map<string, Area> areas(inWhichAreas(waypoint_list[i])) ;
|
||||
if (areas.find(z.getName()) != areas.end())
|
||||
points.push_back(waypoint_list[i]) ;
|
||||
}
|
||||
|
||||
return points ;
|
||||
}
|
||||
|
||||
void Positioning::makeReferencePointDistances()
|
||||
{
|
||||
|
||||
unsigned int nb_pts = reference_point_list.size() ; // Nombre de points à traiter.
|
||||
|
||||
reference_point_matrix = new float*[nb_pts] ; // Allocation de la première dimension.
|
||||
for (unsigned int i = 0 ; i < nb_pts ; i++) // Initialisation de la matrice :
|
||||
{
|
||||
reference_point_matrix[i] = new float[nb_pts] ;
|
||||
for (unsigned int k = 0; k < nb_pts; k++) // Initialisation des distances à -1
|
||||
reference_point_matrix[i][k] = -1 ;
|
||||
}
|
||||
|
||||
for (unsigned int cur_idx = 0 ; cur_idx < nb_pts ; cur_idx++)
|
||||
{
|
||||
reference_point_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
|
||||
{
|
||||
float dist = distanceTopology((Point) reference_point_list[cur_idx], (Point) reference_point_list[k]) ; // On calcule la distance
|
||||
reference_point_matrix[cur_idx][k] = dist ; // et on l'insère dans le tableau,
|
||||
reference_point_matrix[k][cur_idx] = dist ; // dans les deux sens.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Positioning::checkTopology()
|
||||
{
|
||||
|
||||
for (unsigned int i = 0 ; i < waypoint_list.size() ; i++)
|
||||
{
|
||||
map<string, Area> areas(inWhichAreas(waypoint_list[i])) ;
|
||||
if (areas.empty())
|
||||
{
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0 ; i < reference_point_list.size() ; i++)
|
||||
{
|
||||
map<string, Area> areas(inWhichAreas((Point)reference_point_list[i])) ;
|
||||
if (areas.empty())
|
||||
{
|
||||
return false ; // À modifier si on veut permettre aux points de référence de n'appartenir à aucune zone.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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.
|
||||
}
|
||||
|
||||
if (connected_areas.size() != area_list.size())
|
||||
{
|
||||
return false ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
inline bool Positioning::pointExists(const float &x, const float &y, const float &z) const
|
||||
{
|
||||
return pointExists(reference_point_list, Point(x, y, z));
|
||||
}
|
||||
|
||||
inline bool Positioning::pointExists(const Point &p) const
|
||||
{
|
||||
return pointExists(reference_point_list, p);
|
||||
}
|
||||
|
||||
inline bool Positioning::pointExists(const vector<ReferencePoint> &point_list, const float &x, const float &y, const float &z) const
|
||||
{
|
||||
return pointExists(point_list, Point(x, y, z));
|
||||
}
|
||||
|
||||
inline bool Positioning::pointExists(const vector<ReferencePoint> &point_list, const Point &p) const
|
||||
{
|
||||
return (pointIndex(point_list, p) != -1);
|
||||
}
|
||||
|
||||
inline int Positioning::pointIndex(const Point &p) const
|
||||
{
|
||||
return (unsigned int) pointIndex(reference_point_list, p);
|
||||
}
|
||||
|
||||
inline int Positioning::pointIndex(const vector<ReferencePoint> &point_list, const float &x, const float &y, const float &z) const
|
||||
{
|
||||
return (unsigned int) pointIndex(point_list, Point(x, y, z)) ;
|
||||
}
|
||||
|
||||
inline int Positioning::pointIndex(const vector<ReferencePoint> &point_list, const Point &p) const
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0 ; i < point_list.size() ; i++)
|
||||
if (p == point_list[i].getCoordinates())
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Retourne la position du Point "p" dans le tableau à une dimension "point_tab" de taille "size", ou -1 en cas d'échec. */
|
||||
inline int Positioning::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 Positioning::pointIndex(const vector<Point> &point_list, const Point &p) const
|
||||
{
|
||||
|
||||
for (unsigned int i = 0 ; i < point_list.size() ; i++)
|
||||
if (point_list[i] == p)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Positioning::printReferencePointList()
|
||||
{
|
||||
printPointList(reference_point_list) ;
|
||||
}
|
||||
|
||||
void Positioning::printPointList(vector<ReferencePoint> &point_list)
|
||||
{
|
||||
for (unsigned int i = 0 ; i < point_list.size() ; i++)
|
||||
cout << point_list[i] << endl ;
|
||||
}
|
||||
|
||||
void Positioning::printAccessPointList() const
|
||||
{
|
||||
for (unsigned int i = 0; i < access_point_list.size(); i++)
|
||||
cout << access_point_list[i] << endl;
|
||||
}
|
||||
|
||||
void Positioning::printAreatList()
|
||||
{
|
||||
for (map<string, Area>::iterator it = area_list.begin() ; it != area_list.end() ; it++)
|
||||
cout << it -> second << endl;
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
#ifndef _POSITIONING_HH_
|
||||
#define _POSITIONING_HH_
|
||||
|
||||
#include "point.hh"
|
||||
#include "referencepoint.hh"
|
||||
#include "accesspoint.hh"
|
||||
#include "area.hh"
|
||||
#include "measurement.hh"
|
||||
#include "libowlps-positioning.hh"
|
||||
|
||||
class Positioning
|
||||
{
|
||||
private:
|
||||
vector<ReferencePoint> reference_point_list; // Liste des points de référence (calibration).
|
||||
float** reference_point_matrix; // Matrice des distances entre les points de référence.
|
||||
vector<AccessPoint> access_point_list; // Liste des AP connus.
|
||||
vector<Point> waypoint_list; // Liste des points de passage entre les zones.
|
||||
float** waypoint_matrix; // Matrice des distances entre les points de passage.
|
||||
map<string, Area> area_list ; // Liste des zones homogènes (pièces).
|
||||
|
||||
public :
|
||||
Positioning() {};
|
||||
~Positioning() {};
|
||||
|
||||
void makeReferencePointListFromFile(const string &filename, const bool);
|
||||
void makeApListFromFile(const string &filename);
|
||||
void makeTopologyFromFile(const string &filename);
|
||||
void makeWaypointListFromFile(const string &filename);
|
||||
|
||||
void makeReferencePointListFromDb(PGconn*, const bool);
|
||||
void makeApListFromDb(PGconn*);
|
||||
void makeTopologyFromDb(PGconn*);
|
||||
void makeWaypointListFromDb(PGconn*);
|
||||
|
||||
void makeWaypointMatrix(set<Point>);
|
||||
|
||||
map<string, Area> inWhichAreas(const Point &p);
|
||||
bool inTheSameArea(const Point &p1, const Point &p2);
|
||||
float distanceTopology(const Point &p1, const Point &p2);
|
||||
vector<Point> areaConnection(const Area &z1, const Area &z2);
|
||||
vector<Point> areaConnection(const Area &z);
|
||||
|
||||
void makeReferencePointDistances();
|
||||
bool checkTopology();
|
||||
|
||||
bool pointExists(const float &x, const float &y, const float &z)const;
|
||||
bool pointExists(const Point &p)const;
|
||||
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 ;
|
||||
|
||||
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 ;
|
||||
|
||||
vector<AccessPoint> getAccessPointList() const
|
||||
{
|
||||
return access_point_list;
|
||||
};
|
||||
vector<ReferencePoint> getReferencePointList() const
|
||||
{
|
||||
return reference_point_list;
|
||||
};
|
||||
|
||||
void printReferencePointList();
|
||||
void printPointList(vector<ReferencePoint> &point_list);
|
||||
void printAccessPointList() const;
|
||||
void printAreatList();
|
||||
};
|
||||
|
||||
#endif // _POSITIONING_HH_
|
|
@ -1,311 +0,0 @@
|
|||
#include "server.hh"
|
||||
|
||||
|
||||
|
||||
/* Transforme un string en un type différent */
|
||||
template <class T>
|
||||
inline T from_string(const string &s)
|
||||
{
|
||||
T t;
|
||||
istringstream iss(s);
|
||||
|
||||
iss >> t;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Initialisation du serveur */
|
||||
int Server::init(const boost::program_options::variables_map vm)
|
||||
{
|
||||
ostringstream oss;
|
||||
string buf;
|
||||
|
||||
/* Connexion à la BdD */
|
||||
oss << "hostaddr = '";
|
||||
if (vm.count("db.host")) // Recherche du nom de l'hôte de la BdD
|
||||
oss << vm["db.host"].as<string>();
|
||||
else
|
||||
{
|
||||
cerr << "Attention ! Hôte de la BDD non spécifié, utilisation de la valeur par défaut..." << endl ;
|
||||
oss << DEFAULT_BDD_HOST;
|
||||
}
|
||||
|
||||
oss << "' dbname = '";
|
||||
if (vm.count("db.name")) // Recherche du nom de la BdD
|
||||
oss << vm["db.name"].as<string>();
|
||||
else
|
||||
{
|
||||
cerr << "Attention ! Nom de la BDD non spécifié, utilisation de la valeur par défaut..." << endl ;
|
||||
oss << DEFAULT_BDD_NAME;
|
||||
}
|
||||
|
||||
oss << "' user = '";
|
||||
if (vm.count("db.user")) // Recherche du nom d'utilisateur de la BdD
|
||||
oss << vm["db.user"].as<string>();
|
||||
else
|
||||
{
|
||||
cerr << "Attention ! Utilisateur non spécifié pour la connexion à la BDD, utilisation de la valeur par défaut..." << endl ;
|
||||
oss << DEFAULT_BDD_USER;
|
||||
}
|
||||
|
||||
oss << "' password = '";
|
||||
if (vm.count("db.passwd")) // Recherche du mot de passe
|
||||
oss << vm["db.passwd"].as<string>() << "'";
|
||||
else
|
||||
{
|
||||
cerr << "Attention ! Mot de passe non spécifié pour la connexion à la BDD, utilisation de la valeur par défaut..." << endl ;
|
||||
oss << DEFAULT_BDD_PASS << "'";
|
||||
}
|
||||
|
||||
buf = oss.str();
|
||||
|
||||
const char *conninfo = buf.c_str();
|
||||
conn = PQconnectdb(conninfo);
|
||||
|
||||
if (PQstatus(conn) != CONNECTION_OK)
|
||||
{
|
||||
cout << "Erreur ! Connexion à la base de donnée échouée : " << PQerrorMessage(conn) << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Création de la topology */
|
||||
if (vm.count("input-topo")) pos.makeTopologyFromFile(vm["input-topo"].as<string>());
|
||||
else pos.makeTopologyFromDb(conn);
|
||||
|
||||
/* Création de la liste des points de passage */
|
||||
if (vm.count("input-waypoint")) pos.makeWaypointListFromFile(vm["input-waypoint"].as<string>());
|
||||
else pos.makeWaypointListFromDb(conn);
|
||||
|
||||
/* Création de la liste des points de référence */
|
||||
if (vm.count("input-refpoint")) pos.makeReferencePointListFromFile(vm["input-refpoint"].as<string>(), true);
|
||||
else pos.makeReferencePointListFromDb(conn, true);
|
||||
|
||||
if (!pos.checkTopology())
|
||||
{
|
||||
cerr << "Erreur lors de la création de la topologie !" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
pos.makeReferencePointDistances();
|
||||
|
||||
/* Création de la liste des Access Point */
|
||||
if (vm.count("input-ap"))
|
||||
pos.makeApListFromFile(vm["input-ap"].as<string>()) ;
|
||||
else
|
||||
pos.makeApListFromDb(conn) ;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Server::start()
|
||||
{
|
||||
struct sockaddr_in serv_addr;
|
||||
struct sockaddr_in client;
|
||||
socklen_t client_len = sizeof(client);
|
||||
Point solution;
|
||||
char *mac = (char *) malloc(18 * sizeof(char));
|
||||
|
||||
/* Création d'une socket UDP */
|
||||
listen_socket = socket(AF_INET, SOCK_DGRAM, 0) ;
|
||||
if (listen_socket < 0)
|
||||
{
|
||||
cerr << "Échec de la création de la socket " << endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Remise à zéro et initialisation de la structure du serveur */
|
||||
bzero((char *) &serv_addr, sizeof(serv_addr)) ; // RÀZ
|
||||
serv_addr.sin_family = AF_INET ; // Socket INET
|
||||
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY) ; // Toutes les connexions sont acceptées
|
||||
serv_addr.sin_port = htons(listen_port) ; // Port d'écoute
|
||||
|
||||
/* Réservation du port */
|
||||
if (bind(listen_socket, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0)
|
||||
{
|
||||
cerr << "Impossible de créer la socket (bind) " << endl;
|
||||
close(listen_socket) ;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
cout << "Serveur prêt" << endl;
|
||||
|
||||
/* Récupération des données envoyées par le client */
|
||||
while (true)
|
||||
{
|
||||
/* Attente d'une demande d'un serveur d'aggrégation */
|
||||
if (recvfrom(listen_socket, &att_request, sizeof(att_request), 0, (struct sockaddr *) &client, &client_len) < 0)
|
||||
{
|
||||
cerr << "Aucun message reçu du client" << endl;
|
||||
close(listen_socket);
|
||||
return 1;
|
||||
}
|
||||
|
||||
recv_info.resize(att_request.nb_couples);
|
||||
sprintf(mac, "%02x:%02x:%02x:%02x:%02x:%02x", att_request.mobile_mac_addr_bytes[0],att_request.mobile_mac_addr_bytes[1],
|
||||
att_request.mobile_mac_addr_bytes[2],att_request.mobile_mac_addr_bytes[3],
|
||||
att_request.mobile_mac_addr_bytes[4],att_request.mobile_mac_addr_bytes[5]);
|
||||
|
||||
cout << "\n*** Message reçu de l'aggregator ***" << endl;
|
||||
cout << "\tMAC Mobile\t: " << mac << endl;
|
||||
cout << "\tHeure de la demande\t: " << timeval_to_ms(att_request.request_time) << endl;
|
||||
cout << "\tNombre de couples\t: " << att_request.nb_couples << endl;
|
||||
|
||||
/* Récupération des couples (AP;Puissance) */
|
||||
for (int i = 0; i < att_request.nb_couples; i++)
|
||||
recvfrom(listen_socket, &recv_info.at(i), sizeof(couple_info), 0, (struct sockaddr *) &client, &client_len);
|
||||
|
||||
treatment();
|
||||
|
||||
recv_info.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Calcul de la position avec les différents algo */
|
||||
void Server::treatment()
|
||||
{
|
||||
Point solution;
|
||||
|
||||
int id_request; // Permet de récupérer l'id de la requête pour lui assigner les résultats
|
||||
char *mac = (char *) malloc(18 * sizeof(char));
|
||||
ostringstream oss;
|
||||
|
||||
PGresult *res;
|
||||
|
||||
/* */
|
||||
Treatment treat(pos.getAccessPointList(), pos.getReferencePointList());
|
||||
treat.makeMeasurementList(recv_info);
|
||||
|
||||
sprintf(mac, "%02x:%02x:%02x:%02x:%02x:%02x", att_request.mobile_mac_addr_bytes[0],att_request.mobile_mac_addr_bytes[1],
|
||||
att_request.mobile_mac_addr_bytes[2],att_request.mobile_mac_addr_bytes[3],
|
||||
att_request.mobile_mac_addr_bytes[4],att_request.mobile_mac_addr_bytes[5]);
|
||||
|
||||
oss << "SELECT r.id_request FROM request r, mobile m ";
|
||||
oss << "WHERE r.mobile_time = " << timeval_to_ms(att_request.request_time);
|
||||
oss << " AND m.id_mobile = r.id_mobile";
|
||||
oss << " AND m.mobile_addr = '" << mac << "';"; // On recherche dans la BdD la requête consernée
|
||||
|
||||
res = PQexec(conn, oss.str().c_str());
|
||||
id_request = (PQntuples(res) != 0)? from_string<int>(PQgetvalue(res, PQntuples(res) - 1, 0)): -1; // On conserve l'id de la requête
|
||||
PQclear(res);
|
||||
|
||||
/* Interlink Networks */
|
||||
solution = treat.interlink(0) ;
|
||||
createResult(solution, id_request, "Interlink Network");
|
||||
|
||||
/* RADAR */
|
||||
solution = treat.getkClosestInSs(1, NULL)[0] ;
|
||||
createResult(solution, id_request, "Radar");
|
||||
|
||||
/* FBCM */
|
||||
solution = treat.fbcm(0) ;
|
||||
createResult(solution, id_request, "FCBM");
|
||||
|
||||
/* 1-NSS + FBCM */
|
||||
solution = treat.getkClosestInSs(1, NULL)[0] ;
|
||||
solution = treat.fbcm_friis(treat.computeFriisFromRefList(solution), solution.getZ()) ;
|
||||
createResult(solution, id_request, "1-NSS + FBCM");
|
||||
|
||||
/* 2-NSS */
|
||||
solution = treat.getkWeightedInSs(2, NULL);
|
||||
createResult(solution, id_request, "2-NSS");
|
||||
|
||||
/* 3-NSS */
|
||||
solution = treat.getkWeightedInSs(3, NULL);
|
||||
createResult(solution, id_request, "3-NSS");
|
||||
|
||||
/* 5-NSS */
|
||||
solution = treat.getkWeightedInSs(5, NULL);
|
||||
createResult(solution, id_request, "5-NSS");
|
||||
|
||||
sendToClient(solution, mac);
|
||||
free(mac);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Enregistrement du résultat dans la BdD */
|
||||
void Server::createResult(Point solution, int id_request, string use_algo)
|
||||
{
|
||||
int id_result;
|
||||
string buf;
|
||||
ostringstream oss;
|
||||
|
||||
struct timeval current;
|
||||
|
||||
PGresult *res;
|
||||
|
||||
gettimeofday(¤t, NULL); // On récupère l'heure du calcul
|
||||
|
||||
buf = "SELECT * FROM result;";
|
||||
|
||||
res = PQexec(conn, buf.c_str());
|
||||
id_result = (PQntuples(res) != 0)? from_string<int>(PQgetvalue(res, PQntuples(res) - 1, 0)) + 1: 1;
|
||||
|
||||
oss << "INSERT INTO result(id_result, x, y, z, calcul_date, using_algo";
|
||||
if (id_request != -1) oss << ", id_request"; // Si la requête n'a pas été trouvé, on enregistre le résultat mais sans associé de requête
|
||||
oss << ") VALUES('";
|
||||
oss << id_result << "','" << solution.getX() << "','" << solution.getY() << "','" << solution.getZ();
|
||||
oss << "','" << timeval_to_ms(current) << "','" << use_algo;
|
||||
if (id_request != -1) oss << "','" << id_request;
|
||||
oss << "');";
|
||||
|
||||
PQexec(conn, oss.str().c_str());
|
||||
PQclear(res);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Server::sendToClient(Point solution, char *mac)
|
||||
{
|
||||
int sockfd ; // Descripteur de la socket
|
||||
struct sockaddr_in serv;
|
||||
struct sockaddr_in mobile;
|
||||
socklen_t mobile_len = sizeof(mobile);
|
||||
ostringstream oss;
|
||||
float x,y,z;
|
||||
|
||||
PGresult *res;
|
||||
|
||||
oss << "SELECT ip_mobile FROM mobile ";
|
||||
oss << "WHERE mobile_addr = '" << mac << "';"; // On récupére l'adresse IP du mobile
|
||||
|
||||
res = PQexec(conn, oss.str().c_str());
|
||||
if (PQntuples(res) != 0)
|
||||
{
|
||||
/* Ceation de la socket UDP */
|
||||
sockfd = socket(AF_INET, SOCK_DGRAM, 0) ;
|
||||
if (sockfd < 0)
|
||||
{
|
||||
cerr << "Échec de la création de la socket " << endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Remise à zéro et initialisation de la structure du server */
|
||||
bzero((char *) &serv, sizeof(serv)) ;
|
||||
serv.sin_family = AF_INET ; // Socket INET
|
||||
serv.sin_addr.s_addr = htonl(INADDR_ANY) ; // Toutes les connexions
|
||||
|
||||
/* Remise à zéro et initialisation de la structure du mobile */
|
||||
bzero((char *) &mobile, sizeof(mobile)) ; // RÀZ
|
||||
mobile.sin_family = AF_INET ; // Socket INET
|
||||
mobile.sin_addr.s_addr = inet_addr(PQgetvalue(res, 0, 0)) ;
|
||||
mobile.sin_port = htons(mobile_port) ;
|
||||
|
||||
x = solution.getX();
|
||||
y = solution.getY();
|
||||
z = solution.getZ();
|
||||
|
||||
/* On envoie les coordonnées de la position */
|
||||
sendto(sockfd, (void *)&x, sizeof(float), 0, (struct sockaddr *)&mobile, mobile_len);
|
||||
sendto(sockfd, (void *)&y, sizeof(float), 0, (struct sockaddr *)&mobile, mobile_len);
|
||||
sendto(sockfd, (void *)&z, sizeof(float), 0, (struct sockaddr *)&mobile, mobile_len);
|
||||
|
||||
close(sockfd);
|
||||
cout << "Envoi de la position au client " << mac << " à l'adresse IP " << PQgetvalue(res, 0, 0) << endl;
|
||||
}
|
||||
PQclear(res);
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
#ifndef _SERVER_HH_
|
||||
#define _SERVER_HH_
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
|
||||
#include "point.hh"
|
||||
#include "positioning.hh"
|
||||
#include "measurement.hh"
|
||||
#include "treatment.hh"
|
||||
#include "libowlps-positioning.hh"
|
||||
|
||||
class Server
|
||||
{
|
||||
|
||||
private:
|
||||
request att_request;
|
||||
vector<couple_info> recv_info;
|
||||
|
||||
int listen_port;
|
||||
int mobile_port;
|
||||
int listen_socket;
|
||||
|
||||
PGconn *conn;
|
||||
|
||||
Positioning pos;
|
||||
|
||||
public:
|
||||
Server(int port, int mport)
|
||||
{
|
||||
listen_port = port;
|
||||
mobile_port = mport;
|
||||
};
|
||||
~Server()
|
||||
{
|
||||
close(listen_socket);
|
||||
PQfinish(conn);
|
||||
};
|
||||
|
||||
int start();
|
||||
int init(const boost::program_options::variables_map);
|
||||
void treatment();
|
||||
void createResult(Point, int, string);
|
||||
void sendToClient(Point, char *);
|
||||
};
|
||||
|
||||
#endif // _SERVER_HH_
|
|
@ -1,416 +0,0 @@
|
|||
#include "treatment.hh"
|
||||
|
||||
bool Treatment::apExists(const string &ap_addr)const
|
||||
{
|
||||
|
||||
string str;
|
||||
|
||||
for (unsigned int i = 0 ; i < access_point_list.size() ; i++)
|
||||
{
|
||||
str = access_point_list[i].getApAddr() ;
|
||||
const int length = str.length() ;
|
||||
for (int j = 0 ; j < length ; ++j)
|
||||
str[j] = tolower(str[j]) ;
|
||||
if (str == ap_addr)
|
||||
{
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
|
||||
return false ;
|
||||
}
|
||||
|
||||
unsigned int Treatment::apIndex(const string &ap_addr)const
|
||||
{
|
||||
unsigned int i;
|
||||
string str;
|
||||
|
||||
for (i = 0 ; i < access_point_list.size() ; i++)
|
||||
{
|
||||
str = access_point_list[i].getApAddr() ;
|
||||
const int length = str.length() ;
|
||||
for (int j = 0 ; j < length ; ++j)
|
||||
str[j] = tolower(str[j]) ;
|
||||
if (str == ap_addr)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0; // Should never happen
|
||||
}
|
||||
|
||||
void Treatment::makeMeasurementList(vector<couple_info> recv_info)
|
||||
{
|
||||
|
||||
bool inserted = false;
|
||||
Measurement measure;
|
||||
char *ret = (char *)malloc(sizeof(char) * 18) ;
|
||||
string mac_a;
|
||||
int value;
|
||||
|
||||
for (unsigned int i = 0; i < recv_info.size(); i++)
|
||||
{
|
||||
|
||||
sprintf(ret, "%02x:%02x:%02x:%02x:%02x:%02x", recv_info.at(i).ap_mac_addr_bytes[0], recv_info.at(i).ap_mac_addr_bytes[1], recv_info.at(i).ap_mac_addr_bytes[2], recv_info.at(i).ap_mac_addr_bytes[3], recv_info.at(i).ap_mac_addr_bytes[4], recv_info.at(i).ap_mac_addr_bytes[5]) ;
|
||||
ret[17] = '\0';
|
||||
mac_a = ret;
|
||||
value = recv_info.at(i).antenna_signal_dbm;
|
||||
|
||||
for (unsigned int j = 0 ; j < m.size() ; j++)
|
||||
if (m[j].getMacAddr() == mac_a)
|
||||
{
|
||||
m[j].addSsValue(value);
|
||||
inserted = true;
|
||||
break;
|
||||
}
|
||||
if (inserted == false)
|
||||
{
|
||||
measure.setMacAddr(mac_a);
|
||||
measure.addSsValue(value);
|
||||
m.push_back(measure);
|
||||
}
|
||||
}
|
||||
|
||||
free(ret);
|
||||
}
|
||||
|
||||
vector<Point> Treatment::getkClosestInSs(const unsigned int &k, const Point *point_ignored)const
|
||||
{
|
||||
|
||||
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;
|
||||
|
||||
for (i = 0 ; i < reference_point_list.size() ; i++)
|
||||
if (point_ignored == NULL || (reference_point_list[i].getCoordinates() != *point_ignored))
|
||||
{
|
||||
tmp_distance = reference_point_list[i].getSsSquareDistance(m);
|
||||
|
||||
/* 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());
|
||||
dist_max = (dist_max < tmp_distance) ? tmp_distance : dist_max;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if tmp_dst < dist_max, should add it and remove previous greatest dist. */
|
||||
if (dist_max > tmp_distance)
|
||||
{
|
||||
/* remove old max */
|
||||
for (j = 0 ; j < distances_vector.size() ; j++)
|
||||
if (distances_vector[j] == dist_max)
|
||||
{
|
||||
distances_vector[j] = tmp_distance;
|
||||
points_vector[j] = reference_point_list[i].getCoordinates();
|
||||
break;
|
||||
}
|
||||
/* 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];
|
||||
}
|
||||
/* Else nothing needs to be done */
|
||||
}
|
||||
}
|
||||
|
||||
/* Sorts the vector */
|
||||
for (i = 0 ; i < distances_vector.size() - 1 ; i++)
|
||||
{
|
||||
tmp_min = distances_vector[i];
|
||||
min_idx = i;
|
||||
for (j = i+1 ; j < distances_vector.size() ; j++)
|
||||
if (tmp_min > distances_vector[j])
|
||||
{
|
||||
tmp_min = distances_vector[j];
|
||||
min_idx = j;
|
||||
}
|
||||
|
||||
if (min_idx != i)
|
||||
{
|
||||
/* Swap points */
|
||||
tmp_pt = points_vector[i];
|
||||
points_vector[i] = points_vector[min_idx];
|
||||
points_vector[min_idx] = tmp_pt;
|
||||
|
||||
/* Swap distances */
|
||||
distances_vector[min_idx] = distances_vector[i];
|
||||
distances_vector[i] = tmp_min;
|
||||
}
|
||||
}
|
||||
|
||||
return points_vector;
|
||||
}
|
||||
|
||||
Point Treatment::fbcm(const int &client_idx)const
|
||||
{
|
||||
|
||||
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, z = MINMAX_Z_START;
|
||||
|
||||
i = 0;
|
||||
//cout << "FBCM: ";
|
||||
for (i = 0 ; i < m.size() ; i++)
|
||||
if (apExists(m[i].getMacAddr()))
|
||||
{
|
||||
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;
|
||||
constant_term += 20 * log10((300000000.0 / (float) access_point_list[ap_idx].getFrequency()) / (4*M_PI));
|
||||
//end of expr. should be: client_list[client_idx].getAntennaGain() instead of 2.
|
||||
//cout << "20log(" << (300000000.0 / (float) access_point_list[ap_idx].getFrequency()) / (4*M_PI) << ") = ";
|
||||
//cout << constant_term << " ";
|
||||
dist_vect.push_back(pow(10, (constant_term - m[i].getAverage()) / (10 * access_point_list[ap_idx].getFriisIndex())));
|
||||
//cout << endl;
|
||||
}
|
||||
|
||||
/* Then: min-max */
|
||||
minmax_res = 1000000;
|
||||
for (x = MINMAX_X_START ; x < MINMAX_X_STOP ; x += MINMAX_STEP)
|
||||
for (y = MINMAX_Y_START ; y < MINMAX_Y_STOP ; y += MINMAX_STEP)
|
||||
for (z = MINMAX_Z_START ; z <= MINMAX_Z_STOP ; z += MINMAX_STEP)
|
||||
{
|
||||
minmax_max = 0;
|
||||
for (i = 0 ; i < centres.size() ; i++)
|
||||
if (abs(centres[i].distance(x, y, z) - dist_vect[i]) > minmax_max)
|
||||
minmax_max = abs(centres[i].distance(x, y, z) - dist_vect[i]) ;
|
||||
if (minmax_max < minmax_res)
|
||||
{
|
||||
ret.setX(x);
|
||||
ret.setY(y);
|
||||
ret.setZ(z);
|
||||
minmax_res = minmax_max;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear all vectors */
|
||||
addr.clear();
|
||||
dist_vect.clear();
|
||||
centres.clear();
|
||||
|
||||
/* Return position */
|
||||
return ret;
|
||||
}
|
||||
|
||||
Point Treatment::fbcm_friis(const vector<float> friis_idx_list, const float &z)const
|
||||
{
|
||||
|
||||
Point ret(0, 0, 0);
|
||||
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 ;
|
||||
vector<Measurement> vm = m; //Used when filtering 3 strongest APs
|
||||
vector<float> friis_idx = friis_idx_list; //Used when filtering 3 strongest APs
|
||||
|
||||
i = 0;
|
||||
for (i = 0 ; i < vm.size() ; i++)
|
||||
{
|
||||
if (apExists(vm[i].getMacAddr()))
|
||||
{
|
||||
ap_idx = apIndex(vm[i].getMacAddr());
|
||||
constant_term = access_point_list[ap_idx].getOutputPower() + access_point_list[ap_idx].getAntennaGain() + 2;
|
||||
constant_term += 20 * log10((300000000.0 / (float) access_point_list[ap_idx].getFrequency()) / (4*M_PI));
|
||||
if (friis_idx[i] != -1)
|
||||
{
|
||||
centres.push_back(access_point_list[ap_idx].getCoordinates());
|
||||
dist_vect.push_back(pow(10, (constant_term - vm[i].getAverage()) / (10 * friis_idx[i])));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Then: min-max */
|
||||
minmax_res = 1000000;
|
||||
for (x = MINMAX_X_START ; x < MINMAX_X_STOP ; x += MINMAX_STEP)
|
||||
for (y = MINMAX_Y_START ; y < MINMAX_Y_STOP ; y += MINMAX_STEP)
|
||||
{
|
||||
minmax_max = 0;
|
||||
for (i = 0 ; i < centres.size() ; i++)
|
||||
if (abs(centres[i].distance(x, y, z) - dist_vect[i]) > minmax_max)
|
||||
minmax_max = abs(centres[i].distance(x, y, z) - dist_vect[i]) ;
|
||||
if (minmax_max < minmax_res)
|
||||
{
|
||||
ret.setX(x);
|
||||
ret.setY(y);
|
||||
ret.setZ(z);
|
||||
minmax_res = minmax_max;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear all vectors */
|
||||
dist_vect.clear();
|
||||
centres.clear();
|
||||
|
||||
/* Return position */
|
||||
return ret;
|
||||
}
|
||||
|
||||
Point Treatment::interlink(const int &client_idx) const
|
||||
{
|
||||
|
||||
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, z = MINMAX_Z_START;
|
||||
|
||||
i = 0;
|
||||
for (i = 0 ; i < m.size() ; i++)
|
||||
if (apExists(m[i].getMacAddr()))
|
||||
{
|
||||
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();
|
||||
constant_term += 20 * log10((300000000.0 / (float) access_point_list[ap_idx].getFrequency()) / (4*M_PI)) + 2;
|
||||
//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));
|
||||
}
|
||||
|
||||
/* Then: min-max */
|
||||
minmax_res = 1000000;
|
||||
for (x = MINMAX_X_START ; x < MINMAX_X_STOP ; x += MINMAX_STEP)
|
||||
for (y = MINMAX_Y_START ; y < MINMAX_Y_STOP ; y += MINMAX_STEP)
|
||||
for (z = MINMAX_Z_START ; z < MINMAX_Z_STOP ; z += MINMAX_STEP)
|
||||
{
|
||||
minmax_max = 0;
|
||||
for (i = 0 ; i < centres.size() ; i++)
|
||||
if (abs(centres[i].distance(x, y, z) - dist_vect[i]) > minmax_max)
|
||||
minmax_max = abs(centres[i].distance(x, y, z) - dist_vect[i]);
|
||||
if (minmax_max < minmax_res)
|
||||
{
|
||||
ret.setX(x);
|
||||
ret.setY(y);
|
||||
ret.setZ(z);
|
||||
minmax_res = minmax_max;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear all vectors */
|
||||
addr.clear();
|
||||
dist_vect.clear();
|
||||
centres.clear();
|
||||
|
||||
/* Return position */
|
||||
return ret;
|
||||
}
|
||||
|
||||
vector<float> Treatment::computeFriisFromRefList(const Point &p)
|
||||
{
|
||||
|
||||
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;
|
||||
|
||||
|
||||
/* Compute an index for each ref point. List stored in friis_idx_list */
|
||||
/* Compute an index for Point p. List stored in friis_idx_list */
|
||||
for (unsigned int j = 0 ; j < reference_point_list.size() ; j++)
|
||||
{
|
||||
pt_coords = reference_point_list[j].getCoordinates();
|
||||
if (pt_coords==p)
|
||||
{
|
||||
for (unsigned int i = 0 ; i < m.size() ; i++)
|
||||
{
|
||||
if (apExists(m[i].getMacAddr()))
|
||||
{
|
||||
unsigned int ap_idx = apIndex(m[i].getMacAddr());
|
||||
ap_power = access_point_list[ap_idx].getOutputPower();
|
||||
ap_coords = access_point_list[ap_idx].getCoordinates();
|
||||
ap_freq = access_point_list[ap_idx].getFrequency();
|
||||
ap_gain = access_point_list[ap_idx].getAntennaGain();
|
||||
ap_mac = access_point_list[ap_idx].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;
|
||||
|
||||
if (reference_point_list[j].getPowerForAp(ap_mac, &mes_power))
|
||||
friis_idx_list.push_back((const_term - mes_power) / (10 * log10(ap_coords.distance(pt_coords))));
|
||||
else
|
||||
friis_idx_list.push_back(-1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return friis_idx_list;
|
||||
}
|
||||
|
||||
Point Treatment::getkWeightedInSs(const unsigned int &k, const Point *point_ignored)const
|
||||
{
|
||||
|
||||
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;
|
||||
|
||||
for (i = 0 ; i < reference_point_list.size() ; i++)
|
||||
if (point_ignored == NULL || (reference_point_list[i].getCoordinates() != *point_ignored))
|
||||
{
|
||||
tmp_distance = reference_point_list[i].getSsSquareDistance(m);
|
||||
/* 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());
|
||||
dist_max = (dist_max < tmp_distance) ? tmp_distance : dist_max;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if tmp_dst < dist_max, should add it and remove previous greatest dist. */
|
||||
if (dist_max > tmp_distance)
|
||||
{
|
||||
/* remove old max */
|
||||
for (j = 0 ; j < distances_vector.size() ; j++)
|
||||
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 */
|
||||
}
|
||||
}
|
||||
for (i = 0 ; i < distances_vector.size() ; i++)
|
||||
total += (1 / distances_vector[i]);
|
||||
|
||||
for (i = 0 ; i < distances_vector.size() ; i++)
|
||||
{
|
||||
x += points_vector[i].getX() * (1 / distances_vector[i]) / total;
|
||||
y += points_vector[i].getY() * (1 / distances_vector[i]) / total;
|
||||
z += points_vector[i].getZ() * (1 / distances_vector[i]) / total;
|
||||
}
|
||||
|
||||
ret.setX(x);
|
||||
ret.setY(y);
|
||||
ret.setZ(z);
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
#ifndef _TREATMENT_HH_
|
||||
#define _TREATMENT_HH_
|
||||
|
||||
#include "point.hh"
|
||||
#include "measurement.hh"
|
||||
#include "accesspoint.hh"
|
||||
#include "referencepoint.hh"
|
||||
#include "libowlps-positioning.hh"
|
||||
|
||||
class Treatment
|
||||
{
|
||||
private:
|
||||
vector<AccessPoint> access_point_list;
|
||||
vector<ReferencePoint> reference_point_list;
|
||||
vector<Measurement> m;
|
||||
|
||||
public:
|
||||
Treatment(vector<AccessPoint> access_point, vector<ReferencePoint> reference_point)
|
||||
{
|
||||
access_point_list = access_point;
|
||||
reference_point_list = reference_point;
|
||||
};
|
||||
~Treatment()
|
||||
{
|
||||
access_point_list.clear();
|
||||
m.clear();
|
||||
reference_point_list.clear();
|
||||
};
|
||||
|
||||
bool apExists(const string &)const;
|
||||
unsigned int apIndex(const string &)const;
|
||||
void makeMeasurementList(vector<couple_info>);
|
||||
|
||||
vector<Point> getkClosestInSs(const unsigned int &k, const Point *point_ignored)const;
|
||||
|
||||
Point kPointsAverage(const vector<Point> &vp)const;
|
||||
Point fbcm(const int &client_idx)const;
|
||||
Point fbcm_friis(const vector<float> friis_idx_list, const float &z)const;
|
||||
Point interlink(const int &client_idx)const;
|
||||
|
||||
vector<float> computeFriisFromRefList(const Point &p);
|
||||
Point getkWeightedInSs(const unsigned int &k, const Point *point_ignored)const ;
|
||||
};
|
||||
|
||||
#endif // _TREATMENT_HH_
|
Loading…
Reference in New Issue