From 1a51d234c635340cda6353976db54b5439ec2a22 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Mon, 22 Mar 2010 13:47:19 +0100 Subject: [PATCH] [Positioning] Add InterlinkNetworks, MinMax & associates Add classes: - MultilaterationMethod - MinMax (extends MultilaterationMethod) - MultilaterationAlgorithm (extends PositioningAlgorithm) - InterlinkNetworks (extends MultilaterationAlgorithm) --- owlps-positioning/Makefile | 14 +++++ owlps-positioning/TODO | 5 ++ owlps-positioning/src/interlinknetworks.cc | 24 ++++++++ owlps-positioning/src/interlinknetworks.hh | 17 ++++++ owlps-positioning/src/minmax.cc | 36 ++++++++++++ owlps-positioning/src/minmax.hh | 29 ++++++++++ .../src/multilaterationalgorithm.cc | 56 +++++++++++++++++++ .../src/multilaterationalgorithm.hh | 44 +++++++++++++++ .../src/multilaterationmethod.hh | 26 +++++++++ .../tests/interlinknetworks_test.hh | 35 ++++++++++++ owlps-positioning/tests/minmax_test.hh | 36 ++++++++++++ 11 files changed, 322 insertions(+) create mode 100644 owlps-positioning/src/interlinknetworks.cc create mode 100644 owlps-positioning/src/interlinknetworks.hh create mode 100644 owlps-positioning/src/minmax.cc create mode 100644 owlps-positioning/src/minmax.hh create mode 100644 owlps-positioning/src/multilaterationalgorithm.cc create mode 100644 owlps-positioning/src/multilaterationalgorithm.hh create mode 100644 owlps-positioning/src/multilaterationmethod.hh create mode 100644 owlps-positioning/tests/interlinknetworks_test.hh create mode 100644 owlps-positioning/tests/minmax_test.hh diff --git a/owlps-positioning/Makefile b/owlps-positioning/Makefile index acd9aff..6569dbf 100644 --- a/owlps-positioning/Makefile +++ b/owlps-positioning/Makefile @@ -52,6 +52,8 @@ OBJ_LIST = \ request.o \ calibrationrequest.o \ result.o \ + minmax.o \ + interlinknetworks.o \ realposition.o \ configuration.o \ userinterface.o \ @@ -65,10 +67,12 @@ OBJ_LIST = \ inputlogcsv.o OBJ_NOTEST_LIST = \ posexcept.o \ + multilaterationalgorithm.o \ inputmedium.o INTERFACES_LIST = \ inputlogmedium.hh \ outputmedium.hh \ + multilaterationmethod.hh \ positioningalgorithm.hh OBJ = $(OBJ_LIST:%=$(OBJ_DIR)/%) @@ -157,6 +161,16 @@ output.o: \ $(OBJ_DIR)/outputterminal.o \ $(OBJ_DIR)/configuration.o \ $(OBJ_DIR)/posexcept.o +multilaterationalgorithm.o: \ + $(SRC_DIR)/positioningalgorithm.hh \ + $(OBJ_DIR)/minmax.o \ + $(OBJ_DIR)/mobile.o +minmax.o: \ + $(SRC_DIR)/multilaterationmethod.hh \ + $(OBJ_DIR)/point3d.o \ + $(OBJ_DIR)/accesspoint.o +interlinknetworks.o: \ + $(OBJ_DIR)/multilaterationalgorithm.o realposition.o: \ $(SRC_DIR)/positioningalgorithm.hh \ $(OBJ_DIR)/result.o \ diff --git a/owlps-positioning/TODO b/owlps-positioning/TODO index 87ddafd..7512320 100644 --- a/owlps-positioning/TODO +++ b/owlps-positioning/TODO @@ -3,6 +3,7 @@ ° Finir le test de Input. ° Finir le test de Output. ° Finir le test de Positioning. + ° Tester InterlinkNetworks::compute() ? - Revoir le diagramme UML ° Associations : devraient êtres représentées par des attributs @@ -26,6 +27,10 @@ ° Faire quelque chose pour le code commenté (idem dans Measurement). +- MinMax + ° Différencier le pas pour X, Y et Z ? + ° Régler le start & stop dans MultilaterationAlgorithm. + - Mobile Attributs Viterbi ? (Cf. l'ancien clientinfo.hh.) diff --git a/owlps-positioning/src/interlinknetworks.cc b/owlps-positioning/src/interlinknetworks.cc new file mode 100644 index 0000000..f41242d --- /dev/null +++ b/owlps-positioning/src/interlinknetworks.cc @@ -0,0 +1,24 @@ +#include "interlinknetworks.hh" +#include "mobile.hh" + +using std::tr1::unordered_map ; + + + +float InterlinkNetworks::estimate_distance(const Measurement &measurement) +{ + const AccessPoint &ap = *measurement.get_ap() ; + assert(&ap) ; + + double constant_term = + ap.get_trx_power() + + ap.get_antenna_gain() + + 20 * log10( + 300000000.0 / + ap.get_frequency() / + (4 * M_PI) + ) + + mobile->get_antenna_gain() ; + const float &average_ss = measurement.get_average_ss() ; + return pow(10, (constant_term - average_ss) / 35) ; +} diff --git a/owlps-positioning/src/interlinknetworks.hh b/owlps-positioning/src/interlinknetworks.hh new file mode 100644 index 0000000..f4189ff --- /dev/null +++ b/owlps-positioning/src/interlinknetworks.hh @@ -0,0 +1,17 @@ +#ifndef _OWLPS_POSITIONING_INTERLINKNETWORKS_HH_ +#define _OWLPS_POSITIONING_INTERLINKNETWORKS_HH_ + +#include "multilaterationalgorithm.hh" + +/// Computes a position using the Interlink Networks formula +class InterlinkNetworks: public MultilaterationAlgorithm +{ +public: + InterlinkNetworks(const Mobile *_mobile = NULL): + MultilaterationAlgorithm(_mobile) {} + ~InterlinkNetworks(void) {} + + float estimate_distance(const Measurement &measurement) ; +} ; + +#endif // _OWLPS_POSITIONING_INTERLINKNETWORKS_HH_ diff --git a/owlps-positioning/src/minmax.cc b/owlps-positioning/src/minmax.cc new file mode 100644 index 0000000..d3c3e47 --- /dev/null +++ b/owlps-positioning/src/minmax.cc @@ -0,0 +1,36 @@ +#include "minmax.hh" +#include "accesspoint.hh" + +using std::tr1::unordered_map ; + + + +Point3D MinMax::multilaterate( + const unordered_map &ap_distances) +{ + float min = INFINITE ; + Point3D centre(start) ; + + for (float x = start.get_x() ; x <= stop.get_x() ; x += step) + for (float y = start.get_y() ; y <= stop.get_y() ; y += step) + for (float z = start.get_z() ; z <= stop.get_z() ; z += step) + { + float d_max = 0 ; + for (unordered_map::const_iterator i = + ap_distances.begin() ; i != ap_distances.end() ; ++i) + { + float dist = + Point3D(x, y, z).distance_to_sphere( + i->first->get_coordinates(), i->second) ; + if (dist > d_max) + d_max = dist ; + } + if (d_max < min) + { + min = d_max ; + centre.set_coordinates(x, y, z) ; + } + } + + return centre ; +} diff --git a/owlps-positioning/src/minmax.hh b/owlps-positioning/src/minmax.hh new file mode 100644 index 0000000..0fe4633 --- /dev/null +++ b/owlps-positioning/src/minmax.hh @@ -0,0 +1,29 @@ +#ifndef _OWLPS_POSITIONING_MINMAX_HH_ +#define _OWLPS_POSITIONING_MINMAX_HH_ + +#include "multilaterationmethod.hh" + +/// Multilaterates using the Lassabe's MinMax algorithm +class MinMax: public MultilaterationMethod +{ +protected: + const Point3D &start ; + const Point3D &stop ; + float step ; + + static const float MINMAX_DEFAULT_STEP = 0.5 ; + static const float INFINITE = 1000000 ; + +public: + MinMax(const Point3D &_start, + const Point3D &_stop, + const float _step = MINMAX_DEFAULT_STEP): + start(_start), stop(_stop), step(_step) {} + + ~MinMax(void) {} + + Point3D multilaterate( + const std::tr1::unordered_map &ap_distances) ; +} ; + +#endif // _OWLPS_POSITIONING_MINMAX_HH_ diff --git a/owlps-positioning/src/multilaterationalgorithm.cc b/owlps-positioning/src/multilaterationalgorithm.cc new file mode 100644 index 0000000..68d7a5f --- /dev/null +++ b/owlps-positioning/src/multilaterationalgorithm.cc @@ -0,0 +1,56 @@ +#include "multilaterationalgorithm.hh" +#include "minmax.hh" + +using namespace std ; +using std::tr1::unordered_map ; + + + +/* *** Constructors *** */ + + +MultilaterationAlgorithm:: +MultilaterationAlgorithm(const Mobile *_mobile): + mobile(_mobile), request(NULL) +{ + // Will be changed when other multilateration methods will be + // implemented + multilateration_method = new MinMax(Point3D(-0.5, -0.5, 0), + Point3D(10, 31.5, 6)) ; + // FIXME: minmax start and stop +} + + +MultilaterationAlgorithm::~MultilaterationAlgorithm() +{ + delete multilateration_method ; +} + + + +/* *** Operations *** */ + + +Result MultilaterationAlgorithm::compute(const Request &_request) +{ + request = &_request ; + mobile = request->get_mobile() ; + + compute_ap_distance_circles() ; + Point3D position = multilaterate() ; + + return Result(request, position) ; +} + + +void MultilaterationAlgorithm::compute_ap_distance_circles() +{ + ap_distances.clear() ; + + const unordered_map &measurements = + request->get_measurements() ; + + for (unordered_map::const_iterator i = + measurements.begin() ; i != measurements.end() ; ++i) + ap_distances[i->second.get_ap()] = estimate_distance(i->second) ; +} diff --git a/owlps-positioning/src/multilaterationalgorithm.hh b/owlps-positioning/src/multilaterationalgorithm.hh new file mode 100644 index 0000000..742dc60 --- /dev/null +++ b/owlps-positioning/src/multilaterationalgorithm.hh @@ -0,0 +1,44 @@ +#ifndef _OWLPS_POSITIONING_MULTILATERATIONALGORITHM_HH_ +#define _OWLPS_POSITIONING_MULTILATERATIONALGORITHM_HH_ + +#include "positioningalgorithm.hh" +#include "multilaterationmethod.hh" + +/// Super-class of multilateration-based positioning algorithms +class MultilaterationAlgorithm: public PositioningAlgorithm +{ +protected: + const Mobile *mobile ; + const Request *request ; + + std::tr1::unordered_map ap_distances ; + MultilaterationMethod *multilateration_method ; + + /** @name Operations */ + //@{ + void compute_ap_distance_circles() ; + Point3D multilaterate() ; + //@} + +public: + MultilaterationAlgorithm(const Mobile *_mobile = NULL) ; + + virtual ~MultilaterationAlgorithm(void) ; + + /** @name Operations */ + //@{ + Result compute(const Request &_request) ; + virtual float estimate_distance(const Measurement &measurement) = 0 ; + //@} +} ; + + + +inline Point3D MultilaterationAlgorithm::multilaterate() +{ + return multilateration_method->multilaterate(ap_distances) ; +} + + + +#endif // _OWLPS_POSITIONING_MULTILATERATIONALGORITHM_HH_ diff --git a/owlps-positioning/src/multilaterationmethod.hh b/owlps-positioning/src/multilaterationmethod.hh new file mode 100644 index 0000000..722986e --- /dev/null +++ b/owlps-positioning/src/multilaterationmethod.hh @@ -0,0 +1,26 @@ +#ifndef _OWLPS_POSITIONING_MULTILATERATIONMETHOD_HH_ +#define _OWLPS_POSITIONING_MULTILATERATIONMETHOD_HH_ + +class AccessPoint ; + +#include "point3d.hh" + +#include + +/// Super-class of all multilateration methods +/** + * The source data is a list of access points associated with the + * distances to the mobile. These distances are estimated using a + * MultilaterationAlgorithm. + */ +class MultilaterationMethod +{ +public: + MultilaterationMethod(void) {} + virtual ~MultilaterationMethod(void) {} + + virtual Point3D multilaterate( + const std::tr1::unordered_map &ap_distances) = 0 ; +} ; + +#endif // _OWLPS_POSITIONING_MULTILATERATIONMETHOD_HH_ diff --git a/owlps-positioning/tests/interlinknetworks_test.hh b/owlps-positioning/tests/interlinknetworks_test.hh new file mode 100644 index 0000000..6c70ad8 --- /dev/null +++ b/owlps-positioning/tests/interlinknetworks_test.hh @@ -0,0 +1,35 @@ +#include + +#include "interlinknetworks.hh" + +class InterlinkNetworks_test: public CxxTest::TestSuite +{ +public: + + void test_distance(void) + { + char mobile_gain = 3, mobile_power = 15 ; + Mobile mobile("", "", mobile_gain, mobile_power) ; + MultilaterationAlgorithm *algo = new InterlinkNetworks(&mobile) ; + + char ap_gain = 5, ap_power = 20, ap_channel = 1 ; + AccessPoint ap(Point3D(), "", "", ap_gain, ap_power, ap_channel) ; + + std::vector ss_list ; + ss_list.push_back(-42) ; + Measurement measurement(&ap, ss_list) ; + + /* ** How to check ref_distance in Scilab? ** + * C = 5 + 20 + 20 * log10(300000000 / 2412000000 / (4 * PI)) + 3 + * L = -42 + * ref_distance = 10^((C-L)/35) + */ + float ref_distance = 7.1547 ; + + float computed_distance = algo->estimate_distance(measurement) ; + TS_ASSERT_DELTA(computed_distance, ref_distance, 0.0001) ; + + delete algo ; + } + +} ; diff --git a/owlps-positioning/tests/minmax_test.hh b/owlps-positioning/tests/minmax_test.hh new file mode 100644 index 0000000..88f6df0 --- /dev/null +++ b/owlps-positioning/tests/minmax_test.hh @@ -0,0 +1,36 @@ +#include + +#include "minmax.hh" + +class MinMax_test: public CxxTest::TestSuite +{ +public: + + void test_multilaterate(void) + { + Point3D start(0,0,0), stop(10,10,4) ; + float step = 0.5 ; + MultilaterationMethod *minmax = new MinMax(start, stop, step) ; + + AccessPoint + ap1(Point3D(0,0,0)), + ap2(Point3D(10,0,0)), + ap3(Point3D(0,10,0)), + ap4(Point3D(5,5,4)) ; + std::tr1::unordered_map ap_distances ; + ap_distances[&ap1] = 7.071 ; + ap_distances[&ap2] = 7.071 ; + ap_distances[&ap3] = 7.071 ; + ap_distances[&ap4] = 4 ; + Point3D wanted_result(5,5,0) ; + + Point3D result = minmax->multilaterate(ap_distances) ; + // Wrong with a step of 0.1 (for this test case): + TS_ASSERT_EQUALS(result, wanted_result) ; + // We can then use something like that: + //TS_ASSERT_LESS_THAN(result.distance(wanted_result), 0.01) ; + + delete minmax ; + } + +} ;