This commit is contained in:
toni
2016-10-01 13:33:04 +02:00
15 changed files with 343 additions and 64 deletions

View File

@@ -10,6 +10,12 @@ struct GridNodeImportance {
/** get the node's nav importance */
float getNavImportance() const {return navImportance;}
/** importance-weight for random walks */
float walkImportance;
/** get the node's random-walk importance */
float getWalkImportance() const {return walkImportance;}
/** ctor */
GridNodeImportance() : navImportance(1.0f) {;}

View File

@@ -86,7 +86,7 @@ public:
KNN<KNNArray<std::vector<T>>, 3> knnStairs(knnArrStairs);
// probability adjustments
Distribution::Triangle<float> avoidWalls(0.0, 0.45f);
Distribution::Triangle<float> avoidWalls(0.0, 0.35f);
Distribution::Normal<float> favorDoors(0.0f, 0.4f);
Distribution::Normal<float> favorStairs(0.0f, 1.5f);
@@ -111,8 +111,8 @@ public:
// 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 outline node [an outline node is directly adjacent to a wall]
const float distToOutline_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} ));
@@ -120,7 +120,13 @@ public:
// 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);
// use wall-avoidance?
//const bool useWallAvoidance = (distToWall_m*6.0 < distToDoor_m && distToWall_m*6.0 < distToStair_m);
//const bool useWallAvoidance = (distToDoor_m > 0.4f) && (distToStair_m > 0.4f);
const bool useWallAvoidance =
(distToOutline_m < 0.001f) && // node is an outline node [outline-nodes are adjacent to a wall]
(distToDoor_m > 0.3f) && // doors are 30cm away
(distToStair_m > 0.6f); // stairs are 60cm away;
// final probability
n1.walkImportance = 1.0f;
@@ -128,18 +134,20 @@ public:
n1.walkImportance += favorStairs.getProbability(distToStair_m) * 1.0f;
// use wall avoidance
if (useNormal) {
n1.walkImportance -= avoidWalls.getProbability(distToWall_m) * 0.4f;
if (useWallAvoidance) {
//n1.walkImportance -= avoidWalls.getProbability(distToWall_m) * 0.3f;
n1.walkImportance = 0.20f; // only addresses direct outline nodes
}
// navigation importance is calculated using other formulae
n1.navImportance = 1.0f;
if (useNormal) {
n1.navImportance -= avoidWalls.getProbability(distToWall_m) * 0.4;
if (useWallAvoidance) {
n1.navImportance -= avoidWalls.getProbability(distToOutline_m) * 0.3f;
}
//n1.navImportance += favorDoors.getProbability(distToDoor_m) * 0.5;
n1.navImportance += favorStairs.getProbability(distToStair_m) * 1.0;
n1.navImportance += favorStairs.getProbability(distToStair_m) * 1.0f;

View File

@@ -6,6 +6,7 @@
#include "../../../math/DrawList.h"
#include "modules/WalkModule.h"
#include "../../../math/Distributions.h"
#include "../../../math/Stats.h"
/**
* modular grid-walker that takes various sub-components to determine
@@ -28,6 +29,16 @@ public:
}
/** perform the walk based on the configured setup */
WalkState getDestination(Grid<Node>& grid, const WalkState& _startState, const float _dist_m) {
double tmp; // ignored
return getDestination(grid, _startState, _dist_m, tmp);
}
/**
* perform the walk based on the configured setup
* returns the walks overall probability using the out-parameter
*/
WalkState getDestination(Grid<Node>& grid, const WalkState& _startState, const float _dist_m, double& probability) {
Assert::isTrue(_dist_m >= 0, "walk distance must not be negative!");
@@ -53,8 +64,7 @@ public:
// add the previous walked-distance-error to the desired distance (is usually negative, thus dist_m is reduced)
float dist_m = _dist_m + _startState.distance.error_m;
probability = 1.0;
int cnt = 0;
Stats::Maximum<double> maxEdgeProb;
// until distance is reached
while (dist_m > 0) {
@@ -71,12 +81,13 @@ public:
for (const Node& neighbor : grid.neighbors(*curNode)) {
const double prob = getProbability(currentState, *startNode, *curNode, neighbor);
drawer.add(&neighbor, prob);
maxEdgeProb.add(prob);
}
// pick a neighbor and get its probability
double nodeProbability;
const Node* nextNode = drawer.get(nodeProbability);
if ( nodeProbability < probability ) {probability = nodeProbability;} // keep the smallest one
//double nodeProbability;
const Node* nextNode = drawer.get();
//if ( nodeProbability < probability ) {probability = nodeProbability;} // keep the smallest one
//probability += nodeProbability;
//++cnt;
@@ -91,7 +102,10 @@ public:
}
//if (cnt != 0) {probability /= cnt;} else {probability = 1.0;}
probability *= curNode->getWalkImportance() < 0.4f ? (1e-5) : (1.0); // "kill" particles that walk near walls (most probably trapped ones)
probability = 1.0;
//probability = (maxEdgeProb.isValid()) ? (maxEdgeProb.get()) : (1.0); // dist_m might be zero -> no edges -> no maximum
probability *= curNode->getWalkImportance();// < 0.4f ? (0.1) : (1.0); // "kill" particles that walk near walls (most probably trapped ones)
//probability = std::pow(probability, 5);
// update after
updateAfter(currentState, *startNode, *curNode);