Nav2 Navigation Stack - jazzy  jazzy
ROS 2 Navigation Stack
selector.cpp
1 // Copyright (c) 2024 Neobotix GmbH
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.
14 
15 #include "nav2_rviz_plugins/selector.hpp"
16 #include "nav2_rviz_plugins/utils.hpp"
17 #include "rviz_common/display_context.hpp"
18 
19 using namespace std::chrono_literals;
20 
21 namespace nav2_rviz_plugins
22 {
23 Selector::Selector(QWidget * parent)
24 : Panel(parent)
25 {
26  client_node_ = std::make_shared<rclcpp::Node>("nav2_rviz_selector_node");
27  rclcpp::QoS qos(rclcpp::KeepLast(1));
28  qos.transient_local().reliable();
29 
30  pub_controller_ =
31  client_node_->create_publisher<std_msgs::msg::String>("controller_selector", qos);
32  pub_planner_ = client_node_->create_publisher<std_msgs::msg::String>("planner_selector", qos);
33  pub_goal_checker_ =
34  client_node_->create_publisher<std_msgs::msg::String>("goal_checker_selector", qos);
35  pub_smoother_ = client_node_->create_publisher<std_msgs::msg::String>("smoother_selector", qos);
36  pub_progress_checker_ =
37  client_node_->create_publisher<std_msgs::msg::String>("progress_checker_selector", qos);
38 
39  main_layout_ = new QVBoxLayout;
40  row_1_label_layout_ = new QHBoxLayout;
41  row_2_label_layout_ = new QHBoxLayout;
42  row_3_label_layout_ = new QHBoxLayout;
43  row_1_layout_ = new QHBoxLayout;
44  row_2_layout_ = new QHBoxLayout;
45  row_3_layout_ = new QHBoxLayout;
46  controller_ = new QComboBox;
47  planner_ = new QComboBox;
48  goal_checker_ = new QComboBox;
49  smoother_ = new QComboBox;
50  progress_checker_ = new QComboBox;
51 
52  main_layout_->setContentsMargins(10, 10, 10, 10);
53 
54  row_1_label_layout_->addWidget(new QLabel("Controller"));
55  row_1_layout_->addWidget(controller_);
56  row_1_label_layout_->addWidget(new QLabel("Planner"));
57  row_1_layout_->addWidget(planner_);
58  row_2_label_layout_->addWidget(new QLabel("Goal Checker"));
59  row_2_layout_->addWidget(goal_checker_);
60  row_2_label_layout_->addWidget(new QLabel("Smoother"));
61  row_2_layout_->addWidget(smoother_);
62  row_3_label_layout_->addWidget(new QLabel("Progress Checker"));
63  row_3_layout_->addWidget(progress_checker_);
64 
65  main_layout_->addLayout(row_1_label_layout_);
66  main_layout_->addLayout(row_1_layout_);
67  main_layout_->addLayout(row_2_label_layout_);
68  main_layout_->addLayout(row_2_layout_);
69  main_layout_->addLayout(row_3_label_layout_);
70  main_layout_->addLayout(row_3_layout_);
71 
72  setLayout(main_layout_);
73  loadPlugins();
74 
75  connect(
76  controller_, QOverload<int>::of(&QComboBox::activated), this,
77  &Selector::setController);
78 
79  connect(
80  planner_, QOverload<int>::of(&QComboBox::activated), this,
81  &Selector::setPlanner);
82 
83  connect(
84  goal_checker_, QOverload<int>::of(&QComboBox::activated), this,
85  &Selector::setGoalChecker);
86 
87  connect(
88  smoother_, QOverload<int>::of(&QComboBox::activated), this,
89  &Selector::setSmoother);
90 
91  connect(
92  progress_checker_, QOverload<int>::of(&QComboBox::activated), this,
93  &Selector::setProgressChecker);
94 }
95 
96 Selector::~Selector()
97 {
98 }
99 
100 // Publish the selected controller or planner
101 void Selector::setSelection(
102  QComboBox * combo_box, rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher)
103 {
104  // If "default" option is selected, it gets removed and the next item is selected
105  if (combo_box->findText("Default") != -1) {
106  combo_box->removeItem(0);
107  }
108 
109  // if there are no plugins available, return
110  if (combo_box->count() == 0) {
111  return;
112  }
113 
114  std_msgs::msg::String msg;
115  msg.data = combo_box->currentText().toStdString();
116 
117  publisher->publish(msg);
118 }
119 
120 // Call setSelection() for controller
121 void Selector::setController()
122 {
123  setSelection(controller_, pub_controller_);
124 }
125 
126 // Call setSelection() for planner
127 void Selector::setPlanner()
128 {
129  setSelection(planner_, pub_planner_);
130 }
131 
132 // Call setSelection() for goal checker
133 void Selector::setGoalChecker()
134 {
135  setSelection(goal_checker_, pub_goal_checker_);
136 }
137 
138 // Call setSelection() for smoother
139 void Selector::setSmoother()
140 {
141  setSelection(smoother_, pub_smoother_);
142 }
143 
144 void Selector::setProgressChecker()
145 {
146  setSelection(progress_checker_, pub_progress_checker_);
147 }
148 
149 void
150 Selector::loadPlugins()
151 {
152  load_plugins_thread_ = std::thread([this]() {
153  rclcpp::Rate rate(0.2);
154  while (rclcpp::ok() && !plugins_loaded_) {
155  RCLCPP_INFO(client_node_->get_logger(), "Trying to load plugins...");
156  nav2_rviz_plugins::pluginLoader(
157  client_node_, server_failed_, "controller_server", "controller_plugins", controller_);
158  nav2_rviz_plugins::pluginLoader(
159  client_node_, server_failed_, "planner_server", "planner_plugins", planner_);
160  nav2_rviz_plugins::pluginLoader(
161  client_node_, server_failed_, "controller_server", "goal_checker_plugins",
162  goal_checker_);
163  nav2_rviz_plugins::pluginLoader(
164  client_node_, server_failed_, "smoother_server", "smoother_plugins", smoother_);
165  nav2_rviz_plugins::pluginLoader(
166  client_node_, server_failed_, "controller_server", "progress_checker_plugins",
167  progress_checker_);
168  if (controller_->count() > 0 &&
169  planner_->count() > 0 &&
170  goal_checker_->count() > 0 &&
171  smoother_->count() > 0 &&
172  progress_checker_->count() > 0)
173  {
174  plugins_loaded_ = true;
175  } else {
176  RCLCPP_INFO(client_node_->get_logger(), "Failed to load plugins. Retrying...");
177  }
178  rate.sleep();
179  }
180  });
181 }
182 
183 } // namespace nav2_rviz_plugins
184 #include "pluginlib/class_list_macros.hpp"
185 PLUGINLIB_EXPORT_CLASS(nav2_rviz_plugins::Selector, rviz_common::Panel)