local_planner_adapter.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 
39 #include <nav_2d_utils/tf_help.h>
40 #include <nav_core2/exceptions.h>
42 #include <memory>
43 #include <string>
44 #include <vector>
45 
46 namespace nav_core_adapter
47 {
48 
50  planner_loader_("nav_core2", "nav_core2::LocalPlanner")
51 {
52 }
53 
58 {
59  tf_ = createSharedPointerWithNoDelete<tf::TransformListener>(tf);
60  costmap_ros_ = costmap_ros;
61  costmap_adapter_ = std::make_shared<CostmapAdapter>();
62  costmap_adapter_->initialize(costmap_ros);
63 
64  ros::NodeHandle nh;
65  ros::NodeHandle private_nh("~");
66  ros::NodeHandle adapter_nh("~/" + name);
67  std::string planner_name;
68  adapter_nh.param("planner_name", planner_name, std::string("dwb_local_planner::DWBLocalPlanner"));
69  ROS_INFO_NAMED("LocalPlannerAdapter", "Loading plugin %s", planner_name.c_str());
70  planner_ = planner_loader_.createInstance(planner_name);
71  planner_->initialize(private_nh, planner_loader_.getName(planner_name), tf_, costmap_adapter_);
72  has_active_goal_ = false;
73 
74  odom_sub_ = std::make_shared<nav_2d_utils::OdomSubscriber>(nh);
75 }
76 
80 bool LocalPlannerAdapter::computeVelocityCommands(geometry_msgs::Twist& cmd_vel)
81 {
82  if (!has_active_goal_)
83  {
84  return false;
85  }
86 
87  // Get the Pose
88  nav_2d_msgs::Pose2DStamped pose2d;
89  if (!getRobotPose(pose2d))
90  {
91  return false;
92  }
93 
94  // Get the Velocity
95  nav_2d_msgs::Twist2D velocity = odom_sub_->getTwist();
96 
97  nav_2d_msgs::Twist2DStamped cmd_vel_2d;
98  try
99  {
100  cmd_vel_2d = planner_->computeVelocityCommands(pose2d, velocity);
101  }
102  catch (const nav_core2::PlannerException& e)
103  {
104  ROS_ERROR_NAMED("LocalPlannerAdapter", "computeVelocityCommands exception: %s", e.what());
105  return false;
106  }
107  cmd_vel = nav_2d_utils::twist2Dto3D(cmd_vel_2d.velocity);
108  return true;
109 }
110 
115 {
116  // Get the Pose
117  nav_2d_msgs::Pose2DStamped pose2d;
118  if (!getRobotPose(pose2d))
119  return false;
120 
121  nav_2d_msgs::Twist2D velocity = odom_sub_->getTwist();
122  bool ret = planner_->isGoalReached(pose2d, velocity);
123  if (ret)
124  {
125  has_active_goal_ = false;
126  }
127  return ret;
128 }
129 
133 bool LocalPlannerAdapter::setPlan(const std::vector<geometry_msgs::PoseStamped>& orig_global_plan)
134 {
135  nav_2d_msgs::Path2D path = nav_2d_utils::posesToPath2D(orig_global_plan);
136  try
137  {
138  if (path.poses.size() > 0)
139  {
140  nav_2d_msgs::Pose2DStamped goal_pose;
141  goal_pose.header = path.header;
142  goal_pose.pose = path.poses.back();
143 
144  if (!has_active_goal_ || hasGoalChanged(goal_pose))
145  {
146  last_goal_ = goal_pose;
147  has_active_goal_ = true;
148  planner_->setGoalPose(goal_pose);
149  }
150  }
151 
152  planner_->setPlan(path);
153  return true;
154  }
155  catch (const nav_core2::PlannerException& e)
156  {
157  ROS_ERROR_NAMED("LocalPlannerAdapter", "setPlan Exception: %s", e.what());
158  return false;
159  }
160 }
161 
162 bool LocalPlannerAdapter::hasGoalChanged(const nav_2d_msgs::Pose2DStamped& new_goal)
163 {
164  if (last_goal_.header.frame_id != new_goal.header.frame_id)
165  {
166  return true;
167  }
168 
169  return last_goal_.pose.x != new_goal.pose.x || last_goal_.pose.y != new_goal.pose.y ||
170  last_goal_.pose.theta != new_goal.pose.theta;
171 }
172 
173 bool LocalPlannerAdapter::getRobotPose(nav_2d_msgs::Pose2DStamped& pose2d)
174 {
175  tf::Stamped<tf::Pose> current_pose;
176  if (!costmap_ros_->getRobotPose(current_pose))
177  {
178  ROS_ERROR_NAMED("LocalPlannerAdapter", "Could not get robot pose");
179  return false;
180  }
181  pose2d = nav_2d_utils::stampedPoseToPose2D(current_pose);
182  return true;
183 }
184 
185 } // namespace nav_core_adapter
186 
187 // register this planner as a BaseLocalPlanner plugin
bool hasGoalChanged(const nav_2d_msgs::Pose2DStamped &new_goal)
See if the back of the global plan matches the most recent goal pose.
#define ROS_INFO_NAMED(name,...)
std::shared_ptr< CostmapAdapter > costmap_adapter_
bool getRobotPose(tf::Stamped< tf::Pose > &global_pose) const
std::shared_ptr< nav_2d_utils::OdomSubscriber > odom_sub_
helper class for subscribing to odometry
bool isGoalReached() override
Collect the additional information needed by nav_core2 and call the child isGoalReached.
PLUGINLIB_EXPORT_CLASS(BAGReader, nodelet::Nodelet)
bool computeVelocityCommands(geometry_msgs::Twist &cmd_vel) override
Collect the additional information needed by nav_core2 and call the child computeVelocityCommands.
geometry_msgs::Twist twist2Dto3D(const nav_2d_msgs::Twist2D &cmd_vel_2d)
nav_2d_msgs::Path2D posesToPath2D(const std::vector< geometry_msgs::PoseStamped > &poses)
bool getRobotPose(nav_2d_msgs::Pose2DStamped &pose2d)
Get the robot pose from the costmap and store as Pose2DStamped.
used for employing a nav_core2 local planner (such as dwb) as a nav_core plugin, like in move_base...
bool param(const std::string &param_name, T &param_val, const T &default_val) const
virtual std::string getName(const std::string &lookup_name)
nav_2d_msgs::Pose2DStamped stampedPoseToPose2D(const tf::Stamped< tf::Pose > &pose)
bool setPlan(const std::vector< geometry_msgs::PoseStamped > &plan) override
Convert from 2d to 3d and call child setPlan.
#define ROS_ERROR_NAMED(name,...)
void initialize(std::string name, tf::TransformListener *tf, costmap_2d::Costmap2DROS *costmap_ros) override
Load the nav_core2 local planner and initialize it.
boost::shared_ptr< nav_core2::LocalPlanner > planner_
pluginlib::ClassLoader< nav_core2::LocalPlanner > planner_loader_


nav_core_adapter
Author(s):
autogenerated on Sun Jan 10 2021 04:08:46