15 #ifndef NAV2_BEHAVIORS__TIMED_BEHAVIOR_HPP_
16 #define NAV2_BEHAVIORS__TIMED_BEHAVIOR_HPP_
28 #include "rclcpp/clock.hpp"
29 #include "rclcpp/duration.hpp"
30 #include "rclcpp/logger.hpp"
31 #include "rclcpp/logging.hpp"
32 #include "rclcpp/utilities.hpp"
33 #include "nav2_ros_common/tf2_factories.hpp"
34 #include "geometry_msgs/msg/pose_stamped.hpp"
35 #include "geometry_msgs/msg/twist.hpp"
36 #include "nav2_util/robot_utils.hpp"
37 #include "nav2_util/twist_publisher.hpp"
38 #include "nav2_ros_common/simple_action_server.hpp"
39 #include "nav2_ros_common/rate.hpp"
40 #include "nav2_core/behavior.hpp"
41 #include "tf2/utils.hpp"
44 namespace nav2_behaviors
47 enum class Status : int8_t
57 uint16_t error_code{0};
58 std::string error_msg;
61 using namespace std::chrono_literals;
67 template<
typename ActionT>
77 : action_server_(nullptr),
78 cycle_frequency_(10.0),
80 transform_tolerance_(0.0)
89 virtual ResultStatus onRun(
const std::shared_ptr<const typename ActionT::Goal> command) = 0;
101 virtual void onConfigure()
107 virtual void onCleanup()
112 virtual void onActionCompletion(std::shared_ptr<typename ActionT::Result>)
118 const nav2::LifecycleNode::WeakPtr & parent,
119 const std::string & name, nav2::TransformBuffer::SharedPtr tf,
120 std::shared_ptr<nav2_costmap_2d::CostmapTopicCollisionChecker> local_collision_checker,
121 std::shared_ptr<nav2_costmap_2d::CostmapTopicCollisionChecker> global_collision_checker)
125 auto node = node_.lock();
126 logger_ = node->get_logger();
127 clock_ = node->get_clock();
129 RCLCPP_INFO(logger_,
"Configuring %s", name.c_str());
131 behavior_name_ = name;
134 node->get_parameter(
"cycle_frequency", cycle_frequency_);
135 node->get_parameter(
"local_frame", local_frame_);
136 node->get_parameter(
"global_frame", global_frame_);
137 node->get_parameter(
"robot_base_frame", robot_base_frame_);
138 node->get_parameter(
"transform_tolerance", transform_tolerance_);
140 action_server_ = node->create_action_server<ActionT>(
142 std::bind(&TimedBehavior::execute,
this),
nullptr,
nullptr, std::chrono::milliseconds(
145 local_collision_checker_ = local_collision_checker;
146 global_collision_checker_ = global_collision_checker;
148 vel_pub_ = std::make_unique<nav2_util::TwistPublisher>(node,
"cmd_vel");
156 action_server_.reset();
164 RCLCPP_INFO(logger_,
"Activating %s", behavior_name_.c_str());
166 vel_pub_->on_activate();
167 action_server_->activate();
174 vel_pub_->on_deactivate();
175 action_server_->deactivate();
180 nav2::LifecycleNode::WeakPtr node_;
182 std::string behavior_name_;
183 std::unique_ptr<nav2_util::TwistPublisher> vel_pub_;
184 typename ActionServer::SharedPtr action_server_;
185 std::shared_ptr<nav2_costmap_2d::CostmapTopicCollisionChecker> local_collision_checker_;
186 std::shared_ptr<nav2_costmap_2d::CostmapTopicCollisionChecker> global_collision_checker_;
187 nav2::TransformBuffer::SharedPtr tf_;
189 double cycle_frequency_;
191 std::string local_frame_;
192 std::string global_frame_;
193 std::string robot_base_frame_;
194 double transform_tolerance_;
195 rclcpp::Duration elapsed_time_{0, 0};
198 rclcpp::Clock::SharedPtr clock_;
201 rclcpp::Logger logger_{rclcpp::get_logger(
"nav2_behaviors")};
207 RCLCPP_INFO(logger_,
"Running %s", behavior_name_.c_str());
212 "Called while inactive, ignoring request.");
217 auto result = std::make_shared<typename ActionT::Result>();
219 ResultStatus on_run_result = onRun(action_server_->get_current_goal());
220 if (on_run_result.status != Status::SUCCEEDED) {
221 result->error_code = on_run_result.error_code;
222 result->error_msg = on_run_result.error_msg;
224 logger_,
"Initial checks failed for %s - %s", behavior_name_.c_str(),
225 on_run_result.error_msg.c_str());
226 action_server_->terminate_current(result);
230 auto start_time = clock_->now();
231 auto node = node_.lock();
235 "Failed to run %s because the parent node is no longer available.",
236 behavior_name_.c_str());
237 result->error_msg = behavior_name_ +
" failed: parent node expired";
238 result->total_elapsed_time = clock_->now() - start_time;
239 onActionCompletion(result);
240 action_server_->terminate_current(result);
245 while (rclcpp::ok()) {
246 elapsed_time_ = clock_->now() - start_time;
248 if (action_server_->is_preempt_requested()) {
250 logger_,
"Received a preemption request for %s,"
251 " however feature is currently not implemented. Aborting and stopping.",
252 behavior_name_.c_str());
254 result->total_elapsed_time = clock_->now() - start_time;
255 onActionCompletion(result);
256 action_server_->terminate_current(result);
260 if (action_server_->is_cancel_requested()) {
261 RCLCPP_INFO(logger_,
"Canceling %s", behavior_name_.c_str());
263 result->total_elapsed_time = elapsed_time_;
264 onActionCompletion(result);
265 action_server_->terminate_all(result);
269 ResultStatus on_cycle_update_result = onCycleUpdate();
270 switch (on_cycle_update_result.status) {
271 case Status::SUCCEEDED:
274 "%s completed successfully", behavior_name_.c_str());
275 result->total_elapsed_time = clock_->now() - start_time;
276 onActionCompletion(result);
277 action_server_->succeeded_current(result);
282 result->error_code = on_cycle_update_result.error_code;
283 result->error_msg = behavior_name_ +
" failed:" + on_cycle_update_result.error_msg;
284 RCLCPP_WARN(logger_,
"%s", result->error_msg.c_str());
285 result->total_elapsed_time = clock_->now() - start_time;
286 onActionCompletion(result);
287 action_server_->terminate_current(result);
290 case Status::RUNNING:
302 auto cmd_vel = std::make_unique<geometry_msgs::msg::TwistStamped>();
303 cmd_vel->header.frame_id = robot_base_frame_;
304 cmd_vel->header.stamp = clock_->now();
305 cmd_vel->twist.linear.x = 0.0;
306 cmd_vel->twist.linear.y = 0.0;
307 cmd_vel->twist.angular.z = 0.0;
309 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.