Nav2 Navigation Stack - kilted  kilted
ROS 2 Navigation Stack
behavior_server.cpp
1 // Copyright (c) 2018 Samsung Research America
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. Reserved.
14 
15 #include <memory>
16 #include <string>
17 #include <vector>
18 #include <utility>
19 #include "nav2_util/node_utils.hpp"
20 #include "nav2_behaviors/behavior_server.hpp"
21 
22 namespace behavior_server
23 {
24 
25 BehaviorServer::BehaviorServer(const rclcpp::NodeOptions & options)
26 : LifecycleNode("behavior_server", "", options),
27  plugin_loader_("nav2_core", "nav2_core::Behavior"),
28  default_ids_{"spin", "backup", "drive_on_heading", "wait"},
29  default_types_{"nav2_behaviors::Spin",
30  "nav2_behaviors::BackUp",
31  "nav2_behaviors::DriveOnHeading",
32  "nav2_behaviors::Wait"}
33 {
34  declare_parameter(
35  "local_costmap_topic",
36  rclcpp::ParameterValue(std::string("local_costmap/costmap_raw")));
37 
38  declare_parameter(
39  "global_costmap_topic",
40  rclcpp::ParameterValue(std::string("global_costmap/costmap_raw")));
41 
42  declare_parameter(
43  "local_footprint_topic",
44  rclcpp::ParameterValue(std::string("local_costmap/published_footprint")));
45 
46  declare_parameter(
47  "global_footprint_topic",
48  rclcpp::ParameterValue(std::string("global_costmap/published_footprint")));
49 
50  declare_parameter("cycle_frequency", rclcpp::ParameterValue(10.0));
51  declare_parameter("behavior_plugins", default_ids_);
52 
53  get_parameter("behavior_plugins", behavior_ids_);
54  if (behavior_ids_ == default_ids_) {
55  for (size_t i = 0; i < default_ids_.size(); ++i) {
56  declare_parameter(default_ids_[i] + ".plugin", default_types_[i]);
57  }
58  }
59 
60  declare_parameter(
61  "local_frame",
62  rclcpp::ParameterValue(std::string("odom")));
63  declare_parameter(
64  "global_frame",
65  rclcpp::ParameterValue(std::string("map")));
66  declare_parameter(
67  "robot_base_frame",
68  rclcpp::ParameterValue(std::string("base_link")));
69  declare_parameter(
70  "transform_tolerance",
71  rclcpp::ParameterValue(0.1));
72 }
73 
74 
75 BehaviorServer::~BehaviorServer()
76 {
77  behaviors_.clear();
78 }
79 
80 nav2_util::CallbackReturn
81 BehaviorServer::on_configure(const rclcpp_lifecycle::State & state)
82 {
83  RCLCPP_INFO(get_logger(), "Configuring");
84 
85  tf_ = std::make_shared<tf2_ros::Buffer>(get_clock());
86  auto timer_interface = std::make_shared<tf2_ros::CreateTimerROS>(
87  get_node_base_interface(),
88  get_node_timers_interface());
89  tf_->setCreateTimerInterface(timer_interface);
90  transform_listener_ = std::make_shared<tf2_ros::TransformListener>(*tf_);
91 
92  behavior_types_.resize(behavior_ids_.size());
93  if (!loadBehaviorPlugins()) {
94  on_cleanup(state);
95  return nav2_util::CallbackReturn::FAILURE;
96  }
99 
100  return nav2_util::CallbackReturn::SUCCESS;
101 }
102 
103 bool
105 {
106  auto node = shared_from_this();
107 
108  for (size_t i = 0; i != behavior_ids_.size(); i++) {
109  try {
110  behavior_types_[i] = nav2_util::get_plugin_type_param(node, behavior_ids_[i]);
111  RCLCPP_INFO(
112  get_logger(), "Creating behavior plugin %s of type %s",
113  behavior_ids_[i].c_str(), behavior_types_[i].c_str());
114  behaviors_.push_back(plugin_loader_.createUniqueInstance(behavior_types_[i]));
115  } catch (const std::exception & ex) {
116  RCLCPP_FATAL(
117  get_logger(), "Failed to create behavior %s of type %s."
118  " Exception: %s", behavior_ids_[i].c_str(), behavior_types_[i].c_str(),
119  ex.what());
120  return false;
121  }
122  }
123 
124  return true;
125 }
126 
128 {
129  auto node = shared_from_this();
130 
131  for (size_t i = 0; i != behavior_ids_.size(); i++) {
132  behaviors_[i]->configure(
133  node,
134  behavior_ids_[i],
135  tf_,
136  local_collision_checker_,
137  global_collision_checker_);
138  }
139 }
140 
142 {
143  std::string local_costmap_topic, global_costmap_topic;
144  std::string local_footprint_topic, global_footprint_topic;
145  std::string robot_base_frame;
146  double transform_tolerance;
147  get_parameter("local_costmap_topic", local_costmap_topic);
148  get_parameter("global_costmap_topic", global_costmap_topic);
149  get_parameter("local_footprint_topic", local_footprint_topic);
150  get_parameter("global_footprint_topic", global_footprint_topic);
151  get_parameter("robot_base_frame", robot_base_frame);
152  transform_tolerance = get_parameter("transform_tolerance").as_double();
153 
154  bool need_local_costmap = false;
155  bool need_global_costmap = false;
156  for (const auto & behavior : behaviors_) {
157  auto costmap_info = behavior->getResourceInfo();
158  if (costmap_info == nav2_core::CostmapInfoType::BOTH) {
159  need_local_costmap = true;
160  need_global_costmap = true;
161  break;
162  }
163  if (costmap_info == nav2_core::CostmapInfoType::LOCAL) {
164  need_local_costmap = true;
165  }
166  if (costmap_info == nav2_core::CostmapInfoType::GLOBAL) {
167  need_global_costmap = true;
168  }
169  }
170 
171  if (need_local_costmap) {
172  local_costmap_sub_ = std::make_unique<nav2_costmap_2d::CostmapSubscriber>(
173  shared_from_this(), local_costmap_topic);
174 
175  local_footprint_sub_ = std::make_unique<nav2_costmap_2d::FootprintSubscriber>(
176  shared_from_this(), local_footprint_topic, *tf_, robot_base_frame, transform_tolerance);
177 
178  local_collision_checker_ = std::make_shared<nav2_costmap_2d::CostmapTopicCollisionChecker>(
179  *local_costmap_sub_, *local_footprint_sub_, get_name());
180  }
181 
182  if (need_global_costmap) {
183  global_costmap_sub_ = std::make_unique<nav2_costmap_2d::CostmapSubscriber>(
184  shared_from_this(), global_costmap_topic);
185 
186  global_footprint_sub_ = std::make_unique<nav2_costmap_2d::FootprintSubscriber>(
187  shared_from_this(), global_footprint_topic, *tf_, robot_base_frame, transform_tolerance);
188 
189  global_collision_checker_ = std::make_shared<nav2_costmap_2d::CostmapTopicCollisionChecker>(
190  *global_costmap_sub_, *global_footprint_sub_, get_name());
191  }
192 }
193 
194 nav2_util::CallbackReturn
195 BehaviorServer::on_activate(const rclcpp_lifecycle::State & /*state*/)
196 {
197  RCLCPP_INFO(get_logger(), "Activating");
198  std::vector<pluginlib::UniquePtr<nav2_core::Behavior>>::iterator iter;
199  for (iter = behaviors_.begin(); iter != behaviors_.end(); ++iter) {
200  (*iter)->activate();
201  }
202 
203  // create bond connection
204  createBond();
205 
206  return nav2_util::CallbackReturn::SUCCESS;
207 }
208 
209 nav2_util::CallbackReturn
210 BehaviorServer::on_deactivate(const rclcpp_lifecycle::State & /*state*/)
211 {
212  RCLCPP_INFO(get_logger(), "Deactivating");
213 
214  std::vector<pluginlib::UniquePtr<nav2_core::Behavior>>::iterator iter;
215  for (iter = behaviors_.begin(); iter != behaviors_.end(); ++iter) {
216  (*iter)->deactivate();
217  }
218 
219  // destroy bond connection
220  destroyBond();
221 
222  return nav2_util::CallbackReturn::SUCCESS;
223 }
224 
225 nav2_util::CallbackReturn
226 BehaviorServer::on_cleanup(const rclcpp_lifecycle::State & /*state*/)
227 {
228  RCLCPP_INFO(get_logger(), "Cleaning up");
229 
230  std::vector<pluginlib::UniquePtr<nav2_core::Behavior>>::iterator iter;
231  for (iter = behaviors_.begin(); iter != behaviors_.end(); ++iter) {
232  (*iter)->cleanup();
233  }
234 
235  behaviors_.clear();
236  transform_listener_.reset();
237  tf_.reset();
238 
239  local_costmap_sub_.reset();
240  global_costmap_sub_.reset();
241 
242  local_footprint_sub_.reset();
243  global_footprint_sub_.reset();
244 
245  local_collision_checker_.reset();
246  global_collision_checker_.reset();
247 
248  return nav2_util::CallbackReturn::SUCCESS;
249 }
250 
251 nav2_util::CallbackReturn
252 BehaviorServer::on_shutdown(const rclcpp_lifecycle::State &)
253 {
254  RCLCPP_INFO(get_logger(), "Shutting down");
255  return nav2_util::CallbackReturn::SUCCESS;
256 }
257 
258 } // end namespace behavior_server
259 
260 #include "rclcpp_components/register_node_macro.hpp"
261 
262 // Register the component with class_loader.
263 // This acts as a sort of entry point, allowing the component to be discoverable when its library
264 // is being loaded into a running process.
265 RCLCPP_COMPONENTS_REGISTER_NODE(behavior_server::BehaviorServer)
An server hosting a map of behavior plugins.
nav2_util::CallbackReturn on_cleanup(const rclcpp_lifecycle::State &state) override
Cleanup lifecycle server.
BehaviorServer(const rclcpp::NodeOptions &options=rclcpp::NodeOptions())
A constructor for behavior_server::BehaviorServer.
nav2_util::CallbackReturn on_deactivate(const rclcpp_lifecycle::State &state) override
Deactivate lifecycle server.
nav2_util::CallbackReturn on_activate(const rclcpp_lifecycle::State &state) override
Activate lifecycle server.
void configureBehaviorPlugins()
configures behavior plugins
nav2_util::CallbackReturn on_shutdown(const rclcpp_lifecycle::State &state) override
Shutdown lifecycle server.
void setupResourcesForBehaviorPlugins()
configures behavior plugins
nav2_util::CallbackReturn on_configure(const rclcpp_lifecycle::State &state) override
Configure lifecycle server.
bool loadBehaviorPlugins()
Loads behavior plugins from parameter file.
std::shared_ptr< nav2_util::LifecycleNode > shared_from_this()
Get a shared pointer of this.
void createBond()
Create bond connection to lifecycle manager.
void destroyBond()
Destroy bond connection to lifecycle manager.