locomove_base.cpp
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2017, Locus Robotics
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of the copyright holder nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  */
34 
38 #include <nav_2d_utils/path_ops.h>
39 #include <memory>
40 #include <string>
41 #include <vector>
42 
43 namespace locomove_base
44 {
50 std::string getNamespace(const std::string& s)
51 {
52  std::vector<std::string> split;
53  boost::split(split, s, boost::is_any_of("/:"));
54  return split.back();
55 }
56 
67 {
68  // Double check robot_base_frame parameters for backwards compatibility
69  if (!nh.hasParam("robot_base_frame"))
70  {
71  // If robot_base_frame was not set, use one of the values from the costmaps
72  std::string planner_frame, controller_frame, value_to_use;
73  nh.param("global_costmap/robot_base_frame", planner_frame, std::string(""));
74  nh.param("local_costmap/robot_base_frame", controller_frame, std::string(""));
75  if (planner_frame != controller_frame)
76  {
77  if (planner_frame.length() == 0)
78  {
79  value_to_use = controller_frame;
80  }
81  else if (controller_frame.length() == 0)
82  {
83  value_to_use = planner_frame;
84  }
85  else
86  {
87  ROS_WARN_NAMED("LocoMoveBase", "Two different robot_base_frames set for global and local planner. "
88  "This could be problematic. Using the global base frame.");
89  value_to_use = planner_frame;
90  }
91  }
92  else
93  {
94  value_to_use = planner_frame;
95  }
96  nh.setParam("robot_base_frame", value_to_use);
97  }
98 
99  // Set the Global Planner Parameters
100  std::string planner_class, planner_namespace;
101  std::vector<std::string> plugin_namespaces;
102 
103  // Load the name of the nav_core1 global planner
104  nh.param("base_global_planner", planner_class, std::string("navfn/NavfnROS"));
105  planner_namespace = getNamespace(planner_class);
106  if (planner_class == "nav_core_adapter::GlobalPlannerAdapter2")
107  {
108  // If the planner class is the adapter, then get and use the nav_core2 planner
109  nh.param(planner_namespace + "/planner_name", planner_class, std::string("global_planner::GlobalPlanner"));
110  planner_namespace = getNamespace(planner_class);
111  nh.setParam(planner_namespace + "/plugin_class", planner_class);
112  plugin_namespaces.push_back(planner_namespace);
113  nh.setParam("global_planner_namespaces", plugin_namespaces);
114  }
115  else
116  {
117  // Otherwise, we need to inject the routing through the adapter
118  std::string adapter_namespace = "global_planner_adapter";
119  plugin_namespaces.push_back(adapter_namespace);
120  nh.setParam("global_planner_namespaces", plugin_namespaces);
121  nh.setParam(adapter_namespace + "/planner_name", planner_class);
122  nh.setParam(adapter_namespace + "/plugin_class", "nav_core_adapter::GlobalPlannerAdapter2");
123  }
124  plugin_namespaces.clear();
125 
126  // Since the nav_core1 local planners are not compatible with nav_core2, we either need to load the
127  // class that is being adapted, or we just load DWB instead
128  nh.param("base_local_planner", planner_class, std::string("base_local_planner/TrajectoryPlannerROS"));
129  planner_namespace = getNamespace(planner_class);
130  if (planner_namespace == "LocalPlannerAdapter")
131  {
132  nh.param(planner_namespace + "/planner_name", planner_class, std::string("dwb_local_planner::DWBLocalPlanner"));
133  planner_namespace = getNamespace(planner_class);
134  nh.setParam(planner_namespace + "/plugin_class", planner_class);
135  plugin_namespaces.push_back(planner_namespace);
136  nh.setParam("local_planner_namespaces", plugin_namespaces);
137  }
138  else if (planner_namespace == "DWAPlannerROS")
139  {
140  ROS_WARN_NAMED("LocoMoveBase", "Using DWB as the local planner instead of DWA.");
141  nh.setParam(planner_namespace + "/plugin_class", "dwb_local_planner::DWBLocalPlanner");
142  plugin_namespaces.push_back(planner_namespace);
143  nh.setParam("local_planner_namespaces", plugin_namespaces);
144  }
145  else
146  {
147  ROS_FATAL_NAMED("LocoMoveBase", "%s is unsupported in LocoMoveBase because it is not forwards compatible.",
148  planner_class.c_str());
149  }
150 
151  return nh;
152 }
153 
155  private_nh_(nh), locomotor_(loadBackwardsCompatibleParameters(nh)),
156  server_(ros::NodeHandle(), "move_base", false),
157  recovery_loader_("nav_core", "nav_core::RecoveryBehavior"),
158  local_planning_ex_(private_nh_, false), global_planning_ex_(private_nh_)
159 {
161  if (planner_frequency_ > 0.0)
162  {
165  this, false, false); // one_shot=false(default), auto_start=false
166  }
167 
172  this, false, false); // one_shot=false(default), auto_start=false
177 
180 
181  goal_pub_ = private_nh_.advertise<geometry_msgs::PoseStamped>("current_goal", 1);
182 
184 
185  // load any user specified recovery behaviors, and if that fails load the defaults
187  {
189  }
190 
191  // Patience
195 
196  // Oscillation
199 
200  // we'll provide a mechanism for some people to send goals as PoseStamped messages over a topic
201  // they won't get any useful information back about its status, but this is useful for tools
202  // like nav_view and rviz
203  ros::NodeHandle simple_nh("move_base_simple");
204  goal_sub_ = simple_nh.subscribe<geometry_msgs::PoseStamped>("goal", 1, boost::bind(&LocoMoveBase::goalCB, this, _1));
205 
208  server_.start();
209 
210  resetState();
211 }
212 
213 void LocoMoveBase::setGoal(nav_2d_msgs::Pose2DStamped goal)
214 {
215  resetState();
216  locomotor_.setGoal(goal);
218  if (planner_frequency_ > 0.0)
219  {
221  }
222  else
223  {
225  }
226 }
227 
229 {
230  std::shared_ptr<nav_core_adapter::CostmapAdapter> ptr =
231  std::dynamic_pointer_cast<nav_core_adapter::CostmapAdapter>(costmap);
232 
233  if (!ptr)
234  {
235  ROS_FATAL_NAMED("LocoMoveBase", "LocoMoveBase can only be used with the CostmapAdapter, not other Costmaps!");
236  exit(-1);
237  }
238  return ptr->getCostmap2DROS();
239 }
240 
242 {
243  // we'll start executing recovery behaviors at the beginning of our list
244  recovery_index_ = 0;
246 
247  // we want to make sure that we reset the last time we had a valid plan and control
251  planning_retries_ = 0;
252  has_global_plan_ = false;
253 }
254 
256 {
257  locomotor_.publishTwist(nav_2d_msgs::Twist2DStamped());
258 }
259 
260 void LocoMoveBase::requestNavigationFailure(const locomotor_msgs::ResultCode& result)
261 {
263  std::bind(&LocoMoveBase::onNavigationFailure, this, std::placeholders::_1));
264 }
265 
267 {
269 }
270 
272 {
274  std::bind(&LocoMoveBase::onGlobalCostmapUpdate, this, std::placeholders::_1),
275  std::bind(&LocoMoveBase::onGlobalCostmapException, this, std::placeholders::_1, std::placeholders::_2));
276 }
277 
279 {
280  // Run the global planning on the separate executor, but put the result on the main executor
282  std::bind(&LocoMoveBase::onNewGlobalPlan, this, std::placeholders::_1, std::placeholders::_2),
283  std::bind(&LocoMoveBase::onGlobalPlanningException, this, std::placeholders::_1, std::placeholders::_2));
284 }
285 
287 {
288  // If the planner_frequency is non-zero, the costmap will attempt to update again on its own (via the Timer).
289  // If it is zero, then we manually request a new update
290  if (planner_frequency_ == 0.0)
291  {
293  }
294 }
295 
296 void LocoMoveBase::onNewGlobalPlan(nav_2d_msgs::Path2D new_global_plan, const ros::Duration& planning_time)
297 {
298  has_global_plan_ = true;
300  planning_retries_ = 0;
301  locomotor_.publishPath(new_global_plan);
302  locomotor_.getCurrentLocalPlanner().setPlan(new_global_plan);
303  if (planning_time > desired_plan_duration_)
304  {
305  ROS_WARN_NAMED("locomotor", "Global planning missed its desired rate of %.4fHz... "
306  "the loop actually took %.4f seconds (>%.4f).",
308  }
310  {
311  recovery_index_ = 0;
312  }
314 }
315 
317 {
318  if (has_global_plan_)
319  {
320  // If we have a global plan already, we can ignore this exception for the time being
321  return;
322  }
323 
327  {
330  recovery();
331  }
332 }
333 
335 {
337  std::bind(&LocoMoveBase::onLocalCostmapUpdate, this, std::placeholders::_1),
338  std::bind(&LocoMoveBase::onLocalCostmapException, this, std::placeholders::_1, std::placeholders::_2));
339 }
340 
342 {
343  // check for an oscillation condition
345  {
348  recovery();
349  return;
350  }
352  std::bind(&LocoMoveBase::onNewLocalPlan, this, std::placeholders::_1, std::placeholders::_2),
353  std::bind(&LocoMoveBase::onLocalPlanningException, this, std::placeholders::_1, std::placeholders::_2),
354  std::bind(&LocoMoveBase::onNavigationCompleted, this));
355 }
356 
358 {
359  ROS_WARN_NAMED("LocoMoveBase",
360  "Sensor data is out of date, we're not going to allow commanding of the base for safety");
362 }
363 
364 void LocoMoveBase::onNewLocalPlan(nav_2d_msgs::Twist2DStamped new_command, const ros::Duration& planning_time)
365 {
367  {
368  recovery_index_ = 0;
369  }
371  locomotor_.publishTwist(new_command);
372 
373  nav_2d_msgs::Pose2DStamped current_pose = locomotor_.getLocalRobotPose();
374 
375  // check to see if we've moved far enough to reset our oscillation timeout
377  {
379  oscillation_pose_ = current_pose.pose;
380 
381  // if our last recovery was caused by oscillation, we want to reset the recovery index
383  {
384  recovery_index_ = 0;
385  }
386  }
387 
388  if (!server_.isActive())
389  {
390  return;
391  }
392 
393  // publish feedback
394  move_base_msgs::MoveBaseFeedback feedback;
395  feedback.base_position = nav_2d_utils::pose2DToPoseStamped(current_pose);
396  server_.publishFeedback(feedback);
397 }
398 
400 {
401  // check if we've tried to find a valid control for longer than our time limit
403  {
405  recovery();
406  }
407  else
408  {
409  ROS_WARN_NAMED("Locomotor", "Local planning error. Creating new global plan.");
412  planning_retries_ = 0;
414  }
415 }
416 
418 {
419  ROS_INFO_NAMED("Locomotor", "Plan completed! Stopping.");
420  if (server_.isActive())
421  {
423  }
426 }
427 
428 void LocoMoveBase::onNavigationFailure(const locomotor_msgs::ResultCode result)
429 {
430  if (server_.isActive())
431  {
433  }
436 }
437 
439 {
440  ROS_DEBUG_NAMED("locomotor", "In clearing/recovery state");
441 
442  // we'll invoke whatever recovery behavior we're currently on if they're enabled
444  {
445  ROS_DEBUG_NAMED("locomotor_recovery", "Executing behavior %u of %zu",
447  recovery_behaviors_[recovery_index_]->runBehavior();
448 
449  // we'll check if the recovery behavior actually worked
450  // ROS_DEBUG_NAMED("locomotor_recovery","Going back to planning state");
453 
454  // we at least want to give the robot some time to stop oscillating after executing the behavior
457  planning_retries_ = 0;
458 
459  // update the index of the next recovery behavior that we'll try
460  recovery_index_++;
461  }
462  else
463  {
464  ROS_DEBUG_NAMED("locomotor_recovery",
465  "All recovery behaviors have failed, locking the planner and disabling it.");
466 
468  {
469  ROS_ERROR("Aborting because a valid control could not be found."
470  "Even after executing all recovery behaviors");
471  requestNavigationFailure(locomotor::makeResultCode(locomotor_msgs::ResultCode::LOCAL_PLANNER, CONTROLLING_R,
472  "Failed to find a valid control. Even after executing recovery behaviors."));
473  }
474  else if (recovery_trigger_ == PLANNING_R)
475  {
476  ROS_ERROR("Aborting because a valid plan could not be found. Even after executing all recovery behaviors");
477  requestNavigationFailure(locomotor::makeResultCode(locomotor_msgs::ResultCode::GLOBAL_PLANNER, PLANNING_R,
478  "Failed to find a valid plan. Even after executing recovery behaviors."));
479  }
480  else if (recovery_trigger_ == OSCILLATION_R)
481  {
482  ROS_ERROR("Aborting because the robot appears to be oscillating over and over."
483  "Even after executing all recovery behaviors");
484  requestNavigationFailure(locomotor::makeResultCode(locomotor_msgs::ResultCode::LOCAL_PLANNER, OSCILLATION_R,
485  "Robot is oscillating. Even after executing recovery behaviors."));
486  }
487  }
488 }
489 
491 {
492  XmlRpc::XmlRpcValue behavior_list;
493  if (!node.getParam("recovery_behaviors", behavior_list))
494  {
495  // if no recovery_behaviors are specified, we'll just load the defaults
496  return false;
497  }
498 
499  if (behavior_list.getType() != XmlRpc::XmlRpcValue::TypeArray)
500  {
501  ROS_ERROR("The recovery behavior specification must be a list, but is of XmlRpcType %d. "
502  "We'll use the default recovery behaviors instead.",
503  behavior_list.getType());
504  return false;
505  }
506 
507  for (int i = 0; i < behavior_list.size(); ++i)
508  {
509  if (behavior_list[i].getType() != XmlRpc::XmlRpcValue::TypeStruct)
510  {
511  ROS_ERROR("Recovery behaviors must be specified as maps, but they are XmlRpcType %d. "
512  "We'll use the default recovery behaviors instead.",
513  behavior_list[i].getType());
514  return false;
515  }
516 
517  if (!behavior_list[i].hasMember("name") || !behavior_list[i].hasMember("type"))
518  {
519  ROS_ERROR("Recovery behaviors must have a name and a type and this does not. "
520  "Using the default recovery behaviors instead.");
521  return false;
522  }
523 
524  // check for recovery behaviors with the same name
525  std::string name_i = behavior_list[i]["name"];
526  for (int j = i + 1; j < behavior_list.size(); j++)
527  {
528  if (behavior_list[j].getType() != XmlRpc::XmlRpcValue::TypeStruct || !behavior_list[j].hasMember("name"))
529  {
530  continue;
531  }
532 
533  std::string name_j = behavior_list[j]["name"];
534  if (name_i == name_j)
535  {
536  ROS_ERROR("A recovery behavior with the name %s already exists, "
537  "this is not allowed. Using the default recovery behaviors instead.",
538  name_i.c_str());
539  return false;
540  }
541  }
542  }
543 
545  // if we've made it to this point, we know that the list is legal so we'll create all the recovery behaviors
546  for (int i = 0; i < behavior_list.size(); ++i)
547  {
548  try
549  {
550  boost::shared_ptr<nav_core::RecoveryBehavior> behavior(recovery_loader_.createInstance(behavior_list[i]["type"]));
551 
552  // shouldn't be possible, but it won't hurt to check
553  if (behavior.get() == nullptr)
554  {
555  ROS_ERROR("The ClassLoader returned a null pointer without throwing an exception. "
556  "This should not happen");
557  return false;
558  }
559 
560  // initialize the recovery behavior with its name
561  behavior->initialize(behavior_list[i]["name"], tf.get(), planner_costmap_ros_, controller_costmap_ros_);
562  recovery_behaviors_.push_back(behavior);
563  }
565  {
566  ROS_ERROR("Failed to load a plugin. Using default recovery behaviors. Error: %s", ex.what());
567  return false;
568  }
569  }
570  // if we've made it here... we've constructed a recovery behavior list successfully
571  return true;
572 }
573 
574 // we'll load our default recovery behaviors here
576 {
577  recovery_behaviors_.clear();
578  // Transform shared pointers to raw pointers for backwards compatibility with the recovery behaviors
580  try
581  {
582  // we need to set some parameters based on what's been passed in to us to maintain backwards compatibility
583  ros::NodeHandle n("~");
584 
585  // first, we'll load a recovery behavior to clear the costmap
587  recovery_loader_.createInstance("clear_costmap_recovery/ClearCostmapRecovery"));
588  cons_clear->initialize("conservative_reset", tf.get(), planner_costmap_ros_, controller_costmap_ros_);
589  recovery_behaviors_.push_back(cons_clear);
590 
591  // next, we'll load a recovery behavior to rotate in place
592  bool clearing_rotation_allowed;
593  n.param("clearing_rotation_allowed", clearing_rotation_allowed, true);
594 
596  recovery_loader_.createInstance("rotate_recovery/RotateRecovery"));
597  if (clearing_rotation_allowed)
598  {
599  rotate->initialize("rotate_recovery", tf.get(), planner_costmap_ros_, controller_costmap_ros_);
600  recovery_behaviors_.push_back(rotate);
601  }
602 
603  // next, we'll load a recovery behavior that will do an aggressive reset of the costmap
605  recovery_loader_.createInstance("clear_costmap_recovery/ClearCostmapRecovery"));
606  ags_clear->initialize("aggressive_reset", tf.get(), planner_costmap_ros_, controller_costmap_ros_);
607  recovery_behaviors_.push_back(ags_clear);
608 
609  // we'll rotate in-place one more time
610  if (clearing_rotation_allowed)
611  recovery_behaviors_.push_back(rotate);
612  }
614  {
615  ROS_FATAL("Failed to load a plugin. This should not happen on default recovery behaviors. Error: %s",
616  ex.what());
617  }
618 
619  return;
620 }
621 
622 void LocoMoveBase::goalCB(const geometry_msgs::PoseStamped::ConstPtr& goal)
623 {
625 }
626 
628 {
629  auto move_base_goal = server_.acceptNewGoal();
630  setGoal(nav_2d_utils::poseStampedToPose2D(move_base_goal->target_pose));
631 }
632 
634 {
635  ROS_INFO("Preempting goal");
638  resetState();
640 }
641 
642 } // namespace locomove_base
643 
644 int main(int argc, char** argv)
645 {
646  ros::init(argc, argv, "move_base");
647  ros::NodeHandle nh("~");
649  ros::spin();
650  return 0;
651 }
virtual void setPlan(const nav_2d_msgs::Path2D &path)=0
nav_2d_msgs::Pose2DStamped getLocalRobotPose() const
boost::shared_ptr< const Goal > acceptNewGoal()
void publishTwist(const nav_2d_msgs::Twist2DStamped &command)
void publishFeedback(const FeedbackConstPtr &feedback)
ros::NodeHandle private_nh_
Definition: locomove_base.h:97
#define ROS_FATAL(...)
nav_core2::LocalPlanner & getCurrentLocalPlanner()
#define ROS_INFO_NAMED(name,...)
int main(int argc, char **argv)
void publish(const boost::shared_ptr< M > &message) const
#define ROS_WARN_NAMED(name,...)
locomotor::Locomotor locomotor_
Definition: locomove_base.h:98
void controlLoopCallback(const ros::TimerEvent &event)
locomotor_msgs::ResultCode makeResultCode(int component=-1, int result_code=-1, const std::string &message="")
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
costmap_2d::Costmap2DROS * planner_costmap_ros_
locomotor::Executor local_planning_ex_
int size() const
void stop()
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
void requestLocalCostmapUpdate(Executor &work_ex, Executor &result_ex, CostmapUpdateCallback cb=nullptr, CostmapUpdateExceptionCallback fail_cb=nullptr)
void start()
void onLocalCostmapUpdate(const ros::Duration &planning_time)
void initializeGlobalPlanners(Executor &ex)
void onGlobalCostmapUpdate(const ros::Duration &planning_time)
Type const & getType() const
geometry_msgs::Pose2D oscillation_pose_
virtual void setGoal(nav_2d_msgs::Pose2DStamped goal)
bool loadRecoveryBehaviors(ros::NodeHandle node)
Load the recovery behaviors for the navigation stack from the parameter server.
void setSucceeded(const Result &result=Result(), const std::string &text=std::string(""))
void onNewLocalPlan(nav_2d_msgs::Twist2DStamped new_command, const ros::Duration &planning_time)
actionlib::SimpleActionServer< move_base_msgs::MoveBaseAction > server_
std::exception_ptr NavCore2ExceptionPtr
void loadDefaultRecoveryBehaviors()
Loads the default recovery behaviors for the navigation stack.
ROSCPP_DECL void spin(Spinner &spinner)
void onNavigationFailure(const locomotor_msgs::ResultCode result)
costmap_2d::Costmap2DROS * getCostmapPointer(const nav_core2::Costmap::Ptr &costmap)
nav_2d_msgs::Pose2DStamped poseStampedToPose2D(const geometry_msgs::PoseStamped &pose)
#define ROS_DEBUG_NAMED(name,...)
void publishPath(const nav_2d_msgs::Path2D &global_plan)
void setPreempted(const Result &result=Result(), const std::string &text=std::string(""))
double poseDistance(const geometry_msgs::Pose2D &pose0, const geometry_msgs::Pose2D &pose1)
geometry_msgs::PoseStamped pose2DToPoseStamped(const nav_2d_msgs::Pose2DStamped &pose2d)
void goalCB(const geometry_msgs::PoseStamped::ConstPtr &goal)
#define ROS_INFO(...)
void onLocalPlanningException(nav_core2::NavCore2ExceptionPtr e_ptr, const ros::Duration &planning_time)
void setGoal(nav_2d_msgs::Pose2DStamped goal)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
ros::Duration desired_plan_duration_
void requestNavigationFailure(const locomotor_msgs::ResultCode &result)
void registerPreemptCallback(boost::function< void()> cb)
void initializeLocalCostmap(Executor &ex)
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
LocoMoveBase(const ros::NodeHandle &nh)
void initializeGlobalCostmap(Executor &ex)
ros::Duration desired_control_duration_
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
std::string getNamespace(const std::string &s)
Reimplementation of ClassLoader::getName without needing a ClassLoader.
TFListenerPtr getTFListener() const
void initializeLocalPlanners(Executor &ex)
pluginlib::ClassLoader< nav_core::RecoveryBehavior > recovery_loader_
void requestNavigationFailure(Executor &result_ex, const locomotor_msgs::ResultCode &result, NavigationFailureCallback cb=nullptr)
void setAborted(const Result &result=Result(), const std::string &text=std::string(""))
bool hasMember(const std::string &name) const
void planLoopCallback(const ros::TimerEvent &event)
std::vector< boost::shared_ptr< nav_core::RecoveryBehavior > > recovery_behaviors_
TFSIMD_FORCE_INLINE Vector3 rotate(const Vector3 &wAxis, const tfScalar angle) const
bool getParam(const std::string &key, std::string &s) const
#define ROS_FATAL_NAMED(name,...)
static Time now()
nav_core2::Costmap::Ptr getLocalCostmap() const
void onLocalCostmapException(nav_core2::NavCore2ExceptionPtr e_ptr, const ros::Duration &planning_time)
std::shared_ptr< Costmap > Ptr
void onNewGlobalPlan(nav_2d_msgs::Path2D new_global_plan, const ros::Duration &planning_time)
bool hasParam(const std::string &key) const
std::shared_ptr< tf::TransformListener > TFListenerPtr
void registerGoalCallback(boost::function< void()> cb)
void onGlobalCostmapException(nav_core2::NavCore2ExceptionPtr e_ptr, const ros::Duration &planning_time)
nav_core2::Costmap::Ptr getGlobalCostmap() const
costmap_2d::Costmap2DROS * controller_costmap_ros_
RecoveryTrigger recovery_trigger_
const ros::NodeHandle & loadBackwardsCompatibleParameters(const ros::NodeHandle &nh)
Copy parameter values to get backwards compatibility.
#define ROS_ERROR(...)
void setParam(const std::string &key, const XmlRpc::XmlRpcValue &v) const
void requestGlobalCostmapUpdate(Executor &work_ex, Executor &result_ex, CostmapUpdateCallback cb=nullptr, CostmapUpdateExceptionCallback fail_cb=nullptr)
void onGlobalPlanningException(nav_core2::NavCore2ExceptionPtr e_ptr, const ros::Duration &planning_time)
locomotor::Executor global_planning_ex_
void requestGlobalPlan(Executor &work_ex, Executor &result_ex, GlobalPlanCallback cb=nullptr, PlannerExceptionCallback fail_cb=nullptr)
void requestLocalPlan(Executor &work_ex, Executor &result_ex, LocalPlanCallback cb=nullptr, PlannerExceptionCallback fail_cb=nullptr, NavigationCompleteCallback complete_cb=nullptr)


locomove_base
Author(s):
autogenerated on Sun Jan 10 2021 04:08:49