Nav2 Navigation Stack - lyrical  lyrical
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_ros_common/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("cycle_frequency", rclcpp::ParameterValue(10.0));
35  behavior_ids_ = declare_or_get_parameter("behavior_plugins", default_ids_);
36  if (behavior_ids_ == default_ids_) {
37  for (size_t i = 0; i < default_ids_.size(); ++i) {
38  declare_parameter(default_ids_[i] + ".plugin", default_types_[i]);
39  }
40  }
41 
42  declare_parameter(
43  "local_frame",
44  rclcpp::ParameterValue(std::string("odom")));
45  declare_parameter(
46  "global_frame",
47  rclcpp::ParameterValue(std::string("map")));
48 }
49 
50 
51 BehaviorServer::~BehaviorServer()
52 {
53  behaviors_.clear();
54 }
55 
56 nav2::CallbackReturn
57 BehaviorServer::on_configure(const rclcpp_lifecycle::State & state)
58 {
59  RCLCPP_INFO(get_logger(), "Configuring");
60 
61  tf_ = nav2::create_transform_buffer(this);
62  transform_listener_ = nav2::create_transform_listener(*tf_, this, true);
63 
64  behavior_types_.resize(behavior_ids_.size());
65  if (!loadBehaviorPlugins()) {
66  on_cleanup(state);
67  return nav2::CallbackReturn::FAILURE;
68  }
71 
72  return nav2::CallbackReturn::SUCCESS;
73 }
74 
75 bool
77 {
78  auto node = shared_from_this();
79 
80  for (size_t i = 0; i != behavior_ids_.size(); i++) {
81  try {
82  behavior_types_[i] = nav2::get_plugin_type_param(node, behavior_ids_[i]);
83  RCLCPP_INFO(
84  get_logger(), "Creating behavior plugin %s of type %s",
85  behavior_ids_[i].c_str(), behavior_types_[i].c_str());
86  behaviors_.push_back(plugin_loader_.createUniqueInstance(behavior_types_[i]));
87  } catch (const std::exception & ex) {
88  RCLCPP_FATAL(
89  get_logger(), "Failed to create behavior %s of type %s."
90  " Exception: %s", behavior_ids_[i].c_str(), behavior_types_[i].c_str(),
91  ex.what());
92  return false;
93  }
94  }
95 
96  return true;
97 }
98 
100 {
101  auto node = shared_from_this();
102 
103  for (size_t i = 0; i != behavior_ids_.size(); i++) {
104  behaviors_[i]->configure(
105  node,
106  behavior_ids_[i],
107  tf_,
108  local_collision_checker_,
109  global_collision_checker_);
110  }
111 }
112 
114 {
115  std::string local_costmap_topic = declare_or_get_parameter(
116  "local_costmap_topic", std::string("local_costmap/costmap_raw"));
117  std::string global_costmap_topic = declare_or_get_parameter(
118  "global_costmap_topic", std::string("global_costmap/costmap_raw"));
119  std::string local_footprint_topic = declare_or_get_parameter(
120  "local_footprint_topic", std::string("local_costmap/published_footprint"));
121  std::string global_footprint_topic = declare_or_get_parameter(
122  "global_footprint_topic", std::string("global_costmap/published_footprint"));
123  std::string robot_base_frame = declare_or_get_parameter(
124  "robot_base_frame", std::string("base_link"));
125  double transform_tolerance = declare_or_get_parameter("transform_tolerance", 0.1);
126 
127  bool need_local_costmap = false;
128  bool need_global_costmap = false;
129  for (const auto & behavior : behaviors_) {
130  auto costmap_info = behavior->getResourceInfo();
131  if (costmap_info == nav2_core::CostmapInfoType::BOTH) {
132  need_local_costmap = true;
133  need_global_costmap = true;
134  break;
135  }
136  if (costmap_info == nav2_core::CostmapInfoType::LOCAL) {
137  need_local_costmap = true;
138  }
139  if (costmap_info == nav2_core::CostmapInfoType::GLOBAL) {
140  need_global_costmap = true;
141  }
142  }
143 
144  if (need_local_costmap) {
145  local_costmap_sub_ = std::make_unique<nav2_costmap_2d::CostmapSubscriber>(
146  shared_from_this(), local_costmap_topic);
147 
148  local_footprint_sub_ = std::make_unique<nav2_costmap_2d::FootprintSubscriber>(
149  shared_from_this(), local_footprint_topic, *tf_, robot_base_frame, transform_tolerance);
150 
151  local_collision_checker_ = std::make_shared<nav2_costmap_2d::CostmapTopicCollisionChecker>(
152  *local_costmap_sub_, *local_footprint_sub_, get_name());
153  }
154 
155  if (need_global_costmap) {
156  global_costmap_sub_ = std::make_unique<nav2_costmap_2d::CostmapSubscriber>(
157  shared_from_this(), global_costmap_topic);
158 
159  global_footprint_sub_ = std::make_unique<nav2_costmap_2d::FootprintSubscriber>(
160  shared_from_this(), global_footprint_topic, *tf_, robot_base_frame, transform_tolerance);
161 
162  global_collision_checker_ = std::make_shared<nav2_costmap_2d::CostmapTopicCollisionChecker>(
163  *global_costmap_sub_, *global_footprint_sub_, get_name());
164  }
165 }
166 
167 nav2::CallbackReturn
168 BehaviorServer::on_activate(const rclcpp_lifecycle::State & /*state*/)
169 {
170  RCLCPP_INFO(get_logger(), "Activating");
171  std::vector<pluginlib::UniquePtr<nav2_core::Behavior>>::iterator iter;
172  for (iter = behaviors_.begin(); iter != behaviors_.end(); ++iter) {
173  (*iter)->activate();
174  }
175 
176  // create bond connection
177  createBond();
178 
179  return nav2::CallbackReturn::SUCCESS;
180 }
181 
182 nav2::CallbackReturn
183 BehaviorServer::on_deactivate(const rclcpp_lifecycle::State & /*state*/)
184 {
185  RCLCPP_INFO(get_logger(), "Deactivating");
186 
187  std::vector<pluginlib::UniquePtr<nav2_core::Behavior>>::iterator iter;
188  for (iter = behaviors_.begin(); iter != behaviors_.end(); ++iter) {
189  (*iter)->deactivate();
190  }
191 
192  // destroy bond connection
193  destroyBond();
194 
195  return nav2::CallbackReturn::SUCCESS;
196 }
197 
198 nav2::CallbackReturn
199 BehaviorServer::on_cleanup(const rclcpp_lifecycle::State & /*state*/)
200 {
201  RCLCPP_INFO(get_logger(), "Cleaning up");
202 
203  std::vector<pluginlib::UniquePtr<nav2_core::Behavior>>::iterator iter;
204  for (iter = behaviors_.begin(); iter != behaviors_.end(); ++iter) {
205  (*iter)->cleanup();
206  }
207 
208  behaviors_.clear();
209  transform_listener_.reset();
210  tf_.reset();
211 
212  local_costmap_sub_.reset();
213  global_costmap_sub_.reset();
214 
215  local_footprint_sub_.reset();
216  global_footprint_sub_.reset();
217 
218  local_collision_checker_.reset();
219  global_collision_checker_.reset();
220 
221  return nav2::CallbackReturn::SUCCESS;
222 }
223 
224 nav2::CallbackReturn
225 BehaviorServer::on_shutdown(const rclcpp_lifecycle::State &)
226 {
227  RCLCPP_INFO(get_logger(), "Shutting down");
228  return nav2::CallbackReturn::SUCCESS;
229 }
230 
231 } // end namespace behavior_server
232 
233 #include "rclcpp_components/register_node_macro.hpp"
234 
235 // Register the component with class_loader.
236 // This acts as a sort of entry point, allowing the component to be discoverable when its library
237 // is being loaded into a running process.
238 RCLCPP_COMPONENTS_REGISTER_NODE(behavior_server::BehaviorServer)
An server hosting a map of behavior plugins.
BehaviorServer(const rclcpp::NodeOptions &options=rclcpp::NodeOptions())
A constructor for behavior_server::BehaviorServer.
nav2::CallbackReturn on_cleanup(const rclcpp_lifecycle::State &state) override
Cleanup lifecycle server.
nav2::CallbackReturn on_deactivate(const rclcpp_lifecycle::State &state) override
Deactivate lifecycle server.
nav2::CallbackReturn on_shutdown(const rclcpp_lifecycle::State &state) override
Shutdown lifecycle server.
void configureBehaviorPlugins()
configures behavior plugins
nav2::CallbackReturn on_activate(const rclcpp_lifecycle::State &state) override
Activate lifecycle server.
void setupResourcesForBehaviorPlugins()
configures behavior plugins
nav2::CallbackReturn on_configure(const rclcpp_lifecycle::State &state) override
Configure lifecycle server.
bool loadBehaviorPlugins()
Loads behavior plugins from parameter file.
void destroyBond()
Destroy bond connection to lifecycle manager.
nav2::LifecycleNode::SharedPtr shared_from_this()
Get a shared pointer of this.
ParameterT declare_or_get_parameter(const std::string &parameter_name, const ParameterDescriptor &parameter_descriptor=ParameterDescriptor())
Declares or gets a parameter with specified type (not value). If the parameter is already declared,...
void createBond()
Create bond connection to lifecycle manager.