diff --git a/owlps-positioner/cfg/owlps-positioner.conf b/owlps-positioner/cfg/owlps-positioner.conf index 762ebaa..c663a07 100644 --- a/owlps-positioner/cfg/owlps-positioner.conf +++ b/owlps-positioner/cfg/owlps-positioner.conf @@ -93,6 +93,19 @@ csv-file = /tmp/owlps-positioner.log #area-start = -2;-2;0 #area-stop = 20;30;6 +# Algorithm to calculate the similarity, in the signal strength space, +# of two measurements. +# The following algorithms are implemented: +# - mean: The mean of all the packets in the measurement is +# computed, then the euclidean distance between the two means is +# used. +# - interval: The mean Im and the standard deviation Is of the +# packets in the measurement I are computed; the closest reference +# measurement R is the one with the highest number of packets in +# the interval [Im-Is, Im+Is]. +# The default is "mean". +#ss-similarity = mean + # Smallest possible value for a received signal strength, in dBm. This # depends on the sensibility of the APs' Wi-Fi hardware. It is used to # compensate for APs that are not in coverage in a given measurement. @@ -144,7 +157,7 @@ csv-file = /tmp/owlps-positioner.log # algorithm and derivated. # For a given positioning request, average all the calibration requests -# associated with a reference point before to compute the SS distance. +# associated with a reference point before to compute the SS similarity. # The default is false, i.e. the positioning request is compared # directly to each calibration request. #average-reference-points = false diff --git a/owlps-positioner/src/measurement.cc b/owlps-positioner/src/measurement.cc index 33c6002..e0145aa 100644 --- a/owlps-positioner/src/measurement.cc +++ b/owlps-positioner/src/measurement.cc @@ -7,6 +7,7 @@ #include "measurement.hh" #include "posexcept.hh" +#include "configuration.hh" #include #include @@ -124,6 +125,35 @@ void Measurement::clear() /* *** Operations *** */ +float Measurement::similarity(const Measurement &source) const +{ + string algorithm( + Configuration::string_value("positioning.ss-similarity")) ; + + if (algorithm == "mean") + return ss_square_distance(source) ; + + if (algorithm == "interval") + { + float + interval_min = average_dbm - get_std_deviation(), + interval_max = average_dbm + get_std_deviation() ; + + // Count the number of SS of source that are within the interval + unsigned int nb_values = 0 ; + for (map::const_iterator ss = + source.ss_list.begin() ; ss != source.ss_list.end() ; ++ss) + if (interval_min < ss->second && ss->second < interval_max) + ++nb_values ; + + return 1 / nb_values ; + } + + throw bad_configuration( + "Bad SS similarity algorithm name \""+ algorithm +"\"!") ; +} + + void Measurement::recalculate_average() { average_dbm = 0 ; diff --git a/owlps-positioner/src/measurement.hh b/owlps-positioner/src/measurement.hh index 313a2ad..b6228f2 100644 --- a/owlps-positioner/src/measurement.hh +++ b/owlps-positioner/src/measurement.hh @@ -91,6 +91,8 @@ public: /** @name Operations */ //@{ + /// Computes the similarity with another Measurement in the SS space + float similarity(const Measurement &source) const ; /// Computes the distance to another Measurement's SS average float ss_square_distance(const Measurement &source) const ; /// Computes the distance to another SS value (in dBm) diff --git a/owlps-positioner/src/posutil.cc b/owlps-positioner/src/posutil.cc index 02b5ff4..d1ab16a 100644 --- a/owlps-positioner/src/posutil.cc +++ b/owlps-positioner/src/posutil.cc @@ -96,7 +96,7 @@ float PosUtil::ss_square_distance( unordered_map::const_iterator i2 = measurements2.find(i1->first) ; assert(i2 != measurements2.end()) ; - distance += i1->second.ss_square_distance(i2->second) ; + distance += i1->second.similarity(i2->second) ; } return distance / measurements1.size() ; diff --git a/owlps-positioner/src/userinterface.cc b/owlps-positioner/src/userinterface.cc index 542dd0e..c74ace8 100644 --- a/owlps-positioner/src/userinterface.cc +++ b/owlps-positioner/src/userinterface.cc @@ -26,6 +26,7 @@ namespace po = boost::program_options ; "/usr/local/etc/owlps/owlps-positioner.conf" /* Positioning options */ +#define DEFAULT_SS_SIMILARITY "mean" #define DEFAULT_MESHING_GRAIN 0.5 #define DEFAULT_Z_MESHING_GRAIN 1 #define DEFAULT_SMALLEST_SS -99 @@ -238,6 +239,10 @@ void UserInterface::fill_positioning_options() ("positioning.smallest-ss", po::value()->default_value(DEFAULT_SMALLEST_SS), "Smallest possible value for a received signal strength, in dBm.") + ("positioning.ss-similarity", + po::value()->default_value(DEFAULT_SS_SIMILARITY), + "Algorithm to calculate the similarity, in the signal strength space," + " between two measurements. Allowed: mean, interval.") ("positioning.generate-reference-points", po::value()->default_value(false), "Generate reference points from the (auto)calibration requests" @@ -280,7 +285,7 @@ void UserInterface::fill_positioning_options() po::value()->default_value(false), "With the NSS algorithm, for a given positioning request, average" " all the calibration requests associated with a reference point" - " before to compute the SS distance." + " before to compute the SS similarity." " The default is false, i.e the positioning request is compared" " directly to each calibration request.") ("positioning.nss.ignore-ap-reference-points",