MIRA
MetricCostmapTopoMapPlanner.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) by
3  * Neuroinformatics and Cognitive Robotics Labs (NICR) at TU Ilmenau, GERMANY
4  * All rights reserved.
5  *
6  * Redistribution and modification of this code is strictly prohibited.
7  *
8  * IN NO EVENT SHALL "NICR" BE LIABLE TO ANY PARTY FOR DIRECT,
9  * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
10  * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF "NICR" HAS BEEN
11  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12  *
13  * "NICR" SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
14  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15  * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND
16  * "NICR" HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
17  * ENHANCEMENTS OR MODIFICATIONS.
18  */
19 
28 #pragma once
29 
30 #include <fw/Framework.h>
31 
32 #include <model/Marker.h>
33 
34 #include <transform/Pose.h>
35 #include <maps/CostMap.h>
36 #include <pilot/AbstractMetricPlanner.h>
37 
38 #include <topomap/TopoMap.h>
39 #include <topomap/TopoMapPlanner.h>
40 
42 #include <topomap/MapAttributes.h>
43 
44 
45 namespace viros { namespace topomap {
46 
48 
53 {
54  typedef std::vector<std::tuple<GatewayNodePtr, GatewayNodePtr, double>> GatewayHops;
55 
56 public:
57 
59 
60  template<typename Reflector>
61  void reflect(Reflector& r)
62  {
63  mira::serialization::Array<PlannerContext> plannerCtx(mPlannerCtx,3);
64  r.property("PlannerCtx", plannerCtx, "");
65  r.property("GatewayWidth", mGatewayWidth, "goal width of gateways in cells", 2);
66  r.property("EnableReplanning", mEnableReplanning, "Specifies whether global replanning within the topological structure is enabled.", true);
67  r.property("TolerableDetourBeforeReplan", mTolerableDetourBeforeReplan,
68  "The allowed detour in meter caused by significant changes in the environment."
69  "If the detour becomes larger than this threshold, a global replanning"
70  "within the topological structure is triggered after the time span specified"
71  "below. (default 10.0 m)", 10.0f);
72  r.property("TimeUntilReplan", mTimeUntilReplan,
73  "Time duration, until replanning is triggered when the current path "
74  "became sub-optimal after significant changes in the environment.",
76  r.property("MaxPlanningTime", mMaxPlanningTime,
77  "How long should we plan until we decide that we can not plan a path",
79  r.property("AllowGoalsWithInfiniteCosts", mAllowGoalsWithInfiniteCosts,
80  "If true planning to goals with infinite costs is allowed. "
81  "This is necessary for moving goals (e.g. follow objective).",
82  false);
83  r.member("CachePath", mCachePath,
84  "The path for caching preplanned maps to enable faster bootup. "
85  "The directory will be created if it does not exist.", "cache");
86  }
87 
88 public:
89 
90  struct PlannerContext {
91  mira::pilot::AbstractMetricPlannerPtr planner;
92  mira::maps::CostMap map;
93  mira::maps::DirtyRegions dirty;
97  bool active;
98  boost::optional<double> lastCosts;
99  PlannerContext() : active(false) {}
100 
101  bool finalApproach() const { return !gw; }
102 
103  void reset() {
104  node.reset();
105  gw.reset();
106  active = false;
107  lastCosts.reset();
108  }
109 
110  template<typename Reflector>
111  void reflect(Reflector& r)
112  {
113  r.property("Planner", planner, "");
114  r.roproperty("Active", active, "");
115  }
116  };
117 
119 
120 /*
121  struct GoalNodeInfo
122  {
123  GoalNodeInfo() {}
124  GoalNodeInfo(NodePtr node, const std::string& frame,
125  const Point2i& goalcell, const Point2f& goalinmap) :
126  node(node), frame(frame), goalcell(goalcell), goalinmap(goalinmap) {}
127  NodePtr node;
128  std::string frame; // frame of the node's map
129  Point2i goalcell;
130  Point2f goalinmap;
131  };
132  typedef std::list<GoalNodeInfo> GoalNodeInfoList;
133 */
135  {
137  NodePosition(NodePtr node, const std::string& frame, const Point2f& pos) :
138  node(node), frame(frame), pos(pos) {}
140  std::string frame; // frame of the node's map
142  };
143  typedef std::list<NodePosition> NodePositionList;
144 
146  {
147  public:
148 
149  virtual ~IEventListener() {}
150 
157  virtual void onNodeChanged(NodePtr currentNode, GatewayNodePtr usedGateway, GatewayNodePtr nextGateway) = 0;
158  };
159 
160  struct NextSubGoal {
163  double costs;
164  double remainingcosts; // remaining costs to final goal when subgoal is reached
165  int hops;
166 
167  template<typename Reflector>
168  void reflect(Reflector& r)
169  {
170  r.member("Node", getter(&NextSubGoal::getNodeName, this), setter(&NextSubGoal::dummySetter, this), "");
171  r.member("GatewayNode", getter(&NextSubGoal::getGatewayNodeName, this), setter(&NextSubGoal::dummySetter, this), "");
172  r.member("Costs", costs, "");
173  r.member("RemainingCosts", remainingcosts, "");
174  r.member("Hops", hops, "");
175  }
176 
178  costs(std::numeric_limits<double>::max()),
179  remainingcosts(std::numeric_limits<double>::max()),
180  hops(std::numeric_limits<int>::max()) {}
181 
182  void reset()
183  {
184  n.reset();
185  gn.reset();
186  costs = std::numeric_limits<double>::max();
187  remainingcosts = std::numeric_limits<double>::max();
188  hops = std::numeric_limits<int>::max();
189  }
190 
191  std::string getNodeName() {
192  return n ? n->getFullName() : "<null>";
193  }
194  std::string getGatewayNodeName() {
195  return gn ? gn->getFullName() : "<null>";
196  }
197  void dummySetter(std::string s) {}
198 
199  };
200  static void printNextSubGoal(const NextSubGoal& nsg,
201  const std::string& name);
202 
203 public:
204 
207  bool isInFinalApproach() const
208  {
209  return mCurrentPlanner->active && mCurrentPlanner->finalApproach();
210  }
211 
212  bool isActive() const;
213  double getValue(const Point2f& worldPos) const;
214  double getValueFiltered(const Point2f& worldPos) const;
215 
216  mira::pilot::AbstractMetricPlanner::Carrot getCarrot(const Point2f& pos, int count, float length = 1e10f) const;
217 
220  void resetCostMaps();
221 
223  mEventListener = listener;
224  }
225 
226  // --- necessary for PilotPathToMovingGoalTopoMap ---
228  {
229  return mCurrentPlanner;
230  }
232  {
233  return mNextPlanner;
234  }
235  // --------------------------------------------------
236 
237  // debugging:
238  mira::maps::GridMap<double> getNavFunction(bool ignoreDoubleBuffer = false);
239  mira::maps::GridMap<uint8,3> dumpNavStatus(bool actualMap = false,
240  bool costsInGoalRegion = true);
241 
242 public:
243 
245  void initialize(TopoMapPtr map, Authority* authority);
246 
247  typedef boost::function<void(mira::pilot::AbstractMetricPlannerPtr, bool)> UpdateGoalFn;
248  void setGoal(const NodePositionList& goalNodes, UpdateGoalFn updateGoalFn);
249 
251  void update(const maps::CostMap& map);
252 
254  void update(const maps::CostMap& map, const maps::DirtyRegions& dirty);
255 
257  bool havePlan() const;
258 
259  void plan(const mira::maps::CostMap& curCostmap,
260  const Point2f& robotPos,
261  const NodePositionList& localizedNodes,
262  Duration plantime);
263 
264  void clearGoal();
265 
266  void setAdditionalLinkCosts(const std::string& fromGWName, const std::string& toGWName, double costs) {
267  mTopoPlanner.setAdditionalLinkCosts(fromGWName, toGWName, costs);
268  }
270  mTopoPlanner.resetAllAdditionalLinkCosts();
271  }
272 
274  mDbgMarkerChannel = c;
275  }
277  mDbgNextSubGoalChannel = c;
278  }
279 
280 private:
281 
282  void drawGateway(mira::model::Marker& marker, std::tuple<GatewayNodePtr, GatewayNodePtr, double> gw);
283  bool traverseLinks(GatewayHops& gatewayHops, NodeSet& localizedNodes, GatewayNodePtr node, int hops);
284 
285  void planCurrentPlanner();
286  bool updateGoalFunction(PlannerContextPtr plannerCtx, bool initial = false);
287 
288  void handleReplanningLastCostBased(const mira::maps::CostMap& curCostmap);
289  double getCurrentPlannerCosts(const Point2f& p, bool ignoreDoubleBuffer);
290 
291  void topologicalPlanning(const NodePositionList& localizedNodes);
292  void prepareVisitedList();
293 
294  void selectSubGoal(const NodePositionList& localizedNodes);
295  void determineLocalizedNodesWithGoal(const NodePositionList& localizedNodes);
296 
297  void determineBestTopoSubGoals(const NodePositionList& localizedNodes,
298  NextSubGoal& oBestSubGoal,
299  NextSubGoal& oSecondBestSubGoal);
300  void determineBestTopoSubGoals(const GatewayNodeSet& gatewayNodes,
301  const Point2f& robotPos,
302  NextSubGoal& oBestSubGoal,
303  NextSubGoal& oSecondBestSubGoal);
304  bool isBetterThanSubGoal(double costs, int hops,
305  const NextSubGoal& subGoal);
306  void assignToSubGoal(GatewayNodePtr gn,
307  double costs,
308  double remainingcosts,
309  int hops,
310  NextSubGoal& oSubGoal);
311 
312  void handleNextPlanner();
313  void prepareNextPlanner();
314 
315  bool isInGoalNode() const;
316  bool isGoalNodeWithLocalization(NodePtr n) const;
317  const NodePosition* getNodePosition(NodePtr n, const NodePositionList& nodePosList) const;
318 
319 private:
320 
321  void preparePlannerContext(PlannerContextPtr ctx, const mira::maps::GridMap<double>& costmap, const std::string& frameID, RegionAttributePtr regionattr);
322  void setGatewayGoal(PlannerContextPtr ctx, int mapHeight, GatewayPtr gw);
323 
324  void computeLeafCosts(NodePtr node);
325 
326  void updateNodeCosts(NodePtr node, const Stamped<mira::maps::GridMap<double>>& costmap);
327  void computeNodeCosts(NodePtr node, const Stamped<mira::maps::GridMap<double>>& costmap, bool useCache);
328 
330  friend struct ResetCostMapsVisitor;
331 
332  void readNavFuncFromCache(const std::string& gatewayName,
333  const Stamped<mira::maps::GridMap<double>>& costmap,
334  const RegionAttributePtr& regionPtr,
335  maps::CostMap& navFn,
336  std::string& md5sum,
337  std::string& cacheFileName);
338  void writeNavFuncToCache(const maps::CostMap& navFn,
339  const std::string& md5sum,
340  std::string& cacheFileName);
341 
342 private:
343 
344  Authority* mAuthority;
345  UpdateGoalFn mUpdateGoalFn;
346  IEventListener* mEventListener;
347 
348  TopoMapPtr mTopoMap;
349  int mGatewayWidth;
350 
351  TopoMapPlanner mTopoPlanner;
352  PlannerContext mPlannerCtx[3];
353  PlannerContextPtr mCurrentPlanner;
354  PlannerContextPtr mNextPlanner;
355  PlannerContextPtr mAuxPlanner;
356 
357  NodePositionList mGoalNodes;
358 
359  Point2f mCurrentRobotPosition;
360  Duration mCurrentPlantime;
361 
362  NodePositionList mLocalizedNodesWithGoal;
363  TopoMapPlanner::VisitedList mVisitedList;
364  NextSubGoal mCurrentSubGoal;
365  bool mAllowGoalsWithInfiniteCosts;
366 
367  std::string dbgTimeNow;
368 
369  bool mEnableReplanning;
370  float mTolerableDetourBeforeReplan;
371  Duration mTimeUntilReplan;
372  Time mReplanTimeoutStart;
373 
374  Duration mMaxPlanningTime;
375  Time mLastValidPlanningTime;
376 
377  Path mCachePath;
378  double mMaxCosts;
379 
380  Channel<mira::model::Marker> mDbgMarkerChannel;
381  Channel<NextSubGoal> mDbgNextSubGoalChannel;
382 };
383 
384 
386 
387 } } // namespace
void reset()
Definition: MetricCostmapTopoMapPlanner.h:182
std::string getGatewayNodeName()
Definition: MetricCostmapTopoMapPlanner.h:194
void reset()
Definition: MetricCostmapTopoMapPlanner.h:103
std::list< NodePosition > NodePositionList
Definition: MetricCostmapTopoMapPlanner.h:143
mira::maps::CostMap map
Definition: MetricCostmapTopoMapPlanner.h:92
void resetCostMaps()
Reset all cost maps to the inital values.
PlannerContextPtr getCurrentPlanner()
Definition: MetricCostmapTopoMapPlanner.h:227
double getValueFiltered(const Point2f &worldPos) const
Definition: MetricCostmapTopoMapPlanner.h:90
boost::filesystem::path Path
PlannerContextPtr getNextPlanner()
Definition: MetricCostmapTopoMapPlanner.h:231
Hybrid metric-topological planner for 2D costmaps.
Definition: MetricCostmapTopoMapPlanner.h:52
NodePtr node
Definition: MetricCostmapTopoMapPlanner.h:139
mira::maps::GridMap< double > getNavFunction(bool ignoreDoubleBuffer=false)
STL namespace.
Setter< T > setter(void(*f)(const T &))
boost::shared_ptr< GatewayNode > GatewayNodePtr
Definition: TopoMapFwd.h:87
void setGoal(const NodePositionList &goalNodes, UpdateGoalFn updateGoalFn)
NodePosition()
Definition: MetricCostmapTopoMapPlanner.h:136
NodePosition(NodePtr node, const std::string &frame, const Point2f &pos)
Definition: MetricCostmapTopoMapPlanner.h:137
static void printNextSubGoal(const NextSubGoal &nsg, const std::string &name)
void reflect(Reflector &r)
Definition: MetricCostmapTopoMapPlanner.h:111
PlannerContext * PlannerContextPtr
Definition: MetricCostmapTopoMapPlanner.h:118
mira::pilot::AbstractMetricPlannerPtr planner
Definition: MetricCostmapTopoMapPlanner.h:91
void update(const maps::CostMap &map)
update the planning context with the current costmap (entire area)
std::set< NodePtr, shared_ptr_sort< Node > > NodeSet
Definition: TopoMapFwd.h:101
Definition: MetricCostmapTopoMapPlanner.h:134
friend struct ResetCostMapsVisitor
Definition: MetricCostmapTopoMapPlanner.h:329
void setEventListener(IEventListener *listener)
Definition: MetricCostmapTopoMapPlanner.h:222
double remainingcosts
Definition: MetricCostmapTopoMapPlanner.h:164
void setDebugNextSubGoalChannel(Channel< NextSubGoal > c)
Definition: MetricCostmapTopoMapPlanner.h:276
void setDebugMarkerChannel(Channel< mira::model::Marker > c)
Definition: MetricCostmapTopoMapPlanner.h:273
sec_type seconds() const
void reflect(Reflector &r)
Definition: MetricCostmapTopoMapPlanner.h:61
mira::pilot::AbstractMetricPlanner::Carrot getCarrot(const Point2f &pos, int count, float length=1e10f) const
boost::shared_ptr< RegionAttribute > RegionAttributePtr
Definition: TopoMapFwd.h:77
Point2f pos
Definition: MetricCostmapTopoMapPlanner.h:141
Definition: MetricCostmapTopoMapPlanner.h:160
void plan(const mira::maps::CostMap &curCostmap, const Point2f &robotPos, const NodePositionList &localizedNodes, Duration plantime)
void initialize(TopoMapPtr map, Authority *authority)
initializes the planner with the given topo map
Getter< T > getter(T(*f)())
virtual ~IEventListener()
Definition: MetricCostmapTopoMapPlanner.h:149
mira::maps::DirtyRegions dirty
Definition: MetricCostmapTopoMapPlanner.h:93
boost::shared_ptr< Gateway > GatewayPtr
Definition: TopoMapFwd.h:86
Definition: MetricCostmapTopoMapPlanner.h:145
void setAdditionalLinkCosts(const std::string &fromGWName, const std::string &toGWName, double costs)
Define additional costs for a specific link.
GatewayNodePtr gw
Definition: MetricCostmapTopoMapPlanner.h:96
boost::function< void(mira::pilot::AbstractMetricPlannerPtr, bool)> UpdateGoalFn
Definition: MetricCostmapTopoMapPlanner.h:247
bool havePlan() const
Returns true if we have or have had a valid to the set goal.
NodePtr n
Definition: MetricCostmapTopoMapPlanner.h:161
void dummySetter(std::string s)
Definition: MetricCostmapTopoMapPlanner.h:197
NextSubGoal()
Definition: MetricCostmapTopoMapPlanner.h:177
PlannerContext()
Definition: MetricCostmapTopoMapPlanner.h:99
double costs
Definition: MetricCostmapTopoMapPlanner.h:163
std::string getNodeName()
Definition: MetricCostmapTopoMapPlanner.h:191
mira::maps::GridMap< uint8, 3 > dumpNavStatus(bool actualMap=false, bool costsInGoalRegion=true)
void setAdditionalLinkCosts(const std::string &fromGWName, const std::string &toGWName, double costs)
Definition: MetricCostmapTopoMapPlanner.h:266
bool active
Definition: MetricCostmapTopoMapPlanner.h:97
int hops
Definition: MetricCostmapTopoMapPlanner.h:165
std::string frame
Definition: MetricCostmapTopoMapPlanner.h:140
bool isInFinalApproach() const
Returns true, if the robot is within the goal node and driving directly to the goal.
Definition: MetricCostmapTopoMapPlanner.h:207
Rect2i rect
Definition: MetricCostmapTopoMapPlanner.h:94
boost::optional< double > lastCosts
Definition: MetricCostmapTopoMapPlanner.h:98
virtual void onNodeChanged(NodePtr currentNode, GatewayNodePtr usedGateway, GatewayNodePtr nextGateway)=0
Is called, after the robot has just moved into the next node.
boost::shared_ptr< TopoMap > TopoMapPtr
Definition: TopoMapFwd.h:91
boost::shared_ptr< Node > NodePtr
Definition: TopoMapFwd.h:84
Definition: MetricCostmapTopoMapPlanner.h:45
void resetAllAdditionalLinkCosts()
Definition: MetricCostmapTopoMapPlanner.h:269
NodePtr node
Definition: MetricCostmapTopoMapPlanner.h:95
bool finalApproach() const
Definition: MetricCostmapTopoMapPlanner.h:101
double getValue(const Point2f &worldPos) const
GatewayNodePtr gn
Definition: MetricCostmapTopoMapPlanner.h:162
Definition: TopoMapPlanner.h:34
std::map< GatewayNodePtr, CostInfo > VisitedList
Definition: TopoMapPlanner.h:125
void resetAllAdditionalLinkCosts()
Reset all additional gateways costs to zero.
std::set< GatewayNodePtr, shared_ptr_sort< GatewayNode > > GatewayNodeSet
Definition: TopoMapFwd.h:102
void reflect(Reflector &r)
Definition: MetricCostmapTopoMapPlanner.h:168