22 #include "lifecycle_msgs/msg/state.hpp"
23 #include "nav2_core/controller_exceptions.hpp"
24 #include "nav_2d_utils/conversions.hpp"
25 #include "nav_2d_utils/tf_help.hpp"
26 #include "nav2_util/node_utils.hpp"
27 #include "nav2_util/geometry_utils.hpp"
28 #include "nav2_controller/controller_server.hpp"
30 using namespace std::chrono_literals;
31 using rcl_interfaces::msg::ParameterType;
32 using std::placeholders::_1;
34 namespace nav2_controller
37 ControllerServer::ControllerServer(
const rclcpp::NodeOptions & options)
38 : nav2_util::LifecycleNode(
"controller_server",
"", options),
39 progress_checker_loader_(
"nav2_core",
"nav2_core::ProgressChecker"),
40 default_progress_checker_ids_{
"progress_checker"},
41 default_progress_checker_types_{
"nav2_controller::SimpleProgressChecker"},
42 goal_checker_loader_(
"nav2_core",
"nav2_core::GoalChecker"),
43 default_goal_checker_ids_{
"goal_checker"},
44 default_goal_checker_types_{
"nav2_controller::SimpleGoalChecker"},
45 lp_loader_(
"nav2_core",
"nav2_core::Controller"),
46 default_ids_{
"FollowPath"},
47 default_types_{
"dwb_core::DWBLocalPlanner"},
48 costmap_update_timeout_(300ms)
50 RCLCPP_INFO(get_logger(),
"Creating controller server");
52 declare_parameter(
"controller_frequency", 20.0);
54 declare_parameter(
"progress_checker_plugins", default_progress_checker_ids_);
55 declare_parameter(
"goal_checker_plugins", default_goal_checker_ids_);
56 declare_parameter(
"controller_plugins", default_ids_);
57 declare_parameter(
"min_x_velocity_threshold", rclcpp::ParameterValue(0.0001));
58 declare_parameter(
"min_y_velocity_threshold", rclcpp::ParameterValue(0.0001));
59 declare_parameter(
"min_theta_velocity_threshold", rclcpp::ParameterValue(0.0001));
61 declare_parameter(
"speed_limit_topic", rclcpp::ParameterValue(
"speed_limit"));
63 declare_parameter(
"failure_tolerance", rclcpp::ParameterValue(0.0));
64 declare_parameter(
"use_realtime_priority", rclcpp::ParameterValue(
false));
65 declare_parameter(
"publish_zero_velocity", rclcpp::ParameterValue(
true));
66 declare_parameter(
"costmap_update_timeout", 0.30);
69 costmap_ros_ = std::make_shared<nav2_costmap_2d::Costmap2DROS>(
70 "local_costmap", std::string{get_namespace()},
71 get_parameter(
"use_sim_time").as_bool());
76 progress_checkers_.clear();
77 goal_checkers_.clear();
79 costmap_thread_.reset();
82 nav2_util::CallbackReturn
87 RCLCPP_INFO(get_logger(),
"Configuring controller interface");
89 RCLCPP_INFO(get_logger(),
"getting progress checker plugins..");
90 get_parameter(
"progress_checker_plugins", progress_checker_ids_);
91 if (progress_checker_ids_ == default_progress_checker_ids_) {
92 for (
size_t i = 0; i < default_progress_checker_ids_.size(); ++i) {
93 nav2_util::declare_parameter_if_not_declared(
94 node, default_progress_checker_ids_[i] +
".plugin",
95 rclcpp::ParameterValue(default_progress_checker_types_[i]));
99 RCLCPP_INFO(get_logger(),
"getting goal checker plugins..");
100 get_parameter(
"goal_checker_plugins", goal_checker_ids_);
101 if (goal_checker_ids_ == default_goal_checker_ids_) {
102 for (
size_t i = 0; i < default_goal_checker_ids_.size(); ++i) {
103 nav2_util::declare_parameter_if_not_declared(
104 node, default_goal_checker_ids_[i] +
".plugin",
105 rclcpp::ParameterValue(default_goal_checker_types_[i]));
109 get_parameter(
"controller_plugins", controller_ids_);
110 if (controller_ids_ == default_ids_) {
111 for (
size_t i = 0; i < default_ids_.size(); ++i) {
112 nav2_util::declare_parameter_if_not_declared(
113 node, default_ids_[i] +
".plugin",
114 rclcpp::ParameterValue(default_types_[i]));
118 controller_types_.resize(controller_ids_.size());
119 goal_checker_types_.resize(goal_checker_ids_.size());
120 progress_checker_types_.resize(progress_checker_ids_.size());
122 get_parameter(
"controller_frequency", controller_frequency_);
123 get_parameter(
"min_x_velocity_threshold", min_x_velocity_threshold_);
124 get_parameter(
"min_y_velocity_threshold", min_y_velocity_threshold_);
125 get_parameter(
"min_theta_velocity_threshold", min_theta_velocity_threshold_);
126 RCLCPP_INFO(get_logger(),
"Controller frequency set to %.4fHz", controller_frequency_);
128 std::string speed_limit_topic;
129 get_parameter(
"speed_limit_topic", speed_limit_topic);
130 get_parameter(
"failure_tolerance", failure_tolerance_);
131 get_parameter(
"use_realtime_priority", use_realtime_priority_);
132 get_parameter(
"publish_zero_velocity", publish_zero_velocity_);
134 costmap_ros_->configure();
136 costmap_thread_ = std::make_unique<nav2_util::NodeThread>(costmap_ros_);
138 for (
size_t i = 0; i != progress_checker_ids_.size(); i++) {
140 progress_checker_types_[i] = nav2_util::get_plugin_type_param(
141 node, progress_checker_ids_[i]);
142 nav2_core::ProgressChecker::Ptr progress_checker =
143 progress_checker_loader_.createUniqueInstance(progress_checker_types_[i]);
145 get_logger(),
"Created progress_checker : %s of type %s",
146 progress_checker_ids_[i].c_str(), progress_checker_types_[i].c_str());
147 progress_checker->initialize(node, progress_checker_ids_[i]);
148 progress_checkers_.insert({progress_checker_ids_[i], progress_checker});
149 }
catch (
const std::exception & ex) {
152 "Failed to create progress_checker. Exception: %s", ex.what());
154 return nav2_util::CallbackReturn::FAILURE;
158 for (
size_t i = 0; i != progress_checker_ids_.size(); i++) {
159 progress_checker_ids_concat_ += progress_checker_ids_[i] + std::string(
" ");
164 "Controller Server has %s progress checkers available.", progress_checker_ids_concat_.c_str());
166 for (
size_t i = 0; i != goal_checker_ids_.size(); i++) {
168 goal_checker_types_[i] = nav2_util::get_plugin_type_param(node, goal_checker_ids_[i]);
169 nav2_core::GoalChecker::Ptr goal_checker =
170 goal_checker_loader_.createUniqueInstance(goal_checker_types_[i]);
172 get_logger(),
"Created goal checker : %s of type %s",
173 goal_checker_ids_[i].c_str(), goal_checker_types_[i].c_str());
174 goal_checker->initialize(node, goal_checker_ids_[i], costmap_ros_);
175 goal_checkers_.insert({goal_checker_ids_[i], goal_checker});
176 }
catch (
const pluginlib::PluginlibException & ex) {
179 "Failed to create goal checker. Exception: %s", ex.what());
181 return nav2_util::CallbackReturn::FAILURE;
185 for (
size_t i = 0; i != goal_checker_ids_.size(); i++) {
186 goal_checker_ids_concat_ += goal_checker_ids_[i] + std::string(
" ");
191 "Controller Server has %s goal checkers available.", goal_checker_ids_concat_.c_str());
193 for (
size_t i = 0; i != controller_ids_.size(); i++) {
195 controller_types_[i] = nav2_util::get_plugin_type_param(node, controller_ids_[i]);
196 nav2_core::Controller::Ptr controller =
197 lp_loader_.createUniqueInstance(controller_types_[i]);
199 get_logger(),
"Created controller : %s of type %s",
200 controller_ids_[i].c_str(), controller_types_[i].c_str());
201 controller->configure(
202 node, controller_ids_[i],
203 costmap_ros_->getTfBuffer(), costmap_ros_);
204 controllers_.insert({controller_ids_[i], controller});
205 }
catch (
const pluginlib::PluginlibException & ex) {
208 "Failed to create controller. Exception: %s", ex.what());
210 return nav2_util::CallbackReturn::FAILURE;
214 for (
size_t i = 0; i != controller_ids_.size(); i++) {
215 controller_ids_concat_ += controller_ids_[i] + std::string(
" ");
220 "Controller Server has %s controllers available.", controller_ids_concat_.c_str());
222 odom_sub_ = std::make_unique<nav_2d_utils::OdomSubscriber>(node);
223 vel_publisher_ = std::make_unique<nav2_util::TwistPublisher>(node,
"cmd_vel", 1);
225 double costmap_update_timeout_dbl;
226 get_parameter(
"costmap_update_timeout", costmap_update_timeout_dbl);
227 costmap_update_timeout_ = rclcpp::Duration::from_seconds(costmap_update_timeout_dbl);
232 action_server_ = std::make_unique<ActionServer>(
237 std::chrono::milliseconds(500),
238 true , rcl_action_server_get_default_options(),
239 use_realtime_priority_ );
240 }
catch (
const std::runtime_error & e) {
241 RCLCPP_ERROR(get_logger(),
"Error creating action server! %s", e.what());
243 return nav2_util::CallbackReturn::FAILURE;
247 speed_limit_sub_ = create_subscription<nav2_msgs::msg::SpeedLimit>(
248 speed_limit_topic, rclcpp::QoS(10),
249 std::bind(&ControllerServer::speedLimitCallback,
this, std::placeholders::_1));
251 return nav2_util::CallbackReturn::SUCCESS;
254 nav2_util::CallbackReturn
257 RCLCPP_INFO(get_logger(),
"Activating");
259 const auto costmap_ros_state = costmap_ros_->activate();
260 if (costmap_ros_state.id() != lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE) {
261 return nav2_util::CallbackReturn::FAILURE;
263 ControllerMap::iterator it;
264 for (it = controllers_.begin(); it != controllers_.end(); ++it) {
265 it->second->activate();
267 vel_publisher_->on_activate();
268 action_server_->activate();
272 dyn_params_handler_ = node->add_on_set_parameters_callback(
278 return nav2_util::CallbackReturn::SUCCESS;
281 nav2_util::CallbackReturn
284 RCLCPP_INFO(get_logger(),
"Deactivating");
286 action_server_->deactivate();
287 ControllerMap::iterator it;
288 for (it = controllers_.begin(); it != controllers_.end(); ++it) {
289 it->second->deactivate();
299 costmap_ros_->deactivate();
302 vel_publisher_->on_deactivate();
304 remove_on_set_parameters_callback(dyn_params_handler_.get());
305 dyn_params_handler_.reset();
310 return nav2_util::CallbackReturn::SUCCESS;
313 nav2_util::CallbackReturn
316 RCLCPP_INFO(get_logger(),
"Cleaning up");
319 ControllerMap::iterator it;
320 for (it = controllers_.begin(); it != controllers_.end(); ++it) {
321 it->second->cleanup();
323 controllers_.clear();
325 goal_checkers_.clear();
326 progress_checkers_.clear();
328 costmap_ros_->cleanup();
332 action_server_.reset();
334 costmap_thread_.reset();
335 vel_publisher_.reset();
336 speed_limit_sub_.reset();
338 return nav2_util::CallbackReturn::SUCCESS;
341 nav2_util::CallbackReturn
344 RCLCPP_INFO(get_logger(),
"Shutting down");
345 return nav2_util::CallbackReturn::SUCCESS;
349 const std::string & c_name,
350 std::string & current_controller)
352 if (controllers_.find(c_name) == controllers_.end()) {
353 if (controllers_.size() == 1 && c_name.empty()) {
355 get_logger(),
"No controller was specified in action call."
356 " Server will use only plugin loaded %s. "
357 "This warning will appear once.", controller_ids_concat_.c_str());
358 current_controller = controllers_.begin()->first;
361 get_logger(),
"FollowPath called with controller name %s, "
362 "which does not exist. Available controllers are: %s.",
363 c_name.c_str(), controller_ids_concat_.c_str());
367 RCLCPP_DEBUG(get_logger(),
"Selected controller: %s.", c_name.c_str());
368 current_controller = c_name;
375 const std::string & c_name,
376 std::string & current_goal_checker)
378 if (goal_checkers_.find(c_name) == goal_checkers_.end()) {
379 if (goal_checkers_.size() == 1 && c_name.empty()) {
381 get_logger(),
"No goal checker was specified in parameter 'current_goal_checker'."
382 " Server will use only plugin loaded %s. "
383 "This warning will appear once.", goal_checker_ids_concat_.c_str());
384 current_goal_checker = goal_checkers_.begin()->first;
387 get_logger(),
"FollowPath called with goal_checker name %s in parameter"
388 " 'current_goal_checker', which does not exist. Available goal checkers are: %s.",
389 c_name.c_str(), goal_checker_ids_concat_.c_str());
393 RCLCPP_DEBUG(get_logger(),
"Selected goal checker: %s.", c_name.c_str());
394 current_goal_checker = c_name;
401 const std::string & c_name,
402 std::string & current_progress_checker)
404 if (progress_checkers_.find(c_name) == progress_checkers_.end()) {
405 if (progress_checkers_.size() == 1 && c_name.empty()) {
407 get_logger(),
"No progress checker was specified in parameter 'current_progress_checker'."
408 " Server will use only plugin loaded %s. "
409 "This warning will appear once.", progress_checker_ids_concat_.c_str());
410 current_progress_checker = progress_checkers_.begin()->first;
413 get_logger(),
"FollowPath called with progress_checker name %s in parameter"
414 " 'current_progress_checker', which does not exist. Available progress checkers are: %s.",
415 c_name.c_str(), progress_checker_ids_concat_.c_str());
419 RCLCPP_DEBUG(get_logger(),
"Selected progress checker: %s.", c_name.c_str());
420 current_progress_checker = c_name;
428 std::lock_guard<std::mutex> lock(dynamic_params_lock_);
430 RCLCPP_INFO(get_logger(),
"Received a goal, begin computing control effort.");
433 auto goal = action_server_->get_current_goal();
438 std::string c_name = goal->controller_id;
439 std::string current_controller;
441 current_controller_ = current_controller;
446 std::string gc_name = goal->goal_checker_id;
447 std::string current_goal_checker;
449 current_goal_checker_ = current_goal_checker;
454 std::string pc_name = goal->progress_checker_id;
455 std::string current_progress_checker;
457 current_progress_checker_ = current_progress_checker;
463 progress_checkers_[current_progress_checker_]->reset();
465 last_valid_cmd_time_ = now();
466 rclcpp::WallRate loop_rate(controller_frequency_);
467 while (rclcpp::ok()) {
468 auto start_time = this->now();
470 if (action_server_ ==
nullptr || !action_server_->is_server_active()) {
471 RCLCPP_DEBUG(get_logger(),
"Action server unavailable or inactive. Stopping.");
475 if (action_server_->is_cancel_requested()) {
476 if (controllers_[current_controller_]->cancel()) {
477 RCLCPP_INFO(get_logger(),
"Cancellation was successful. Stopping the robot.");
478 action_server_->terminate_all();
482 RCLCPP_INFO_THROTTLE(
483 get_logger(), *get_clock(), 1000,
"Waiting for the controller to finish cancellation");
489 auto waiting_start = now();
490 while (!costmap_ros_->isCurrent()) {
491 if (now() - waiting_start > costmap_update_timeout_) {
502 RCLCPP_INFO(get_logger(),
"Reached the goal!");
506 auto cycle_duration = this->now() - start_time;
507 if (!loop_rate.sleep()) {
510 "Control loop missed its desired rate of %.4f Hz. Current loop rate is %.4f Hz.",
511 controller_frequency_, 1 / cycle_duration.seconds());
515 RCLCPP_ERROR(this->get_logger(),
"%s", e.what());
517 std::shared_ptr<Action::Result> result = std::make_shared<Action::Result>();
518 result->error_code = Action::Result::INVALID_CONTROLLER;
519 result->error_msg = e.what();
520 action_server_->terminate_current(result);
523 RCLCPP_ERROR(this->get_logger(),
"%s", e.what());
525 std::shared_ptr<Action::Result> result = std::make_shared<Action::Result>();
526 result->error_code = Action::Result::TF_ERROR;
527 result->error_msg = e.what();
528 action_server_->terminate_current(result);
531 RCLCPP_ERROR(this->get_logger(),
"%s", e.what());
533 std::shared_ptr<Action::Result> result = std::make_shared<Action::Result>();
534 result->error_code = Action::Result::NO_VALID_CONTROL;
535 result->error_msg = e.what();
536 action_server_->terminate_current(result);
539 RCLCPP_ERROR(this->get_logger(),
"%s", e.what());
541 std::shared_ptr<Action::Result> result = std::make_shared<Action::Result>();
542 result->error_code = Action::Result::FAILED_TO_MAKE_PROGRESS;
543 result->error_msg = e.what();
544 action_server_->terminate_current(result);
547 RCLCPP_ERROR(this->get_logger(),
"%s", e.what());
549 std::shared_ptr<Action::Result> result = std::make_shared<Action::Result>();
550 result->error_code = Action::Result::PATIENCE_EXCEEDED;
551 result->error_msg = e.what();
552 action_server_->terminate_current(result);
555 RCLCPP_ERROR(this->get_logger(),
"%s", e.what());
557 std::shared_ptr<Action::Result> result = std::make_shared<Action::Result>();
558 result->error_code = Action::Result::INVALID_PATH;
559 result->error_msg = e.what();
560 action_server_->terminate_current(result);
563 RCLCPP_ERROR(this->get_logger(),
"%s", e.what());
565 std::shared_ptr<Action::Result> result = std::make_shared<Action::Result>();
566 result->error_code = Action::Result::CONTROLLER_TIMED_OUT;
567 result->error_msg = e.what();
568 action_server_->terminate_current(result);
571 RCLCPP_ERROR(this->get_logger(),
"%s", e.what());
573 std::shared_ptr<Action::Result> result = std::make_shared<Action::Result>();
574 result->error_code = Action::Result::UNKNOWN;
575 result->error_msg = e.what();
576 action_server_->terminate_current(result);
578 }
catch (std::exception & e) {
579 RCLCPP_ERROR(this->get_logger(),
"%s", e.what());
581 std::shared_ptr<Action::Result> result = std::make_shared<Action::Result>();
582 result->error_code = Action::Result::UNKNOWN;
583 result->error_msg = e.what();
584 action_server_->terminate_current(result);
588 RCLCPP_DEBUG(get_logger(),
"Controller succeeded, setting result");
593 action_server_->succeeded_current();
600 "Providing path to the controller %s", current_controller_.c_str());
601 if (path.poses.empty()) {
604 controllers_[current_controller_]->setPlan(path);
606 end_pose_ = path.poses.back();
607 end_pose_.header.frame_id = path.header.frame_id;
608 goal_checkers_[current_goal_checker_]->reset();
611 get_logger(),
"Path end point is (%.2f, %.2f)",
612 end_pose_.pose.position.x, end_pose_.pose.position.y);
614 current_path_ = path;
619 geometry_msgs::msg::PoseStamped pose;
625 if (!progress_checkers_[current_progress_checker_]->check(pose)) {
631 geometry_msgs::msg::TwistStamped cmd_vel_2d;
635 controllers_[current_controller_]->computeVelocityCommands(
637 nav_2d_utils::twist2Dto3D(twist),
638 goal_checkers_[current_goal_checker_].get());
639 last_valid_cmd_time_ = now();
640 cmd_vel_2d.header.frame_id = costmap_ros_->getBaseFrameID();
641 cmd_vel_2d.header.stamp = last_valid_cmd_time_;
645 if (failure_tolerance_ > 0 || failure_tolerance_ == -1.0) {
646 RCLCPP_WARN(this->get_logger(),
"%s", e.what());
647 cmd_vel_2d.twist.angular.x = 0;
648 cmd_vel_2d.twist.angular.y = 0;
649 cmd_vel_2d.twist.angular.z = 0;
650 cmd_vel_2d.twist.linear.x = 0;
651 cmd_vel_2d.twist.linear.y = 0;
652 cmd_vel_2d.twist.linear.z = 0;
653 cmd_vel_2d.header.frame_id = costmap_ros_->getBaseFrameID();
654 cmd_vel_2d.header.stamp = now();
655 if ((now() - last_valid_cmd_time_).seconds() > failure_tolerance_ &&
656 failure_tolerance_ != -1.0)
665 RCLCPP_DEBUG(get_logger(),
"Publishing velocity at time %.2f", now().seconds());
669 geometry_msgs::msg::PoseStamped robot_pose_in_path_frame;
670 rclcpp::Duration tolerance(rclcpp::Duration::from_seconds(costmap_ros_->getTransformTolerance()));
671 if (!nav_2d_utils::transformPose(
672 costmap_ros_->getTfBuffer(), current_path_.header.frame_id, pose,
673 robot_pose_in_path_frame, tolerance))
678 std::shared_ptr<Action::Feedback> feedback = std::make_shared<Action::Feedback>();
679 feedback->speed = std::hypot(cmd_vel_2d.twist.linear.x, cmd_vel_2d.twist.linear.y);
681 nav_msgs::msg::Path & current_path = current_path_;
682 auto find_closest_pose_idx = [&robot_pose_in_path_frame, ¤t_path]()
684 size_t closest_pose_idx = 0;
685 double curr_min_dist = std::numeric_limits<double>::max();
686 for (
size_t curr_idx = 0; curr_idx < current_path.poses.size(); ++curr_idx) {
688 nav2_util::geometry_utils::euclidean_distance(robot_pose_in_path_frame,
689 current_path.poses[curr_idx]);
690 if (curr_dist < curr_min_dist) {
691 curr_min_dist = curr_dist;
692 closest_pose_idx = curr_idx;
695 return closest_pose_idx;
698 const std::size_t closest_pose_idx = find_closest_pose_idx();
699 feedback->distance_to_goal = nav2_util::geometry_utils::calculate_path_length(current_path_,
701 action_server_->publish_feedback(feedback);
706 if (action_server_->is_preempt_requested()) {
707 RCLCPP_INFO(get_logger(),
"Passing new path to controller.");
708 auto goal = action_server_->accept_pending_goal();
709 std::string current_controller;
711 current_controller_ = current_controller;
713 std::shared_ptr<Action::Result> result = std::make_shared<Action::Result>();
714 result->error_code = Action::Result::INVALID_CONTROLLER;
715 result->error_msg =
"Terminating action, invalid controller " +
716 goal->controller_id +
" requested.";
717 action_server_->terminate_current(result);
720 std::string current_goal_checker;
722 current_goal_checker_ = current_goal_checker;
724 std::shared_ptr<Action::Result> result = std::make_shared<Action::Result>();
725 result->error_code = Action::Result::INVALID_CONTROLLER;
726 result->error_msg =
"Terminating action, invalid goal checker " +
727 goal->goal_checker_id +
" requested.";
728 action_server_->terminate_current(result);
731 std::string current_progress_checker;
733 if (current_progress_checker_ != current_progress_checker) {
735 get_logger(),
"Change of progress checker %s requested, resetting it",
736 goal->progress_checker_id.c_str());
737 current_progress_checker_ = current_progress_checker;
738 progress_checkers_[current_progress_checker_]->reset();
741 std::shared_ptr<Action::Result> result = std::make_shared<Action::Result>();
742 result->error_code = Action::Result::INVALID_CONTROLLER;
743 result->error_msg =
"Terminating action, invalid progress checker " +
744 goal->progress_checker_id +
" requested.";
745 action_server_->terminate_current(result);
754 auto cmd_vel = std::make_unique<geometry_msgs::msg::TwistStamped>(velocity);
755 if (!nav2_util::validateTwist(cmd_vel->twist)) {
756 RCLCPP_ERROR(get_logger(),
"Velocity message contains NaNs or Infs! Ignoring as invalid!");
759 if (vel_publisher_->is_activated() && vel_publisher_->get_subscription_count() > 0) {
760 vel_publisher_->publish(std::move(cmd_vel));
766 geometry_msgs::msg::TwistStamped velocity;
767 velocity.twist.angular.x = 0;
768 velocity.twist.angular.y = 0;
769 velocity.twist.angular.z = 0;
770 velocity.twist.linear.x = 0;
771 velocity.twist.linear.y = 0;
772 velocity.twist.linear.z = 0;
773 velocity.header.frame_id = costmap_ros_->getBaseFrameID();
774 velocity.header.stamp = now();
780 if (publish_zero_velocity_ || force_stop) {
785 for (
auto & controller : controllers_) {
786 controller.second->reset();
792 geometry_msgs::msg::PoseStamped pose;
799 geometry_msgs::msg::Twist velocity = nav_2d_utils::twist2Dto3D(twist);
801 geometry_msgs::msg::PoseStamped transformed_end_pose;
802 rclcpp::Duration tolerance(rclcpp::Duration::from_seconds(costmap_ros_->getTransformTolerance()));
803 nav_2d_utils::transformPose(
804 costmap_ros_->getTfBuffer(), costmap_ros_->getGlobalFrameID(),
805 end_pose_, transformed_end_pose, tolerance);
807 return goal_checkers_[current_goal_checker_]->isGoalReached(
808 pose.pose, transformed_end_pose.pose,
814 geometry_msgs::msg::PoseStamped current_pose;
815 if (!costmap_ros_->getRobotPose(current_pose)) {
822 void ControllerServer::speedLimitCallback(
const nav2_msgs::msg::SpeedLimit::SharedPtr msg)
824 ControllerMap::iterator it;
825 for (it = controllers_.begin(); it != controllers_.end(); ++it) {
826 it->second->setSpeedLimit(msg->speed_limit, msg->percentage);
830 rcl_interfaces::msg::SetParametersResult
833 rcl_interfaces::msg::SetParametersResult result;
835 for (
auto parameter : parameters) {
836 const auto & param_type = parameter.get_type();
837 const auto & param_name = parameter.get_name();
841 if (param_name.find(
'.') != std::string::npos) {
845 if (!dynamic_params_lock_.try_lock()) {
848 "Unable to dynamically change Parameters while the controller is currently running");
849 result.successful =
false;
851 "Unable to dynamically change Parameters while the controller is currently running";
855 if (param_type == ParameterType::PARAMETER_DOUBLE) {
856 if (param_name ==
"min_x_velocity_threshold") {
857 min_x_velocity_threshold_ = parameter.as_double();
858 }
else if (param_name ==
"min_y_velocity_threshold") {
859 min_y_velocity_threshold_ = parameter.as_double();
860 }
else if (param_name ==
"min_theta_velocity_threshold") {
861 min_theta_velocity_threshold_ = parameter.as_double();
862 }
else if (param_name ==
"failure_tolerance") {
863 failure_tolerance_ = parameter.as_double();
867 dynamic_params_lock_.unlock();
870 result.successful =
true;
876 #include "rclcpp_components/register_node_macro.hpp"
This class hosts variety of plugins of different algorithms to complete control tasks from the expose...
rcl_interfaces::msg::SetParametersResult dynamicParametersCallback(std::vector< rclcpp::Parameter > parameters)
Callback executed when a parameter change is detected.
void publishVelocity(const geometry_msgs::msg::TwistStamped &velocity)
Calls velocity publisher to publish the velocity on "cmd_vel" topic.
bool getRobotPose(geometry_msgs::msg::PoseStamped &pose)
Obtain current pose of the robot in costmap's frame.
nav_2d_msgs::msg::Twist2D getThresholdedTwist(const nav_2d_msgs::msg::Twist2D &twist)
get the thresholded Twist
void onGoalExit(bool force_stop)
Called on goal exit.
void computeControl()
FollowPath action server callback. Handles action server updates and spins server until goal is reach...
bool isGoalReached()
Checks if goal is reached.
nav2_util::CallbackReturn on_deactivate(const rclcpp_lifecycle::State &state) override
Deactivates member variables.
~ControllerServer()
Destructor for nav2_controller::ControllerServer.
nav2_util::CallbackReturn on_activate(const rclcpp_lifecycle::State &state) override
Activates member variables.
bool findGoalCheckerId(const std::string &c_name, std::string &name)
Find the valid goal checker ID name for the specified parameter.
nav2_util::CallbackReturn on_cleanup(const rclcpp_lifecycle::State &state) override
Calls clean up states and resets member variables.
void updateGlobalPath()
Calls setPlannerPath method with an updated path received from action server.
void setPlannerPath(const nav_msgs::msg::Path &path)
Assigns path to controller.
void publishZeroVelocity()
Calls velocity publisher to publish zero velocity.
nav2_util::CallbackReturn on_configure(const rclcpp_lifecycle::State &state) override
Configures controller parameters and member variables.
nav2_util::CallbackReturn on_shutdown(const rclcpp_lifecycle::State &state) override
Called when in Shutdown state.
bool findControllerId(const std::string &c_name, std::string &name)
Find the valid controller ID name for the given request.
bool findProgressCheckerId(const std::string &c_name, std::string &name)
Find the valid progress checker ID name for the specified parameter.
void computeAndPublishVelocity()
Calculates velocity and publishes to "cmd_vel" topic.
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.