Nav2 Navigation Stack - lyrical  lyrical
ROS 2 Navigation Stack
costmap_topic_collision_checker.cpp
1 // Copyright (c) 2019 Intel Corporation
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // Modified by: Shivang Patel (shivaan14@gmail.com)
16 
17 #include <memory>
18 #include <mutex>
19 #include <string>
20 #include <vector>
21 #include <algorithm>
22 #include <iostream>
23 
24 #include "tf2/utils.hpp"
25 
26 #include "nav2_costmap_2d/costmap_topic_collision_checker.hpp"
27 
28 #include "nav2_costmap_2d/cost_values.hpp"
29 #include "nav2_costmap_2d/exceptions.hpp"
30 #include "nav2_costmap_2d/footprint.hpp"
31 #include "nav2_util/line_iterator.hpp"
32 
33 using namespace std::chrono_literals;
34 
35 namespace nav2_costmap_2d
36 {
37 
38 CostmapTopicCollisionChecker::CostmapTopicCollisionChecker(
39  CostmapSubscriber & costmap_sub,
40  FootprintSubscriber & footprint_sub,
41  std::string name)
42 : name_(name),
43  costmap_sub_(costmap_sub),
44  footprint_sub_(&footprint_sub),
45  collision_checker_(nullptr)
46 {}
47 
49  CostmapSubscriber & costmap_sub,
50  std::string footprint_string,
51  std::string name)
52 : name_(name),
53  costmap_sub_(costmap_sub),
54  collision_checker_(nullptr)
55 {
56  if (!makeFootprintFromString(footprint_string, footprint_)) {
57  throw CollisionCheckerException("Failed to create footprint from string");
58  }
59 }
60 
62  const geometry_msgs::msg::Pose & pose,
63  bool fetch_costmap_and_footprint)
64 {
65  try {
66  if (scorePose(pose, fetch_costmap_and_footprint) >= LETHAL_OBSTACLE) {
67  return false;
68  }
69  return true;
70  } catch (const IllegalPoseException & e) {
71  RCLCPP_ERROR(rclcpp::get_logger(name_), "%s", e.what());
72  return false;
73  } catch (const CollisionCheckerException & e) {
74  RCLCPP_ERROR(rclcpp::get_logger(name_), "%s", e.what());
75  return false;
76  } catch (...) {
77  RCLCPP_ERROR(rclcpp::get_logger(name_), "Failed to check pose score!");
78  return false;
79  }
80 }
81 
83  const geometry_msgs::msg::Pose & pose,
84  bool fetch_costmap_and_footprint)
85 {
86  if (fetch_costmap_and_footprint) {
87  try {
88  collision_checker_.setCostmap(costmap_sub_.getCostmap());
89  } catch (const std::runtime_error & e) {
90  throw CollisionCheckerException(e.what());
91  }
92  }
93  auto costmap = collision_checker_.getCostmap();
94  std::lock_guard<Costmap2D::mutex_t> costmap_lock(*costmap->getMutex());
95 
96  unsigned int cell_x, cell_y;
97  if (!collision_checker_.worldToMap(pose.position.x, pose.position.y, cell_x, cell_y)) {
98  RCLCPP_DEBUG(rclcpp::get_logger(name_), "Map Cell: [%d, %d]", cell_x, cell_y);
99  throw IllegalPoseException(name_, "Pose Goes Off Grid.");
100  }
101 
102  return collision_checker_.footprintCost(getFootprint(pose, fetch_costmap_and_footprint));
103 }
104 
106  const geometry_msgs::msg::Pose & pose,
107  bool fetch_latest_footprint)
108 {
109  if (fetch_latest_footprint) {
110  std_msgs::msg::Header header;
111 
112  // if footprint_sub_ was not initialized (alternative constructor), we are using the
113  // footprint built from the footprint_string alternative constructor argument.
114  if (footprint_sub_ && !footprint_sub_->getFootprintInRobotFrame(footprint_, header)) {
115  throw CollisionCheckerException("Current footprint not available.");
116  }
117  }
118 
119  Footprint footprint;
120  double x = pose.position.x;
121  double y = pose.position.y;
122  double theta = tf2::getYaw(pose.orientation);
123  transformFootprint(x, y, theta, footprint_, footprint);
124 
125  return footprint;
126 }
127 
128 } // namespace nav2_costmap_2d
Exceptions thrown if collision checker determines a pose is in collision with the environment costmap...
Definition: exceptions.hpp:49
Subscribes to the costmap via a ros topic.
std::shared_ptr< Costmap2D > getCostmap()
Get current costmap.
double scorePose(const geometry_msgs::msg::Pose &pose, bool fetch_costmap_and_footprint=true)
Returns the obstacle footprint score for a particular pose.
Footprint getFootprint(const geometry_msgs::msg::Pose &pose, bool fetch_latest_footprint=true)
Get a footprint at a set pose.
bool isCollisionFree(const geometry_msgs::msg::Pose &pose, bool fetch_costmap_and_footprint=true)
Returns if a pose is collision free.
CostmapTopicCollisionChecker(CostmapSubscriber &costmap_sub, FootprintSubscriber &footprint_sub, std::string name="collision_checker")
A constructor.
Subscriber to the footprint topic to get current robot footprint (if changing) for use in collision a...
bool getFootprintInRobotFrame(std::vector< geometry_msgs::msg::Point > &footprint, std_msgs::msg::Header &footprint_header)
Returns the latest robot footprint, transformed into robot base frame (unoriented).
Thrown when CollisionChecker encounters a fatal error.
Definition: exceptions.hpp:60
void transformFootprint(double x, double y, double theta, const std::vector< geometry_msgs::msg::Point > &footprint_spec, std::vector< geometry_msgs::msg::Point > &oriented_footprint)
Given a pose and base footprint, build the oriented footprint of the robot (list of Points)
Definition: footprint.cpp:112
bool makeFootprintFromString(const std::string &footprint_string, std::vector< geometry_msgs::msg::Point > &footprint)
Make the footprint from the given string.
Definition: footprint.cpp:177