current TeX

minor code changes
This commit is contained in:
2017-05-06 17:32:40 +02:00
parent 2438080389
commit edd41293c1
12 changed files with 650 additions and 132 deletions

View File

@@ -62,7 +62,7 @@ ADD_DEFINITIONS(
-fstack-protector-all
-g3
-O2
-O0
-march=native
-DWITH_TESTS

49
WalkResult.h Executable file
View File

@@ -0,0 +1,49 @@
#ifndef WALKRESULT_H
#define WALKRESULT_H
#include <vector>
#include <Indoor/geo/Point3.h>
#include <Indoor/data/Timestamp.h>
#include <fstream>
struct WalkResult {
struct Entry {
Timestamp ts;
Point3 estimation;
Point3 groundTruth;
float err;
};
std::vector<Entry> entries;
void serialize(const std::string& file) {
std::ofstream out(file);
for (const Entry& e : entries) {
out << e.ts.ms() << "\t";
out << e.estimation.x << "\t";
out << e.estimation.y << "\t";
out << e.estimation.z << "\t";
out << e.groundTruth.x << "\t";
out << e.groundTruth.y << "\t";
out << e.groundTruth.z << "\t";
out << e.err << "\n";
}
out.close();
}
void deserialize(const std::string& file) {
std::ifstream inp(file);
while(inp) {
Entry e;
uint64_t ms; inp >> ms; e.ts = Timestamp::fromMS(ms);
if (!inp) {break;}
inp >> e.estimation.x; inp >> e.estimation.y; inp >> e.estimation.z;
inp >> e.groundTruth.x; inp >> e.groundTruth.y; inp >> e.groundTruth.z;
inp >> e.err;
entries.push_back(e);
}
}
};
#endif // WALKRESULT_H

269
main.cpp
View File

@@ -749,7 +749,7 @@ void paperOutputs() {
}
/** plot wifi eval results */
if (1 == 0) {
if (1 == 1) {
WiFiFingerprints fps;
fps.load(Settings::fCalib);
@@ -791,15 +791,14 @@ 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.getCustom() << "set pm3d; set cbrange [0:20]; set palette defined (0 '#ffffff', 1 '#ff0000'); \n";
//p3->splot.getCustom() << "set colorbox horizontal user origin screen -0.11, 0.08 size 0.45,0.05 front;\n";
p3->splot.getCustom() << "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());
@@ -960,10 +959,261 @@ void showModelFor(const std::string& mapFile, const std::string& modelXml, const
}
void compareAll() {
Floorplan::IndoorMap* map = Floorplan::Reader::readFromFile(Settings::fMap);
// std::vector<std::string> files = {
// Settings::path1a, //Settings::path1b,
// //Settings::path2a, Settings::path2b,
// //Settings::path_toni_all_1a, Settings::path_toni_all_1b,
// //Settings::path_toni_all_2a, Settings::path_toni_all_2b,
// //Settings::path_toni_inst_1a, Settings::path_toni_inst_1b,
// //Settings::path_toni_inst_2a, Settings::path_toni_inst_2b,
// //Settings::path_toni_inst_3a, Settings::path_toni_inst_3b,
// };
// std::vector<std::vector<int>> gtIndices = {
// Settings::GroundTruth::path1, //Settings::GroundTruth::path1,
// //Settings::GroundTruth::path2, Settings::GroundTruth::path2,
// //Settings::GroundTruth::path1, Settings::GroundTruth::path1,
// //Settings::GroundTruth::path2, Settings::GroundTruth::path2,
// //Settings::GroundTruth::path_toni_inst_1, Settings::GroundTruth::path_toni_inst_1,
// //Settings::GroundTruth::path_toni_inst_2, Settings::GroundTruth::path_toni_inst_2,
// //Settings::GroundTruth::path_toni_inst_3, Settings::GroundTruth::path_toni_inst_3,
// };
const std::string path = Settings::path1a;
const std::vector<int> gtIndices = Settings::GroundTruth::path1;
WalkResult res1;
WalkResult res2;
WalkResult res3;
WalkResult res4;
// {
// EvalWiFiPaths ewp1(Settings::fMap);
// ewp1.loadModel(Settings::wifiAllFixed, "A");
// res1 = ewp1.walk(path, gtIndices);
// res1.serialize("/tmp/walk1.dat");
// }
// {
// EvalWiFiPaths ewp2(Settings::fMap);
// ewp2.loadModel(Settings::wifiEachOptParPos_multimodel, "B");
// res2 = ewp2.walk(path, gtIndices);
// res2.serialize("/tmp/walk2.dat");
// }
// {
// EvalWalk ew(map);
// ew.walk(path, gtIndices, Settings::wifiEachOptParPos_multimodel);
// ew.res.serialize("/tmp/walk3.dat");
// }
// {
// EvalWalk ew(map);
// ew.walk(path, gtIndices, Settings::wifiAllFixed);
// ew.res.serialize("/tmp/walk4.dat");
// }
res1.deserialize("/tmp/walk1.dat");
res2.deserialize("/tmp/walk2.dat");
res3.deserialize("/tmp/walk3.dat");
res4.deserialize("/tmp/walk4.dat");
PlotErrTime pet("time", "error (m)", "");
pet.getPlot().getAxisY().setRange(0, 25);
Plotty p(map);
p.buildFloorplan();
Plotty p2(map);
p2.settings.maxZ = 4.1;
p2.buildFloorplan();
K::GnuplotSplotElementLines line1; p.splot.add(&line1); line1.setTitle("\\noOptEmpiric{}"); line1.getStroke().getColor().setHexStr("#ff0000"); line1.getStroke().setType(K::GnuplotDashtype::DOTTED); line1.getStroke().setWidth(2);
K::GnuplotSplotElementLines line1b; p.splot.add(&line1b); line1b.getStroke().getColor().setHexStr("#ff0000"); line1b.getStroke().setWidth(5);
K::GnuplotSplotElementLines line2; p.splot.add(&line2); line2.setTitle("\\optPerFloor{}"); line2.getStroke().getColor().setHexStr("#0000ff"); line2.getStroke().setType(K::GnuplotDashtype::DASHED); line2.getStroke().setWidth(2);
K::GnuplotSplotElementLines line2b; p.splot.add(&line2b); line2b.getStroke().getColor().setHexStr("#0000ff"); line2b.getStroke().setWidth(5);
K::GnuplotSplotElementLines line3; p.splot.add(&line3); line3.setTitle("PF + \\optPerFloor{}"); line3.getStroke().getColor().setHexStr("#00dd00"); line3.getStroke().setWidth(2);
K::GnuplotSplotElementLines line3b; p.splot.add(&line3b); line3b.getStroke().getColor().setHexStr("#00dd00"); line3b.getStroke().setWidth(6);
K::GnuplotSplotElementLines line4; line4.setTitle("PF + \\noOptEmpiric{}");
K::GnuplotSplotElementLines line4b; line4b.getStroke().setWidth(4);
p2.splot.add(&line4); // the failing path
p2.splot.add(&line4b); // the failing path
p2.splot.add(&line1);
p2.splot.add(&line1b);
p2.splot.add(&line2);
p2.splot.add(&line2b);
p2.splot.add(&line3);
p2.splot.add(&line3b);
// ERROR OVER TIME
int ms;
// EMPIRIC
MovingAVG<float> avga1(12);
for (const WalkResult::Entry& e : res1.entries) {avga1.add(e.err); pet.addErr(e.ts, avga1.get(), 0); ms += 500;}
pet.setColor(0, "#ff0000");
pet.setLabel(0, "\\noOptEmpiric{}");
pet.getStroke(0).setType(K::GnuplotDashtype::DOTTED);
// OPT_PER_FLOOR
MovingAVG<float> avga2(12);
for (const WalkResult::Entry& e : res2.entries) {avga2.add(e.err); pet.addErr(e.ts, avga2.get(), 1); ms += 500;}
pet.setColor(1, "#0000ff");
pet.setLabel(1, "\\optPerFloor{}");
pet.getStroke(1).setType(K::GnuplotDashtype::DASHED);
// PARTICLE FILTER
MovingAVG<float> avga3(3);
for (const WalkResult::Entry& e : res3.entries) {avga3.add(e.err); pet.addErr(e.ts, avga3.get(), 2); ms += 500;}
pet.setColor(2, "#00dd00");
pet.setLabel(2, "PF + \\optPerFloor{}");
auto isOutdoor = [] (const Timestamp ts) {
return ts.sec() > 95 && ts.sec() < 119;
};
K::GnuplotCoordinate2 rFrom(92, K::GnuplotCoordinateSystem::FIRST, 0, K::GnuplotCoordinateSystem::GRAPH);
K::GnuplotCoordinate2 rTo(121, K::GnuplotCoordinateSystem::FIRST, 1, K::GnuplotCoordinateSystem::GRAPH);
K::GnuplotFill rFill(K::GnuplotFillStyle::SOLID, K::GnuplotColor::fromRGB(200,200,200));
K::GnuplotStroke rStroke = K::GnuplotStroke::NONE();
K::GnuplotObjectRectangle rect(rFrom, rTo, rFill, rStroke);
pet.getPlot().getObjects().add(&rect);
pet.getPlot().getKey().setVisible(true);
//pet.plot();
pet.getPlot().getKey().setOpaque(true);
pet.getPlot().getKey().setWidthIncrement(5.5);
pet.getPlot().getKey().setPosition(K::GnuplotKey::Hor::RIGHT, K::GnuplotKey::Ver::TOP);
pet.getPlot().getMargin().set(5, 0.2, 0.1, 2.0);
pet.getPlot().getAxisX().setTicsLabelFormat("%h s");
pet.getPlot().getAxisX().setLabel("");
pet.getPlot().getAxisY().setLabel("error (m)");
pet.getPlot().getAxisY().setLabelOffset(2.0, 0);
pet.getPlot().setStringMod(new K::GnuplotStringModLaTeX());
pet.getGP().setTerminal("epslatex", K::GnuplotSize(7.80*2, 3.0));
pet.getGP().writePlotToFile(Settings::fPathGFX + "final-error.gp");
pet.getGP().setOutput(Settings::fPathGFX + "final-error.tex");
pet.getGP() << "set label 1 '\\footnotesize{outdoor}' at first 98, graph 0.1 front\n";
pet.plot();
MovingAVG<Point3> avg1(15);
for (const WalkResult::Entry& e : res1.entries) {
avg1.add(e.estimation);
const Point3 pt = avg1.get();
const K::GnuplotPoint3 gp3(pt.x, pt.y, pt.z);
line1.add(gp3);
if (isOutdoor(e.ts)) {line1b.add(gp3);}
}
MovingAVG<Point3> avg2(15);
for (const WalkResult::Entry& e : res2.entries) {
avg2.add(e.estimation);
const Point3 pt = avg2.get();
const K::GnuplotPoint3 gp3(pt.x, pt.y, pt.z);
line2.add(gp3);
if (isOutdoor(e.ts)) {line2b.add(gp3);}
}
for (const WalkResult::Entry& e : res3.entries) {
const Point3 pt = e.estimation;
const K::GnuplotPoint3 gp3(pt.x, pt.y, pt.z);
line3.add(gp3);
if (isOutdoor(e.ts)) {line3b.add(gp3);}
}
// failing walk
for (const WalkResult::Entry& e : res4.entries) {
const Point3 pt = e.estimation;
const K::GnuplotPoint3 gp3(pt.x, pt.y, pt.z);
line4.add(gp3);
if (isOutdoor(e.ts)) {line4b.add(gp3);}
}
p.addStartIndicator(res1.entries[0].estimation, "#ff0000");
p.addStartIndicator(res2.entries[0].estimation, "#0000ff");
p.addStartIndicator(res3.entries[0].estimation, "#00cc00");
p2.addStartIndicator(res1.entries[0].estimation, "#ff0000");
p2.addStartIndicator(res2.entries[0].estimation, "#0000ff");
p2.addStartIndicator(res3.entries[0].estimation, "#00cc00");
p2.addStartIndicator(res4.entries[0].estimation, "#000000");
p.splot.getCustom() << "set view equal xy\n";
p.splot.getCustom() << "unset border\n";
p.splot.getMargin().set(1, 0,0,0);
p.splot.getAxisX().setTicsVisible(false);
p.splot.getAxisY().setTicsVisible(false);
p.splot.getAxisZ().setTicsVisible(false);
p.splot.getAxisZ().setRange(K::GnuplotAxis::Range(-8, 19.5));
p.splot.getView().setCamera(74,30);
p.splot.getView().setScaleAll(3.9);
p.splot.getKey().setVisible(true);
p.splot.getKey().setSampleLength(0.5);
p.splot.getKey().setWidthIncrement(4.5);
p.splot.setStringMod(new K::GnuplotStringModLaTeX());
p.splot.getKey().setOpaque(true);
//p.splot.getKey().setPosition(K::GnuplotCoordinate2(0.2, 1.0, K::GnuplotCoordinateSystem::SCREEN));
p.splot.getKey().setPosition(K::GnuplotCoordinate2(1.0, 1.0, K::GnuplotCoordinateSystem::SCREEN));
p.gp.setTerminal("epslatex", K::GnuplotSize(8.3, 4.8));
p.gp.writePlotToFile(Settings::fPathGFX + "final3D.gp");
p.gp.setOutput(Settings::fPathGFX + "final3D.tex");
p.plot();
p2.splot.getCustom() << "set view equal xy\n";
p2.splot.getCustom() << "unset border\n";
p2.splot.getMargin().set(1, 0,0,0);
p2.splot.getAxisX().setTicsVisible(false);
p2.splot.getAxisY().setTicsVisible(false);
p2.splot.getAxisZ().setTicsVisible(false);
p2.splot.getAxisZ().setRange(K::GnuplotAxis::Range(-8, 19.5));
p2.splot.getView().setCamera(74,30);
p2.splot.getView().setScaleAll(3.9);
p2.splot.getKey().setVisible(true);
p2.splot.getKey().setSampleLength(0.5);
p2.splot.getKey().setWidthIncrement(4.5);
p2.splot.setStringMod(new K::GnuplotStringModLaTeX());
// only list the additional line within the key
line1.setTitle("");
line2.setTitle("");
line3.setTitle("");
p2.splot.getKey().setVisible(true);
p2.splot.getKey().setPosition(K::GnuplotCoordinate2(0.71, 0.35, K::GnuplotCoordinateSystem::SCREEN));
p2.splot.getView().setCamera(0,0);
p2.splot.getView().setScaleAll(4.0);
p2.gp.setTerminal("epslatex", K::GnuplotSize(8.3, 4.8));
p2.gp.writePlotToFile(Settings::fPathGFX + "final2D.gp");
p2.gp.setOutput(Settings::fPathGFX + "final2D.tex");
p2.setScale(1,1, 0.02, -0.04);
p2.plot();
int i = 0;
(void) i;
}
int main(void) {
//Toni::run();
//return 0;
compareAll();
//Toni::run();
return 0;
Floorplan::IndoorMap* map = Floorplan::Reader::readFromFile(Settings::fMap);
@@ -973,7 +1223,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");
@@ -1072,7 +1322,7 @@ int main(void) {
// }
// walks
if (1 == 1) {
if (1 == 0) {
Floorplan::IndoorMap* map = Floorplan::Reader::readFromFile(Settings::fMap);;
//EvalWalk walk(map);
//walk.walk1();
@@ -1312,5 +1562,4 @@ int main(void) {
pef.plot();
}
}

View File

@@ -11,6 +11,7 @@
#include <KLib/math/filter/particles/resampling/ParticleFilterResamplingNEff.h>
#include "../plots/PlotErrFunc.h"
#include "../WalkResult.h"
#include <thread>
@@ -45,7 +46,7 @@
#include <Indoor/sensors/offline/Listener.h>
//#define PLOT_LIVE
#define PLOT_LIVE
//#define PLOT_WIFI
//#define PLOT_ERROR_TIME
//#define PLOT_ERROR_FUNC
@@ -102,6 +103,8 @@ class EvalWalk : public Offline::Listener {
public:
WalkResult res;
~EvalWalk() {
delete grid;
delete pf;
@@ -487,6 +490,42 @@ public:
}
void walk(const std::string& path, const std::vector<int> pathPoints, const std::string& model) {
absHead = 0;
runName = "";
// get ground-truth
groundTruth = FloorplanHelper::getGroundTruth(map, pathPoints);
// wifi model
//WiFiModelLogDistCeiling wifiModel(map);
//wifiModel.loadXML(Settings::wifiAllFixed);
//wifiModel.loadXML(Settings::wifiEachOptParPos);
//WiFiModelPerFloor wifiModel(map);
//wifiModel.loadXML(Settings::wifiEachOptParPos_multimodel);
//WiFiModelPerBBox wifiModel(map);
//wifiModel.loadXML(model);
WiFiModelFactory fac(map);
WiFiModel* wifiModel = fac.loadXML(model);
// eval
std::unique_ptr<PFEval> eval = std::unique_ptr<PFEval>( new PFEval(grid, *wifiModel, em) );
pf->setEvaluation( std::move(eval) );
// data-file
reader.open(path);
groundTruthLive = reader.getGroundTruth(map, pathPoints);
player.setReader(&reader);
player.setListener(this);
player.start();
// wait for completion
player.join();
}
@@ -654,11 +693,20 @@ private:
const Point3 curGT = groundTruthLive.get(lastTransition);
// error between ground-truth and estimation
const float estRealErr = curEst.position.inMeter().getDistance(curGT);
WalkResult::Entry e;
e.ts = lastTransition;
e.estimation = curEst.position.inMeter();
e.groundTruth = curGT;
e.err = estRealErr;
this->res.entries.push_back(e);
// start the error-over-time plot after some filter updates
if (updateCount > 12) {
// error between ground-truth and estimation
const float estRealErr = curEst.position.inMeter().getDistance(curGT);
statsErr.add(estRealErr);
#ifdef PLOT_ERROR_FUNC

View File

@@ -58,6 +58,10 @@ public:
lineErr[idx].getStroke().setWidth(w);
}
K::GnuplotStroke& getStroke(const int idx) {
return lineErr[idx].getStroke();
}
K::Gnuplot& getGP() {
return gp;
}

View File

@@ -342,6 +342,29 @@ public:
splot.getObjects().add(poly);
}
K::GnuplotObjectPolygon* addStartIndicator(const Point3 pt, const std::string& color) {
// for (const Point3 p : points) {
// if (p.z < settings.minZ) {return nullptr;}
// if (p.z > settings.maxZ) {return nullptr;}
// }
const float s = 2.0;
K::GnuplotObjectPolygon* poly = new K::GnuplotObjectPolygon();
poly->setFill(K::GnuplotFill(K::GnuplotFillStyle::SOLID, K::GnuplotColor::fromHexStr(color)));
poly->setStroke(K::GnuplotStroke(K::GnuplotDashtype::SOLID, 1, K::GnuplotColor::fromRGB(0,0,0)));
//poly->setStroke(K::GnuplotStroke::NONE());
poly->add(K::GnuplotCoordinate3(pt.x-s, pt.y-s, pt.z, K::GnuplotCoordinateSystem::FIRST));
poly->add(K::GnuplotCoordinate3(pt.x+s, pt.y-s, pt.z, K::GnuplotCoordinateSystem::FIRST));
poly->add(K::GnuplotCoordinate3(pt.x+s, pt.y+s, pt.z, K::GnuplotCoordinateSystem::FIRST));
poly->add(K::GnuplotCoordinate3(pt.x-s, pt.y+s, pt.z, K::GnuplotCoordinateSystem::FIRST));
poly->close();
poly->setFront(true);
splot.getObjects().add(poly);
return poly;
}
K::GnuplotObjectPolygon* addPolygon(const std::vector<Point3>& points, const std::string& color, bool front = false, bool fill = true, const float alpha = 1) {
for (const Point3 p : points) {

View File

@@ -1,7 +1,5 @@
\section{Conclusion and Future Work}
\todo{ueberleitung?}
As denoted within the previous evaluations and discussions, the accuracy of
indoor localization systems based on \docWIFI{} depends on a manifold
of parameters and even minor adjustments can yield visible improvements.
@@ -33,12 +31,19 @@
be able to reduce the remaining maximum error, which remains for some locations, at the cost of additional computations.
Special data-structures for pre-computation combined with online interpolation might
be a viable choice for utmost accuracy that is still able to run on
a commodity smartphone in realtime.
a commodity smartphone in real-time.
While we were able to improve the performance of the \docWIFI{} sensor component,
the filtering process should be more robust against erroneous observations.
Getting stuck should be prevented, independent of minor changes in quality for
the signal strength prediction model \cite{todo-toni}.
\commentByFrank{cite auf toni?!}
Our \docWIFI{} quality metric often was able to determine situations that
would yield multimodal or bad \docWIFI{} estimations and temporarily
ignoring this sensor prevented additional errors. Still, there were some
cases where the metric failed to correctly determine a potentially bad
observation, which leaves room for future improvements.
%100 prozent optimierung ist nicht moeglich, es gibt

View File

@@ -2,6 +2,14 @@
% intro
\todo{reihenfolge so jetzt klar?}
Within our experiments we will first have a look at model optimizations to reduce the error
between model predictions and real-world conditions.
Hereafter we examine the resulting accuracy when using the optimized models for localization
using just the \docWIFI{} component without additional sensors or assumptions.
Finally, all models are evaluated in the context of our indoor localization system \refeq{eq:recursiveDensity},
using additional smartphone sensors and the building's floorplan.
All optimizations and evaluations took place within two adjacent buildings (4 and 2 floors, respectively)
and two connected outdoor regions (entrance and inner courtyard),
\SI{110}{\meter} x \SI{60}{\meter} in size.
@@ -29,15 +37,18 @@
\subsection{Model optimization}
As the signal strength prediction model is the core of the absolute positioning component
described in section \ref{sec:system}, we start with the model parameter estimation (see \ref{sec:optimization}) for
\mTXP{}, \mPLE{} and \mWAF{} based on some reference measurements and compare the results
between various optimization strategies and a basic empiric choice of \mTXP{} = \SI{-40}{\decibel{}m} @ \SI{1}{\meter}
(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}.
described in section \ref{sec:system}, we start with the model parameter optimization (see \ref{sec:optimization}).
\mTXP{}, \mPLE{} and \mWAF{} will be estimated based on some reference measurements using
various optimization strategies. The results of those optimization strategies are compared
with each other and an empiric parameter choice:
\mTXP{} = \SI{-40}{\decibel{}m} @ \SI{1}{\meter}
(defined by the usual \docAPshort{} transmit power for Europe), a path loss exponent $\mPLE{} = 2.5$ and
$\mWAF{} = \SI{-8}{\decibel}$ per floor/ceiling (made of reinforced concrete)
\cite{PathLossPredictionModelsForIndoor, ElectromagneticPropagation, ANewPathLossPrediction}.
\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})
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.
\begin{figure}
@@ -53,8 +64,8 @@
\begin{subfigure}[t!]{0.48\textwidth}
\input{gfx2/model-bboxes.tex}
\caption{
More than one bounding box is needed for each model to approximate the building's shape.
Each distinct floor-color denotes a single model (7 in total).
Each distinct floor-color denotes one model (7 in total) for {\em \optPerRegion{}}.
Often, more than one bounding box is needed to approximate the region's shape.
}
\label{fig:modelBBoxes}
\end{subfigure}
@@ -84,8 +95,8 @@
\input{gfx/compare-wifi-in-out.tex}
\caption{
Measurable signal strengths of a testing \docAPshort{} (black dot).
While the signal diminishes slowly along the corridor (upper rectangle)
the metallised windows (dashed outline) attenuate the signal by over \SI{30}{\decibel} (lower rectangle).
While the signal diminishes slowly along the corridor (wide rectangle)
the metallized windows (dashed outline) attenuate the signal by over \SI{30}{\decibel} (small rectangle).
}
\label{fig:wifiIndoorOutdoor}
\end{figure}
@@ -93,28 +104,42 @@
\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}
of corridor (wide box). The model described in section \ref{sec:sigStrengthModel} will not be able
measurement (small box), the metallized windows attenuate the signal as much as \SI{50}{\meter}
of corridor (wide rectangle). The model described in section \ref{sec:sigStrengthModel} will not be able
to match such situations, due to the lack of obstacle information.
%
We will thus look at various optimization strategies and the error between
the resulting estimation model and our reference measurements:
{\em\noOptEmpiric{}} uses the same three empiric parameters \mTXP{}, \mPLE{}, \mWAF{} for each \docAPshort{} in combination
with its position, which is well known from the floorplan.
\begin{itemize}
{\em\optParamsAllAP{}} is the same as above, except that the three parameters are optimized
using the reference measurements. However, all transmitters share the same three parameters.
\item{
{\em\noOptEmpiric{}} uses the same three empiric parameters \mTXP{}, \mPLE{}, \mWAF{} for each \docAPshort{} in combination
with its position, which is well known from the floorplan.
}
{\em\optParamsEachAP{}} optimizes the three parameters per \docAP{} instead of using the same
parameters for all.
\item{
{\em\optParamsAllAP{}} is the same as above, except that the three parameters are optimized
using the reference measurements. However, all transmitters share the same three parameters.
}
{\em\optParamsPosEachAP{}} does not need any prior knowledge and will optimize all six parameters
(3D position, \mTXP, \mPLE, \mWAF) based on the reference measurements.
\item{
{\em\optParamsEachAP{}} optimizes the three parameters per \docAP{} instead of using the same
parameters for all.
}
{\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 \reffig{fig:modelBBoxes}.
\item{
{\em\optParamsPosEachAP{}} does not need any prior knowledge and will optimize all six parameters
(3D position, \mTXP, \mPLE, \mWAF) based on the reference measurements.
}
\item{
{\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 \reffig{fig:modelBBoxes}.
}
\end{itemize}
\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.
@@ -154,7 +179,7 @@
\caption{
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.
The higher the number of variable parameters, the better the model resembles real-world conditions.
}
\label{fig:wifiModelError}
\end{figure}
@@ -164,19 +189,19 @@
\begin{figure}
\begin{subfigure}{0.32\textwidth}
\centering
\input{gfx/wifiMaxErrorNN_opt0.tex}
\input{gfx2/wifiMaxErrorNN_opt0.tex}
\caption{\em \noOptEmpiric{}}
\label{fig:wifiModelErrorMaxA}
\end{subfigure}
\begin{subfigure}{0.32\textwidth}
\centering
\input{gfx/wifiMaxErrorNN_opt3.tex}
\input{gfx2/wifiMaxErrorNN_opt3.tex}
\caption{\em \optParamsPosEachAP{}}
\label{fig:wifiModelErrorMaxB}
\end{subfigure}
\begin{subfigure}{0.32\textwidth}
\centering
\input{gfx/wifiMaxErrorNN_opt5.tex}
\input{gfx2/wifiMaxErrorNN_opt5.tex}
\caption{\em \optPerRegion{}}
\label{fig:wifiModelErrorMaxC}
\end{subfigure}
@@ -277,7 +302,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
estimation error for all other positions (hallway, etc.) as expected, the error within the skipped locations is dramatically
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.
@@ -466,6 +491,8 @@
as likely as the pedestrian's actual location, we examined various approaches.
Unfortunately, most of which did not provide a viable enhancement under all conditions for the performed walks.
\commentByFrank{ja, eig gehoert das vor in die theorie, aber da es so kurz ist und vorne immer die ueberleitung kaputt macht
oder anderen dingen vorgreifen wuerde, steht es hier}
The misclassification-rate is determined by counting the amount of (random) locations within
the building that produce a similar probability \refeq{eq:wifiProb} as the actual ground-truth
position.
@@ -514,7 +541,7 @@
for areas where a transmitter was hardly seen within the reference measurements and its optimization is thus
expected to be inaccurate.
Using a smaller $\sigma$ or a more strict exponential distribution for the model vs. scan comparison in \refeq{eq:wifiProb}
Using a smaller $\sigma$ or a stricter exponential distribution for the model vs. scan comparison in \refeq{eq:wifiProb}
had a positive effect on the misclassification error for some of the walks, but also slightly increased the overall estimation error.
%(see figure \ref{fig:normalVsExponential}).
Due to those negative side-effects, the final localization system (\refeq{eq:recursiveDensity}) is unlikely to profit from such changes.
@@ -546,13 +573,13 @@
% -------------------------------- final system -------------------------------- %
\subsection{System error using filtering}
\subsection{Filtered location estimation error}
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
Due to transition constraints from the building's floorplan, we expect the
posterior density to often get stuck when the \docWIFI{} component provides erroneous estimations
due to bad signal strength predictions or observations (see \reffig{fig:wifiMultimodality}):
@@ -573,40 +600,44 @@
resulting from all executions for each walk conducted with the smartphone.
While most values represent the expected results (more optimization yields better results),
the values for {\em \noOptEmpiric{}} and {\em \optPerRegion{}} do not.
The slightly increased error for both strategies can be explained by having a closer look at the walked
the values for {\em \optParamsAllAP{}} and {\em \optPerRegion{}} do not.
The increased error for both strategies can be explained by having a closer look at the walked
paths and relates to exceptional regions like outdoors. In both cases there is some sort of model overadaption.
%
As mentioned earlier, {\em \noOptEmpiric{}} is unable to accurately model the signal strength for the whole
building, resulting in increased estimation errors for outdoor regions, where the filter fails to conclude
the walk.
As mentioned earlier, a single, simple model is unable to accurately estimate the signal strength for both
buildings and adjacent outdoor regions. Due to metallized glass (see \reffig{fig:wifiIndoorOutdoor}), in- and
outdoor conditions strongly differ. The model's optimization
builds a compromise among all locations and renders indoor places unnecessarily bad: Previous
discussions showed that outdoor regions do not provide viable \docWIFI{} signals at all. It thus makes sense
to just omit badly covered regions from the model optimization process, as the filter's evaluation will simply
omit \docWIFI{} when the quality is insufficient (see section \ref{sec:wifiQuality}).
%
While {\em \optPerRegion{}} does not suffer from such issues due to separated optimization regions for in- and outdoor,
its increased error relates to movements between such adjacent regions, as there often is a huge model difference.
While this difference is perfectly fine, as it also exists within real world conditions,
the filtering process suffers especially at such model-boundaries:
While this difference is perfectly fine, as it also exists within real-world conditions,
the filtering process suffers at such model-boundaries:
The model prevents the particles from moving e.g. from inside the building towards outdoor regions, as the
outdoor-model does not match at all. Due to sensor delays and issues with the absolute heading near in- and outdoor boundaries
outdoor-model does not yet match. Due to sensor delays and issues with the absolute heading near in- and outdoor boundaries
(metal-framed doors) the error is slightly increased and retained for some time until the density stabilizes itself.
Such situations should be mitigated by the smartphone's GPS sensor. However, within our testing walks, the GPS
did rarely provide accurate measurements, as the outdoor-time was too short for the sensor to receive a valid
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 \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.
Additionally increasing the number of particles from 5000 to 10000 indicated only a minor increase in accuracy and slightly decreased
the risk of getting stuck. For battery- and performance-constrained use-cases on the smartphone 5000 thus seems to be a sufficient.
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 \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
keep the pedestrian's current heading until the signal quality reached sane levels again.
Issues while moving from the inside out, or vice versa, should also be mitigated by incorporating the smartphone's GPS sensor.
However, within our testing walks, the GPS did rarely provide accurate measurements, as the outdoor-time often was too short
for the sensor to receive a valid fix. The accuracy indicated by the GPS usually was $\ge \SI{50}{\meter}$ and thus
did not provide usefull information.
However, comparing the error results within \reffig{fig:modelPerformance} and \reffig{fig:overallSystemError}, one can
denote the positive impact of fusing multiple sensors with a transition model based on the building's
actual floorplan. Even within outdoor regions and staircases that suffer from erroneous \docWIFI{} estimations due to a bad
signal strength coverage. The quality metric described in section \ref{sec:wifiQuality} was able to detect such
cases and \docWIFI{} was temporarily ignored. The remaining sensors, like the IMU, and the floorplan were able to
keep the pedestrian's heading until the signal quality reached sane levels again.
\begin{figure}
\begin{subfigure}{0.49\textwidth}
@@ -640,11 +671,52 @@
%
\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.
Especially {\em \optParamsAllAP{}} suffered from overadaption and thus provided worse results. Compared to just using \docWIFI{}
(\reffig{fig:modelPerformance}) the error difference between the models now is much more pronounced.
Starting from {\em \optParamsEachAP{}} the system rarely gets stuck and provides a viable accuracy.
}
\label{fig:overallSystemError}
\end{figure}
Finally, \reffig{fig:final} depicts all of the previously discussed improvements and issues by examining {\em path 1}
from \reffig{fig:allWalks}.
For better visibility within path- and error-plots, the non filtered estimations were smoothed using a moving average of
ten consecutive values ($\approx \SI{7}{\second}$). As can be seen, optimizing the \docWIFI{} model yields an improvement
for indoor situations, as the estimation is closer to the ground truth, and the starting position (indicated by the rectangle)
is more accurate.
For the depicted walk, the error outdoors is increased, as the likeliest position is shifted. Adding
the particle filter (\refeq{eq:recursiveDensity}) on top of the optimized model fixes this issue. What cannot be seen
within the images: while the likeliest position is deteriorated by the optimization, the likelihood of the region around
the pedestrian's ground truth actually is increased. Thus, combined with transition model and other sensors, the system
is able to stay right on track. The filter fails for {\em \noOptEmpiric}, as one \docAPshort{} near the entry of the second
building prevents the density from entering due to a very high difference between model and real-world conditions.
\begin{figure}
\begin{subfigure}{0.49\textwidth}
\centering
\input{gfx/final3D.tex}
\end{subfigure}
\begin{subfigure}{0.49\textwidth}
\centering
\input{gfx/final2D.tex}
\end{subfigure}
\\
\begin{subfigure}{0.99\textwidth}
\input{gfx/final-error.tex}
\end{subfigure}
\caption{
Detailed analysis of the \docWIFI{} error for {\em \noOptEmpiric{}} (unoptimized) and {\em \optPerFloor{}}
using {\em path 1} (see \reffig{fig:allWalks}). While optimization reduces the error indoors, the error outdoors
is increased (bold line). A particle filter (PF, \refeq{eq:recursiveDensity}) on top of the optimized model
takes \SI{5}{\second} to initialize the starting-position (rectangles), fixes the outdoor-issue and
improves indoor situations. A filter on top of {\em \noOptEmpiric{}} got stuck right before
entering the 2nd building.
}
\label{fig:final}
\end{figure}
% results
% 5000 particles
%

View File

@@ -1,7 +1,7 @@
\section{Related Work}
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
2000 and the work of Bahl and Padmanabhan \cite{radar}. During a 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.
The pedestrian's location is inferred using the $k$-nearest neighbor(s) based on the Euclidean distance between currently
@@ -21,21 +21,21 @@
distorted measurements and thus improve the matching process.
Despite a very high accuracy due to real-world comparisons, aforementioned approaches suffer from tremendous setup-
and maintainance times.
and maintenance times.
Using robots instead of human workforce to accurately gather the necessary
fingerprints might thus be a viable choice \cite{robotFingerprinting}.
Being cheaper and more accurate, this technique can also
be combined with SLAM for cases where the floorplan is unavailable.
Besides using real world measurements via fingerprinting, model predictions can be used to determine
signal strengths for arbitrary locations. Propagation models are a well established field of research,
Besides using real-world measurements via fingerprinting, model predictions can be used to determine
signal strengths for arbitrary locations. Propagation models are a well-established field of research,
initially used to determine the \docWIFI{}-coverage for new installations.
While many of them are intended for outdoor and line-of-sight purposes, they are often applied to indoor use-cases as well
\cite{ANewPathLossPrediction, PredictingRFCoverage, empiricalPathLossModel}.
The model-based approach presented by Chintalapudi et al. \cite{WithoutThePain} works without any prior knowledge.
During a setup phase, pedestrians just walk within the building and transmit all observations to a central
server. Some GPS fixes with well known position (e.g. entering and leaving the building) observed by the pedestrians
server. Some GPS fixes with well-known position (e.g. entering and leaving the building) observed by the pedestrians
are used as reference points. A genetic optimization algorithm hereafter estimates both, the parameters for a
signal strength prediction model and the pedestrian's locations during the walk. The estimated parameters
can be refined using additional walks and may hereafter be used for the indoor localization process.
@@ -55,7 +55,7 @@
We therefore focus on the 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.
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.

View File

@@ -3,7 +3,7 @@
The \docWIFI{} sensor infers the pedestrian's current location based on a comparison between live observations
(the smartphone continuously scans for nearby \docAP{}s) and fingerprints or
signal strength predictions for well known locations. The location that fits the observations best,
signal strength predictions for well-known locations. The location that fits the observations best,
is the pedestrian's current location. Assuming statistical independence of all transmitters
installed within a building, this matching probability can be written as
@@ -63,11 +63,11 @@
like one floor, solely divided by drywalls of the same thickness and material.
%
The log normal shadowing-, or wall-attenuation-factor model \cite{PathLossPredictionModelsForIndoor}
is a slight modification, to adapt the log distance model to indoor use cases.
is a slight modification, to adapt the log distance model to indoor use-cases.
It introduces an additional parameter, that considers obstacles between (line-of-sight) the \docAPshort{} and the
location in question by attenuating the signal with a constant value.
%
Depending on the use case, this value describes the number and type of walls, ceilings, floors etc. between both positions.
Depending on the use-case, this value describes the number and type of walls, ceilings, floors etc. between both positions.
For obstacles, this requires an intersection-test of each obstacle with the line-of-sight, which is costly
for larger buildings. For real-time use on a smartphone, a (discretized) model pre-computation might thus be necessary
\cite{competition2016}.
@@ -76,7 +76,7 @@
Throughout this work, we thus use a tradeoff between both models, where walls are ignored and only floors/ceilings are considered.
Assuming buildings with even floor levels, the number of floors/ceilings between two position can be determined
without costly intersection checks and thus allows for real-time use cases running on smartphones.
without costly intersection checks and thus allows for real-time use-cases running on smartphones.
\begin{equation}
\mRssi = \mTXP{} + 10 \mPLE{} + \log_{10} \frac{d}{d_0} + \numFloors{} \mWAF{} + \mGaussNoise{}
@@ -92,14 +92,14 @@
\subsection {Model Parameters}
As previously mentioned, for the prediction model to work, one needs to know the location $\mPosAPVec_i$ for every
As previously mentioned, for the prediction model to work, it is necessary to know the location $\mPosAPVec_i$ for every
permanently installed \docAP{} $i$ within the building to derive the distance $d$, plus its environmental parameters
\mTXP{}, \mPLE{} and \mWAF{}.
While it is possible to use empiric values for those environmental parameters \cite{Ebner-15}, the positions are mandatory.
For many buildings, there should be floorplans that include the locations of all installed transmitters.
If so, a model setup takes only several minutes to (vaguely) position the \docAPshort{}s within a virtual
map and assigning them some fixed, empirically chosen parameters for \mTXP{}, \mPLE{} and \mWAF{}.
map and assign some fixed, empirically chosen parameters for \mTXP{}, \mPLE{} and \mWAF{}.
Depending on the building's architecture this might already provide enough accuracy for some use-cases,
where a vague location information is sufficient.
@@ -119,7 +119,7 @@
For systems that demand a higher accuracy, one can choose a compromise between fingerprinting and
aforementioned pure empiric model parameters by optimizing those parameters
based on a few reference measurements throughout the building.
Obviously, the more parameters are staged for optimization ($\mPosAPVec{}, \mTXP{}, \mPLE{}, \mWAF{}$) the more
The more parameters are staged for optimization ($\mPosAPVec{}, \mTXP{}, \mPLE{}, \mWAF{}$) the more
reference measurements are necessary to provide a stable result.
Depending on the desired accuracy, setup time and whether the transmitter positions are known or unknown,
several optimization strategies arise, where not all 6 parameters are optimized, but only some of them.
@@ -142,10 +142,10 @@
Just optimizing \mTXP{} and \mPLE{} with constant \mWAF{} and known transmitter position
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.
are well suited and will provide the global minimum.
However, optimizing an unknown transmitter position usually means optimizing a non-convex, discontinuous
function, especially when the $z$-coordinate, that influences the number of attenuating floors / ceilings,
function, especially when the $z$-coordinate, that influences the number of attenuating floors/ceilings,
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.
@@ -188,18 +188,19 @@
% \label{fig:wifiOptFuncPosYZ}
%\end{figure}
Such functions demand for optimization algorithms, that are able to deal with non-convex functions,
like genetic approaches. However, initial tests indicated that while being superior to simplex
and similar algorithms, the results were not satisfactorily and the optimization often did not converge.
Such functions demand for optimization algorithms, that are able to deal with non-convex functions.
We thus used a genetic algorithm to perform this task.
However, initial tests indicated that while being superior to simplex
and similar algorithms, the results were not yet satisfying as the optimization often did not converge.
As the Range of the six to-be-optimized parameters is known ($\mPosAPVec{}$ within the building,
\mTXP{}, \mPLE{}, \mWAF{} within a sane interval around empiric values), we used some modifications.
The algorithms initial population is uniformly sampled from the known range. During each iteration
As the range of the six to-be-optimized parameters is known ($\mPosAPVec{}$ within the building,
\mTXP{}, \mPLE{}, \mWAF{} within a sane interval around empiric values), we slightly modified the
genetic algorithm: The initial population is now uniformly sampled from the known range. During each iteration,
the best \SI{25}{\percent} of the population are kept and the remaining entries are
re-created by modifying the best entries with uniform random values within
$\pm$\SI{10}{\percent} of the known range. To stabilize the result, the allowed modification range
$\pm$\SI{10}{\percent} of the known range. The result is stabilized by narrowing the allowed modification range
%(starting at \SI{10}{\percent})
is reduced over time, often referred to as {\em cooling} \cite{Kirkpatrick83optimizationby}.
over time, often referred to as {\em cooling} \cite{Kirkpatrick83optimizationby}.
\subsection{Modified Signal Strength Model}
@@ -215,30 +216,39 @@
%the inferred location was more erroneous than before.
As the used model tradeoff does not consider walls, it is expected to provide erroneous values
for regions that are heavily shrouded, e.g. by steel-enforced concrete or metallised glass.
for regions that are heavily shrouded, e.g. by steel-enforced concrete or metallized glass.
Instead of using only one optimized model per \docAP{}, we use several instances with different
parameters that are limited to some region within the building. By reducing the area
that the model has to describe, we expect the limited number of model parameters to
provide better (local) results.
{\em \optPerFloor{}} will use one model for each story, that is optimized using
only the fingerprints that belong to the corresponding floor. During evaluation,
the $z$-value from $\mPosVec{}$ in \refeq{eq:wifiProb} is used to select the correct model
for this location's signal strength estimation.
\begin{itemize}
{\em \optPerRegion{}} works similar, except that each model is limited to a predefined,
axis-aligned bounding box. This approach allows for an even more refined distinction between
several areas like in- and outdoor-regions or locations that are expected to highly differ
from their surroundings.
\item{
{\em \optPerFloor{}} will use one model for each story, that is optimized using
only the fingerprints that belong to the corresponding floor. During evaluation,
the $z$-value from $\mPosVec{}$ in \refeq{eq:wifiProb} is used to select the correct model
for this location's signal strength estimation.
}
\item{
{\em \optPerRegion{}} works similar, except that each model is limited to a predefined,
axis-aligned bounding box. This approach allows for an even more refined distinction between
several areas like in- and outdoor regions or locations that are expected to highly differ
from their surroundings.
}
\end{itemize}
Especially the second model imposes a potential issue we need to address:
If an \docAPshort{} is seen only once or twice within such a bounding box, it is impossible
to optimize its parameters, just like a line can not be defined using one single point.
to optimize its parameters, just like a line cannot be defined using one single point.
However, due to \refeq{eq:wifiProb}, we need each model to provide the same number of
\docAP{}s. Otherwise regions with less known transmitters would automatically be more
likely than others. We therefore use fixed model parameters,
\mTXP = \SI{-100}{\decibel{}m}, \mPLE = 0 and \mWAF = \SI{0}{\decibel}. This yields
$\mTXP = \SI{-100}{\decibel{}m}$, $\mPLE = 0$ and $\mWAF = \SI{0}{\decibel}$ for every
transmitter with less than three reference measurements per region. This yields
a model that always returns \SI{-100}{\decibel{}m}, independent of the distance from the transmitter.
While this most probably is not the correct reading for all locations, it works
for most cases, as usual smartphones are unable to measure signals below this threshold.
@@ -250,10 +260,10 @@
\label{sec:wifiQuality}
Evaluations within previous works showed, that there are many situations where the overall \docWIFI{} location estimation
is highly erroneous. Either when the signal strength prediction model does not match real world
is highly erroneous. Either when the signal strength prediction model does not match real-world
conditions or the received measurements are ambiguous and there is more than one location
within the building that matches those readings. Both cases can occur e.g. in areas surrounded by
concrete walls, where the model does not match the real world conditions as those walls are not considered,
concrete walls, where the model does not match the real-world conditions as those walls are not considered,
and the smartphone barely receives \docAPshort{}s due to the high attenuation.
If such a sensor error occurs only for a short time period, the recursive density estimation from
@@ -267,32 +277,34 @@
temporarily disabling \docWIFI{}'s contribution within the evaluation \refeq{eq:evalDensity}
if the quality is insufficient.
In \refeq{eq:wifiQuality} we use the average signal strength of all \docAP{}s seen within one measurement
and scale this value to match a region of $[0, 1]$ depending on an upper- and lower bound.
In \refeq{eq:wifiQuality} we use the average signal strength $\bar\mRssi$ among all \docAP{}s seen within one measurement
$\mRssiVec$ and scale this value to match a region of $[0, 1]$ depending on an upper and lower bound.
If the returned quality is below a certain threshold, \docWIFI{} is ignored within the evaluation.
\begin{equation}
\newcommand{\leMin}{l_\text{min}}
\newcommand{\leMax}{l_\text{max}}
\text{quality}(\mRssiVec) =
\max(0,
\min(
\max \left(0,
\min \left(
\frac{
\bar\mRssi - \leMin
}{
\leMax - \leMin
},
1
)
)
\right)
\right)
,\enskip
\bar\mRssi = \frac{1}{n} \sum_{i = 1}^{n} \mRssi_i
\label{eq:wifiQuality}
\end{equation}
\subsection {VAP grouping}
\subsection {Virtual \docAP{}s}
\label{sec:vap}
Assuming normal conditions, the received signal strength at one location will also (strongly) vary over time
due to environmental conditions like temperature, humidity, open / closed doors and RF interference.
due to environmental conditions like temperature, humidity, open/closed doors and RF interference.
Fast variations can be addressed by averaging several consecutive measurements at the expense
of a delay in time.
To prevent this delay we use the fact, that many buildings use so called virtual access points

View File

@@ -69,7 +69,7 @@ public:
//splot.setTitle("optimizing TXP and EXP}");
splot.getAxisX().setLabel("TXP (dBm)");
splot.getAxisX().setLabelOffset(-3.9, -1.9);
splot.getAxisX().setLabelOffset(-3.9 + 1.5, -1.9);
splot.getAxisX().setTicsStep(2.5);
splot.getAxisX().setTicsOffset(-1, -0.1);
@@ -87,15 +87,19 @@ public:
std::string name = Settings::fPathGFX + "/wifiop_show_optfunc_params";
gp.setOutput(name + ".tex");
gp.setTerminal("epslatex", K::GnuplotSize(8.7, 5.0));
gp.setTerminal("epslatex", K::GnuplotSize(7.7, 4.5));
splot.getAxisZ().setTicsVisible(false);
splot.getAxisZ().setLabel("");
gp << "set palette defined (0 '#00ff00', 1 '#eeeeee', 9 '#222222')\n";
gp << "set margins 0,0,0,0\n";
gp << "set multiplot layout 1,1 scale 1.25, 1.4 offset 0.02, 0.05\n";
gp << "set multiplot layout 1,1 scale 1.25, 1.4 offset -0.04, 0.05\n";
gp << "set colorbox horizontal user origin 0.03, 0.95 size 0.4, 0.03\n";
//gp << "set pm3d implicit\n";
//gp << "set hidden3d front\n";
//p mac="D8:84:66:4A:23:F0" px="46" py="47.400002" pz="13.8" txp="-40" exp="2.6500001" waf="-6.5"/>
const MACAddress mac("D8:84:66:4A:23:F0");
const Point3 pos_m(46, 47.4, 13.8);
@@ -176,19 +180,19 @@ public:
K::Gnuplot gp;
K::GnuplotSplot splot;
K::GnuplotSplotElementMesh mesh; splot.add(&mesh);
K::GnuplotSplotElementLines lines1; splot.add(&lines1); lines1.getStroke().setWidth(2); lines1.getStroke().setType(K::GnuplotDashtype::DOTTED);
K::GnuplotSplotElementLines lines2; splot.add(&lines2); lines2.getStroke().setWidth(2); lines2.getStroke().setType(K::GnuplotDashtype::DASHED);
K::GnuplotSplotElementLines lines1; splot.add(&lines1); lines1.getStroke().setWidth(1); lines1.getStroke().getColor().setHexStr("#444444"); lines1.getStroke().setType(K::GnuplotDashtype::DOTTED);
K::GnuplotSplotElementLines lines2; splot.add(&lines2); lines2.getStroke().setWidth(1); lines2.getStroke().getColor().setHexStr("#444444"); //lines2.getStroke().setType(K::GnuplotDashtype::DASHED);
K::GnuplotSplotElementLines lines3; splot.add(&lines3); lines3.getStroke().setWidth(2);
K::GnuplotSplotElementPoints points; splot.add(&points); points.setPointSize(1.5); points.setPointType(7);
//splot.setTitle("optimizing position");
splot.getAxisX().setLabel("y-pos (meter)");
splot.getAxisX().setLabelOffset(-0.9, -1.4);
splot.getAxisX().setLabelOffset(-0.9 + 0.2, -1.4 - 0.5);
splot.getAxisX().setTicsOffset(-0.9, 0);
splot.getAxisX().setTicsStep(25);
splot.getAxisY().setLabel("z-pos (meter)");
splot.getAxisY().setLabelOffset(0, -0.3);
splot.getAxisY().setLabelOffset(-0.3, -0.3 - 0.3);
splot.getAxisY().setTicsOffset(0, -0.5);
splot.getAxisY().setTicsStep(3);
@@ -203,11 +207,12 @@ public:
std::string name = Settings::fPathGFX + "/wifiop_show_optfunc_pos_yz";
gp.setOutput(name + ".tex");
gp.setTerminal("epslatex", K::GnuplotSize(8.7, 5.0));
gp.setTerminal("epslatex", K::GnuplotSize(7.7, 4.5));
gp << "set palette defined (0 '#00ff00', 1 '#eeeeee', 9 '#222222')\n";
gp << "set margins 0,0,0,0\n";
gp << "set multiplot layout 1,1 scale 1.25,1.4 offset 0.02, 0.05\n";
gp << "set multiplot layout 1,1 scale 1.25,1.4 offset -0.04, 0.05\n";
gp << "set colorbox horizontal user origin 0.57, 0.95 size 0.4, 0.03\n";
gp << "set hidden3d front\n";
// paper out
splot.setStringMod(new K::GnuplotStringModLaTeX());
@@ -223,6 +228,13 @@ public:
const int steps = 35;
std::vector<std::vector<K::GnuplotPoint3>> hor;
hor.resize(3);
std::vector<std::vector<K::GnuplotPoint3>> ver;
ver.resize(5);
for (float sz = 0; sz < steps; ++sz) {
for (int sy = 0; sy < steps; ++sy) {
@@ -239,16 +251,44 @@ public:
const K::GnuplotPoint3 gp3(pos.y, pos.z, err);
mesh.add(gp3);
if (sy == 0) {lines1.add(gp3);}
if (sy == 17) {lines2.add(gp3);}
if (sz == 24) {lines3.add(gp3);}
// horizontal lines
if (sy == 9) {hor[0].push_back(gp3);}
if (sy == 17) {hor[1].push_back(gp3);}
if (sy == 26) {hor[2].push_back(gp3);}
if (sy == 9 && sz == 24) {points.add(gp3);}
if (sy == 26 && sz == 24) {points.add(gp3);}
// vertical lines
if (sz == 0) {ver[0].push_back(gp3);}
if (sz == 8) {ver[1].push_back(gp3);}
if (sz == 14) {ver[2].push_back(gp3);}
if (sz == 20) {ver[3].push_back(gp3);}
if (sz == 28) {ver[4].push_back(gp3);}
if (sz == 24) {lines3.add(gp3);}
if (sy == 9 && sz == 24) {points.add(gp3 + K::GnuplotPoint3(0,0,0.10));} // minor z-offset for Hidden3D to work
if (sy == 26 && sz == 24) {points.add(gp3 + K::GnuplotPoint3(0,0,0.10));} // minor z-offset for Hidden3D to work
}
}
// horizontal lines
for (const std::vector<K::GnuplotPoint3>& vec : hor) {
for (const K::GnuplotPoint3 p3 : vec) {
lines1.add(p3 + K::GnuplotPoint3(0,0,0.05)); // minor z-offset for Hidden3D to work
}
lines1.add(K::GnuplotPoint3::getEmpty());
lines1.add(K::GnuplotPoint3::getEmpty());
}
// vertical lines
for (const std::vector<K::GnuplotPoint3>& vec : ver) {
for (const K::GnuplotPoint3 p3 : vec) {
lines2.add(p3 + K::GnuplotPoint3(0,0,0.05)); // minor z-offset for Hidden3D to work
}
lines2.add(K::GnuplotPoint3::getEmpty());
lines2.add(K::GnuplotPoint3::getEmpty());
}
gp.draw(splot);
LeHelper::writeCode(name + ".gp", gp.getBuffer());
gp.flush();

View File

@@ -32,6 +32,7 @@
#include "../plots/PlotErrTime.h"
#include "../plots/PlotErrFunc.h"
#include "../plots/PlotWiFiGroundProb.h"
#include "../WalkResult.h"
//#include "CSV.h"
#include <unordered_set>
@@ -142,12 +143,16 @@ public:
}
}
void walk(const std::string& fPath, const std::vector<int> gtIndices) {
WalkResult walk(const std::string& fPath, const std::vector<int> gtIndices) {
static PlotErrTime pet_m("","",""); pet_m.clear();
static PlotErrTime pet_p("","",""); pet_p.clear();
Offline::FileReader reader(fPath);
WalkResult res;
const Offline::FileReader::GroundTruth gtp = reader.getGroundTruth(map, gtIndices);
// process each wifi entry within the offline file
@@ -233,6 +238,15 @@ public:
stats_m->add(err_m);
pet_m.addErr(ts, err_m, idx);
// remember
WalkResult::Entry e;
e.ts = ts;
e.estimation = curEst;
e.groundTruth = gt;
e.err = err_m;
res.entries.push_back(e);
// error in -log(p)
float gtFloat[3] = {gt.x, gt.y, gt.z};
const double probOnGT = -func(gtFloat);
@@ -255,6 +269,8 @@ public:
}
return res;
}
};