MIRA
MetricPlannerBase.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) by
3  * MetraLabs GmbH (MLAB), GERMANY
4  * and
5  * Neuroinformatics and Cognitive Robotics Labs (NICR) at TU Ilmenau, GERMANY
6  * All rights reserved.
7  *
8  * Redistribution and modification of this code is strictly prohibited.
9  *
10  * IN NO EVENT SHALL "MLAB" OR "NICR" BE LIABLE TO ANY PARTY FOR DIRECT,
11  * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
12  * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF "MLAB" OR
13  * "NICR" HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14  *
15  * "MLAB" AND "NICR" SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
16  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
18  * ON AN "AS IS" BASIS, AND "MLAB" AND "NICR" HAVE NO OBLIGATION TO
19  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR MODIFICATIONS.
20  */
21 
30 #ifndef _MIRA_PILOT_METRICPLANNERBASE_H_
31 #define _MIRA_PILOT_METRICPLANNERBASE_H_
32 
34 
35 namespace mira { namespace pilot {
36 
38 
39 inline double plannerDefaultInfinity()
40 {
41 #ifdef WIN32
42  // Under some circumstances, Visual C++ does not seem to like the
43  // "proper" way, but sometimes it does. Anyway, this workaround
44  // should do the trick. Note that initializing a non-integer static
45  // const is not supposed to be standard either...
46  return DBL_MAX;
47 #else
48  return std::numeric_limits<double>::max();
49 #endif
50 }
51 
56 {
58 public:
59 
60  MetricPlannerBase(bool useDoubleBuffer = false,
61  bool persistentDoubleBuffer = false);
62  virtual ~MetricPlannerBase() {}
63 
64  template <typename Reflector>
65  void reflect(Reflector& r)
66  {
68 
69  r.member("UseDoubleBuffer",
72  "Use double buffering for the planner map", false, REFLECT_CTRLFLAG_MEMBER_AS_ROPROPERTY);
73  r.property("PersistentDoubleBuffer",
76  "Do NOT invalidate double buffer when a new goal is set",
77  false);
78  r.property("CarrotFromDoubleBuffer", mGetCarrotFromDoubleBuffer,
79  "Whether getCarrot should be performed on the DoubleBuffer, if active and valid.",
80  false);
81  r.property("MaxPlanningTime", mMaxPlanningTime,
82  "How long should we plan until we decide that we can not plan a path",
83  Duration::seconds(30));
84  r.property("PathLostTimeout", mPathLostTimeout,
85  "If the planner has no path since the specified time (but had one before) XPathLost is thrown",
86  Duration::seconds(10));
87  r.property("Navfscale", mNavfscale, "The color scaling of the path costs during visualization", 0.02);
88  }
89 
90 public:
91 
96  virtual void setOnewayMap(const maps::OccupancyGrid& onewayMap) {
97  MIRA_THROW(XNotImplemented, "MetricPlannerBase::setOnewayMap() not overridden by concrete subclass!")
98  }
99 
101  void setUseDoubleBuffer(bool useDoubleBuffer) {
102  mUseDoubleBuffer = useDoubleBuffer;
103  if (!useDoubleBuffer)
104  mDoubleBufferValid = false;
105  }
106 
108  void setPersistentDoubleBuffer(bool persistentDoubleBuffer) {
109  mPersistentDoubleBuffer = persistentDoubleBuffer;
110  }
111 
112 public:
113 
115  virtual Point2f getGradient(const Point2f& worldPos) const;
116 
118  Point2f getGradientMap(const Point2i& mapPos) const;
119 
121  virtual Point2f getCurrentGradientMap(const Point2i& mapPos) const;
122 
124  virtual void update(const maps::CostMap& map, const maps::DirtyRegions& dirty);
125 
130  virtual double infinity() const;
131 
133  double getValue(const Point2f& worldPos, bool ignoreDoubleBuffer = false) const;
134 
141  double getValueMap(const Point2i& mapPos, bool ignoreDoubleBuffer = false) const;
142 
144  virtual double getCurrentValueMap(const Point2i& mapPos) const = 0;
145 
147  virtual double getValueFiltered(const Point2f& worldPos, bool ignoreDoubleBuffer = false) const;
148 
150  virtual Carrot getCarrot(const Point2f& pos, int maxCount, float maxDistance = 1e10f) const;
151 
156  virtual Carrot getCurrentCarrot(const Point2f& pos, int maxCount, float maxDistance = 1e10f) const = 0;
157 
162  virtual Carrot getDoubleBufferCarrot(const Point2f& pos, int maxCount, float maxDistance = 1e10f) const;
163 
165  virtual Pose2 getCurrentGoal(const Point2f& pos) const;
166 
167 public:
168 
174  Point2i world2map(const Point2f& p) const {
175  if(mCostMap.empty())
176  MIRA_THROW(XLogical, "No costmap created yet. Call update() first.")
177  return mCostMap.world2map(p);
178  }
179 
184  Point2f map2world(const Point2i& p) const {
185  if (mCostMap.empty())
186  MIRA_THROW(XLogical, "No costmap created yet. Call update() first.")
187  return mCostMap.map2world(p);
188  }
189 
194  float getCellSize() const {
195  if (mCostMap.empty())
196  MIRA_THROW(XLogical, "No costmap created yet. Call update() first.")
197  return mCostMap.getCellSize();
198  }
199 
204  Rect2f getRegion() const {
205  if (mCostMap.empty())
206  MIRA_THROW(XLogical, "No costmap created yet. Call update() first.")
207  return mCostMap.getRegion();
208  }
209 
215  if (mCostMap.empty())
216  MIRA_THROW(XLogical, "No costmap created yet. Call update() first.")
217  return mCostMap.getMapRegion();
218  }
219 
221  bool getUseDoubleBuffer() const {
222  return mUseDoubleBuffer;
223  }
224 
228  }
229 
233  }
234 
235 public:
236 
238  void setGoal(const Point2f& goal, float radius,
239  bool clearDoubleBuffer = true, bool prepareNew = true);
240 
242  void setGoal(const Polygon2i& polygon, int radius = 1,
243  bool clearDoubleBuffer = true, bool prepareNew = true);
244 
246  void setGoal(const Polygon2f& polygon, float radius = 0.1f,
247  bool clearDoubleBuffer = true, bool prepareNew = true);
248 
250  void setGoal(const Polygon2i& polygon, int radius, CostFn& costFn,
251  bool clearDoubleBuffer = true, bool prepareNew = true);
252 
254  void setGoal(const Polygon2f& polygon, float radius, CostFn& costFn,
255  bool clearDoubleBuffer = true, bool prepareNew = true);
256 
258  float defaultCostFn(int x, int y, float r);
259 
260 protected:
261 
263  virtual bool isValid() const;
264 
266  virtual void reset();
267 
273  virtual void resetDoubleBuffer(bool createNew);
274 
276  virtual void copyDoubleBuffer() = 0;
277 
283  void prepareNewGoal(bool clearDoubleBuffer);
284 
286  virtual void removeGoals() = 0;
287 
292  virtual void addGoal(const Point2i& p, float cost) = 0;
293 
295  virtual void freeCell(const Point2i& p) = 0;
296 
298  virtual void dirtyCell(const Point2i& p, double value) = 0;
299 
307  int maxCount, float maxDistance) const;
308 
309  int computeStableGradientFromMap(const maps::CostMap& map, int ix, int iy, double baseVal, double stepsize,
310  double& dx, double& dy, double& gx, double& gy) const;
311 
312 public:
313 
315  void plan(const Point2f& pos, Duration plantime);
316 
318  bool havePlan() const { return mHadValidPlan; }
319 
322 
324  Time lastValidPlan() const { return mLastValidPlan; }
325 
327  void planTime(Duration plantime);
328 
330  void planSteps(int steps);
331 
333  void resetPlanningTimeout();
334 
336  maps::CostMap getNavFunction(bool ignoreDoubleBuffer = false) const;
337 
343  virtual maps::CostMap getCurrentNavFunction() const = 0;
344 
345 public:
346 
348  maps::GridMap<uint8,3> dumpNavStatus(bool useDoubleBuffer = false,
349  bool costsInGoalRegion = true);
350 
353 
354 public:
355 
357  Status getStatus(const Point2f& p) const;
358 
363  virtual Status getStatusMap(const Point2i& p) const;
364 
365 protected:
366 
371  virtual Img8U1 getStatusField() const;
372 
378  double filteredCorner(double self, double xnb,
379  double ynb, double diagnb) const;
380 
381 protected:
382 
385 
386  // the buffer is used to copy complete paths when after the planning wave
387  // reached the robot
388  maps::CostMap mDoubleBuffer; // buffer for nav function
389 
390  // last point of time, where planning was started or a valid plan existed
391  // internally used as timeout when no valid plan exists
393 
394  // last point of time, where a valid plan existed
395  // equals mLastPlan if havePlan()
396  // is older than mLastPlan if !havePlan()
397  // externally provided, because this is the age of the double buffer
399 
400  // How much time has been spent planning until we reach the goal
402 
408 
409  float mNavfscale;
410 
411  // in order to achieve subcell nav function resolution at goal proximity
412  // (enabling to reach the goal point and not just the goal cell):
413  // nav function is overlaid with pyramidal cost function in goal point's
414  // 3x3 cell neighborhood (pyramid base = 3x3 cell area,
415  // pyramid tip = goal point)
419  Eigen::VectorXf mPointGoalPyrBorder;
420  Eigen::VectorXf mPointGoalPyrSlope;
421 
424 
425  // To ensure, that we only access the double buffer when the double buffer
426  // contains valid data, this flag will be set to true if mUseDoubleBuffer
427  // is true AND the function copyDoubleBuffer was called. Otherwise, the
428  // double buffer might be (still) invalid or infinity and therefore will
429  // not be accessed.
431 
432  // Usually, the double buffer should be invalidated when setting a new goal.
433  // However, for a continuously moving target, it is reasonable to keep the
434  // double buffer, in order to follow the path to the previous goal position
435  // while planning to the new goal. This can be achieved with this
436  // flag.
438 };
439 
441 
442 }}
443 
444 #endif
Point2f map2world(const Point2i &p) const
Implementation of AbstractMetricPlanner::world2map(const Point2i&)
Definition: MetricPlannerBase.h:184
Point2f map2world(const Point2i &p) const
std::function< float(int x, int y, float r)> CostFn
Type declaration for a cost function to be used with setGoal(const Polygon2i, ...) or setGoal(const P...
Definition: AbstractMetricPlanner.h:198
Rect2i getMapRegion() const
Implementation of AbstractMetricPlanner::getMapRegion()
Definition: MetricPlannerBase.h:214
Point2i mPointGoalCell
Definition: MetricPlannerBase.h:418
virtual maps::CostMap getCurrentNavFunction() const =0
Creates a deep copy of the current navigation function that contains the accumulated costs from each ...
bool havePlan() const
Implementation of AbstractMetricPlanner::havePlan()
Definition: MetricPlannerBase.h:318
virtual void reset()
Re-initialize internal structures.
Base class for implementations of metric planners like Dijkstra and E*.
Definition: MetricPlannerBase.h:55
maps::CostMap getNavFunction(bool ignoreDoubleBuffer=false) const
Implementation of AbstractMetricPlanner::getNavFunction(bool)
Duration mAccumulatedPlanningTime
Definition: MetricPlannerBase.h:401
Time lastValidPlan() const
Implementation of AbstractMetricPlanner::lastValidPlan()
Definition: MetricPlannerBase.h:324
virtual Carrot getCarrot(const Point2f &pos, int maxCount, float maxDistance=1e10f) const
Implementation of AbstractMetricPlanner::getCarrot(const Point2f&, int, float)
virtual void addGoal(const Point2i &p, float cost)=0
Add a goal cell with a certain cost (e.g.
#define MIRA_REFLECT_BASE(reflector, BaseClass)
virtual void resetDoubleBuffer(bool createNew)
Set the entire double buffer to infinity.
void resetPlanningTimeout()
Implementation of AbstractMetricPlanner::resetPlanningTimeout()
bool mHadValidPlanSinceUpdate
Definition: MetricPlannerBase.h:406
Setter< T > setter(void(*f)(const T &))
Interface for metric planners like Dijkstra and E*.
Definition: AbstractMetricPlanner.h:48
Point2f mPointGoal
Definition: MetricPlannerBase.h:417
bool havePlanSinceUpdate() const
Implementation of AbstractMetricPlanner::havePlanSinceUpdate()
Definition: MetricPlannerBase.h:321
virtual Pose2 getCurrentGoal(const Point2f &pos) const
Implementation of AbstractMetricPlanner::getCurrentGoal(const Point2f&)
maps::GridMap< uint8, 3 > dumpNavStatus(bool useDoubleBuffer=false, bool costsInGoalRegion=true)
Implementation of AbstractMetricPlanner::dumpNavStatus(bool, bool)
StatusMap getStatusMap() const
virtual Carrot getCurrentCarrot(const Point2f &pos, int maxCount, float maxDistance=1e10f) const =0
Return the optimal path to the goal, starting at pos, based on the current planner map...
Point2i world2map(const Point2f &p) const
Implementation of AbstractMetricPlanner::world2map(const Point2f&)
Definition: MetricPlannerBase.h:174
#define MIRA_THROW(ex, msg)
void plan(const Point2f &pos, Duration plantime)
Implementation of AbstractMetricPlanner::plan(const Point2f&, Duration)
double filteredCorner(double self, double xnb, double ynb, double diagnb) const
Fix infinite (invalid) values by replacing with finite neighbour values, if available.
std::vector< Point2f > Carrot
Definition: AbstractMetricPlanner.h:53
int computeStableGradientFromMap(const maps::CostMap &map, int ix, int iy, double baseVal, double stepsize, double &dx, double &dy, double &gx, double &gy) const
#define MIRA_ABSTRACT_OBJECT(classIdentifier)
Interface for metric planners like Dijkstra and E*.
virtual double getValueFiltered(const Point2f &worldPos, bool ignoreDoubleBuffer=false) const
Implementation of AbstractMetricPlanner::getValueFiltered(const Point2f&, bool)
Duration getAccumulatedPlanningTime() const
Implementation of AbstractMetricPlanner::getAccumulatedPlanningTime()
Definition: MetricPlannerBase.h:231
float getCellSize() const
Implementation of AbstractMetricPlanner::getCellSize()
Definition: MetricPlannerBase.h:194
void reflect(Reflector &r)
Definition: MetricPlannerBase.h:65
bool mDoubleBufferValid
Definition: MetricPlannerBase.h:430
maps::GridMap< uint8, 3 > showNavFunctionNearGoal()
Implementation of AbstractMetricPlanner::showNavFunctionNearGoal()
MetricPlannerBase(bool useDoubleBuffer=false, bool persistentDoubleBuffer=false)
Time mLastValidPlan
Definition: MetricPlannerBase.h:398
maps::CostMap mDoubleBuffer
Definition: MetricPlannerBase.h:388
Eigen::VectorXf mPointGoalPyrBorder
Definition: MetricPlannerBase.h:419
bool getPersistentDoubleBuffer() const
Persistent double buffer enabled (i.e. not reset on setting goal)?
Definition: MetricPlannerBase.h:226
boost::geometry::model::ring< Point2i > Polygon2i
sec_type seconds() const
Rect2i getMapRegion() const
void planSteps(int steps)
Implementation of AbstractMetricPlanner::planSteps(int)
bool mPersistentDoubleBuffer
Definition: MetricPlannerBase.h:437
void setUseDoubleBuffer(bool useDoubleBuffer)
Enable/disable double buffer.
Definition: MetricPlannerBase.h:101
Point2f getGradientMap(const Point2i &mapPos) const
Returns the gradient for a position in map coordinates.
Getter< T > getter(T(*f)())
void prepareNewGoal(bool clearDoubleBuffer)
Call removeGoals() and reset all status and timing data related to planning on the current goal...
virtual void dirtyCell(const Point2i &p, double value)=0
Update a cell&#39;s cost map value in the planner&#39;s internal cost function representation.
std::list< Rect2i > DirtyRegions
void planTime(Duration plantime)
Implementation of AbstractMetricPlanner::planTime(Duration)
virtual void update(const maps::CostMap &map, const maps::DirtyRegions &dirty)
Implementation of AbstractMetricPlanner::update(const maps::CostMap&, const maps::DirtyRegions&) ...
virtual void freeCell(const Point2i &p)=0
Mark a cell as free in the planner&#39;s internal cost function representation.
AbstractMetricPlanner::Carrot getCarrotFromMap(const maps::CostMap &map, const Point2f &pos, int maxCount, float maxDistance) const
Calculate a path through the given costmap, starting at pos and following the gradient computed by co...
virtual Point2f getCurrentGradientMap(const Point2i &mapPos) const
Returns the gradient for a position in map coordinates from current costs.
bool mHasPointGoal
Definition: MetricPlannerBase.h:416
virtual Point2f getGradient(const Point2f &worldPos) const
Implementation of AbstractMetricPlanner::getGradient(const Point2f&)
virtual void copyDoubleBuffer()=0
Copy entire field of internally calculated cost values to mDoubleBuffer.
bool mGetCarrotFromDoubleBuffer
Definition: MetricPlannerBase.h:423
virtual void removeGoals()=0
Remove all set goals.
bool mHadValidPlan
Definition: MetricPlannerBase.h:405
double getValue(const Point2f &worldPos, bool ignoreDoubleBuffer=false) const
Implementation of AbstractMetricPlanner::getValue(const Point2f&, bool)
void setGoal(const Point2f &goal, float radius, bool clearDoubleBuffer=true, bool prepareNew=true)
Implementation of AbstractMetricPlanner::setGoal(const Point2f&, float, bool, bool) ...
virtual Carrot getDoubleBufferCarrot(const Point2f &pos, int maxCount, float maxDistance=1e10f) const
Return the optimal path to the goal, starting at pos, based on the double buffer. ...
float getCellSize() const
Point2i world2map(const Point2f &p, bool roundDown=true) const
double plannerDefaultInfinity()
Definition: MetricPlannerBase.h:39
virtual bool isValid() const
Return whether planner is properly initialized and able to calculate a path (when a goal is set) ...
Size2i mSize
Definition: MetricPlannerBase.h:383
Eigen::VectorXf mPointGoalPyrSlope
Definition: MetricPlannerBase.h:420
virtual double infinity() const
Implementation of AbstractMetricPlanner::infinity().
float defaultCostFn(int x, int y, float r)
A default cost function which is always returning r (radius)
bool mUseDoubleBuffer
Definition: MetricPlannerBase.h:422
bool getUseDoubleBuffer() const
Double buffer enabled?
Definition: MetricPlannerBase.h:221
void setPersistentDoubleBuffer(bool persistentDoubleBuffer)
Enable/disable persistent double buffer (i.e. not reset when setting goal)
Definition: MetricPlannerBase.h:108
Duration mPathLostTimeout
Definition: MetricPlannerBase.h:404
float mNavfscale
Definition: MetricPlannerBase.h:409
boost::geometry::model::ring< Point2f > Polygon2f
Time mLastPlan
Definition: MetricPlannerBase.h:392
Rect2f getRegion() const
Implementation of AbstractMetricPlanner::getRegion()
Definition: MetricPlannerBase.h:204
maps::CostMap mCostMap
Definition: MetricPlannerBase.h:384
Duration mMaxPlanningTime
Definition: MetricPlannerBase.h:403
virtual ~MetricPlannerBase()
Definition: MetricPlannerBase.h:62
virtual Img8U1 getStatusField() const
Return the result of getStatusMap(const Point2i&) over the entire map area.
virtual double getCurrentValueMap(const Point2i &mapPos) const =0
Returns the cost value at position (in map coordinates) in the current planner map.
virtual void setOnewayMap(const maps::OccupancyGrid &onewayMap)
Implementation of AbstractMetricPlanner::setOnewayMap().
Definition: MetricPlannerBase.h:96
bool mPathLostReported
Definition: MetricPlannerBase.h:407
Status::StatusMode getStatus() const
double getValueMap(const Point2i &mapPos, bool ignoreDoubleBuffer=false) const
Returns the cost value at position (in map coordinates) in the planner map.
REFLECT_CTRLFLAG_MEMBER_AS_ROPROPERTY
Rect2f getRegion() const