carrot_planner.cpp
Go to the documentation of this file.
1 /*********************************************************************
2 *
3 * Software License Agreement (BSD License)
4 *
5 * Copyright (c) 2008, Willow Garage, Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * * Redistributions in binary form must reproduce the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer in the documentation and/or other materials provided
17 * with the distribution.
18 * * Neither the name of Willow Garage, Inc. nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 *
35 * Authors: Eitan Marder-Eppstein, Sachin Chitta
36 *********************************************************************/
37 #include <angles/angles.h>
40 #include <tf2/convert.h>
41 #include <tf2/utils.h>
43 
44 //register this planner as a BaseGlobalPlanner plugin
46 
47 namespace carrot_planner {
48 
50  : costmap_ros_(NULL), costmap_(NULL), world_model_(NULL), initialized_(false){}
51 
52  CarrotPlanner::CarrotPlanner(std::string name, costmap_2d::Costmap2DROS* costmap_ros)
53  : costmap_ros_(NULL), costmap_(NULL), world_model_(NULL), initialized_(false){
54  initialize(name, costmap_ros);
55  }
56 
57  CarrotPlanner::~CarrotPlanner() {
58  // deleting a nullptr is a noop
59  delete world_model_;
60  }
61 
62  void CarrotPlanner::initialize(std::string name, costmap_2d::Costmap2DROS* costmap_ros){
63  if(!initialized_){
64  costmap_ros_ = costmap_ros;
65  costmap_ = costmap_ros_->getCostmap();
66 
67  ros::NodeHandle private_nh("~/" + name);
68  private_nh.param("step_size", step_size_, costmap_->getResolution());
69  private_nh.param("min_dist_from_robot", min_dist_from_robot_, 0.10);
70  world_model_ = new base_local_planner::CostmapModel(*costmap_);
71 
72  initialized_ = true;
73  }
74  else
75  ROS_WARN("This planner has already been initialized... doing nothing");
76  }
77 
78  //we need to take the footprint of the robot into account when we calculate cost to obstacles
79  double CarrotPlanner::footprintCost(double x_i, double y_i, double theta_i){
80  if(!initialized_){
81  ROS_ERROR("The planner has not been initialized, please call initialize() to use the planner");
82  return -1.0;
83  }
84 
85  std::vector<geometry_msgs::Point> footprint = costmap_ros_->getRobotFootprint();
86  //if we have no footprint... do nothing
87  if(footprint.size() < 3)
88  return -1.0;
89 
90  //check if the footprint is legal
91  double footprint_cost = world_model_->footprintCost(x_i, y_i, theta_i, footprint);
92  return footprint_cost;
93  }
94 
95 
96  bool CarrotPlanner::makePlan(const geometry_msgs::PoseStamped& start,
97  const geometry_msgs::PoseStamped& goal, std::vector<geometry_msgs::PoseStamped>& plan){
98 
99  if(!initialized_){
100  ROS_ERROR("The planner has not been initialized, please call initialize() to use the planner");
101  return false;
102  }
103 
104  ROS_DEBUG("Got a start: %.2f, %.2f, and a goal: %.2f, %.2f", start.pose.position.x, start.pose.position.y, goal.pose.position.x, goal.pose.position.y);
105 
106  plan.clear();
107  costmap_ = costmap_ros_->getCostmap();
108 
109  if(goal.header.frame_id != costmap_ros_->getGlobalFrameID()){
110  ROS_ERROR("This planner as configured will only accept goals in the %s frame, but a goal was sent in the %s frame.",
111  costmap_ros_->getGlobalFrameID().c_str(), goal.header.frame_id.c_str());
112  return false;
113  }
114 
115  const double start_yaw = tf2::getYaw(start.pose.orientation);
116  const double goal_yaw = tf2::getYaw(goal.pose.orientation);
117 
118  //we want to step back along the vector created by the robot's position and the goal pose until we find a legal cell
119  double goal_x = goal.pose.position.x;
120  double goal_y = goal.pose.position.y;
121  double start_x = start.pose.position.x;
122  double start_y = start.pose.position.y;
123 
124  double diff_x = goal_x - start_x;
125  double diff_y = goal_y - start_y;
126  double diff_yaw = angles::normalize_angle(goal_yaw-start_yaw);
127 
128  double target_x = goal_x;
129  double target_y = goal_y;
130  double target_yaw = goal_yaw;
131 
132  bool done = false;
133  double scale = 1.0;
134  double dScale = 0.01;
135 
136  while(!done)
137  {
138  if(scale < 0)
139  {
140  target_x = start_x;
141  target_y = start_y;
142  target_yaw = start_yaw;
143  ROS_WARN("The carrot planner could not find a valid plan for this goal");
144  break;
145  }
146  target_x = start_x + scale * diff_x;
147  target_y = start_y + scale * diff_y;
148  target_yaw = angles::normalize_angle(start_yaw + scale * diff_yaw);
149 
150  double footprint_cost = footprintCost(target_x, target_y, target_yaw);
151  if(footprint_cost >= 0)
152  {
153  done = true;
154  }
155  scale -=dScale;
156  }
157 
158  plan.push_back(start);
159  geometry_msgs::PoseStamped new_goal = goal;
160  tf2::Quaternion goal_quat;
161  goal_quat.setRPY(0, 0, target_yaw);
162 
163  new_goal.pose.position.x = target_x;
164  new_goal.pose.position.y = target_y;
165 
166  new_goal.pose.orientation.x = goal_quat.x();
167  new_goal.pose.orientation.y = goal_quat.y();
168  new_goal.pose.orientation.z = goal_quat.z();
169  new_goal.pose.orientation.w = goal_quat.w();
170 
171  plan.push_back(new_goal);
172  return (done);
173  }
174 
175 };
carrot_planner.h
tf2::getYaw
double getYaw(const A &a)
utils.h
tf2::Quaternion::setRPY
void setRPY(const tf2Scalar &roll, const tf2Scalar &pitch, const tf2Scalar &yaw)
angles::normalize_angle
def normalize_angle(angle)
base_local_planner::CostmapModel
PLUGINLIB_EXPORT_CLASS
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
ROS_DEBUG
#define ROS_DEBUG(...)
carrot_planner
Definition: carrot_planner.h:49
ROS_WARN
#define ROS_WARN(...)
carrot_planner::CarrotPlanner
Provides a simple global planner that will compute a valid goal point for the local planner by walkin...
Definition: carrot_planner.h:89
start
ROSCPP_DECL void start()
initialize
ROSCONSOLE_DECL void initialize()
ROS_ERROR
#define ROS_ERROR(...)
class_list_macros.hpp
tf2::Quaternion
tf2_geometry_msgs.h
convert.h
costmap_2d::Costmap2DROS::getCostmap
Costmap2D * getCostmap() const
nav_core::BaseGlobalPlanner
costmap_2d::Costmap2DROS
ros::NodeHandle
angles.h
carrot_planner::CarrotPlanner::CarrotPlanner
CarrotPlanner()
Constructor for the CarrotPlanner.
Definition: carrot_planner.cpp:84


carrot_planner
Author(s): Eitan Marder-Eppstein, Sachin Chitta, contradict@gmail.com
autogenerated on Mon Mar 6 2023 03:50:28