DHART
Loading...
Searching...
No Matches
graph_generator.h
Go to the documentation of this file.
1
6
7#pragma once
8#define _USE_MATH_DEFINES
9
10#include <cmath>
11#include <set>
12#include <vector>
13#include <array>
14#include <Node.h>
15#include <cassert>
16#include <variant>
17#include <MultiRT.h>
18#include <unordered_map>
19
20// Forward declares for embree raytracer.
21namespace HF::RayTracer {
22 class EmbreeRayTracer;
23 class NanoRTRayTracer;
24}
26 class Graph;
27 struct Edge;
28 enum STEP;
29}
30
59namespace HF::GraphGenerator {
60
61 /* For C++ 2020.
62 template <typename T>
63 concept Point = requires(T pt) {
64 {pt[0]}->std::convertible_to<float>;
65 {pt[1]}->std::convertible_to<float>;
66 {pt[2]}->std::convertible_to<float>;
67 };
68 */
69
70 class UniqueQueue;
71 struct optional_real3;
72
73 using real_t = double;
74 using real3 = std::array<real_t, 3>;
76
77 constexpr real_t default_z_precision = 0.0001;
78 constexpr real_t default_ground_offset = 0.01;
79 constexpr real_t default_spacing_precision = 0.00001;
80
82 using pair = std::pair<int, int>;
83
90 template<typename real_type>
91 inline real_t CastToReal(real_type t) { return static_cast<real_t>(t); }
92
103 template<typename real_3_type>
104 inline real3 CastToReal3(real_3_type t) {
105 return real3{
106 CastToReal(t[0]), CastToReal(t[1]), CastToReal(t[2])
107 };
108 };
109
111 struct Precision {
115 };
123 enum HIT_FLAG {
131 BOTH = 3
132 };
133
134 using hashmap = std::unordered_map<int, HIT_FLAG>;
135
146 OBSTACLES_ONLY = 1,
148 };
149
158
159 private:
161
177 const std::vector<int>& walkable,
178 const std::vector<int>& obstacle)
179 {
180 bool has_walkable = !(walkable.empty());
181 bool has_obstacle = !(obstacle.empty());
182
183 if (has_walkable && has_obstacle) this->Mode = GeometryFilterMode::OBSTACLES_AND_FLOORS;
184 else if (has_obstacle && !has_walkable) this->Mode = GeometryFilterMode::OBSTACLES_ONLY;
186 }
187
188 public:
190
200 inline void SetGeometryIds(
201 const std::vector<int> & obstacle_geometry,
202 const std::vector<int> & walkable_geometry)
203 {
204 for (auto id : obstacle_geometry)
205 this->Set(id, HIT_FLAG::OBSTACLES);
206 for (auto id : walkable_geometry)
207 this->Set(id, HIT_FLAG::FLOORS);
208
209 DetermineFilterMode(walkable_geometry, obstacle_geometry);
210 }
211
219 inline bool HasKey(int id) const {
220 return internal_dictionary.count(id) >= 1;
221 }
222
236 inline HIT_FLAG operator[](int id) const {
237 if (!HasKey(id)) return HIT_FLAG::NO_FLAG;
238 return internal_dictionary.at(id);
239 }
240
249 inline void Set(int id, HIT_FLAG flag) {
250 internal_dictionary[id] = flag;
251 }
252 };
253
255 struct GraphParams {
262 };
263
282 real3 pt{ NAN, NAN, NAN };
283
285 inline optional_real3() {};
286
293 inline optional_real3(real_t x, real_t y, real_t z) : pt(real3{ x,y,z }) {};
294
299 inline optional_real3(const real3 & in_real3) : pt(in_real3) {};
300
305 inline real3 & operator *() { return pt; }
306
312 inline explicit operator bool() const {
313 return !(std::isnan(pt[0]) && std::isnan(pt[1]) && std::isnan(pt[2]));
314 }
315 };
316
317
318
326 std::set<std::pair<int, int>> permutations(int limit);
327
345 {
346 public:
349
353
355
357 public:
358
371 GraphGenerator(HF::RayTracer::EmbreeRayTracer& ray_tracer, const std::vector<int> & obstacle_ids = std::vector<int>(0), const std::vector<int> & walkable_ids = std::vector<int>(0));
372
385 GraphGenerator(HF::RayTracer::NanoRTRayTracer& ray_tracer, const std::vector<int> & obstacle_ids = std::vector<int>(0), const std::vector<int>& walkable_ids = std::vector<int>(0));
386
399 GraphGenerator(HF::RayTracer::MultiRT& ray_tracer, const std::vector<int> & obstacle_ids = std::vector<int>(0), const std::vector<int>& walkable_ids = std::vector<int>(0));
400
401
453 template <
454 typename node_type,
455 typename node2_type,
456 typename up_step_type,
457 typename up_slope_type,
458 typename down_step_type,
459 typename down_slope_type,
460 typename z_precision_type = real_t,
461 typename connect_offset_type = real_t,
462 typename spacing_precision_type = real_t
463 >
465 const node_type& start_point,
466 const node2_type& Spacing,
467 int MaxNodes,
468 up_step_type UpStep,
469 up_slope_type UpSlope,
470 down_step_type DownStep,
471 down_slope_type DownSlope,
472 int max_step_connections,
473 int min_connections = 1,
474 int cores = -1,
475 z_precision_type node_z_precision = default_z_precision,
476 connect_offset_type node_spacing_precision = default_spacing_precision,
477 spacing_precision_type ground_offset = default_ground_offset
478 ) {
479 assert(node_z_precision != 0);
480 return IMPL_BuildNetwork(
481 CastToReal3(start_point),
482 CastToReal3(Spacing),
483 MaxNodes,
484 CastToReal(UpStep),
485 CastToReal(UpSlope),
486 CastToReal(DownStep),
487 CastToReal(DownSlope),
488 max_step_connections,
490 cores,
491 CastToReal(node_z_precision),
492 CastToReal(node_spacing_precision),
493 CastToReal(ground_offset)
494 );
495 }
496
497
537 const real3& start_point,
538 const real3& Spacing,
539 int MaxNodes,
540 real_t UpStep,
541 real_t UpSlope,
542 real_t DownStep,
543 real_t DownSlope,
544 int max_step_connections,
545 int min_connections,
546 int cores = -1,
547 real_t node_z_precision = default_z_precision,
548 real_t node_spacing_precision = default_spacing_precision,
549 real_t ground_offset = default_ground_offset
550 );
551
552
573
592 };
593
611 optional_real3 ValidateStartPoint(RayTracer& RT, const real3& start_point, const GraphParams & Params);
612
635 optional_real3 CheckRay(
636 RayTracer& RT,
637 const real3& origin,
638 const real3& direction,
639 real_t node_z_tolerance,
640 HIT_FLAG flag = BOTH,
641 const GeometryFlagMap& geometry_dict = GeometryFlagMap()
642 );
643
644
659 std::vector<pair> CreateDirecs(int max_step_connections);
660
686 std::vector<graph_edge> GetChildren(
687 const real3 & parent,
688 const std::vector<real3>& possible_children,
689 RayTracer & rt,
690 const GraphParams & GP
691 );
692
711 std::vector<real3> GeneratePotentialChildren(
712 const real3& parent,
713 const std::vector<pair>& direcs,
714 const real3& spacing,
715 const GraphParams & gp
716 );
717
730 template<typename A, typename D, typename N>
731 inline void MoveNode(const A& dist, const D& direction, N& node) {
732 node[0] = std::fma(direction[0], dist, node[0]);
733 node[1] = std::fma(direction[1], dist, node[1]);
734 node[2] = std::fma(direction[2], dist, node[2]);
735 }
736
755 std::vector<real3> CheckChildren(
756 const real3& parent,
757 const std::vector<real3>& possible_children,
758 RayTracer& rt,
759 const GraphParams & params
760 );
761
779 const real3 & parent,
780 const real3 & child,
781 RayTracer& rt,
782 const GraphParams & params
783 );
784
802 bool OcclusionCheck(const real3 & parent, const real3 & child, RayTracer& RT);
803
819 bool CheckSlope(
820 const real3 & parent,
821 const real3 & child,
822 const GraphParams & gp
823 );
824
825}
826
Contains definitions for the Node structure.
Generate a graph of accessible space from a given start point.
Various parameters to set the precision of certain parts of the graph generator.
Holds parameters for the GraphGenerator.
real_t up_step
Maximum height of a step the graph can traverse.Any steps higher this will be considered inaccessible...
constexpr real_t default_spacing_precision
std::vector< real3 > GeneratePotentialChildren(const real3 &parent, const std::vector< pair > &direcs, const real3 &spacing, const GraphParams &gp)
Populare out_children with a potential child position for every direction in directions.
std::vector< real3 > CheckChildren(const real3 &parent, const std::vector< real3 > &possible_children, RayTracer &rt, const GraphParams &params)
Determine whether children are over valid ground, and and meet upstep/downstep requirements.
real_t ground_offset
Distance to offset nodes from the ground before checking line of sight.
real3 CastToReal3(real_3_type t)
Cast an array of 3 values to the graph_generator's real_3 type.
void MoveNode(const A &dist, const D &direction, N &node)
Move a node in direction by dist units.
GeometryFlagMap geom_ids
Stores a map of geometry IDs to their HIT_FLAGS and the current filter mode of the graph.
HIT_FLAG
Determines which geometry the ray will collide with.
@ NO_FLAG
No flag set.
@ OBSTACLES
Obstacles only.
@ BOTH
Collide with floors and obstacles.
@ FLOORS
Floors only.
double real_t
Internal decimal type of the graph generator.
real_t node_z
Precision to round the z-component of nodes after a raycast is performed.
real_t CastToReal(real_type t)
Cast an input value to real_t using static cast.
optional_real3 CheckRay(RayTracer &RT, const real3 &origin, const real3 &direction, real_t node_z_tolerance, HIT_FLAG flag=BOTH, const GeometryFlagMap &geometry_dict=GeometryFlagMap())
Cast a ray and get the point of intersection if it connects.
real_t down_slope
The maximum downward slope the graph can traverse. Any slopes steeper than this will be considered in...
std::array< real_t, 3 > real3
Type used for the standard coordinate set of the graph generator.
bool CheckSlope(const real3 &parent, const real3 &child, const GraphParams &gp)
Determine if the slope between parent and child is traversable according to the graph parameters.
optional_real3 ValidateStartPoint(RayTracer &RT, const real3 &start_point, const GraphParams &Params)
Determine if the start point of the graph is over valid ground.
std::pair< int, int > pair
Type for Directions to be stored as.
std::vector< graph_edge > GetChildren(const real3 &parent, const std::vector< real3 > &possible_children, RayTracer &rt, const GraphParams &GP)
Calculate all possible edges between parent and possible_children.
real_t node_spacing
Precision to round nodes after spacing is calculated.
bool OcclusionCheck(const real3 &parent, const real3 &child, RayTracer &RT)
Determine if there is a valid line of sight between parent and child.
constexpr real_t default_ground_offset
constexpr real_t default_z_precision
std::unordered_map< int, HIT_FLAG > hashmap
Hashmap used for assigning and storing hitflags for IDs.
real_t down_step
Maximum step down the graph can traverse.Any steps steeper than this will be considered inaccessible.
real_t up_slope
Maximum upward slope the graph can traverse in degrees.Any slopes steeper than this will be considere...
HF::SpatialStructures::STEP CheckConnection(const real3 &parent, const real3 &child, RayTracer &rt, const GraphParams &params)
Determine what kind of step (if any) is between parent and child.
HF::RayTracer::MultiRT RayTracer
Type of raytracer to be used internally.
std::vector< pair > CreateDirecs(int max_step_connections)
Create a set of directions based on max_step_connections.
Precision precision
Tolerances for the graph.
GeometryFilterMode
Different rules for how geometry is filtered by the graph generator.
@ ALL_INTERSECTIONS
Consider all geometry as walkable surfaces.
@ OBSTACLES_ONLY
Consider all geometry that isn't an obstacle as walkable.
@ OBSTACLES_AND_FLOORS
Explicitly tag geometry ids as either obstacle or floor. Any ids outside of these ranges will always ...
std::set< std::pair< int, int > > permutations(int limit)
Calculate P(n,r) as an array with each unique permutaton of 2 values being a pair.
Cast rays to determine if and where they intersect geometry.
Contains standard fundamental data structures for representing space used throughout DHARTAPI.
STEP
Describes the type of step an edge connects to.
Definition: Edge.h:15
Manages rules and ids for different types of geometry in the graph generator.
bool HasKey(int id) const
Check if this id exists in the dictionary.
void SetGeometryIds(const std::vector< int > &obstacle_geometry, const std::vector< int > &walkable_geometry)
Set geometry ids as being walkable or obstacles.
GeometryFilterMode Mode
Filter mode of this GeometryFlagMap.
void DetermineFilterMode(const std::vector< int > &walkable, const std::vector< int > &obstacle)
Set the filter mode of this GeometryFlagMap based on the input types.
void Set(int id, HIT_FLAG flag)
Set the value of a key in the internal dictionary.
HIT_FLAG operator[](int id) const
Get the flag of the geometry in this hit dictionary.
A simple wrapper for real3 that is able to determine whether or not it's defined.
optional_real3()
Construct an invalid optional_real3.
real3 & operator*()
Get a reference to the point held by this optional_real3.
optional_real3(real_t x, real_t y, real_t z)
Construct an valid optreal3 from x,y,z parameters.
optional_real3(const real3 &in_real3)
Construct an optreal3 from x,y,z parameters.
Generate a graph of accessible space from a given start point.
SpatialStructures::Graph BuildNetwork(const node_type &start_point, const node2_type &Spacing, int MaxNodes, up_step_type UpStep, up_slope_type UpSlope, down_step_type DownStep, down_slope_type DownSlope, int max_step_connections, int min_connections=1, int cores=-1, z_precision_type node_z_precision=default_z_precision, connect_offset_type node_spacing_precision=default_spacing_precision, spacing_precision_type ground_offset=default_ground_offset)
Generate a graph of accessible space.
int core_count
Number of cores to use for graph generation.
SpatialStructures::Graph IMPL_BuildNetwork(const real3 &start_point, const real3 &Spacing, int MaxNodes, real_t UpStep, real_t UpSlope, real_t DownStep, real_t DownSlope, int max_step_connections, int min_connections, int cores=-1, real_t node_z_precision=default_z_precision, real_t node_spacing_precision=default_spacing_precision, real_t ground_offset=default_ground_offset)
Generate a graph of accessible space.
RayTracer ray_tracer
A pointer to the raytracer to use for ray intersections.
int max_nodes
Maximum number of nodes to generate. If less than zero, generate nodes without a limit.
GraphParams params
Parameters to run the graph generator.
int max_step_connection
Multiplier for number of children to generate. The higher this is, the more directions there will be.
SpatialStructures::Graph CrawlGeomParallel(UniqueQueue &todo)
Perform breadth first search to populate the graph with nodes and edges using multiple cores.
real3 spacing
Spacing between nodes. New nodes will be generated with atleast this much distance between them.
int min_connections
Minimum number of step connections for a node to be valid (minimum out degree of node)
SpatialStructures::Graph CrawlGeom(UniqueQueue &todo)
Perform breadth first search to populate the graph with with nodes and edges.
A queue that remembers every object inserted, and prevents the addition of nodes that have already be...
Definition: unique_queue.h:29
A wrapper for Intel's Embree Library.
A connection to a child node.
Definition: Edge.h:29
A Graph of nodes connected by edges that supports both integers and HF::SpatialStructures::Node.
Definition: graph.h:486