conversions_and_types.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  *
3  * Software License Agreement (BSD License)
4  *
5  * Copyright (c) 2010, 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  * Author: Christian Connette
36  *********************************************************************/
37 
39 
40 namespace eband_local_planner{
41 
42  void PoseToPose2D(const geometry_msgs::Pose pose, geometry_msgs::Pose2D& pose2D)
43  {
44  // use tf-pkg to convert angles
45  tf::Pose pose_tf;
46 
47  // convert geometry_msgs::PoseStamped to tf::Pose
48  tf::poseMsgToTF(pose, pose_tf);
49 
50  // now get Euler-Angles from pose_tf
51  double useless_pitch, useless_roll, yaw;
52  pose_tf.getBasis().getEulerYPR(yaw, useless_pitch, useless_roll);
53 
54  // normalize angle
55  yaw = angles::normalize_angle(yaw);
56 
57  // and set to pose2D
58  pose2D.x = pose.position.x;
59  pose2D.y = pose.position.y;
60  pose2D.theta = yaw;
61 
62  return;
63  }
64 
65 
66  void Pose2DToPose(geometry_msgs::Pose& pose, const geometry_msgs::Pose2D pose2D)
67  {
68  // use tf-pkg to convert angles
69  tf::Quaternion frame_quat;
70 
71  // transform angle from euler-angle to quaternion representation
72  frame_quat = tf::createQuaternionFromYaw(pose2D.theta);
73 
74  // set position
75  pose.position.x = pose2D.x;
76  pose.position.y = pose2D.y;
77  pose.position.z = 0.0;
78 
79  // set quaternion
80  pose.orientation.x = frame_quat.x();
81  pose.orientation.y = frame_quat.y();
82  pose.orientation.z = frame_quat.z();
83  pose.orientation.w = frame_quat.w();
84 
85  return;
86  }
87 
88 
89  bool transformGlobalPlan(const tf::TransformListener& tf, const std::vector<geometry_msgs::PoseStamped>& global_plan,
90  costmap_2d::Costmap2DROS& costmap, const std::string& global_frame,
91  std::vector<geometry_msgs::PoseStamped>& transformed_plan, std::vector<int>& start_end_counts)
92  {
93  const geometry_msgs::PoseStamped& plan_pose = global_plan[0];
94 
95  // initiate refernce variables
96  transformed_plan.clear();
97 
98  try
99  {
100  if (!global_plan.size() > 0)
101  {
102  ROS_ERROR("Recieved plan with zero length");
103  return false;
104  }
105 
106  tf::StampedTransform transform;
107  tf.lookupTransform(global_frame, ros::Time(), plan_pose.header.frame_id, plan_pose.header.stamp,
108  plan_pose.header.frame_id, transform);
109 
110  //let's get the pose of the robot in the frame of the plan
111  tf::Stamped<tf::Pose> robot_pose;
112  robot_pose.setIdentity();
113  robot_pose.frame_id_ = costmap.getBaseFrameID();
114  robot_pose.stamp_ = ros::Time();
115  tf.transformPose(plan_pose.header.frame_id, robot_pose, robot_pose);
116 
117  //we'll keep points on the plan that are within the window that we're looking at
118 
119  double dist_threshold = std::max(
120  costmap.getCostmap()->getSizeInMetersX() / 2.0,
121  costmap.getCostmap()->getSizeInMetersY() / 2.0
122  );
123 
124  unsigned int i = 0;
125  double sq_dist_threshold = dist_threshold * dist_threshold;
126  double sq_dist = DBL_MAX;
127 
128  // --- start - modification w.r.t. base_local_planner
129  // initiate start_end_count
130  std::vector<int> start_end_count;
131  start_end_count.assign(2, 0);
132 
133  // we know only one direction and that is forward! - initiate search with previous start_end_counts
134  // this is neccesserry to work with the sampling based planners - path may severall time enter and leave moving window
135  ROS_ASSERT( (start_end_counts.at(0) > 0) && (start_end_counts.at(0) <= (int) global_plan.size()) );
136  i = (unsigned int) global_plan.size() - (unsigned int) start_end_counts.at(0);
137  // --- end - modification w.r.t. base_local_planner
138 
139  //we need to loop to a point on the plan that is within a certain distance of the robot
140  while(i < (unsigned int)global_plan.size() && sq_dist > sq_dist_threshold)
141  {
142  double x_diff = robot_pose.getOrigin().x() - global_plan[i].pose.position.x;
143  double y_diff = robot_pose.getOrigin().y() - global_plan[i].pose.position.y;
144  sq_dist = x_diff * x_diff + y_diff * y_diff;
145 
146  // --- start - modification w.r.t. base_local_planner
147  // not yet in reach - get next frame
148  if( sq_dist > sq_dist_threshold )
149  ++i;
150  else
151  // set counter for start of transformed intervall - from back as beginning of plan might be prunned
152  start_end_count.at(0) = (int) (((unsigned int) global_plan.size()) - i);
153  // --- end - modification w.r.t. base_local_planner
154  }
155 
156 
157  tf::Stamped<tf::Pose> tf_pose;
158  geometry_msgs::PoseStamped newer_pose;
159 
160  //now we'll transform until points are outside of our distance threshold
161  while(i < (unsigned int)global_plan.size() && sq_dist < sq_dist_threshold)
162  {
163  double x_diff = robot_pose.getOrigin().x() - global_plan[i].pose.position.x;
164  double y_diff = robot_pose.getOrigin().y() - global_plan[i].pose.position.y;
165  sq_dist = x_diff * x_diff + y_diff * y_diff;
166 
167  const geometry_msgs::PoseStamped& pose = global_plan[i];
168  poseStampedMsgToTF(pose, tf_pose);
169  tf_pose.setData(transform * tf_pose);
170  tf_pose.stamp_ = transform.stamp_;
171  tf_pose.frame_id_ = global_frame;
172  poseStampedTFToMsg(tf_pose, newer_pose);
173 
174  transformed_plan.push_back(newer_pose);
175 
176  // --- start - modification w.r.t. base_local_planner
177  // set counter for end of transformed intervall - from back as beginning of plan might be prunned
178  start_end_count.at(1) = int (((unsigned int) global_plan.size()) - i);
179  // --- end - modification w.r.t. base_local_planner
180 
181  ++i;
182  }
183 
184  // --- start - modification w.r.t. base_local_planner
185  // write to reference variable
186  start_end_counts = start_end_count;
187  // --- end - modification w.r.t. base_local_planner
188  }
189  catch(tf::LookupException& ex)
190  {
191  ROS_ERROR("No Transform available Error: %s\n", ex.what());
192  return false;
193  }
194  catch(tf::ConnectivityException& ex)
195  {
196  ROS_ERROR("Connectivity Error: %s\n", ex.what());
197  return false;
198  }
199  catch(tf::ExtrapolationException& ex)
200  {
201  ROS_ERROR("Extrapolation Error: %s\n", ex.what());
202  if (global_plan.size() > 0)
203  ROS_ERROR("Global Frame: %s Plan Frame size %d: %s\n", global_frame.c_str(), (unsigned int)global_plan.size(), global_plan[0].header.frame_id.c_str());
204 
205  return false;
206  }
207 
208  return true;
209  }
210 
212  std::vector<geometry_msgs::Point> footprint(costmap.getRobotFootprint());
213  double max_distance_sqr = 0;
214  for (size_t i = 0; i < footprint.size(); ++i) {
215  geometry_msgs::Point& p = footprint[i];
216  double distance_sqr = p.x*p.x + p.y*p.y;
217  if (distance_sqr > max_distance_sqr) {
218  max_distance_sqr = distance_sqr;
219  }
220  }
221  return sqrt(max_distance_sqr);
222  }
223 
224 
225 }
static void poseMsgToTF(const geometry_msgs::Pose &msg, Pose &bt)
void setData(const T &input)
void getEulerYPR(tfScalar &yaw, tfScalar &pitch, tfScalar &roll, unsigned int solution_number=1) const
TFSIMD_FORCE_INLINE Matrix3x3 & getBasis()
double getSizeInMetersX() const
void Pose2DToPose(geometry_msgs::Pose &pose, const geometry_msgs::Pose2D pose2D)
Converts a frame of type Pose to type Pose2D (mainly -> conversion of orientation from euler angles t...
double getSizeInMetersY() const
#define DBL_MAX
static Quaternion createQuaternionFromYaw(double yaw)
double getCircumscribedRadius(costmap_2d::Costmap2DROS &costmap)
Gets the footprint of the robot and computes the circumscribed radius for the eband approach...
std::string getBaseFrameID()
INLINE Rall1d< T, V, S > sqrt(const Rall1d< T, V, S > &arg)
def normalize_angle(angle)
void lookupTransform(const std::string &target_frame, const std::string &source_frame, const ros::Time &time, StampedTransform &transform) const
ros::Time stamp_
std::string frame_id_
void transformPose(const std::string &target_frame, const geometry_msgs::PoseStamped &stamped_in, geometry_msgs::PoseStamped &stamped_out) const
Costmap2D * getCostmap()
#define ROS_ASSERT(cond)
std::vector< geometry_msgs::Point > getRobotFootprint()
#define ROS_ERROR(...)
bool transformGlobalPlan(const tf::TransformListener &tf, const std::vector< geometry_msgs::PoseStamped > &global_plan, costmap_2d::Costmap2DROS &costmap, const std::string &global_frame, std::vector< geometry_msgs::PoseStamped > &transformed_plan, std::vector< int > &start_end_counts_from_end)
Transforms the global plan of the robot from the planner frame to the local frame. This replaces the transformGlobalPlan as defined in the base_local_planner/goal_functions.h main difference is that it additionally outputs counter indicating which part of the plan has been transformed.
void PoseToPose2D(const geometry_msgs::Pose pose, geometry_msgs::Pose2D &pose2D)
Converts a frame of type Pose to type Pose2D (mainly -> conversion of orientation from quaternions to...


eband_local_planner
Author(s): Christian Connette, Bhaskara Marthi, Piyush Khandelwal
autogenerated on Sat Feb 22 2020 04:03:28