diff --git a/Binning.h b/Binning.h new file mode 100755 index 0000000..4ff14c5 --- /dev/null +++ b/Binning.h @@ -0,0 +1,114 @@ +#ifndef BINNING_H +#define BINNING_H + +#include +#include + +struct BinningRange { + float min; + float max; + BinningRange(float min, float max) : min(min), max(max) {;} + float getWidth() const {return max-min;} +}; + +template class Binning { + +private: + + /** size to use for each dimension's bin */ + std::vector binSizes; + + std::vector binRanges; + + std::unordered_set used; + +public: + + /** add a new dimension for binning with its corresponding size */ + void setBinSizes(const std::vector binSizes) { + this->binSizes = binSizes; + } + + /** manually set min/max range for each dimension */ + void setRanges(const std::vector ranges) { + this->binRanges = ranges; + } + + /** estimate each dimension's min/max from the given entry set */ + void setRanges(const std::vector& entries) { + + clearUsed(); + binRanges.clear(); + + // process each to-be-binned dimension + const int numDimensions = binSizes.size(); + for (int dim = 0; dim < numDimensions; ++dim) { + + // determin min and max value for the current dimension + BinningRange r(+1e30, -1e30); + for (const Binable& b : entries) { + const float val = b.getBinValue(dim); + if(val < r.min) {r.min = val;} + if(val > r.max) {r.max = val;} + } + + // remember + binRanges.push_back(r); + + } + + } + + /** remove all tracked usages */ + void clearUsed() { + used.clear(); + } + + /** does the given element relate to an used or unsed bin? */ + bool isFree(const Binable& b) const { + const uint64_t hash = getHash(b); + return used.find(hash) == used.end(); + } + + /** mark the bin the given element belongs to as used */ + void markUsed(const Binable& b) { + const uint64_t hash = getHash(b); + used.insert(hash); + } + +private: + + /** calculate unique-bin-hash for the given element */ + uint64_t getHash(const Binable& b) const { + + uint64_t hash = 0; + + const int numDimensions = binSizes.size(); + for (int dim = 0; dim < numDimensions; ++dim) { + + // get binable's value for the current dimension + const float val = b.getBinValue(dim); + + // snap value to bin-number + const int binNr = std::round((val-binRanges[dim].min) / binSizes[dim]); + + // maximum binNr + const int binNrMax = binRanges[dim].getWidth() / binSizes[dim]; + + // sanity check + if (binNr < 0 || binNr > 255) {throw "bin index out of range!!";} + + // update hash + hash *= (binNrMax+1); + hash += binNr; + + } + + // done + return hash; + + } + +}; + +#endif // BINNING_H diff --git a/CMakeLists.txt b/CMakeLists.txt index 77205a2..93b7967 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,7 +62,7 @@ ADD_DEFINITIONS( -fstack-protector-all -g3 - -O0 + -O2 -march=native -DWITH_TESTS diff --git a/EvalWifiOptResult.h b/EvalWifiOptResult.h index 248dba8..cc1596a 100755 --- a/EvalWifiOptResult.h +++ b/EvalWifiOptResult.h @@ -8,6 +8,7 @@ #include "Indoor/sensors/radio/VAPGrouper.h" #include "Indoor/sensors/offline/FileReader.h" +#include "Indoor/sensors/radio/WiFiQualityAnalyzer.h" #include "Indoor/floorplan/v2/Floorplan.h" #include "Indoor/floorplan/v2/FloorplanReader.h" @@ -195,9 +196,187 @@ public: // const float h = 90 * (1 - std::pow(factor, 1.0)); // K::GnuplotColor color = K::GnuplotColor::fromHSV(h, 255, 255); + // scale + //factor = std::pow(factor, 2.0); + // hsv white->red const float sat = 255 * factor; - K::GnuplotColor color = K::GnuplotColor::fromHSV(0, sat, 255); + const float val = 255;//255 - 128 * factor; + K::GnuplotColor color = K::GnuplotColor::fromHSV(0, sat, val); + + K::GnuplotObjectPolygon* poly = new K::GnuplotObjectPolygon( + K::GnuplotFill(K::GnuplotFillStyle::SOLID, color), + K::GnuplotStroke::NONE() + ); + + // slightly overlapping?? + const float s = ss * 0.50; + + poly->add(K::GnuplotCoordinate3(ep.pos.x-s, ep.pos.y-s, ep.pos.z-oz, K::GnuplotCoordinateSystem::FIRST)); + poly->add(K::GnuplotCoordinate3(ep.pos.x+s, ep.pos.y-s, ep.pos.z-oz, K::GnuplotCoordinateSystem::FIRST)); + poly->add(K::GnuplotCoordinate3(ep.pos.x+s, ep.pos.y+s, ep.pos.z-oz, K::GnuplotCoordinateSystem::FIRST)); + poly->add(K::GnuplotCoordinate3(ep.pos.x-s, ep.pos.y+s, ep.pos.z-oz, K::GnuplotCoordinateSystem::FIRST)); + poly->close(); + poly->setZIndex(ep.pos.z - 1.5); + plot->splot.getObjects().add(poly); + + } + + plot->splot.getObjects().reOrderByZIndex(); + plot->plot(); + + return plot; + + } + + + + + + + + + + + + + + + + + + + + + + + + + Plotty* showWifiQuality(const std::vector& readers, const std::vector>& paths) { + + Plotty* plot = new Plotty(map); + + plot->settings.obstacles = true; + plot->settings.outline = false; + plot->settings.stairs = false; + plot->settings.outlineColorCustom = true; + //plot->settings.outlineColor = K::GnuplotColor::fromRGB(0,0,0); + plot->buildFloorplan(); + plot->equalXY(); + + plot->gp << "unset border\n"; + plot->splot.getAxisX().setTicsVisible(false); + plot->splot.getAxisY().setTicsVisible(false); + plot->splot.getAxisZ().setTicsVisible(false); + plot->setScale(1.5, 1.5); + + // combine position and quality + struct ErrPoint { + Point3 pos; + float err; + ErrPoint(const Point3 pos, const float err) : pos(pos), err(err) {;} + }; + + std::vector errors; + + // process each location + for (int i = 0; i < readers.size(); ++i) { + + const Offline::FileReader& reader = readers[i]; + Offline::FileReader::GroundTruth gt = reader.getGroundTruth(map, paths[i]); + + WiFiQualityAnalyzer analyzer; + + for (const auto& entry : reader.getWiFiGroupedByTime()) { + + analyzer.add(entry.data); + + Point3 pt = gt.get(Timestamp::fromMS(entry.ts)); + const float quality = analyzer.getQuality(); + + // enqueue MAX error + errors.push_back(ErrPoint(pt, quality)); + + } + } + + // interpolated error points + std::vector errorsInt; + K::Statistics errStats; + const float oz = 1.3; + const float ss = 4.0; + + for (Floorplan::Floor* floor : map->floors) { + + for (float y = -20; y < 70; y+=ss) { + for (float x = -10; x < 130; x+=ss) { + + const Point3 pos(x,y,floor->atHeight+oz); + float errSum = 0; + float distSum = 0; + int cnt = 0; + + float minDist = 99999; + + for (const ErrPoint& ep : errors) { + //if (ep.pos.z != pos.z) {continue;} + const float dist = ep.pos.getDistance(pos); + //if (dist > 4.0) {continue;} + //const float imp = 1.0 / (std::pow((dist+0.01)/4.0, 3)); + //errSum += ep.err * imp; + //distSum += imp; + if (dist < minDist) { + errSum = ep.err; + distSum = 1.0; + minDist = dist; + } + + + ++cnt; + } + + // limit estimations to the floorplan's outline + bool contained = false; + for (Floorplan::FloorOutlinePolygon* poly : floor->outline) { + HelperPoly hp(*poly); + if (hp.contains(pos.xy()*100)) { + if (poly->method == Floorplan::OutlineMethod::ADD) { + contained = true; + } else { + //contained = false; break; + } + } + } + + if (distSum == 0) {continue;} + if (!contained) {continue;} + const float err = errSum/distSum; + + // add + errStats.add(err); + errorsInt.push_back(ErrPoint(pos, err)); + + } + } + + } + + const float minErr = 0.0;//errStats.getMin(); + const float maxErr = 20.0;//errStats.getQuantile(0.9); + + //plot->splot.setTitle("max error: " + std::to_string(errStats.getMax()) + " dB"); + + // draw interpolated errors between min/max + for (const ErrPoint& ep : errorsInt) { + + float factor = ep.err; + + factor = std::pow(factor, 0.5); + + // hsv white->red + const float sat = 128 - 128 * factor; + const float val = 255;//128 + 127 * factor; + K::GnuplotColor color = K::GnuplotColor::fromHSV(0, sat, val); K::GnuplotObjectPolygon* poly = new K::GnuplotObjectPolygon( K::GnuplotFill(K::GnuplotFillStyle::SOLID, color), @@ -223,6 +402,13 @@ public: } + + + + + + + }; #endif // EVALWIFIOPTRESULT_H diff --git a/main.cpp b/main.cpp index 6dcfa88..64c2bf6 100755 --- a/main.cpp +++ b/main.cpp @@ -1,5 +1,7 @@ #define BREAK raise(SIGTRAP); +#include "for_toni/Toni.h" + #include "Indoor/sensors/radio/setup/WiFiOptimizer.h" #include "Indoor/sensors/radio/setup/WiFiFingerprint.h" #include "Indoor/sensors/radio/setup/WiFiFingerprints.h" @@ -34,7 +36,7 @@ #include "wifi/EvalWiFi.h" #include "wifi/EvalWiFiPaths.h" #include "wifi/EvalWiFiPathMethods.h" - +#include "pf/MarkusB.h" #include "plots/PlotErrFunc.h" @@ -248,6 +250,14 @@ void errorPlotAllModels(Floorplan::IndoorMap* map) { std::vector> errors = errorStatAllModels(map); + for (K::Statistics stats : errors) { + std::cout << stats.getQuantile(0.25) << "\t&\t" << + stats.getMedian() << "\t&\t" << + stats.getQuantile(0.75) << "\t&\t" << + stats.getAvg() << + "\\\hline" << std::endl; + } + PlotErrFunc plot("", "reference measurements (%)"); plot.getPlot().getAxisX().setTicsLabelFormat("%h dB"); plot.add("\\noOptEmpiric{}", &errors[0]); @@ -695,10 +705,12 @@ void paperOutputs() { // generate error plot showing the performance of each // save the resulting wifi-models to XML for later re-use during the walk-eval <<<<<< !!!! if (1 == 0) { - rebuildAllModels(map, 0); - /** detailled error analysis for above optimization routine */ + //rebuildAllModels(map, 0); + + /** detailled error analysis for above optimization routine */ errorPlotAllModels(map); + } @@ -737,7 +749,7 @@ void paperOutputs() { } /** plot wifi eval results */ - if (1 == 1) { + if (1 == 0) { WiFiFingerprints fps; fps.load(Settings::fCalib); @@ -760,15 +772,16 @@ void paperOutputs() { EvalWiFiOptResult evalBBox(Settings::fMap); Plotty* p3 = evalBBox.showErrorPerFingerprint(Settings::wifiEachOptParPos_perBBox, fps); - K::GnuplotSize size(3.75, 2.8); - const float s = 4.6; + K::GnuplotSize size(5.15, 3.4); + const float s = 4.4; auto adjust = [&] (Plotty* pp) { + //pp->setScale(1,1, -0.075, 0); pp->gp.setTerminal("epslatex", size); pp->splot.setTitle(""); pp->splot.getView().setCamera(74, 30); pp->splot.getView().setScaleAll(s); - pp->splot.getAxisZ().setRange(K::GnuplotAxis::Range(-3, 15.5)); + pp->splot.getAxisZ().setRange(K::GnuplotAxis::Range(-6, 18.5)); pp->plot(); }; @@ -778,10 +791,19 @@ void paperOutputs() { p2->gp.writePlotToFile(Settings::fPathGFX + "wifiMaxErrorNN_opt3.gp"); p2->gp.setOutput(Settings::fPathGFX + "wifiMaxErrorNN_opt3.tex"); + //p2->gp << "set colorbox horizontal user origin screen 0.4, 0.96 size 0.5,0.05\n"; + p2->splot.setStringMod(new K::GnuplotStringModLaTeX()); adjust(p2); p3->gp.writePlotToFile(Settings::fPathGFX + "wifiMaxErrorNN_opt5.gp"); p3->gp.setOutput(Settings::fPathGFX + "wifiMaxErrorNN_opt5.tex"); + p3->gp << "set pm3d; set cbrange [0:20]; set palette defined (0 '#ffffff', 1 '#ff0000'); \n"; + //p3->gp << "set colorbox horizontal user origin screen -0.11, 0.08 size 0.45,0.05 front;\n"; + p3->gp << "set colorbox vertical user origin screen 0.77, 0.55 size 0.04,0.40 front;\n"; + p3->splot.getAxisCB().setTicsLabelFormat("%h dB"); + p3->splot.getAxisCB().setTicsStep(10); + p3->splot.setStringMod(new K::GnuplotStringModLaTeX()); + adjust(p3); @@ -940,7 +962,10 @@ void showModelFor(const std::string& mapFile, const std::string& modelXml, const int main(void) { - Floorplan::IndoorMap* map = Floorplan::Reader::readFromFile(Settings::fMap); + //Toni::run(); + //return 0; + + Floorplan::IndoorMap* map = Floorplan::Reader::readFromFile(Settings::fMap); //testWAF(); //sleep(1); @@ -948,7 +973,7 @@ int main(void) { //const float rssi = LogDistanceModel::distanceToRssi(-100, 0, 999); //int i = 0; (void) i; - paperOutputs(); return 0; + // paperOutputs(); return 0; //showFingerprintsFor(Settings::fMap, Settings::fCalib, "D8:84:66:4A:4A:D0"); //showModelFor(Settings::fMap, Settings::wifiEachOptParPos_multimodel, "D8:84:66:4A:4A:D0"); @@ -1040,6 +1065,12 @@ int main(void) { } +// // markus B +// if (1 == 0) { +// Floorplan::IndoorMap* map = Floorplan::Reader::readFromFile(Settings::fMap);; +// MarkusB::walkEverything(map); +// } + // walks if (1 == 1) { Floorplan::IndoorMap* map = Floorplan::Reader::readFromFile(Settings::fMap);; @@ -1129,6 +1160,8 @@ int main(void) { } + + // wifi vs ground-truth distance error if (1 == 0) { std::vector files = { @@ -1160,6 +1193,34 @@ int main(void) { std::cout << "num scans: " << numScans << std::endl; + // stats as table + if (1 == 1) { + + EvalWiFiPaths ewp(Settings::fMap); + ewp.loadModel(Settings::wifiAllFixed, "0"); + ewp.walks(files, gtIndices); + + ewp.loadModel(Settings::wifiAllOptPar, "1"); + ewp.walks(files, gtIndices); + + ewp.loadModel(Settings::wifiEachOptPar, "2"); + ewp.walks(files, gtIndices); + + ewp.loadModel(Settings::wifiEachOptParPos, "3"); + ewp.walks(files, gtIndices); + + ewp.loadModel(Settings::wifiEachOptParPos_multimodel, "4"); + ewp.walks(files, gtIndices); + + ewp.loadModel(Settings::wifiEachOptParPos_perBBox, "5"); + ewp.walks(files, gtIndices); + + // FOR PAPER + ewp.dumpStats(); + + } + + // stats as GFX if (1 == 1) { EvalWiFiPaths ewp(Settings::fMap); @@ -1179,7 +1240,8 @@ int main(void) { } - // examine various modifications + + // examine various modifications [did not work out.. not within the paper] if (1 == 0) { EvalWiFiPathMethods ewpm(Settings::fMap); @@ -1192,7 +1254,6 @@ int main(void) { } - sleep(10000); } diff --git a/pf/EvalWalk.h b/pf/EvalWalk.h index 1491084..a1dfd4e 100755 --- a/pf/EvalWalk.h +++ b/pf/EvalWalk.h @@ -328,6 +328,7 @@ public: } std::cout << " | OVERALL:" << "(" << modelStatsSingle->getMedian() << "@" << (numStuck*100/numTotal) << "%)" << std::endl; + //std::cout << " | OVERALL:" << modelStatsSingle->getQuantile(0.25) << " " << modelStatsSingle->getMedian() << " " << modelStatsSingle->getQuantile(0.75) << " " << modelStatsSingle->getAvg() << std::endl; sleep(1); } diff --git a/plots/PlotErrFunc.h b/plots/PlotErrFunc.h index 8e51ced..575fa95 100755 --- a/plots/PlotErrFunc.h +++ b/plots/PlotErrFunc.h @@ -63,6 +63,10 @@ public: gplot.getAxisX().setRange(K::GnuplotAxis::Range(K::GnuplotAxis::Range::AUTO, K::GnuplotAxis::Range::AUTO)); } + const std::vector& getEntries() { + return entries; + } + /** set the percentage range to show */ void setYRange(const int fromPercent, const int toPercent, const int increment = 5) { this->range.fromPercent = fromPercent; diff --git a/plots/PlotErrTime.h b/plots/PlotErrTime.h index 4aa1803..d734971 100755 --- a/plots/PlotErrTime.h +++ b/plots/PlotErrTime.h @@ -46,6 +46,18 @@ public: } + void setColor(const int idx, const std::string& color) { + lineErr[idx].getStroke().getColor().setHexStr(color); + } + + void setLabel(const int idx, const std::string& label) { + lineErr[idx].setTitle(label); + } + + void setWidth(const int idx, const float w) { + lineErr[idx].getStroke().setWidth(w); + } + K::Gnuplot& getGP() { return gp; } diff --git a/plots/Plotty.h b/plots/Plotty.h index 204a6a6..5bc7c33 100755 --- a/plots/Plotty.h +++ b/plots/Plotty.h @@ -119,6 +119,7 @@ public: bool obstacles = true; bool outline = true; bool outlineColorCustom = false; + bool skipI1 = false; K::GnuplotColor outlineColor = K::GnuplotColor::fromRGB(128,128,128); float minZ = -9999; float maxZ = +9999; @@ -501,6 +502,16 @@ public: if (floor->atHeight < settings.minZ) {continue;} if (floor->atHeight > settings.maxZ) {continue;} + // for toni + if (settings.skipI1) { + if (floor->atHeight == 4) { + //if (poly->poly.points[2].y < 0) { + if (poly->poly.points[0].x > 70 && poly->poly.points[0].y < 50) { + continue; + } + } + } + const float v = 180 + vo; K::GnuplotColor color = K::GnuplotColor::fromRGB(v,v,v); diff --git a/tex/chapters/abstract.tex b/tex/chapters/abstract.tex index dd2e9f6..b8381b9 100755 --- a/tex/chapters/abstract.tex +++ b/tex/chapters/abstract.tex @@ -15,7 +15,7 @@ Within this work we will thus focus on simple, easy to set-up models and evaluate their performance compared to real-world measurements. The evaluation ranges from a fully empiric, instant - setup, given the transmitter locations are well-known, to a highly optimized scenario based + setup, given the transmitter locations are well-known, to a highly-optimized scenario based on some reference measurements within the building. Furthermore, we will propose a new signal strength prediction model as a combination of several simple ones. This tradeoff increases accuracy with only minor additional computations. diff --git a/tex/chapters/experiments.tex b/tex/chapters/experiments.tex index 841701c..fe7c3c9 100755 --- a/tex/chapters/experiments.tex +++ b/tex/chapters/experiments.tex @@ -35,7 +35,7 @@ (defined by the usual \docAPshort{} transmit power for europe), a path loss exponent $\mPLE{} \approx $ \SI{2.5} and $\mWAF{} \approx$ \SI{-8}{\decibel} per floor / ceiling (made of reinforced concrete) \todo{cite für werte}. - Figure \ref{fig:referenceMeasurements} depicts the location of the used 121 reference measurements. + \reffig{fig:referenceMeasurements} depicts the location of the used 121 reference measurements. Each location was scanned 30 times ($\approx$ \SI{25}{\second} scan time), non permanent \docAP{}s were removed, the values were grouped per physical transmitter (see \ref{sec:vap}) and aggregated to form the average signal strength per transmitter. @@ -90,7 +90,7 @@ \label{fig:wifiIndoorOutdoor} \end{figure} - Figure \ref{fig:wifiIndoorOutdoor} depicts the to-be-expected issues by examining the signal strength + \reffig{fig:wifiIndoorOutdoor} depicts the to-be-expected issues by examining the signal strength values of the reference measurements for one \docAP{}. Even though the transmitter is only \SI{5}{\meter} away from the reference measurement (small box), the metallised windows attenuate the signal as much as \SI{50}{\meter} @@ -114,12 +114,13 @@ {\em\optPerFloor{}} and {\em\optPerRegion{}} are just like {\em \optParamsPosEachAP{}} except that there are several sub-models, each of which is optimized for one floor / region instead of the whole building. - The chosen bounding boxes and resulting sub-models are depicted in figure \ref{fig:modelBBoxes}. + The chosen bounding boxes and resulting sub-models are depicted in \reffig{fig:modelBBoxes}. - Figure \ref{fig:wifiModelError} shows the optimization results for all strategies, which are as expected: + \reffig{fig:wifiModelError} shows the optimization results for all strategies, which are as expected: The estimation error is indirectly proportional to the number of optimized parameters. - However, even with {\em \optPerRegion{}} the maximal error is relatively high due to some locations that do - not fit the model at all, which is shown in figure \ref{fig:wifiModelErrorB}. + However, while median- and average-errors are fine, maximal errors sometimes are relatively high. + As depicted in \reffig{fig:wifiModelErrorMax}, even with {\em \optPerRegion{}} some locations simply do not fit the model, + and thus lead to high (local) errors. % Looking at the optimization results for \mTXP{}, \mPLE{} and \mWAF{} supports this finding. While the median for those values based on all optimized transmitters is totally sane @@ -130,30 +131,62 @@ For \SI{68}{\percent} of all installed transmitters, the estimated floor-number matched the real location. \begin{figure} + % cumulative error density \begin{subfigure}{0.52\textwidth} \input{gfx2/wifi_model_error_0_95.tex} \end{subfigure} - \begin{subfigure}{0.23\textwidth} - \input{gfx/wifiMaxErrorNN_opt0.tex} - \caption{\em \noOptEmpiric{}} - \label{fig:wifiModelErrorA} - \end{subfigure} - %\begin{subfigure}{0.25\textwidth} - % \input{gfx/wifiMaxErrorNN_opt3.tex} - %\end{subfigure} - \begin{subfigure}{0.23\textwidth} - \input{gfx/wifiMaxErrorNN_opt5.tex} - \caption{\em \optPerRegion{}} - \label{fig:wifiModelErrorB} + % table + \begin{subfigure}{0.47\textwidth} + \smaller + \centering + \begin{tabular}{|l|c|c|c|c|} + \hline + & 25 \% & median & 75 \% & avg \\\hline + \noOptEmpiric{} & \SI{2.5}{\decibel} & \SI{5.6}{\decibel} & \SI{9.3}{\decibel} & \SI{6.5}{\decibel} \\\hline + \optParamsAllAP{} & \SI{2.0}{\decibel} & \SI{4.3}{\decibel} & \SI{7.5}{\decibel} & \SI{5.4}{\decibel} \\\hline + \optParamsEachAP{} & \SI{1.6}{\decibel} & \SI{3.3}{\decibel} & \SI{6.2}{\decibel} & \SI{4.4}{\decibel} \\\hline + \optParamsPosEachAP{} & \SI{1.5}{\decibel} & \SI{3.0}{\decibel} & \SI{5.5}{\decibel} & \SI{3.8}{\decibel} \\\hline + \optPerFloor{} & \SI{0.7}{\decibel} & \SI{1.6}{\decibel} & \SI{3.3}{\decibel} & \SI{2.6}{\decibel} \\\hline + \optPerRegion{} & \SI{0.6}{\decibel} & \SI{1.4}{\decibel} & \SI{3.1}{\decibel} & \SI{2.4}{\decibel} \\\hline + \end{tabular} + \vspace{9mm} \end{subfigure} \caption{ - Comparison between different optimization strategies by examining the error (in \decibel) at each reference measurement. + Cumulative error distribution for all optimization strategies. The error results from the (absolute) difference + between model predictions and real-world values for each reference measurement. The higher the number of variable parameters, the better the model resembles real world conditions. - Both figures on the right depict the highest error for each reference measurement, where full red means $\ge$ \SI{20}{\decibel}. } \label{fig:wifiModelError} \end{figure} + + + \begin{figure} + \begin{subfigure}{0.32\textwidth} + \centering + \input{gfx/wifiMaxErrorNN_opt0.tex} + \caption{\em \noOptEmpiric{}} + \label{fig:wifiModelErrorMaxA} + \end{subfigure} + \begin{subfigure}{0.32\textwidth} + \centering + \input{gfx/wifiMaxErrorNN_opt3.tex} + \caption{\em \optParamsPosEachAP{}} + \label{fig:wifiModelErrorMaxB} + \end{subfigure} + \begin{subfigure}{0.32\textwidth} + \centering + \input{gfx/wifiMaxErrorNN_opt5.tex} + \caption{\em \optPerRegion{}} + \label{fig:wifiModelErrorMaxC} + \end{subfigure} + \caption{ + Local maximum error between model estimation and reference measurements among all known transmitters. + While optimization is able to reduce such errors, some local maxima remain due to overadaption. + } + \label{fig:wifiModelErrorMax} + \end{figure} + %\begin{figure} @@ -173,7 +206,7 @@ %Pos: cnt(34) min(3.032438) max(26.767128) range(23.734690) med(7.342710) avg(8.571227) stdDev(4.801449) While {\em \optPerRegion{}} is able to overcome the indoor vs. outdoor issues depicted in - figure \ref{fig:wifiIndoorOutdoor}, by using a separate bounding box just for the outdoor area, + \reffig{fig:wifiIndoorOutdoor}, by using a separate bounding box just for the outdoor area, it obviously requires a profound prior knowledge to correctly select the individual regions for the sub-model. %Such issues can only be fixed using more appropriate models that consider walls and other obstacles. @@ -229,7 +262,7 @@ % \label{fig:wifiNumFingerprints}% %\end{figure} - Figure \ref{fig:wifiNumFingerprints} depicts the impact of reducing the number of reference measurements + \reffig{fig:wifiNumFingerprints} depicts the impact of reducing the number of reference measurements during the optimization process for the {\em \optPerRegion{}} strategy. The error is determined by using the (absolute) difference between expected signal strength and the optimized model's corresponding prediction for all of the 121 reference measurements. @@ -245,7 +278,7 @@ Additionally we examined the impact of skipping reference measurements for difficult locations like staircases, surrounded by steel-enforced concrete. While this slightly decreases the estimation error for all other positions (hallway, etc) as expected, the error within the skipped locations is dramatically - increasing (see right half of figure \ref{fig:wifiNumFingerprints}). It is thus highly recommended + increasing (see right half of \reffig{fig:wifiNumFingerprints}). It is thus highly recommended to also perform reference measurements for locations, that are expected to strongly deviate (signal strength) from their surroundings. @@ -286,15 +319,20 @@ % -------------------------------- wifi walk error -------------------------------- % - \subsection{Location estimation error} - - \todo{uebergang holprig?} + \subsection{\docWIFI{} location estimation error} + \todo{uebergang jetzt besser?} + Having optimized several signal strength prediction models, we can now examine the resulting localization + accuracy for each one. For now, this will just cover the \docWIFI{} component itself. + The impact of adding additional sensors and a transition model will be evaluated later. + + %Using the optimized model setups and the measurements $\mRssiVec$ determined by scanning for nearby \docAPshort{}s, %we can directly perform a location estimation by rewriting \refeq{eq:wifiProb}: - For each of the discussed optimization strategies we can now determine the resulting localization accuracy. - The position within the building that best fits some signal strength measurements $\mRssiVec$ received by the smartphone - is the one that maximizes $p(\mPosVec \mid \mRssiVec)$ and can be rewritten as: + %For each of the discussed optimization strategies we can now determine the resulting localization accuracy. + The position $\mPosVec{}$ within the building that best fits some \docWIFI{} signal strength measurements $\mRssiVec$ received by the smartphone + is the one that maximizes $p(\mPosVec \mid \mRssiVec)$. + Omitting prior knowledge and normalization, this can be rewritten as: \begin{equation} p(\mPosVec \mid \mRssiVec) = @@ -312,12 +350,13 @@ \mPosVec^* = \argmax_{\mPosVec} \prod_{\mRssi_{i} \in \mRssiVec{}} \mathcal{N}(\mRssi_i \mid \mu_{i,\mPosVec}, \sigma^2) + \enskip. \label{eq:bestWiFiPos} \end{equation} - where $\mu_{i,\mPosVec}$ is the signal strength for \docAP{} $i$ - at location $\mPosVec$ returned from the to-be-examined prediction model. - For all comparisons we use a constant uncertainty $\sigma = \SI{8}{\decibel}$. + Within \refeq{eq:bestWiFiPos} $\mu_{i,\mPosVec}$ is the signal strength for \docAP{} $i$, + installed at location $\mPosVec$, returned from the to-be-examined prediction model. + For all comparisons we use a constant uncertainty of $\sigma = \SI{8}{\decibel}$. The quality of the estimated location is determined by using the Euclidean distance between estimation $\mPosVec^*$ and the pedestrian's ground truth position at the time the scan $\mRssiVec$ @@ -327,7 +366,7 @@ We therefore conducted 13 walks on 5 different paths within our building, each of which is defined by connecting marker points at well known positions - (see figure \ref{fig:allWalks}). + (see \reffig{fig:allWalks}). Whenever the pedestrian reached such a marker, the current time was recorded. Due to constant walking speeds, the ground-truth for any timestamp can be approximated using linear interpolation between adjacent markers. @@ -335,7 +374,7 @@ % walked paths \begin{figure} \centering - \input{gfx/all_walks.tex} + \input{gfx2/all_walks.tex} \caption{ Overview of all conducted paths. Outdoor areas are marked in green. @@ -344,12 +383,40 @@ \end{figure} \begin{figure} - \input{gfx/modelPerformance_meter.tex} - \caption{ - Cumulative error distribution between ground truth and location estimation using \refeq{eq:bestWiFiPos} depending - on the underlying signal strength prediction model. - Extremely high errors between the \SIrange{90}{100}{\percent} quartile are related to bad \docWIFI{} - coverage within outdoor areas (see figure \ref{fig:wifiIndoorOutdoor}). + % error gfx + \begin{subfigure}{0.52\textwidth} + \centering + \input{gfx2/modelPerformance_meter.tex} + \end{subfigure} + % table + %5.98767 9.23025 14.4272 11.9649 + %6.53764 9.01424 12.8797 12.0121 + %6.85665 9.82203 13.8528 12.9988 + %5.35629 8.5921 14.8037 11.9996 + %4.30191 6.91534 14.0746 11.948 + %4.26189 6.35975 11.5646 10.7466 + \begin{subfigure}{0.47\textwidth} + \smaller + \centering + \begin{tabular}{|l|c|c|c|c|} + \hline + & \SI{25}{\percent} & median & \SI{75}{\percent} & avg \\\hline + \noOptEmpiric{} & \SI{6.0}{\meter} & \SI{9.2}{\meter} & \SI{14.4}{\meter} & \SI{11.9}{\meter} \\\hline + \optParamsAllAP{} & \SI{6.5}{\meter} & \SI{9.0}{\meter} & \SI{12.8}{\meter} & \SI{12.0}{\meter} \\\hline + \optParamsEachAP{} & \SI{6.8}{\meter} & \SI{9.8}{\meter} & \SI{13.8}{\meter} & \SI{13.0}{\meter} \\\hline + \optParamsPosEachAP{} & \SI{5.4}{\meter} & \SI{8.6}{\meter} & \SI{14.8}{\meter} & \SI{12.0}{\meter} \\\hline + \optPerFloor{} & \SI{4.3}{\meter} & \SI{6.9}{\meter} & \SI{14.0}{\meter} & \SI{11.9}{\meter} \\\hline + \optPerRegion{} & \SI{4.2}{\meter} & \SI{6.5}{\meter} & \SI{11.6}{\meter} & \SI{10.7}{\meter} \\\hline + \end{tabular} + \vspace{9mm} + \end{subfigure} + \caption { + Cumulative error distribution between walked ground truth and \docWIFI{}-only location estimation using \refeq{eq:bestWiFiPos}. + %depending on the signal strength prediction model. + All models suffer from several (extremely) high errors that relate to bad \docWIFI{} + coverage e.g. within outdoor areas (see \reffig{fig:wifiIndoorOutdoor}). This negatively affects the average and 75th + percentile. The strategies {\em \optParamsAllAP{}} and {\em \optParamsEachAP{}} sometimes suffered from overadaption, + indicated by increased error values for the 25th percentile. } \label{fig:modelPerformance} \end{figure} @@ -359,11 +426,11 @@ %against the corresponding ground-truth, which indicates the absolute 3D error in meter. The position estimation for each \docWIFI{} measurement within the recorded walks (3756 scans in total) is compared against its corresponding ground-truth, indicating the 3D distance error. - The resulting cumulative error distribution can be seen in figure \ref{fig:modelPerformance}. + The resulting cumulative error distribution can be seen in \reffig{fig:modelPerformance}. The quality of the location estimation directly scales with the quality of the signal strength prediction model. However, as discussed earlier, the maximal estimation error might increase for some setups. % - This is either due to multimodalities, where more than one area is possible based on the recent + This is either due to multimodalities, where more than one area matches the recent \docWIFI{} observation, or optimization yielded an overadaption where the average signal strength prediction error is small, but the maximum error is dramatically increased for some regions. @@ -372,17 +439,18 @@ % -------------------------------- plots indicating walk issues -------------------------------- % \begin{figure} - \input{gfx/wifiMultimodality.tex} + \input{gfx2/wifiMultimodality.tex} \caption{ - Location probability \refeq{eq:bestWiFiPos} for three scans. Higher color intensities are more likely. - Ideally, places near the black ground truth are highly highly probable (green). - Often, other locations are just as likely as the ground truth (blue), - or the location with the highest probability does not match at all (red). + \docWIFI{}-only location probability for three distinct scans where + higher color intensities denote a higher likelihood for \refeq{eq:bestWiFiPos}. + The first scan (left, green) depicts a best-case scenario, where the region around the ground truth (black rectangle) is highly probable. + Often, other locations are just as likely as the ground truth (2nd scan, blue), + or the location with the highest probability is far from the actual ground truth (3rd scan, right, red). } \label{fig:wifiMultimodality} \end{figure} - Figure \ref{fig:wifiMultimodality} depicts aforementioned issues of multimodal (blue) or wrong (red) location + \reffig{fig:wifiMultimodality} depicts aforementioned issues of multimodal (blue) or wrong (red) location estimations. Filtering (\refeq{eq:recursiveDensity}) thus is highly recommended, as minor errors are compensated using other sensors or a movement model that prevents the estimation from leaping within the building. However, if wrong sensor values are observed for longer time periods, even filtering will produce erroneous @@ -410,23 +478,30 @@ %as the Smartphone did not see this \docAPshort{} the other location can be ruled out. While this works in theory, evaluations revealed several issues: - There is a chance that even a nearby \docAPshort{} is unseen during a scan due to packet collisions or - temporal effects within the surrounding. It thus might make sense to opt-out other locations - only, if at least two \docAPshort{}s are missing. On the other hand, this obviously demands for (at least) - two \docAPshort{}s to actually be different between the two locations, and requires a lot of permanently - installed transmitters to work out. + \begin{itemize} + + \item{ + There is a chance that even a nearby \docAPshort{} is unseen during a scan due to packet collisions or + temporal effects within the surrounding. It thus might make sense to opt-out other locations + only, if at least two \docAPshort{}s are missing. On the other hand, this obviously demands for (at least) + two \docAPshort{}s to actually be different between the two locations, and requires a lot of permanently + installed transmitters to work out. + } + + \item{ + Furthermore, this requires the signal strength prediction model to be fairly accurate. Within our testing + walks, several places are surrounded by concrete walls, which cause a harsh, local drop in signal strength. + The models used within this work will not accurately predict the signal strength for such locations. + %%Including \docAPshort{}s unseen by the Smartphone thus often increases the estimation error instead + %%of fixing the multimodality. + } + + \end{itemize} - Furthermore, this requires the signal strength prediction model to be fairly accurate. Within our testing - walks, several places are surrounded by concrete walls, which cause a harsh, local drop in signal strength. - The models used within this work will not accurately predict the signal strength for such locations. - %%Including \docAPshort{}s unseen by the Smartphone thus often increases the estimation error instead - %%of fixing the multimodality. - To sum up, while some situations, e.g. outdoors, could be improved, many other situations are deteriorated, especially when some transmitters are (temporarily) attenuated by ambient conditions like concrete walls. - - + We therefore examined variations of the probability calculation from \refeq{eq:wifiProb}. Despite the results show in \cite{PotentialRisks}, removing weak \docAPshort{}s from $\mRssiVec{}$ yielded similar results. While some estimations were improved, the overall error increased @@ -471,15 +546,16 @@ % -------------------------------- final system -------------------------------- % - \subsection{Overall system error} + \subsection{System error using filtering} - After examining the \docWIFI{} component on its own, we will now analyze the impact of aforementioned model - optimizations on our smartphone-based indoor localization system described in section \ref{sec:system}. + After examining the \docWIFI{} component on its own, we will now analyze the impact of previously discussed model + optimizations on our smartphone-based indoor localization system described in section \ref{sec:system}, based on + \refeq{eq:recursiveDensity}. Due to transition constraints from the buildings floorplan, we expect the posterior density to often get stuck when the \docWIFI{} component provides erroneous estimations - due to bad signal strength predictions: - % + due to bad signal strength predictions or observations (see \reffig{fig:wifiMultimodality}): + A pedestrian walks along a hallway, but bad model values indicate that his most likely position is within a room right next to the hallway. If the density (described by the particles) is dragged (completely) into this room, @@ -493,7 +569,7 @@ we calculated each combination of the {\em 13 walks and six optimization strategies}, 25 times, using 5000, 7500 and 10000 particles resulting in 75 runs per walk, 975 per strategy and 5850 in total. % - Figure \ref{fig:overallSystemError} depicts the cumulative error distribution per optimization strategy, + \reffig{fig:overallSystemError} depicts the cumulative error distribution per optimization strategy, resulting from all executions for each walk conducted with the smartphone. While most values represent the expected results (more optimization yields better results), @@ -518,14 +594,14 @@ fix and the accuracy indicated by the GPS usually was \SI{50}{\meter} and above. Especially for {\em path 1}, the particle-filter often got stuck within the upper right outdoor area between both buildings - (see figure \ref{fig:allWalks}). Using the empirical parameters, \SI{40}{\percent} of all runs for this path got stuck at this location. + (see \reffig{fig:allWalks}). Using the empirical parameters, \SI{40}{\percent} of all runs for this path got stuck at this location. {\em \optParamsAllAP{}} already reduced the risk to \SI{20}{\percent} and all other optimization strategies did not get stuck at all. The same effect holds for all other conducted walks: The better the model optimization, the lower the risk of getting stuck somewhere along the path. Varying the number of particles between 5000 and 10000 indicated only a minor increase in accuracy and slightly decreased the risk of getting stuck. - Comparing the error results within figure \ref{fig:modelPerformance} and \ref{fig:overallSystemError}, one can + Comparing the error results within \reffig{fig:modelPerformance} and \reffig{fig:overallSystemError}, one can denote the positive impact of fusioning multiple sensors with a transition model based on the building's actual floorplan. Outdoor regions indicated a very low signal quality (see section \ref{sec:wifiQuality}). By omitting \docWIFI{} from the system's evaluation step, the IMU was able to @@ -533,7 +609,35 @@ \begin{figure} - \input{gfx/overall-system-error.tex} + \begin{subfigure}{0.49\textwidth} + \input{gfx2/overall-system-error.tex} + \end{subfigure} + % + \begin{subfigure}{0.50\textwidth} + %OVERALL:2.62158 5.13701 11.1822 9.00261 + %OVERALL:2.92524 6.00231 12.4425 10.6983 + %OVERALL:1.98318 3.99259 7.92429 5.81281 + %OVERALL:1.8647 3.86918 7.10482 5.62054 + %OVERALL:1.60847 3.15739 6.13963 4.79148 + %OVERALL:1.63617 3.34828 6.5379 5.12281 + \footnotesize + \centering + \setlength{\tabcolsep}{0.25em} % for the horizontal padding + \begin{tabular}{|l|c|c|c|c|c|} + + \hline + & \SI{25}{\percent} & median & \SI{75}{\percent} & avg & stuck \\\hline + \noOptEmpiric{} & \SI{2.6}{\meter} & \SI{5.1}{\meter} & \SI{11.2}{\meter} & \SI{9.0}{\meter} & \SI{22}{\percent} \\\hline + \optParamsAllAP{} & \SI{2.9}{\meter} & \SI{6.0}{\meter} & \SI{12.4}{\meter} & \SI{10.7}{\meter} & \SI{15}{\percent} \\\hline + \optParamsEachAP{} & \SI{1.9}{\meter} & \SI{4.0}{\meter} & \SI{7.9}{\meter} & \SI{5.8}{\meter} & \SI{5}{\percent} \\\hline + \optParamsPosEachAP{} & \SI{1.9}{\meter} & \SI{3.9}{\meter} & \SI{7.1}{\meter} & \SI{5.6}{\meter} & \SI{5}{\percent} \\\hline + \optPerFloor{} & \SI{1.6}{\meter} & \SI{3.2}{\meter} & \SI{6.1}{\meter} & \SI{4.8}{\meter} & \SI{4}{\percent} \\\hline + \optPerRegion{} & \SI{1.6}{\meter} & \SI{3.3}{\meter} & \SI{6.5}{\meter} & \SI{5.0}{\meter} & \SI{4}{\percent} \\\hline + \end{tabular} + \setlength{\tabcolsep}{1.0em} % reset the horizontal padding + \vspace{11.5mm} + \end{subfigure} + % \caption{ Cumulative error distribution for each model when used within the final localization system from \refeq{eq:recursiveDensity}. Despite some discussed exceptions, highly optimized models lead to lower localization errors. diff --git a/tex/chapters/introduction.tex b/tex/chapters/introduction.tex index f418f5c..7b79f7f 100755 --- a/tex/chapters/introduction.tex +++ b/tex/chapters/introduction.tex @@ -9,9 +9,9 @@ like step- and turn-detection. However, this requires the pedestrian's initial position to be well known, e.g. using a GPS-fix just before entering the building. Additionally, the sensor's error will sum up over - time. + time \cite{Koeping14}. - Depending on the used fusion-method, the latter can be addressed, + Depending on the used fusion-method, the latter can be addressed using a movement model for the pedestrian, that prevents unlikely movements and locations. However, this will obviously work only to some extent and still requires the initial position to be at least vaguely known. @@ -24,25 +24,25 @@ it can be stabilized by the IMU and vice versa. - The downside of such an approach: both, \docWIFI{} and \docIBeacon{}s, require additional prior - knowledge to work: To infer the probability of the pedestrian currently - residing at an arbitrary location, one compares the signal strengths received - by the smartphone with the signal strengths one should receive at this + The downside of this approach is that both, \docWIFI{} and \docIBeacon{}s, require additional prior + knowledge to work. To infer the probability of the pedestrian currently + residing at an arbitrary location, the signal strengths received + by the smartphone are compared with the signal strengths which should be received at this location (prior knowledge). As RF-signals are highly dependent on the surroundings, those values can change rapidly within meters. % That is why fingerprinting became popular, where the required prior knowledge is gathered by manually scanning each location within the building e.g. - using cells with \SI{2}{\meter} in size. While this provides the highest - possible accuracy due to actual measurements of the real situation, - one can easily realize the necessary amount of work for both, the initial - setup and maintenance when transmitters are changed or renovations take - place. + using cells of $\approx \SI{2}{\meter}$ in size. This usually leads to + a very high accuracy due to actual measurements of the real situation. + However, the amount of work for the initial + setup and the maintenance when transmitters are changed or renovations take + place, is very high. - To prevent setup- and maintenance effort, models can be used to predict - the signal strengths one should receive at some arbitrary location. - Depending on the used model, only a few parameters and the location of the - transmitter within the building are required. For newer installations + Setup- and maintenance effort can be prevented by using models to predict + the signal strengths that should be received at some arbitrary location. + Depending on the used model, only a few parameters and the locations of the + transmitters within the building are required. For newer installations the latter is often available and tagged within the building's floorplan. %As signals are attenuated by the buildings architecture like walls and floors, %advanced models additionally include the floorplan within their prediction. @@ -51,7 +51,7 @@ Furthermore, the choice of the model's parameters depends on the actual architecture and \docWIFI{} setup: Parameters that work within building A might not work out within building B. - Thus, a compromise comes to mind: Instead of using hundreds of fingerprints, + Thus, a compromise comes to mind: Instead of using several hundreds of fingerprints, a few reference measurements used for a model setup might be a valid tradeoff between resulting accuracy and necessary setup time. diff --git a/tex/chapters/relatedwork.tex b/tex/chapters/relatedwork.tex index 45eb1f4..39cd2c7 100755 --- a/tex/chapters/relatedwork.tex +++ b/tex/chapters/relatedwork.tex @@ -1,6 +1,6 @@ \section{Related Work} - Indoor localization based on received \docWIFI{} signal strengths (RSSI) dates back to the year + Indoor localization based on \docWIFI{} and received signal strength indications (RSSI) dates back to the year 2000 and the work of Bahl and Padmanabhan \cite{radar}. During an one-time offline-phase, a multitude of reference measurements are conducted. During the online-phase, where the pedestrian walks along the building, those prior measurements are compared against live readings. @@ -47,12 +47,15 @@ %This induces both, the need for more complex prediction models and the need for filtering approaches %to limit the impact of potentially erroneous readings. % - Approaches based on timing like TOA and TDOA as used within the GPS or methods estimating the signal's angle-of-arrival (AOA) + Approaches based on timing like TOA and TDOA, as used within the GPS, or methods estimating the signal's angle-of-arrival (AOA) are more accurate, and mostly invariant to architectural obstacles \cite{TimeDifferenceOfArrival1, TOAAOA}. - However, each of those requires special hardware to work. - % - We therefore focus on the well-known RSSI that is available on each commodity smartphone and use a - a simple signal strength prediction model to estimate the most probable location given the phone's observations. - To reduce the prediction error, we propose a new model based on multiple simple ones. - Several strategies to optimize such a model and the to-be-expected accuracy are hereafter discussed and evaluated. + Especially signal runtimes are unaffected by walls and thus allow for stable distance estimations, if the used components + support measuring time-delays down to a few picoseconds. This is why those techniques often need special (measurement) hardware + to estimate parameters like signal-runtime or signal-phase-shifts. Those requirements usually allow only for some use-cases. + + + We therefore focus on the RSSI, that is available on each commodity smartphone and uses a + a simple signal strength prediction model to estimate the most probable location given the phone's observations. + Furthermore, we propose a new model based on multiple simple ones, which will reduce the prediction error. + Several strategies to optimize simple models and the resulting accuracies are hereafter evaluated and discussed. diff --git a/tex/chapters/system.tex b/tex/chapters/system.tex index ce8b4df..053d3fc 100755 --- a/tex/chapters/system.tex +++ b/tex/chapters/system.tex @@ -44,7 +44,7 @@ $\mRssiVecWiFi$ contains the signal strength measurements of all \docAP{}s (\docAPshort{}s) currently visible to the smartphone, $\mObsSteps$ describes the number of steps detected since the last filter-step, $\mObsHeadingRel$ the (relative) angular change since the last filter-step, - $\mObsHeadingAbs$ the current, vague absolute heading, + $\mObsHeadingAbs$ the vague absolute heading as provided by the magnetometer, $\mPressure$ the ambient pressure in hPa and $\mObsGPS = ( \mObsGPSlat, \mObsGPSlon, \mObsGPSaccuracy)$ the current location (if available) given by the GPS. @@ -85,6 +85,8 @@ to further enhance the localization. Their values are incorporated by simply comparing the sensor readings against a distribution that models the sensor's uncertainty. + \todo{verteilung fuer gps und abs-heading} + %\todo{neues resampling? je nach dem was sich noch in der eval zeigt} As GPS will only work outdoors, e.g. when moving from one building into another, diff --git a/tex/chapters/work.tex b/tex/chapters/work.tex index 7d4bf9c..cc84f03 100755 --- a/tex/chapters/work.tex +++ b/tex/chapters/work.tex @@ -132,7 +132,7 @@ \end{equation} Just optimizing \mTXP{} and \mPLE{} with constant \mWAF{} and known transmitter position - usually means optimizing a convex function, as can be seen in figure \ref{fig:wifiOptFuncTXPEXP}. + usually means optimizing a convex function, as can be seen in \reffig{fig:wifiOptFuncTXPEXP}. For such error functions, algorithms like gradient descent and simplex \cite{gradientDescent, downhillSimplex1, downhillSimplex2} are well suited and will provide the global minima. @@ -141,7 +141,7 @@ is involved. While the latter can be mitigated by introducing a continuous function for the number $n$, e.g. a sigmoid, the function is not necessarily convex. - Figure \ref{fig:wifiOptFuncPosYZ} depicts two local minima and only one of both also is a global one. + \reffig{fig:wifiOptFuncPosYZ} depicts two local minima and only one of both also is a global one. \begin{figure*} \centering diff --git a/tex/make.sh b/tex/make.sh index fabcb72..f3609c4 100755 --- a/tex/make.sh +++ b/tex/make.sh @@ -13,3 +13,4 @@ dvips bare_conf.dvi ps2pdf14 bare_conf.ps okular bare_conf.pdf& +atril bare_conf.pdf& diff --git a/tex/misc/functions.tex b/tex/misc/functions.tex index 514a7ec..c0176d0 100755 --- a/tex/misc/functions.tex +++ b/tex/misc/functions.tex @@ -8,8 +8,8 @@ \newcommand{\mRssi}{\ensuremath{s}} % client's signal-strength measurement \newcommand{\mMdlRSSI}{\ensuremath{\varsigma}} % model's signal-strength -\newcommand{\mPosAP}{\varrho} % char for access point position vector -\newcommand{\mPos}{\rho} % char for positions +\newcommand{\mPosAP}{\hat\varrho} % char for access point position vector +\newcommand{\mPos}{\varrho} % char for positions \newcommand{\mPosVec}{\vec{\mPos}} % position vector @@ -71,7 +71,9 @@ %\newcommand{\docIBeacon}{iBeacon} % for equation references -\newcommand{\refeq}[1]{eq. \eqref{#1}} +\newcommand{\refeq}[1]{eq.~\eqref{#1}} +%\newcommand{\reffig}[1]{\figurename~\ref{#1}} +\newcommand{\reffig}[1]{Fig.~\ref{#1}} % add todo notes \newcommand{\todo}[1]{% diff --git a/wifi/EvalWiFiPaths.h b/wifi/EvalWiFiPaths.h index 29d6176..06c573c 100755 --- a/wifi/EvalWiFiPaths.h +++ b/wifi/EvalWiFiPaths.h @@ -81,6 +81,12 @@ public: } + void dumpStats() { + for (const auto& entry : pef_m->getEntries()) { + const K::Statistics* stats = entry.stats; + std::cout << stats->getQuantile(0.25) << " " << stats->getMedian() << " " << stats->getQuantile(0.75) << " " << stats->getAvg() << std::endl; + } + } void writeGP(const std::string& path, const std::string& name) { writeGP(*pef_m, K::GnuplotSize(8.6, 3.3), path + "/" + name + "_meter");