15 #ifndef NAV2_BEHAVIORS__TIMED_BEHAVIOR_HPP_
16 #define NAV2_BEHAVIORS__TIMED_BEHAVIOR_HPP_
28 #include "rclcpp/rclcpp.hpp"
29 #include "nav2_ros_common/tf2_factories.hpp"
30 #include "geometry_msgs/msg/twist.hpp"
31 #include "nav2_util/robot_utils.hpp"
32 #include "nav2_util/twist_publisher.hpp"
33 #include "nav2_ros_common/simple_action_server.hpp"
34 #include "nav2_ros_common/rate.hpp"
35 #include "nav2_core/behavior.hpp"
36 #pragma GCC diagnostic push
37 #pragma GCC diagnostic ignored "-Wpedantic"
38 #include "tf2/utils.hpp"
39 #pragma GCC diagnostic pop
42 namespace nav2_behaviors
45 enum class Status : int8_t
55 uint16_t error_code{0};
56 std::string error_msg;
59 using namespace std::chrono_literals;
65 template<
typename ActionT>
75 : action_server_(nullptr),
76 cycle_frequency_(10.0),
78 transform_tolerance_(0.0)
87 virtual ResultStatus onRun(
const std::shared_ptr<const typename ActionT::Goal> command) = 0;
99 virtual void onConfigure()
105 virtual void onCleanup()
110 virtual void onActionCompletion(std::shared_ptr<typename ActionT::Result>)
116 const nav2::LifecycleNode::WeakPtr & parent,
117 const std::string & name, nav2::TransformBuffer::SharedPtr tf,
118 std::shared_ptr<nav2_costmap_2d::CostmapTopicCollisionChecker> local_collision_checker,
119 std::shared_ptr<nav2_costmap_2d::CostmapTopicCollisionChecker> global_collision_checker)
123 auto node = node_.lock();
124 logger_ = node->get_logger();
125 clock_ = node->get_clock();
127 RCLCPP_INFO(logger_,
"Configuring %s", name.c_str());
129 behavior_name_ = name;
132 node->get_parameter(
"cycle_frequency", cycle_frequency_);
133 node->get_parameter(
"local_frame", local_frame_);
134 node->get_parameter(
"global_frame", global_frame_);
135 node->get_parameter(
"robot_base_frame", robot_base_frame_);
136 node->get_parameter(
"transform_tolerance", transform_tolerance_);
138 action_server_ = node->create_action_server<ActionT>(
140 std::bind(&TimedBehavior::execute,
this),
nullptr,
nullptr, std::chrono::milliseconds(
143 local_collision_checker_ = local_collision_checker;
144 global_collision_checker_ = global_collision_checker;
146 vel_pub_ = std::make_unique<nav2_util::TwistPublisher>(node,
"cmd_vel");
154 action_server_.reset();
162 RCLCPP_INFO(logger_,
"Activating %s", behavior_name_.c_str());
164 vel_pub_->on_activate();
165 action_server_->activate();
172 vel_pub_->on_deactivate();
173 action_server_->deactivate();
178 nav2::LifecycleNode::WeakPtr node_;
180 std::string behavior_name_;
181 std::unique_ptr<nav2_util::TwistPublisher> vel_pub_;
182 typename ActionServer::SharedPtr action_server_;
183 std::shared_ptr<nav2_costmap_2d::CostmapTopicCollisionChecker> local_collision_checker_;
184 std::shared_ptr<nav2_costmap_2d::CostmapTopicCollisionChecker> global_collision_checker_;
185 nav2::TransformBuffer::SharedPtr tf_;
187 double cycle_frequency_;
189 std::string local_frame_;
190 std::string global_frame_;
191 std::string robot_base_frame_;
192 double transform_tolerance_;
193 rclcpp::Duration elapsed_time_{0, 0};
196 rclcpp::Clock::SharedPtr clock_;
199 rclcpp::Logger logger_{rclcpp::get_logger(
"nav2_behaviors")};
205 RCLCPP_INFO(logger_,
"Running %s", behavior_name_.c_str());
210 "Called while inactive, ignoring request.");
215 auto result = std::make_shared<typename ActionT::Result>();
217 ResultStatus on_run_result = onRun(action_server_->get_current_goal());
218 if (on_run_result.status != Status::SUCCEEDED) {
219 result->error_code = on_run_result.error_code;
220 result->error_msg = on_run_result.error_msg;
222 logger_,
"Initial checks failed for %s - %s", behavior_name_.c_str(),
223 on_run_result.error_msg.c_str());
224 action_server_->terminate_current(result);
228 auto start_time = clock_->now();
229 auto node = node_.lock();
233 "Failed to run %s because the parent node is no longer available.",
234 behavior_name_.c_str());
235 result->error_msg = behavior_name_ +
" failed: parent node expired";
236 result->total_elapsed_time = clock_->now() - start_time;
237 onActionCompletion(result);
238 action_server_->terminate_current(result);
243 while (rclcpp::ok()) {
244 elapsed_time_ = clock_->now() - start_time;
246 if (action_server_->is_preempt_requested()) {
248 logger_,
"Received a preemption request for %s,"
249 " however feature is currently not implemented. Aborting and stopping.",
250 behavior_name_.c_str());
252 result->total_elapsed_time = clock_->now() - start_time;
253 onActionCompletion(result);
254 action_server_->terminate_current(result);
258 if (action_server_->is_cancel_requested()) {
259 RCLCPP_INFO(logger_,
"Canceling %s", behavior_name_.c_str());
261 result->total_elapsed_time = elapsed_time_;
262 onActionCompletion(result);
263 action_server_->terminate_all(result);
267 ResultStatus on_cycle_update_result = onCycleUpdate();
268 switch (on_cycle_update_result.status) {
269 case Status::SUCCEEDED:
272 "%s completed successfully", behavior_name_.c_str());
273 result->total_elapsed_time = clock_->now() - start_time;
274 onActionCompletion(result);
275 action_server_->succeeded_current(result);
279 result->error_code = on_cycle_update_result.error_code;
280 result->error_msg = behavior_name_ +
" failed:" + on_cycle_update_result.error_msg;
281 RCLCPP_WARN(logger_,
"%s", result->error_msg.c_str());
282 result->total_elapsed_time = clock_->now() - start_time;
283 onActionCompletion(result);
284 action_server_->terminate_current(result);
287 case Status::RUNNING:
299 auto cmd_vel = std::make_unique<geometry_msgs::msg::TwistStamped>();
300 cmd_vel->header.frame_id = robot_base_frame_;
301 cmd_vel->header.stamp = clock_->now();
302 cmd_vel->twist.linear.x = 0.0;
303 cmd_vel->twist.linear.y = 0.0;
304 cmd_vel->twist.angular.z = 0.0;
306 vel_pub_->publish(std::move(cmd_vel));
A sim-time-aware rate for Nav2 loops.
An action server wrapper to make applications simpler using Actions.
TimedBehavior()
A TimedBehavior constructor.
void deactivate() override
Method to deactivate Behavior and any threads involved in execution.
void activate() override
Method to active Behavior and any threads involved in execution.
void configure(const nav2::LifecycleNode::WeakPtr &parent, const std::string &name, nav2::TransformBuffer::SharedPtr tf, std::shared_ptr< nav2_costmap_2d::CostmapTopicCollisionChecker > local_collision_checker, std::shared_ptr< nav2_costmap_2d::CostmapTopicCollisionChecker > global_collision_checker) override
void cleanup() override
Method to cleanup resources used on shutdown.
Abstract interface for behaviors to adhere to with pluginlib.