VR-Forces 4.2 Class Documentation
pathFinder.h
Go to the documentation of this file.
1 /*******************************************************************************
2 ** Copyright (c) 2012 MAK Technologies, Inc.
3 ** All rights reserved.
4 *******************************************************************************/
5 
9 
10 #pragma once
11 
13 #include <features/pathFeature.h>
15 
16 #include <vrfutil/asyncJob.h>
17 #include <vrfutil/kinTools.h>
18 #include <vrfutil/railSegment.h>
20 
21 #include <boost/graph/adjacency_list.hpp>
22 #include <boost/graph/properties.hpp>
23 #include <boost/graph/graph_traits.hpp>
24 #include <boost/function.hpp>
25 #include <tbb/spin_rw_mutex.h>
26 
27 #include <list>
28 
29 namespace MAKVRinTerra
30 {
31  //Properties of each vertex
33  {
35  : location(0.0, 0.0, 0.0)
36  {
37  }
38  VertexInfo(DtPoint point)
39  : location(point)
40  {
41  }
42  DtPoint location;
43  };
44 
45  //Properties on each edge
47  {
49  : feature()
50  , distance(1.0)
51  {
52  }
53  EdgeInfo(const DtPathFeature& p, const double& d)
54  : feature(p.getPathPtr())
55  , distance(d)
56  {
57  }
58  EdgeInfo(DtPathFeature::CPtr p, const double& d)
59  : feature(p)
60  , distance(d)
61  {
62  }
64  double distance;
65  };
66 
67  //Key for grid cells, for tracking which tiles of features are
68  //already loaded.
70  {
71  DtGridKey(const int& xIndex, const int& yIndex)
72  : x(xIndex), y(yIndex) { }
73 
74  bool operator<(const DtGridKey& rhs) const
75  {
76  if (x < rhs.x)
77  return true;
78  else if (x == rhs.x && y < rhs.y)
79  return true;
80  return false;
81  }
82 
83  int x;
84  int y;
85  };
86 
87  DT_DLL_features std::ostream& operator<<(std::ostream& s, const DtGridKey& key);
88 
89  //DtPathFinder processes path features to make a graph for path planning.
91  {
92  public:
93 
94  //Weight is a property on edges.
95  typedef boost::property<boost::edge_weight_t, double> Weight;
96 
97  typedef boost::adjacency_list< //graph is adjacency list (vs adjacency matrix)
98  boost::vecS, //per-vertex edge-list is a vector
99  boost::vecS, //graph's vertex-list is a vector
100  boost::directedS, //graph is directed
101  VertexInfo, //VertexInfo struct is property on edges
102  EdgeInfo, //EdgeInfo struct is property on edges
103  boost::no_property, //no property on graph
104  boost::vecS> //graph's edge-list is a vector
106 
107  typedef DtBoostGraph::vertex_descriptor vertex_descriptor;
108  typedef DtBoostGraph::edge_descriptor edge_descriptor;
109  typedef std::list<boost::graph_traits<DtBoostGraph>::vertex_descriptor> VertexList;
110 
115  struct PathVertex
116  {
117  PathVertex() : localLocation(0.0, 0.0, 0.0), nextEdgeFeature() { }
118  PathVertex(const DtPoint& l, DtPathFeature::CPtr& f)
119  : localLocation(l), nextEdgeFeature(f) { }
120 
121  DtPoint localLocation;
123  };
124  typedef std::list<PathVertex> Path;
125 
126  typedef std::pair<DtQuery, double> DtWeightFactor;
127  typedef std::list<DtWeightFactor> DtWeightFactorsList;
128  typedef boost::shared_ptr<DtWeightFactorsList> DtWeightFactorsListPtr;
129 
130  //Used for finding points already in the graph
132  {
133  explicit PointLessThan() : myTolerance(1.0) { }
134  explicit PointLessThan(const double& tolerance)
135  : myTolerance(tolerance) { }
136 
137  bool operator()(const DtPoint& lhs, const DtPoint& rhs) const
138  {
139  if (DtALMOST(lhs.x(), rhs.x(), myTolerance))
140  {
141  if (DtALMOST(lhs.y(), rhs.y(), myTolerance))
142  {
143  if (DtALMOST(lhs.z(), rhs.z(), myTolerance) || lhs.z() > rhs.z())
144  {
145  return false;
146  }
147  return true;
148  }
149  return lhs.y() < rhs.y();
150  }
151  return lhs.x() < rhs.x();
152  }
153 
154  double myTolerance;
155  };
156 
157  typedef std::map<DtPoint, vertex_descriptor, PointLessThan> DtLocationVertexMap;
158 
159  //Represents the results of the astar visitor's search.
161  {
163  : myBestEdgeA(boost::graph_traits<DtPathFinder::DtBoostGraph>::null_vertex())
164  , myBestEdgeB(boost::graph_traits<DtPathFinder::DtBoostGraph>::null_vertex())
165  , myBestPointOnNetwork()
166  , myBestEdgeDistance(std::numeric_limits<double>::infinity())
167  , myEndFeature()
168  , myGoalFound(false)
169  {
170 
171  }
172 
179  };
180 
182  {
190  PathFinderError
191  };
192 
193  DtPathFinder(
194  std::auto_ptr<DtFeatureSet> s,
195  DtProj::CPtr localProj,
196  boost::shared_ptr<DtTerrainInterfaceConfig> config,
197  std::string label = std::string());
198 
200  void addFeatureToGraph(const DtFeature & r);
201 
202  void addGeometryToGraph(DtFeatureGeometry g);
203 
205  DtPoint locationForVertex(const vertex_descriptor& vertex);
207  vertex_descriptor vertexForLocation(const DtPoint& localLocation);
208 
217  Path makePath(const DtPoint& startLocation, const DtPoint& endLocation,
218  const double& maxSearchRadius, const double& startProximityThreshold,
219  DtWeightFactorsListPtr weightFactors, boost::function<bool ()> cancelCheck,
220  ReturnCode& result);
221 
224  bool onPathFeature(const DtPoint& location, double offset = 0.5);
225 
227  static DtRailSegmentList* DtPath2RailSegmentList(const Path& path);
228 
229  DtGridKey MakeGridKey(const DtPoint& localLocation);
230  DtFeatureGeometry::Area MakeGridCell(const DtGridKey& key);
231 
232  bool tileIsLoaded(const DtGridKey& key);
233  void loadTile(const DtGridKey& key,
234  tbb::spin_rw_mutex::scoped_lock&,
235  boost::function<bool ()> cancelCheck = boost::function<bool ()>());
236 
237  DtBoostGraph* graph();
238 
239  std::auto_ptr<DtPathFeatureSet> paths() const
240  {
241  return std::auto_ptr<DtPathFeatureSet>(myInputPathFeatureSet->clone());
242  }
243 
244  DtProj::CPtr localProj() const
245  {
246  return myLocalProj;
247  }
248 
258  DtClosestPathFeatureFinder closestFeatureOnNetwork(const DtPoint& startingLocation,
259  const double& searchRadius, bool* dataAvailable = NULL);
260 
263  int numFeatures() const;
264 
265  void setDrawing(bool);
266  void draw();
267 
268  private:
269 
271  Path makePath(const vertex_descriptor& source, const vertex_descriptor& destination,
272  double maxSearchRadius, DtWeightFactorsListPtr weightFactors,
273  tbb::spin_rw_mutex::scoped_lock& lock, boost::function<bool ()> cancelCheck,
274  AstarSearchResults& astarResults, ReturnCode& pathFindResult);
275 
279  DtPoint closestPointOnNetwork(const DtPoint& startingLocation,
280  const double& searchRadius, vertex_descriptor& edgeA, vertex_descriptor& edgeB,
281  DtPathFeature::CPtr& edgeFeature);
282 
294  bool determineStartAndEndVertices(const DtPoint& startLocation, const DtPoint& endLocation,
295  vertex_descriptor& startEdgeVertexToUse, vertex_descriptor& startEdgeOtherVertex,
296  vertex_descriptor& endEdgeVertexToUse, vertex_descriptor& endEdgeOtherVertex,
297  DtPoint& startEdgeClosestPoint, DtPoint& endEdgeClosestPoint,
298  DtPathFeature::CPtr& startFeature, DtPathFeature::CPtr& endFeature);
299 
301  std::auto_ptr<DtFeatureSet> myInputFeatureSet;
302  std::auto_ptr<DtPathFeatureSet> myInputPathFeatureSet;
303 
304  std::auto_ptr<DtPathFeatureSet::Storage> myLoadedPathFeatureSet;
305 
308 
313 
318 
321 
323  std::set<DtGridKey> myLoadedFeatures;
324 
325  boost::shared_ptr<DtTerrainInterfaceConfig> myTerrainInterfaceConfig;
326 
330 
331  mutable tbb::spin_rw_mutex myGraphMutex;
332 
333  std::auto_ptr<DtSharedMemoryFeaturesDebugDrawer> myDrawer;
334  std::string myLabel;
335  };
336 
338  {
339  public:
342  };
343 
345  {
346  public:
348  const DtPoint& localStart, const DtPoint& localDestination,
349  const double& maxSearchRadius, const double& startProximityThreshold,
351  : DtAsyncJob()
352  , myPathFinder(pathFinder)
353  , myLocalStart(localStart)
354  , myLocalDestination(localDestination)
355  , myMaxSearchRadius(maxSearchRadius)
356  , myStartProximityThreshold(startProximityThreshold)
357  , myWeightFactors(factors)
358  , myPathFindReturnCode(DtPathFinder::PathFinderError)
359  {
360  };
361 
362  task* onExecute()
363  {
364  DtJobCancelledFunc cancelCheck(*this);
365  if (cancelCheck())
366  {
367  DtVerbose << "Job canceled before path plan." << std::endl;
368  throw job_canceled();
369  }
370 
371  {
372  boost::shared_ptr<DtAsyncJobMapEntry> entry = getEntry();
373  if (!entry)
374  return 0;
375 
376  if (entry->status() == queued)
377  {
378  entry->setStatus(processing);
379  }
380  else
381  {
382  DtWarn << "Job " << entry->id() << " in invalid state " << entry->status() << std::endl;
383  entry->setStatus(canceled);
384  throw DtException("Invalid state.");
385  }
386  }
387 
388  DtPathFinder::Path path = myPathFinder.makePath(
389  myLocalStart, myLocalDestination, myMaxSearchRadius,
390  myStartProximityThreshold, myWeightFactors, boost::ref(cancelCheck),
391  myPathFindReturnCode);
392 
393  boost::shared_ptr<DtAsyncJobMapEntry> entry = getEntry();
394  if (!entry)
395  return 0;
396 
397  std::auto_ptr<DtMakePathResult> result(new DtMakePathResult());
398  result->returnCode = myPathFindReturnCode;
399  result->path = path;
400 
401  entry->setResult(complete, result.release());
402  return 0;
403  }
404 
405  task* onException()
406  {
407  boost::shared_ptr<DtAsyncJobMapEntry> entry = getEntry();
408  if (!entry)
409  return 0;
410 
411  std::auto_ptr<DtMakePathResult> result(new DtMakePathResult());
412  result->returnCode = myPathFindReturnCode;
413 
414  entry->setResult(complete, result.release());
415  return 0;
416  }
417 
418  public:
420  DtPoint myLocalStart;
426  };
427 
428  DT_DLL_features std::ostream& operator<<(std::ostream&, DtPathFinder::ReturnCode);
429 }

Document ID: Generated on Sun Nov 24 19:49:21 EST 2013 from SVN revision 133924
Copyright © 2005-2013 VT MÄK. All Rights Reserved (www.mak.com)