This repository has been archived on 2020-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
Files
Indoor/grid/factory/v2/Importance.h
kazu 4f511d907e some fixes [multithreading,..]
needed interface changes [new options]
logger for android
wifi-ap-optimization
new test-cases
2016-09-28 12:19:14 +02:00

159 lines
3.9 KiB
C++

#ifndef IMPORTANCE_H
#define IMPORTANCE_H
#include "../../../geo/Units.h"
#include "../../Grid.h"
#include "GridFactoryListener.h"
#include "../../../misc/KNN.h"
#include "../../../misc/KNNArray.h"
#include "../../../math/MiniMat2.h"
#include "../../../math/Distributions.h"
class Importance {
private:
static constexpr const char* name = "GridImp";
public:
template <typename T> static void addOutlineNodes(Grid<T>& dst, Grid<T>& src) {
for (const T& n : src) {
if (n.getNumNeighbors() < 8) {
if (!dst.hasNodeFor(n)) {
dst.add(n);
}
}
}
}
/** attach importance-factors to the grid */
template <typename T> static void addImportance(Grid<T>& g, GridFactoryListener* l = nullptr) {
Log::add(name, "adding importance information to all nodes");
if (l) {
l->onGridBuildUpdateMajor(2, 0);
l->onGridBuildUpdateMajor("adding importance information");
l->onGridBuildUpdateMinor("performing initial setups");
}
// get an inverted version of the grid
Grid<T> inv(g.getGridSize_cm());
addOutlineNodes(inv, g);
//GridFactory<T> fac(inv);
//fac.addInverted(g, z_cm);
// sanity check
Assert::isFalse(inv.getNumNodes() == 0, "inverted grid is empty!");
// construct KNN search
KNN<Grid<T>, 3> knn(inv);
// create list of all door-nodes
std::vector<T> doors;
// create list of all stair-nodes
std::vector<T> stairs;
// process each node
for (T& n1 : g) {
switch(n1.getType()) {
case GridNode::TYPE_DOOR: doors.push_back(n1); break;
case GridNode::TYPE_STAIR: stairs.push_back(n1); break;
case GridNode::TYPE_ELEVATOR: stairs.push_back(n1); break;
}
}
// KNN for doors
KNNArray<std::vector<T>> knnArrDoors(doors);
KNN<KNNArray<std::vector<T>>, 3> knnDoors(knnArrDoors);
// KNN for stairs
KNNArray<std::vector<T>> knnArrStairs(stairs);
KNN<KNNArray<std::vector<T>>, 3> knnStairs(knnArrStairs);
// probability adjustments
Distribution::Triangle<float> avoidWalls(0.0, 0.45f);
Distribution::Normal<float> favorDoors(0.0f, 0.4f);
Distribution::Normal<float> favorStairs(0.0f, 1.5f);
if (l) {
l->onGridBuildUpdateMajor(2, 1);
l->onGridBuildUpdateMinor("calculating importance for each node");
}
std::cout << "dunno why, but the KNN for stairs searches extremely slow!" << std::endl;
// process each node again
for (int i = 0; i < g.getNumNodes(); ++i) {
// log
if (i % (g.getNumNodes() / 20) == 0) {
if (l) {
l->onGridBuildUpdateMinor(g.getNumNodes(), i);
}
}
// get the node
T& n1 = g[i];
// get the distance to the nearest wall
const float distToWall_m = Units::cmToM(knn.getNearestDistance( {n1.x_cm, n1.y_cm, n1.z_cm} ));
// get the distance to the nearest door
const float distToDoor_m = Units::cmToM(knnDoors.getNearestDistance( {n1.x_cm, n1.y_cm, n1.z_cm} ));
// get the distance to the nearest stair
const float distToStair_m = Units::cmToM(knnStairs.getNearestDistance( {n1.x_cm, n1.y_cm, n1.z_cm} ));
const bool useNormal = (distToWall_m*3.5 < distToDoor_m && distToWall_m*3.5 < distToStair_m);
// final probability
n1.walkImportance = 1.0f;
//n1.walkImportance += favorDoors.getProbability(distToDoor_m) * 0.75f;
n1.walkImportance += favorStairs.getProbability(distToStair_m) * 1.0f;
// use wall avoidance
if (useNormal) {
n1.walkImportance -= avoidWalls.getProbability(distToWall_m) * 0.4f;
}
// navigation importance is calculated using other formulae
n1.navImportance = 1.0f;
if (useNormal) {
n1.navImportance -= avoidWalls.getProbability(distToWall_m) * 0.4;
}
//n1.navImportance += favorDoors.getProbability(distToDoor_m) * 0.5;
n1.navImportance += favorStairs.getProbability(distToStair_m) * 1.0;
// sanity check
Assert::isTrue(n1.walkImportance >= 0, "detected negative walk importance. does not make sense!");
Assert::isTrue(n1.navImportance >= 0, "detected negative nav importance. does not make sense!");
}
}
};
#endif // IMPORTANCE_H