Nav2 Navigation Stack - humble  humble
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  "costmap_topic",
36  rclcpp::ParameterValue(std::string("local_costmap/costmap_raw")));
37  declare_parameter(
38  "footprint_topic",
39  rclcpp::ParameterValue(std::string("local_costmap/published_footprint")));
40  declare_parameter("cycle_frequency", rclcpp::ParameterValue(10.0));
41  declare_parameter("behavior_plugins", default_ids_);
42 
43  get_parameter("behavior_plugins", behavior_ids_);
44  if (behavior_ids_ == default_ids_) {
45  for (size_t i = 0; i < default_ids_.size(); ++i) {
46  declare_parameter(default_ids_[i] + ".plugin", default_types_[i]);
47  }
48  }
49 
50  declare_parameter(
51  "global_frame",
52  rclcpp::ParameterValue(std::string("odom")));
53  declare_parameter(
54  "robot_base_frame",
55  rclcpp::ParameterValue(std::string("base_link")));
56  declare_parameter(
57  "transform_tolerance",
58  rclcpp::ParameterValue(0.1));
59 }
60 
61 
62 BehaviorServer::~BehaviorServer()
63 {
64  behaviors_.clear();
65 }
66 
67 nav2_util::CallbackReturn
68 BehaviorServer::on_configure(const rclcpp_lifecycle::State & /*state*/)
69 {
70  RCLCPP_INFO(get_logger(), "Configuring");
71 
72  tf_ = std::make_shared<tf2_ros::Buffer>(get_clock());
73  auto timer_interface = std::make_shared<tf2_ros::CreateTimerROS>(
74  get_node_base_interface(),
75  get_node_timers_interface());
76  tf_->setCreateTimerInterface(timer_interface);
77  transform_listener_ = std::make_shared<tf2_ros::TransformListener>(*tf_);
78 
79  std::string costmap_topic, footprint_topic, robot_base_frame;
80  double transform_tolerance;
81  this->get_parameter("costmap_topic", costmap_topic);
82  this->get_parameter("footprint_topic", footprint_topic);
83  this->get_parameter("transform_tolerance", transform_tolerance);
84  this->get_parameter("robot_base_frame", robot_base_frame);
85  costmap_sub_ = std::make_unique<nav2_costmap_2d::CostmapSubscriber>(
86  shared_from_this(), costmap_topic);
87  footprint_sub_ = std::make_unique<nav2_costmap_2d::FootprintSubscriber>(
88  shared_from_this(), footprint_topic, *tf_, robot_base_frame, transform_tolerance);
89 
90  collision_checker_ = std::make_shared<nav2_costmap_2d::CostmapTopicCollisionChecker>(
91  *costmap_sub_, *footprint_sub_, this->get_name());
92 
93  behavior_types_.resize(behavior_ids_.size());
94  if (!loadBehaviorPlugins()) {
95  return nav2_util::CallbackReturn::FAILURE;
96  }
97 
98  return nav2_util::CallbackReturn::SUCCESS;
99 }
100 
101 
102 bool
104 {
105  auto node = shared_from_this();
106 
107  for (size_t i = 0; i != behavior_ids_.size(); i++) {
108  behavior_types_[i] = nav2_util::get_plugin_type_param(node, behavior_ids_[i]);
109  try {
110  RCLCPP_INFO(
111  get_logger(), "Creating behavior plugin %s of type %s",
112  behavior_ids_[i].c_str(), behavior_types_[i].c_str());
113  behaviors_.push_back(plugin_loader_.createUniqueInstance(behavior_types_[i]));
114  behaviors_.back()->configure(node, behavior_ids_[i], tf_, collision_checker_);
115  } catch (const pluginlib::PluginlibException & 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 
127 nav2_util::CallbackReturn
128 BehaviorServer::on_activate(const rclcpp_lifecycle::State & /*state*/)
129 {
130  RCLCPP_INFO(get_logger(), "Activating");
131  std::vector<pluginlib::UniquePtr<nav2_core::Behavior>>::iterator iter;
132  for (iter = behaviors_.begin(); iter != behaviors_.end(); ++iter) {
133  (*iter)->activate();
134  }
135 
136  // create bond connection
137  createBond();
138 
139  return nav2_util::CallbackReturn::SUCCESS;
140 }
141 
142 nav2_util::CallbackReturn
143 BehaviorServer::on_deactivate(const rclcpp_lifecycle::State & /*state*/)
144 {
145  RCLCPP_INFO(get_logger(), "Deactivating");
146 
147  std::vector<pluginlib::UniquePtr<nav2_core::Behavior>>::iterator iter;
148  for (iter = behaviors_.begin(); iter != behaviors_.end(); ++iter) {
149  (*iter)->deactivate();
150  }
151 
152  // destroy bond connection
153  destroyBond();
154 
155  return nav2_util::CallbackReturn::SUCCESS;
156 }
157 
158 nav2_util::CallbackReturn
159 BehaviorServer::on_cleanup(const rclcpp_lifecycle::State & /*state*/)
160 {
161  RCLCPP_INFO(get_logger(), "Cleaning up");
162 
163  std::vector<pluginlib::UniquePtr<nav2_core::Behavior>>::iterator iter;
164  for (iter = behaviors_.begin(); iter != behaviors_.end(); ++iter) {
165  (*iter)->cleanup();
166  }
167 
168  behaviors_.clear();
169  transform_listener_.reset();
170  tf_.reset();
171  footprint_sub_.reset();
172  costmap_sub_.reset();
173  collision_checker_.reset();
174 
175  return nav2_util::CallbackReturn::SUCCESS;
176 }
177 
178 nav2_util::CallbackReturn
179 BehaviorServer::on_shutdown(const rclcpp_lifecycle::State &)
180 {
181  RCLCPP_INFO(get_logger(), "Shutting down");
182  return nav2_util::CallbackReturn::SUCCESS;
183 }
184 
185 } // end namespace behavior_server
186 
187 #include "rclcpp_components/register_node_macro.hpp"
188 
189 // Register the component with class_loader.
190 // This acts as a sort of entry point, allowing the component to be discoverable when its library
191 // is being loaded into a running process.
192 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.
nav2_util::CallbackReturn on_shutdown(const rclcpp_lifecycle::State &state) override
Shutdown lifecycle server.
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.