From e12db08b0de1ce513cbf956861ce2cbc665cb1e8 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Thu, 10 Jun 2010 15:57:03 +0200 Subject: [PATCH] [Positioning] Add positioning algorithm FBCM Add class FBCM. AccessPoint: Add attribute friis_index. Measurement: Add function get_ss_list_size(). Stock: Add function update_all_friis_indexes(). --- owlps-positioning/Makefile | 3 ++ owlps-positioning/TODO | 1 - owlps-positioning/src/accesspoint.cc | 5 ++- owlps-positioning/src/accesspoint.hh | 32 +++++++++++---- owlps-positioning/src/fbcm.cc | 12 ++++++ owlps-positioning/src/fbcm.hh | 16 ++++++++ owlps-positioning/src/measurement.hh | 7 ++++ owlps-positioning/src/positioning.cc | 10 ++++- owlps-positioning/src/stock.cc | 55 ++++++++++++++++++++++++++ owlps-positioning/src/stock.hh | 2 + owlps-positioning/src/userinterface.cc | 2 +- owlps-positioning/tests/fbcm_test.hh | 24 +++++++++++ owlps-positioning/tests/stock_test.hh | 5 +++ 13 files changed, 163 insertions(+), 11 deletions(-) create mode 100644 owlps-positioning/src/fbcm.cc create mode 100644 owlps-positioning/src/fbcm.hh create mode 100644 owlps-positioning/tests/fbcm_test.hh diff --git a/owlps-positioning/Makefile b/owlps-positioning/Makefile index fcf3d9f..6454568 100644 --- a/owlps-positioning/Makefile +++ b/owlps-positioning/Makefile @@ -54,6 +54,7 @@ OBJ_LIST = \ result.o \ minmax.o \ interlinknetworks.o \ + fbcm.o \ radar.o \ realposition.o \ configuration.o \ @@ -201,6 +202,8 @@ $(OBJ_DIR)/minmax.o: \ $(OBJ_DIR)/accesspoint.o $(OBJ_DIR)/interlinknetworks.o: \ $(OBJ_DIR)/multilaterationalgorithm.o +$(OBJ_DIR)/fbcm.o: \ + $(OBJ_DIR)/multilaterationalgorithm.o $(OBJ_DIR)/radar.o: \ $(OBJ_DIR)/cartographyalgorithm.o $(OBJ_DIR)/realposition.o: \ diff --git a/owlps-positioning/TODO b/owlps-positioning/TODO index 11bdd08..e8c44fb 100644 --- a/owlps-positioning/TODO +++ b/owlps-positioning/TODO @@ -32,7 +32,6 @@ Stock ? (Pour l'instant ils ne sont pas dans Stock.) - AccessPoint - ° Attribut float friis_index ? ° Lancer une exception si le canal Wi-Fi est mauvais (ou directement dans PosUtil::channel_to_frequency() ?). diff --git a/owlps-positioning/src/accesspoint.cc b/owlps-positioning/src/accesspoint.cc index 9d09876..364bcab 100644 --- a/owlps-positioning/src/accesspoint.cc +++ b/owlps-positioning/src/accesspoint.cc @@ -16,6 +16,7 @@ const AccessPoint& AccessPoint::operator=(const AccessPoint &source) this->WifiDevice::operator=(source) ; coordinates = source.coordinates ; frequency = source.frequency ; + friis_index = source.friis_index ; return *this ; } @@ -29,7 +30,8 @@ bool AccessPoint::operator==(const AccessPoint &source) const return this->WifiDevice::operator==(source) && coordinates == source.coordinates && - frequency == source.frequency ; + frequency == source.frequency && + friis_index == source.friis_index ; } @@ -39,6 +41,7 @@ ostream &operator<<(ostream &os, const AccessPoint &ap) os << "Coordinates: " << ap.coordinates << '\n' << "Frequency: " << ap.frequency << " Hz" << '\n' + << "Friis index: " << ap.friis_index << '\n' << (WifiDevice) ap ; return os ; diff --git a/owlps-positioning/src/accesspoint.hh b/owlps-positioning/src/accesspoint.hh index 058f830..d5fc517 100644 --- a/owlps-positioning/src/accesspoint.hh +++ b/owlps-positioning/src/accesspoint.hh @@ -14,6 +14,7 @@ class AccessPoint: public WifiDevice protected: Point3D coordinates ; unsigned long frequency ; ///< Frequency (channel) in Hz + float friis_index ; ///< Friis index used by FBCM public: /** @@ -26,25 +27,28 @@ public: AccessPoint(const Point3D &_coordinates = Point3D(), const std::string &_ip_addr = "", const std::string &_mac_addr = "", - const float &_antenna_gain = AP_DEFAULT_ANTENNA_GAIN, - const float &_trx_power = WIFIDEVICE_DEFAULT_TRX_POWER, + const float _antenna_gain = AP_DEFAULT_ANTENNA_GAIN, + const float _trx_power = WIFIDEVICE_DEFAULT_TRX_POWER, const unsigned int &channel = AP_DEFAULT_CHANNEL): WifiDevice(_ip_addr, _mac_addr, _antenna_gain, _trx_power), coordinates(_coordinates), - frequency(PosUtil::wifi_channel_to_hz(channel)) {} + frequency(PosUtil::wifi_channel_to_hz(channel)), + friis_index(0) {} AccessPoint(const WifiDevice &source, const Point3D &_coordinates, - const unsigned int &channel = AP_DEFAULT_CHANNEL): + const unsigned int channel = AP_DEFAULT_CHANNEL): WifiDevice(source), coordinates(_coordinates), - frequency(PosUtil::wifi_channel_to_hz(channel)) {} + frequency(PosUtil::wifi_channel_to_hz(channel)), + friis_index(0) {} AccessPoint(const WifiDevice &source): - WifiDevice(source), coordinates(Point3D()), frequency(0) {} + WifiDevice(source), coordinates(Point3D()), frequency(0), + friis_index(0) {} AccessPoint(const AccessPoint &source): WifiDevice(source), coordinates(source.coordinates), - frequency(source.frequency) {} + frequency(source.frequency), friis_index(0) {} ~AccessPoint(void) {} @@ -52,6 +56,7 @@ public: //@{ const Point3D& get_coordinates(void) const ; unsigned long get_frequency(void) const ; + float get_friis_index(void) const ; //@} /** @name Write accessors */ @@ -59,6 +64,7 @@ public: void set_coordinates(const Point3D &_coordinates) ; void set_channel(const unsigned int channel) ; void set_frequency(const unsigned long _frequency) ; + void set_friis_index(const float _friis_index) ; //@} /** @name Operators */ @@ -89,6 +95,12 @@ inline unsigned long AccessPoint::get_frequency() const } +inline float AccessPoint::get_friis_index() const +{ + return friis_index ; +} + + /* *** Write accessors *** */ @@ -123,6 +135,12 @@ inline void AccessPoint::set_frequency(const unsigned long _frequency) } +inline void AccessPoint::set_friis_index(const float _friis_index) +{ + friis_index = _friis_index ; +} + + /* *** Operators *** */ diff --git a/owlps-positioning/src/fbcm.cc b/owlps-positioning/src/fbcm.cc new file mode 100644 index 0000000..3c6aead --- /dev/null +++ b/owlps-positioning/src/fbcm.cc @@ -0,0 +1,12 @@ +#include "fbcm.hh" + + + +float FBCM::estimate_distance(const Measurement &measurement) +{ + double constant_term = make_constant_term(measurement) ; + const float &average_ss = measurement.get_average_ss() ; + const AccessPoint *ap = measurement.get_ap() ; + return pow(10, (constant_term - average_ss) / + (10 * ap->get_friis_index())) ; +} diff --git a/owlps-positioning/src/fbcm.hh b/owlps-positioning/src/fbcm.hh new file mode 100644 index 0000000..5283f43 --- /dev/null +++ b/owlps-positioning/src/fbcm.hh @@ -0,0 +1,16 @@ +#ifndef _OWLPS_POSITIONING_FBCM_HH_ +#define _OWLPS_POSITIONING_FBCM_HH_ + +#include "multilaterationalgorithm.hh" + +/// Computes a position using the Interlink Networks formula +class FBCM: public MultilaterationAlgorithm +{ +public: + FBCM(void) {} + ~FBCM(void) {} + + float estimate_distance(const Measurement &measurement) ; +} ; + +#endif // _OWLPS_POSITIONING_FBCM_HH_ diff --git a/owlps-positioning/src/measurement.hh b/owlps-positioning/src/measurement.hh index cd951cd..a578aaa 100644 --- a/owlps-positioning/src/measurement.hh +++ b/owlps-positioning/src/measurement.hh @@ -42,6 +42,7 @@ public: AccessPoint* get_ap() const ; const std::vector& get_ss_list() const ; double get_average_ss() const ; + int get_ss_list_size() const ; //@} /** @name Write accessors */ @@ -100,6 +101,12 @@ inline double Measurement::get_average_ss() const } +inline int Measurement::get_ss_list_size() const +{ + return ss_list.size() ; +} + + /* *** Write accessors *** */ diff --git a/owlps-positioning/src/positioning.cc b/owlps-positioning/src/positioning.cc index 3f9a7d9..cce5f2a 100644 --- a/owlps-positioning/src/positioning.cc +++ b/owlps-positioning/src/positioning.cc @@ -1,9 +1,11 @@ #include "positioning.hh" #include "realposition.hh" -#include "radar.hh" +#include "fbcm.hh" #include "interlinknetworks.hh" +#include "radar.hh" #include "configuration.hh" #include "posexcept.hh" +#include "stock.hh" using namespace std ; @@ -47,6 +49,12 @@ void Positioning::initialise_algorithms() if (*i == "Real") algorithms.push_back(new RealPosition) ; + else if (*i == "FBCM") + { + Stock::update_all_friis_indexes() ; + algorithms.push_back(new FBCM) ; + } + else if (*i == "InterlinkNetworks") algorithms.push_back(new InterlinkNetworks) ; diff --git a/owlps-positioning/src/stock.cc b/owlps-positioning/src/stock.cc index c3f742f..a65baa9 100644 --- a/owlps-positioning/src/stock.cc +++ b/owlps-positioning/src/stock.cc @@ -153,6 +153,61 @@ const AccessPoint& Stock::find_create_ap(const string &mac) } +void Stock::update_all_friis_indexes() +{ + for (unordered_map::iterator ap = aps.begin() ; + ap != aps.end() ; ++ap) + { + string ap_mac = ap->second.get_mac_addr() ; + double friis_idx_sum = 0 ; + int nb_friis_idx = 0 ; + + // Compute main general term, independant from scans + double ap_freq = ap->second.get_frequency() ; + double const_term = + ap->second.get_antenna_gain() + - 20 * log10(4 * M_PI) + + 20 * log10(PosUtil::LIGHT_SPEED / ap_freq) + + ap->second.get_trx_power() ; + + /* + * Compute an index for each Measurement in each Request in each + * ReferencePoint. The Friis index for an AP is the average of all + * these indexes. + */ + for (unordered_set::const_iterator rp = + reference_points.begin() ; rp != reference_points.end() ; + ++rp) + { + for (vector::const_iterator request = + rp->get_requests().begin() ; + request != rp->get_requests().end() ; ++request) + { + const unordered_map &measurements = + (*request)->get_measurements() ; + unordered_map::const_iterator + measurement = measurements.find(ap_mac) ; + if (measurement != measurements.end()) + { + double ss = measurement->second.get_average_ss() ; + float distance = + rp->distance(ap->second.get_coordinates()) ; + float mobile_gain = + (*request)->get_mobile()->get_antenna_gain() ; + friis_idx_sum += + (const_term + mobile_gain - ss) + / (10 * log10(distance)) ; + ++nb_friis_idx ; + } + } + } + + if (nb_friis_idx > 0) + ap->second.set_friis_index(friis_idx_sum / nb_friis_idx) ; + } +} + + const ReferencePoint& Stock:: find_create_reference_point(const ReferencePoint &point) { diff --git a/owlps-positioning/src/stock.hh b/owlps-positioning/src/stock.hh index 830df51..2f838e7 100644 --- a/owlps-positioning/src/stock.hh +++ b/owlps-positioning/src/stock.hh @@ -64,6 +64,8 @@ public: static const AccessPoint& find_create_ap(const std::string &mac) ; /// Get a reference to the AccessPoint corresponding to a given MAC address static AccessPoint& getw_ap(const std::string &mac) ; + /// Update the friis indexes of all the APs + static void update_all_friis_indexes(void) ; /// Look for a ReferencePoint and add it if it does not exist static const ReferencePoint& diff --git a/owlps-positioning/src/userinterface.cc b/owlps-positioning/src/userinterface.cc index 0f7d14d..725fbec 100644 --- a/owlps-positioning/src/userinterface.cc +++ b/owlps-positioning/src/userinterface.cc @@ -171,7 +171,7 @@ void UserInterface::fill_positioning_options() options.add_options() ("positioning.algorithm,a", po::value< vector >()->composing(), "Algorithms used to compute positions. You can specify \ -this option more than once (but at least once). Allowed: Real, \ +this option more than once (but at least once). Allowed: Real, FBCM, \ InterlinkNetworks, RADAR.") ; diff --git a/owlps-positioning/tests/fbcm_test.hh b/owlps-positioning/tests/fbcm_test.hh new file mode 100644 index 0000000..be55daf --- /dev/null +++ b/owlps-positioning/tests/fbcm_test.hh @@ -0,0 +1,24 @@ +#include + +#include "fbcm.hh" + +class FBCM_test: public CxxTest::TestSuite +{ +public: + + void test_select_point(void) + { + MultilaterationAlgorithm *algo = new FBCM() ; + + /* + * TODO: implement the test. + * I was told to accelerate the development, so I leave unneeded unit + * tests for later. This tests *is* actually needed, but I did some + * result comparison between the old version of OWLPS Positioning and + * the current one, and, hm, let's say it's OK for now… + */ + + delete algo ; + } + +} ; diff --git a/owlps-positioning/tests/stock_test.hh b/owlps-positioning/tests/stock_test.hh index 046982f..a64d052 100644 --- a/owlps-positioning/tests/stock_test.hh +++ b/owlps-positioning/tests/stock_test.hh @@ -101,6 +101,11 @@ public: element_not_found) ; } + void test_update_all_friis_indexes(void) + { + // TODO: implement that + } + void test_reference_points(void) { ReferencePoint referencepoint1(3,5,7) ;