perception_widget.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2018, Mohamad Ayman.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * The name of Mohamad Ayman may not be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  *********************************************************************/
33 
34 /* Author: Mohamad Ayman */
35 
36 // SA
37 #include "perception_widget.h"
38 
39 // Qt
40 #include <QVBoxLayout>
41 #include <QFormLayout>
42 #include <QApplication>
43 
44 namespace moveit_setup_assistant
45 {
46 // ******************************************************************************************
47 // Constructor
48 // ******************************************************************************************
49 PerceptionWidget::PerceptionWidget(QWidget* parent, moveit_setup_assistant::MoveItConfigDataPtr config_data)
50  : SetupScreenWidget(parent), config_data_(config_data)
51 {
52  // Basic widget container
53  QVBoxLayout* layout = new QVBoxLayout();
54  layout->setAlignment(Qt::AlignTop);
55 
56  // Top Header Area ------------------------------------------------
57 
58  HeaderWidget* header =
59  new HeaderWidget("Setup 3D Perception Sensors",
60  "Configure your 3D sensors to work with Moveit! "
61  "Please see <a "
62  "href='http://docs.ros.org/kinetic/api/moveit_tutorials/html/doc/perception_pipeline/"
63  "perception_pipeline_tutorial.html'>Perception Documentation</a> "
64  "for more details.",
65  this);
66  layout->addWidget(header);
67 
68  // Add spacing
69  QSpacerItem* blank_space = new QSpacerItem(1, 8);
70  layout->addSpacerItem(blank_space);
71 
72  // Plugin type combo box
73  QLabel* plugin_field_title = new QLabel(this);
74  plugin_field_title->setText("Optionally choose a type of 3D sensor plugin to configure:");
75  layout->addWidget(plugin_field_title);
76 
77  sensor_plugin_field_ = new QComboBox(this);
78  sensor_plugin_field_->setEditable(false);
79  sensor_plugin_field_->setMaximumWidth(600);
80  connect(sensor_plugin_field_, SIGNAL(currentIndexChanged(int)), this, SLOT(sensorPluginChanged(int)));
81  layout->addWidget(sensor_plugin_field_);
82 
83  // Point Cloud group -------------------------------------------
84  point_cloud_group_ = new QGroupBox("Point Cloud");
85 
86  QFormLayout* point_cloud_form_layout = new QFormLayout();
87  point_cloud_form_layout->setContentsMargins(0, 15, 0, 15);
88 
89  // Point Cloud Topic
90  point_cloud_topic_field_ = new QLineEdit(this);
91  point_cloud_topic_field_->setMaximumWidth(400);
92  // point_cloud_topic_field_->setText(QString("/clud topic"));
93  point_cloud_form_layout->addRow("Point Cloud Topic:", point_cloud_topic_field_);
94 
95  // Max Range
96  max_range_field_ = new QLineEdit(this);
97  max_range_field_->setMaximumWidth(400);
98  point_cloud_form_layout->addRow("Max Range:", max_range_field_);
99 
100  // Point Subsample
101  point_subsample_field_ = new QLineEdit(this);
102  point_subsample_field_->setMaximumWidth(400);
103  point_cloud_form_layout->addRow("Point Subsample:", point_subsample_field_);
104 
105  // Padding Offset
106  padding_offset_field_ = new QLineEdit(this);
107  padding_offset_field_->setMaximumWidth(400);
108  point_cloud_form_layout->addRow("Padding Offset:", padding_offset_field_);
109 
110  // Padding Scale
111  padding_scale_field_ = new QLineEdit(this);
112  padding_scale_field_->setMaximumWidth(400);
113  point_cloud_form_layout->addRow("Padding Scale:", padding_scale_field_);
114 
115  // Filtered Cloud Topic
116  filtered_cloud_topic_field_ = new QLineEdit(this);
117  filtered_cloud_topic_field_->setMaximumWidth(400);
118  point_cloud_form_layout->addRow("Filtered Cloud Topic:", filtered_cloud_topic_field_);
119 
120  // Max Update Rate
121  max_update_rate_field_ = new QLineEdit(this);
122  max_update_rate_field_->setMaximumWidth(400);
123  point_cloud_form_layout->addRow("Max Update Rate:", max_update_rate_field_);
124 
125  // Piont Cloud form layout
126  point_cloud_group_->setLayout(point_cloud_form_layout);
127  layout->addWidget(point_cloud_group_);
128 
129  // Depth map group --------------------------------------------
130  depth_map_group_ = new QGroupBox("Depth Map");
131 
132  // Depth Map form layout
133  QFormLayout* depth_map_form_layout = new QFormLayout();
134  depth_map_form_layout->setContentsMargins(0, 15, 0, 15);
135 
136  // Image Topic
137  image_topic_field_ = new QLineEdit(this);
138  image_topic_field_->setMaximumWidth(400);
139  depth_map_form_layout->addRow("Image Topic:", image_topic_field_);
140 
141  // Queue Size
142  queue_size_field_ = new QLineEdit(this);
143  queue_size_field_->setMaximumWidth(400);
144  depth_map_form_layout->addRow("Queue Size:", queue_size_field_);
145 
146  // Near Clipping Plane Distance
147  near_clipping_field_ = new QLineEdit(this);
148  near_clipping_field_->setMaximumWidth(400);
149  depth_map_form_layout->addRow("Near Clipping Plane Distance:", near_clipping_field_);
150 
151  // Far Clipping Plane Distance
152  far_clipping_field_ = new QLineEdit(this);
153  far_clipping_field_->setMaximumWidth(400);
154  depth_map_form_layout->addRow("Far Clipping Plane Distance:", far_clipping_field_);
155 
156  // Shadow Threshold
157  shadow_threshold_field_ = new QLineEdit(this);
158  shadow_threshold_field_->setMaximumWidth(400);
159  depth_map_form_layout->addRow("Shadow Threshold:", shadow_threshold_field_);
160 
161  // Padding Offset
162  depth_padding_offset_field_ = new QLineEdit(this);
163  depth_padding_offset_field_->setMaximumWidth(400);
164  depth_map_form_layout->addRow("Padding Offset:", depth_padding_offset_field_);
165 
166  // Padding Scale
167  depth_padding_scale_field_ = new QLineEdit(this);
168  depth_padding_scale_field_->setMaximumWidth(400);
169  depth_map_form_layout->addRow("Padding Scale:", depth_padding_scale_field_);
170 
171  // Filtered Cloud Topic
172  depth_filtered_cloud_topic_field_ = new QLineEdit(this);
173  depth_filtered_cloud_topic_field_->setMaximumWidth(400);
174  depth_map_form_layout->addRow("Filtered Cloud Topic:", depth_filtered_cloud_topic_field_);
175 
176  // Filtered Cloud Topic
177  depth_max_update_rate_field_ = new QLineEdit(this);
178  depth_max_update_rate_field_->setMaximumWidth(400);
179  depth_map_form_layout->addRow("Max Update Rate:", depth_max_update_rate_field_);
180 
181  depth_map_group_->setLayout(depth_map_form_layout);
182  layout->addWidget(depth_map_group_);
183 
184  layout->setAlignment(Qt::AlignTop);
185 
186  // Finish Layout --------------------------------------------------
187  this->setLayout(layout);
188 }
189 
190 // ******************************************************************************************
191 // Received when this widget is chosen from the navigation menu
192 // ******************************************************************************************
194 {
196 }
197 
198 // ******************************************************************************************
199 // Received when another widget is chosen from the navigation menu
200 // ******************************************************************************************
202 {
203  // Save the sensor plugin configuration to sensors_plugin_config data structure
204  if (sensor_plugin_field_->currentIndex() == 1)
205  {
206  // Point Cloud plugin feilds
207  config_data_->addGenericParameterToSensorPluginConfig("sensor_plugin", "occupancy_map_monitor/"
208  "PointCloudOctomapUpdater");
209  config_data_->addGenericParameterToSensorPluginConfig("point_cloud_topic",
210  point_cloud_topic_field_->text().trimmed().toStdString());
211  config_data_->addGenericParameterToSensorPluginConfig("max_range",
212  max_range_field_->text().trimmed().toStdString());
213  config_data_->addGenericParameterToSensorPluginConfig("point_subsample",
214  point_subsample_field_->text().trimmed().toStdString());
215  config_data_->addGenericParameterToSensorPluginConfig("padding_offset",
216  padding_offset_field_->text().trimmed().toStdString());
217  config_data_->addGenericParameterToSensorPluginConfig("padding_scale",
218  padding_scale_field_->text().trimmed().toStdString());
219  config_data_->addGenericParameterToSensorPluginConfig("max_update_rate",
220  max_update_rate_field_->text().trimmed().toStdString());
221  config_data_->addGenericParameterToSensorPluginConfig("filtered_cloud_topic",
222  filtered_cloud_topic_field_->text().trimmed().toStdString());
223 
225  }
226  else if (sensor_plugin_field_->currentIndex() == 2)
227  {
228  // Depth Map plugin feilds
229  config_data_->addGenericParameterToSensorPluginConfig("sensor_plugin", "occupancy_map_monitor/"
230  "DepthImageOctomapUpdater");
231  config_data_->addGenericParameterToSensorPluginConfig("image_topic",
232  image_topic_field_->text().trimmed().toStdString());
233  config_data_->addGenericParameterToSensorPluginConfig("queue_size",
234  queue_size_field_->text().trimmed().toStdString());
235  config_data_->addGenericParameterToSensorPluginConfig("near_clipping_plane_distance",
236  near_clipping_field_->text().trimmed().toStdString());
237  config_data_->addGenericParameterToSensorPluginConfig("far_clipping_plane_distance",
238  far_clipping_field_->text().trimmed().toStdString());
239  config_data_->addGenericParameterToSensorPluginConfig("shadow_threshold",
240  shadow_threshold_field_->text().trimmed().toStdString());
241  config_data_->addGenericParameterToSensorPluginConfig("padding_scale",
242  depth_padding_scale_field_->text().trimmed().toStdString());
243  config_data_->addGenericParameterToSensorPluginConfig("padding_offset",
244  depth_padding_offset_field_->text().trimmed().toStdString());
245  config_data_->addGenericParameterToSensorPluginConfig(
246  "filtered_cloud_topic", depth_filtered_cloud_topic_field_->text().trimmed().toStdString());
247  config_data_->addGenericParameterToSensorPluginConfig("max_update_rate",
248  depth_max_update_rate_field_->text().trimmed().toStdString());
249 
251  }
252  else
253  {
254  // Clear the sensors_plugin_config data structure
255  config_data_->clearSensorPluginConfig();
257  }
258  return true;
259 }
260 
262 {
263  if (index == 1)
264  {
265  // Point cloud form visible, depth map form invisible
266  point_cloud_group_->setVisible(true);
267  depth_map_group_->setVisible(false);
268  }
269  else if (index == 2)
270  {
271  // Depth map form visible, point cloud form invisible
272  point_cloud_group_->setVisible(false);
273  depth_map_group_->setVisible(true);
274  }
275  else
276  {
277  // All forms invisible
278  point_cloud_group_->setVisible(false);
279  depth_map_group_->setVisible(false);
280  }
281 }
282 
284 {
285  // Only load this combo box once
286  static bool hasLoaded = false;
287  if (hasLoaded)
288  return;
289  hasLoaded = true;
290 
291  // Remove all old items
292  sensor_plugin_field_->clear();
293 
294  // Add None option, the default
295  sensor_plugin_field_->addItem("None");
296 
297  // Add the two avilable plugins to combo box
298  sensor_plugin_field_->addItem("Point Cloud");
299  sensor_plugin_field_->addItem("Depth Map");
300 
301  // Load deafult config, or use the one in the config package if exists
302  std::vector<std::map<std::string, GenericParameter> > sensors_vec_map = config_data_->getSensorPluginConfig();
303  for (std::size_t i = 0; i < sensors_vec_map.size(); ++i)
304  {
305  if (sensors_vec_map[i]["sensor_plugin"].getValue() == std::string("occupancy_map_monitor/PointCloudOctomapUpdater"))
306  {
307  sensor_plugin_field_->setCurrentIndex(1);
308  point_cloud_topic_field_->setText(QString(sensors_vec_map[i]["point_cloud_topic"].getValue().c_str()));
309  max_range_field_->setText(QString(sensors_vec_map[i]["max_range"].getValue().c_str()));
310  point_subsample_field_->setText(QString(sensors_vec_map[i]["point_subsample"].getValue().c_str()));
311  padding_offset_field_->setText(QString(sensors_vec_map[i]["padding_offset"].getValue().c_str()));
312  padding_scale_field_->setText(QString(sensors_vec_map[i]["padding_scale"].getValue().c_str()));
313  max_update_rate_field_->setText(QString(sensors_vec_map[i]["max_update_rate"].getValue().c_str()));
314  filtered_cloud_topic_field_->setText(QString(sensors_vec_map[i]["filtered_cloud_topic"].getValue().c_str()));
315  }
316  else if (sensors_vec_map[i]["sensor_plugin"].getValue() ==
317  std::string("occupancy_map_monitor/DepthImageOctomapUpdater"))
318  {
319  sensor_plugin_field_->setCurrentIndex(2);
320  image_topic_field_->setText(QString(sensors_vec_map[i]["image_topic"].getValue().c_str()));
321  queue_size_field_->setText(QString(sensors_vec_map[i]["queue_size"].getValue().c_str()));
322  near_clipping_field_->setText(QString(sensors_vec_map[i]["near_clipping_plane_distance"].getValue().c_str()));
323  far_clipping_field_->setText(QString(sensors_vec_map[i]["far_clipping_plane_distance"].getValue().c_str()));
324  shadow_threshold_field_->setText(QString(sensors_vec_map[i]["shadow_threshold"].getValue().c_str()));
325  depth_padding_scale_field_->setText(QString(sensors_vec_map[i]["padding_scale"].getValue().c_str()));
326  depth_padding_offset_field_->setText(QString(sensors_vec_map[i]["padding_offset"].getValue().c_str()));
328  QString(sensors_vec_map[i]["filtered_cloud_topic"].getValue().c_str()));
329  depth_max_update_rate_field_->setText(QString(sensors_vec_map[i]["max_update_rate"].getValue().c_str()));
330  }
331  }
332 
333  // If no sensor config exists, default to None
334  if (sensors_vec_map.size() == 2)
335  {
336  sensor_plugin_field_->setCurrentIndex(0);
337  }
338 }
339 
340 } // namespace
PerceptionWidget(QWidget *parent, moveit_setup_assistant::MoveItConfigDataPtr config_data)
virtual void focusGiven()
Received when this widget is chosen from the navigation menu.
virtual bool focusLost()
Received when another widget is chosen from the navigation menu.
moveit_setup_assistant::MoveItConfigDataPtr config_data_
Contains all the configuration data for the setup assistant.
void loadSensorPluginsComboBox()
Populate the combo dropdown box with sensor plugins.
void sensorPluginChanged(int index)
Called when the selected item in the sensor_plugin_field_ combobox is changed.


moveit_setup_assistant
Author(s): Dave Coleman
autogenerated on Sun Oct 18 2020 13:19:28