VR-Forces 4.1.1 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>
14 
15 #include <vrfutil/asyncJob.h>
16 #include <vrfutil/kinTools.h>
17 #include <vrfutil/railSegment.h>
19 
20 #include <boost/graph/adjacency_list.hpp>
21 #include <boost/graph/properties.hpp>
22 #include <boost/graph/graph_traits.hpp>
23 #include <boost/function.hpp>
24 #include <tbb/spin_rw_mutex.h>
25 
26 #include <list>
27 
28 namespace MAKVRinTerra
29 {
30  //Properties of each vertex
32  {
34  : location(0.0, 0.0, 0.0)
35  {
36  }
38  : location(point)
39  {
40  }
42  };
43 
44  //Properties on each edge
46  {
48  : feature()
49  , distance(1.0)
50  {
51  }
52  EdgeInfo(const DtPathFeature& p, const double& d)
53  : feature(p.getPathPtr())
54  , distance(d)
55  {
56  }
57  EdgeInfo(DtPathFeature::CPtr p, const double& d)
58  : feature(p)
59  , distance(d)
60  {
61  }
63  double distance;
64  };
65 
66  //Key for grid cells, for tracking which tiles of features are
67  //already loaded.
69  {
70  DtGridKey(const int& xIndex, const int& yIndex)
71  : x(xIndex), y(yIndex) { }
72 
73  bool operator<(const DtGridKey& rhs) const
74  {
75  if (x < rhs.x)
76  return true;
77  else if (x == rhs.x && y < rhs.y)
78  return true;
79  return false;
80  }
81 
82  int x;
83  int y;
84  };
85 
86  DT_DLL_features std::ostream& operator<<(std::ostream& s, const DtGridKey& key);
87 
88  //DtPathFinder processes path features to make a graph for path planning.
90  {
91  public:
92 
93  //Weight is a property on edges.
94  typedef boost::property<boost::edge_weight_t, double> Weight;
95 
96  typedef boost::adjacency_list< //graph is adjacency list (vs adjacency matrix)
97  boost::vecS, //per-vertex edge-list is a vector
98  boost::vecS, //graph's vertex-list is a vector
99  boost::directedS, //graph is directed
100  VertexInfo, //VertexInfo struct is property on edges
101  EdgeInfo, //EdgeInfo struct is property on edges
102  boost::no_property, //no property on graph
103  boost::vecS> //graph's edge-list is a vector
105 
106  typedef DtBoostGraph::vertex_descriptor vertex_descriptor;
107  typedef DtBoostGraph::edge_descriptor edge_descriptor;
108  typedef std::list<boost::graph_traits<DtBoostGraph>::vertex_descriptor> VertexList;
109 
114  struct PathVertex
115  {
116  PathVertex() : localLocation(0.0, 0.0, 0.0), nextEdgeFeature() { }
118  : localLocation(l), nextEdgeFeature(f) { }
119 
122  };
123  typedef std::list<PathVertex> Path;
124 
125  typedef std::pair<DtQuery, double> DtWeightFactor;
126  typedef std::list<DtWeightFactor> DtWeightFactorsList;
127  typedef boost::shared_ptr<DtWeightFactorsList> DtWeightFactorsListPtr;
128 
129  //Used for finding points already in the graph
131  {
132  explicit PointLessThan() : myTolerance(1.0) { }
133  explicit PointLessThan(const double& tolerance)
134  : myTolerance(tolerance) { }
135 
136  bool operator()(const DtPoint& lhs, const DtPoint& rhs) const
137  {
138  if (DtALMOST(lhs.x(), rhs.x(), myTolerance))
139  {
140  if (DtALMOST(lhs.y(), rhs.y(), myTolerance))
141  {
142  if (DtALMOST(lhs.z(), rhs.z(), myTolerance) || lhs.z() > rhs.z())
143  {
144  return false;
145  }
146  return true;
147  }
148  return lhs.y() < rhs.y();
149  }
150  return lhs.x() < rhs.x();
151  }
152 
153  double myTolerance;
154  };
155 
156  typedef std::map<DtPoint, vertex_descriptor, PointLessThan> DtLocationVertexMap;
157 
158  //Represents the results of the astar visitor's search.
160  {
162  : myBestEdgeA(boost::graph_traits<DtPathFinder::DtBoostGraph>::null_vertex())
163  , myBestEdgeB(boost::graph_traits<DtPathFinder::DtBoostGraph>::null_vertex())
164  , myBestPointOnNetwork()
165  , myBestEdgeDistance(std::numeric_limits<double>::infinity())
166  , myEndFeature()
167  , myGoalFound(false)
168  {
169 
170  }
171 
178  };
179 
181  {
189  PathFinderError
190  };
191 
192  explicit DtPathFinder(std::auto_ptr<DtPathFeatureSet> s, DtProj::CPtr localProj,
193  boost::shared_ptr<DtTerrainInterfaceConfig> config);
194 
196  void addFeatureToGraph(const DtPathFeature & r);
197 
199  DtPoint locationForVertex(const vertex_descriptor& vertex);
201  vertex_descriptor vertexForLocation(const DtPoint& localLocation);
202 
211  Path makePath(const DtPoint& startLocation, const DtPoint& endLocation,
212  const double& maxSearchRadius, const double& startProximityThreshold,
213  DtWeightFactorsListPtr weightFactors, boost::function<bool ()> cancelCheck,
214  ReturnCode& result);
215 
218  bool onPathFeature(const DtPoint& location, double offset = 0.5);
219 
221  static DtRailSegmentList* DtPath2RailSegmentList(const Path& path);
222 
223  DtGridKey MakeGridKey(const DtPoint& localLocation);
224  DtFeatureGeometry::Area MakeGridCell(const DtGridKey& key);
225 
226  bool tileIsLoaded(const DtGridKey& key);
227  void loadTile(const DtGridKey& key, tbb::spin_rw_mutex::scoped_lock&,
228  boost::function<bool ()> cancelCheck);
229 
230  DtBoostGraph* graph();
231 
232  std::auto_ptr<DtPathFeatureSet> paths() const
233  {
234  return std::auto_ptr<DtPathFeatureSet>(myInputPathFeatureSet->clone());
235  }
236 
237  DtProj::CPtr localProj() const
238  {
239  return myLocalProj;
240  }
241 
251  DtClosestPathFeatureFinder closestFeatureOnNetwork(const DtPoint& startingLocation,
252  const double& searchRadius, bool* dataAvailable = NULL);
253 
256  int numFeatures() const;
257 
258  private:
259 
261  Path makePath(const vertex_descriptor& source, const vertex_descriptor& destination,
262  double maxSearchRadius, DtWeightFactorsListPtr weightFactors,
263  tbb::spin_rw_mutex::scoped_lock& lock, boost::function<bool ()> cancelCheck,
264  AstarSearchResults& astarResults, ReturnCode& pathFindResult);
265 
269  DtPoint closestPointOnNetwork(const DtPoint& startingLocation,
270  const double& searchRadius, vertex_descriptor& edgeA, vertex_descriptor& edgeB,
271  DtPathFeature::CPtr& edgeFeature);
272 
284  bool determineStartAndEndVertices(const DtPoint& startLocation, const DtPoint& endLocation,
285  vertex_descriptor& startEdgeVertexToUse, vertex_descriptor& startEdgeOtherVertex,
286  vertex_descriptor& endEdgeVertexToUse, vertex_descriptor& endEdgeOtherVertex,
287  DtPoint& startEdgeClosestPoint, DtPoint& endEdgeClosestPoint,
288  DtPathFeature::CPtr& startFeature, DtPathFeature::CPtr& endFeature);
289 
291  std::auto_ptr<DtPathFeatureSet> myInputPathFeatureSet;
292 
293  std::auto_ptr<DtPathFeatureSet::Storage> myLoadedPathFeatureSet;
294 
297 
302 
307 
310 
312  std::set<DtGridKey> myLoadedFeatures;
313 
314  boost::shared_ptr<DtTerrainInterfaceConfig> myTerrainInterfaceConfig;
315 
319 
320  mutable tbb::spin_rw_mutex myGraphMutex;
321  };
322 
324  {
325  public:
328  };
329 
331  {
332  public:
334  const DtPoint& localStart, const DtPoint& localDestination,
335  const double& maxSearchRadius, const double& startProximityThreshold,
337  : DtAsyncJob()
338  , myPathFinder(pathFinder)
339  , myLocalStart(localStart)
340  , myLocalDestination(localDestination)
341  , myMaxSearchRadius(maxSearchRadius)
342  , myStartProximityThreshold(startProximityThreshold)
343  , myWeightFactors(factors)
344  , myPathFindReturnCode(DtPathFinder::PathFinderError)
345  {
346  };
347 
348  task* onExecute()
349  {
350  DtJobCancelStruct cancelCheck(myId, myJobServer);
351  if (cancelCheck())
352  {
353  DtVerbose << "Job canceled before path plan." << std::endl;
354  throw job_canceled();
355  }
356 
357  {
358  DtAsyncJobMap::accessor a;
359  myJobServer->accessor(a, myId);
360  DtAsyncJobMapEntry* entry = a->second;
361  if (entry->status() == queued)
362  {
363  entry->setStatus(processing);
364  }
365  else
366  {
367  DtWarn << "Job " << myId << " in invalid state " << entry->status() << std::endl;
368  entry->setStatus(canceled);
369  throw DtException("Invalid state.");
370  }
371  }
372 
373  DtPathFinder::Path path = myPathFinder.makePath(
374  myLocalStart, myLocalDestination, myMaxSearchRadius,
375  myStartProximityThreshold, myWeightFactors, boost::ref(cancelCheck),
376  myPathFindReturnCode);
377 
378  std::auto_ptr<DtMakePathResult> result(new DtMakePathResult());
379  result->returnCode = myPathFindReturnCode;
380  result->path = path;
381 
382  {
383  DtAsyncJobMap::accessor a;
384  myJobServer->accessor(a, myId);
385  DtAsyncJobMapEntry* entry = a->second;
386  entry->setResult(std::auto_ptr<DtAsyncJobResult>(result));
387  entry->setStatus(complete);
388  }
389  return 0;
390  }
391 
392  task* onException()
393  {
394  DtAsyncJobMap::accessor a;
395  myJobServer->accessor(a, myId);
396  DtAsyncJobMapEntry* entry = a->second;
397  std::auto_ptr<DtMakePathResult> result(new DtMakePathResult());
398  result->returnCode = myPathFindReturnCode;
399  entry->setResult(std::auto_ptr<DtAsyncJobResult>(result));
400  entry->setStatus(complete);
401  return 0;
402  }
403 
404  public:
412  };
413 }

Document ID: Generated on Mon Apr 8 19:24:01 EDT 2013 from SVN revision 125877
Copyright © 2005-2013 VT MÄK. All Rights Reserved (www.mak.com)