WidgetController.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5  *
6  * ArmarX is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * ArmarX is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * \package VisionX::gui-plugins::WidgetController
19  * \author Philipp Schmidt ( ufedv at student dot kit dot edu )
20  * \date 2015
21  * \copyright http://www.gnu.org/licenses/gpl-2.0.txt
22  * GNU General Public License
23  */
24 
25 #include "WidgetController.h"
26 
27 #include <algorithm>
28 #include <type_traits>
29 
30 // Ice
31 #include <Ice/Ice.h>
32 #include <IceUtil/Time.h>
33 
34 // VisionX
35 #include <VisionX/interface/core/PointCloudProviderInterface.h>
38 
39 // PCL tools
43 
44 #include "CoinPointCloud.h"
45 
46 #include <QMainWindow>
47 
48 
49 namespace visionx
50 {
51  WidgetController::WidgetController() : recenterCamera(false)
52  {
53  qRegisterMetaType<IceGrid::ObjectInfoSeq>("IceGrid::ObjectInfoSeq");
54  }
55 
57  {
58  }
59 
60  void WidgetController::loadSettings(QSettings* settings)
61  {
62  (void) settings; // Unused.
63  }
64 
65  void WidgetController::saveSettings(QSettings* settings)
66  {
67  (void) settings; // Unused.
68  }
69 
71  {
72  automaticConversion = true;
73  }
74 
76  {
77  // Refresh list once.
78  this->refreshProviderList();
79 
80  // Ice is ready, allow refreshing of list.
81  QMetaObject::invokeMethod(widget.refreshButton, "setEnabled", Q_ARG(bool, true));
82  }
83 
85  {
86  QMetaObject::invokeMethod(widget.refreshButton, "setEnabled", Q_ARG(bool, false));
87  QMetaObject::invokeMethod(this, "disconnectQt");
88  }
89 
90  void WidgetController::disconnectQt()
91  {
92  auto icemanager = this->getIceManager();
93  if (!icemanager)
94  {
95  return;
96  }
97  // Let's check which providers just went offline
98  for (int row = 0; row < widget.providerList->count(); row++)
99  {
100  QListWidgetItem* item = widget.providerList->item(row);
101  const std::string subscriber = item->text().toStdString();
102 
103  ARMARX_LOG << subscriber << " has state " << icemanager->getIceGridSession()->getComponentState(subscriber) << std::endl;
104 
105  // Check component status
106  if (icemanager->getIceGridSession()->getComponentState(subscriber) != armarx::IceGridAdmin::eActivated)
107  {
108  // Unregister cloud
109  manager->unregisterPointCloud(subscriber);
110 
111  // Remove item from provider list (and free memory)
112  delete this->widget.providerList->takeItem(this->widget.providerList->row(item));
113 
114  // Indices got reduced by one
115  row--;
116 
117  // Release point cloud provider
118  this->releasePointCloudProvider(subscriber);
119  }
120  }
121  }
122 
124  {
125  }
126 
128  {
129  // Setup user interface
130  widget.setupUi(getWidget());
131  //qRegisterMetaType<visionx::CoinPointCloud*>("visionx::CoinPointCloud*");
132 
133  // Connect update calls with process calls
134  connect(this, SIGNAL(newPointCloudReceived(QString, CoinPointCloud*)),
135  this, SLOT(processPointCloud(QString, CoinPointCloud*)));
136 
137  // Add manager
138  manager = new Manager();
139  widget.pointCloudDisplay->getDisplay()->getRootNode()->addChild(manager);
140 
141  // Remove line counter in table
142  widget.tableWidget->verticalHeader()->setVisible(false);
143 
144  // Disable editing of table
145  widget.tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
146 
147  // Button for manual refreshing
148  connect(widget.refreshButton, SIGNAL(clicked()), this, SLOT(refreshProviderList()));
149 
150  // Do not allow refreshing until component connected and ice is ready
151  // widget.refreshButton->setEnabled(false);
152 
153  // Allow to chose background color
154  connect(widget.backgroundButton, SIGNAL(clicked()), this, SLOT(selectColor()));
155 
156  // Items get selected and deselected in list, show infos for pointcloud
157  connect(widget.providerList, SIGNAL(itemPressed(QListWidgetItem*)), this, SLOT(showPointCloudInfo(QListWidgetItem*)));
158 
159  // Items get checked and unchecked in list, add to viewport
160  connect(widget.providerList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(pointCloudChecked(QListWidgetItem*)));
161 
162  // Connect save point cloud button
163  connect(widget.saveButton, SIGNAL(clicked()), this, SLOT(savePointCloud()));
164 
165  // Connect spin box to change point size
166  connect(widget.doubleSpinBoxPointSize, SIGNAL(valueChanged(double)), this, SLOT(setPointSize(double)));
167  }
168 
170  {
171  std::lock_guard<std::mutex> lock(mutex);
172 
173  // Fetch all point cloud providers for updates and save in buffer
174  for (const std::string& providerName : manager->getRegisteredPointClouds())
175  {
176  if (!isPointCloudProviderKnown(providerName) || !pointCloudHasNewData(providerName))
177  {
178  // Skip this one (disconnected in mean time or no new data available).
179  continue;
180  }
181 
182  // Save in this buffer
183  pcl::PointCloud<PointT>::Ptr providerBuffer(new pcl::PointCloud<PointT>());
184 
185  // Check point cloud type.
186  const visionx::MetaPointCloudFormatPtr info = getPointCloudFormat(providerName);
187  const visionx::PointContentType pointContentType = info->type;
188 
189  bool colorFromLabel = tools::isLabeled(pointContentType) && this->widget.colorMode_label->isChecked();
190 
191  switch (pointContentType)
192  {
193  case visionx::PointContentType::ePoints:
194  getPointCloudAs(providerName, *providerBuffer);
195  break;
196  case visionx::PointContentType::eColoredPoints:
197  getPointCloudAs(providerName, *providerBuffer);
198  break;
199  case visionx::PointContentType::eColoredLabeledPoints:
200  getPointCloudAs(providerName, *providerBuffer);
201  break;
202  case visionx::PointContentType::eLabeledPoints:
203  getPointCloudAs(providerName, *providerBuffer);
204  break;
205  default:
207  << "Unexpected point cloud content type: " << tools::toString(pointContentType);
208  continue;
209  }
210 
211  CoinPointCloud* cloud = new CoinPointCloud(providerBuffer, pointContentType, colorFromLabel, pointSize);
212  emit newPointCloudReceived(QString::fromStdString(providerName), cloud);
213  }
214  }
215 
216  template <class PointCloudT>
217  void WidgetController::getPointCloudAs(const std::string& providerName, PointCloudT& targetPointCloud)
218  {
219  using InputPointT = typename PointCloudT::PointType;
220 
221  typename pcl::PointCloud<InputPointT>::Ptr inputCloudPtr(new pcl::PointCloud<InputPointT>());
222  if (getPointClouds(providerName, inputCloudPtr))
223  {
224  pcl::copyPointCloud(*inputCloudPtr, targetPointCloud);
225  }
226  }
227 
228  void WidgetController::processPointCloud(QString providerName, CoinPointCloud* cloud)
229  {
230  manager->updatePointCloud(providerName.toStdString(), *cloud);
231  if (recenterCamera)
232  {
233  widget.pointCloudDisplay->getDisplay()->cameraViewAll();
234  recenterCamera = false;
235  }
236 
237  auto* item = widget.providerList->currentItem();
238  if (item && providerName == item->text())
239  {
240  showPointCloudInfo(widget.providerList->currentItem());
241  }
242  }
243 
244  void WidgetController::updateProviderList(IceGrid::ObjectInfoSeq objects)
245  {
246  ARMARX_INFO << "Updating cloudlist.";
247 
248  // Signal user we are fetching providers
249  widget.loadingStatusLabel->setText(QString::fromStdString("Loading..."));
250 
251  // Count how many providers are online
252  int counter = 0;
253 
254  // Iterate over all objects
255  for (const auto& object : objects)
256  {
257  const std::string name = this->getIceManager()->getCommunicator()->proxyToString(object.proxy);
258  const std::string shortName = name.substr(0, name.find(' '));
259 
260  // Check if we didn't connect to this provider yet.
261  // Invariant: Every item in list widget is a provider we already connected in the past.
262  if (widget.providerList->findItems(QString::fromStdString(shortName), Qt::MatchExactly).count() == 0)
263  {
264  // Add new item and make it checkable.
265  QListWidgetItem* item = new QListWidgetItem(QString::fromStdString(shortName), widget.providerList);
266  item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
267  item->setCheckState(Qt::Unchecked);
268 
269  // Subscribe to topic, provider is fetchable after that.
270  this->usingPointCloudProvider(shortName);
271  this->getPointCloudProvider(shortName);
272  }
273 
274  counter++;
275  }
276 
277  // Signal user we are done and show how many providers are online
278  widget.loadingStatusLabel->setText(QString::fromStdString("Loading complete: " + std::to_string(counter) + " provider found"));
279  }
280 
282  {
283  ARMARX_INFO << "Get cloud providers from ice.";
284  // Get ice grid admin
285  armarx::IceGridAdminPtr admin = this->getIceManager()->getIceGridSession();
286  IceGrid::ObjectInfoSeq objects = admin->getRegisteredObjects<PointCloudProviderInterfacePrx>(widget.lineEditPointCloudFilter->text().toStdString());
287  QMetaObject::invokeMethod(this, "updateProviderList", Q_ARG(IceGrid::ObjectInfoSeq, objects));
288  }
289 
290 
291  void WidgetController::showPointCloudInfo(QListWidgetItem* item)
292  {
293  const std::string providerName = item->text().toStdString();
294  visionx::MetaPointCloudFormatPtr info = this->getPointCloudFormat(providerName);
295 
296  widget.tableWidget->setRowCount(8);
297  widget.tableWidget->setColumnCount(2);
298 
299  // Name
300  widget.tableWidget->setItem(0, 0, new QTableWidgetItem("Name"));
301  widget.tableWidget->setItem(0, 1, new QTableWidgetItem(item->text()));
302 
303  // Type
304  widget.tableWidget->setItem(1, 0, new QTableWidgetItem("Type"));
305  widget.tableWidget->setItem(1, 1, new QTableWidgetItem(QString::fromStdString(visionx::tools::toString(info->type))));
306 
307  // Width
308  widget.tableWidget->setItem(2, 0, new QTableWidgetItem("Width"));
309  widget.tableWidget->setItem(2, 1, new QTableWidgetItem(QString::fromStdString(std::to_string(info->width))));
310 
311  // Height
312  widget.tableWidget->setItem(3, 0, new QTableWidgetItem("Height"));
313  widget.tableWidget->setItem(3, 1, new QTableWidgetItem(QString::fromStdString(std::to_string(info->height))));
314 
315  // Size
316  widget.tableWidget->setItem(4, 0, new QTableWidgetItem("Size"));
317  widget.tableWidget->setItem(4, 1, new QTableWidgetItem(QString::fromStdString(std::to_string(info->size))));
318 
319  // Capacity
320  widget.tableWidget->setItem(5, 0, new QTableWidgetItem("Capacity"));
321  widget.tableWidget->setItem(5, 1, new QTableWidgetItem(QString::fromStdString(std::to_string(info->capacity))));
322 
323  // Sequence
324  widget.tableWidget->setItem(6, 0, new QTableWidgetItem("Sequence"));
325  widget.tableWidget->setItem(6, 1, new QTableWidgetItem(QString::fromStdString(std::to_string(info->seq))));
326 
327  // Time provided
328  widget.tableWidget->setItem(7, 0, new QTableWidgetItem("Time Provided"));
329 
330  const bool showRawTimestamp = false;
331  const std::string timeProvided = showRawTimestamp
332  ? std::to_string(info->timeProvided) // Raw time stamp
333  : IceUtil::Time::microSeconds(info->timeProvided).toDateTime(); // Readable time stamp.
334  widget.tableWidget->setItem(7, 1, new QTableWidgetItem(QString::fromStdString(timeProvided)));
335  }
336 
337  void WidgetController::pointCloudChecked(QListWidgetItem* item)
338  {
339  std::lock_guard<std::mutex> lock(mutex);
340 
341  const std::string providerName = item->text().toStdString();
342 
343  if (item->checkState())
344  {
345  manager->registerPointCloud(providerName);
346  }
347  else
348  {
349  manager->unregisterPointCloud(providerName);
350  }
351  recenterCamera = true;
352  }
353 
355  {
356  QColor selectedColor = this->colorDialog.getColor();
357 
358  widget.pointCloudDisplay->getDisplay()->setBackgroundColor(
359  SbColor(selectedColor.red() / 255.0f, selectedColor.green() / 255.0f, selectedColor.blue() / 255.0f));
360  }
361 
363  {
364  if (widget.providerList->selectedItems().size() == 1)
365  {
366  SaveDialog saveDialog(this->getMainWindow());
367  const std::string providerID = widget.providerList->selectedItems()[0]->text().toStdString();
368  const std::vector<std::string> clouds = manager->getRegisteredPointClouds();
369  if (std::find(clouds.begin(), clouds.end(), providerID) != clouds.end())
370  {
371  saveDialog.setPointCloudToSave(manager->getCloudByName(providerID));
372  int result = saveDialog.exec();
373 
374  if (result == QDialog::Accepted)
375  {
376  const CoinPointCloud& coinCloud = *manager->getCloudByName(providerID);
377  const pcl::PointCloud<PointT>& originalCloud = *coinCloud.getPCLCloud();
378  const std::string fileName = saveDialog.getResultFileName();
379 
380  switch (coinCloud.getOriginalType())
381  {
382  case visionx::PointContentType::ePoints:
383  storePointCloudAs(fileName, originalCloud);
384  break;
385  case visionx::PointContentType::eColoredPoints:
386  storePointCloudAs(fileName, originalCloud);
387  break;
388  case visionx::PointContentType::eColoredLabeledPoints:
389  storePointCloudAs(fileName, originalCloud);
390  break;
391  case visionx::PointContentType::eLabeledPoints:
392  storePointCloudAs(fileName, originalCloud);
393  break;
394  default:
396  << "Unexpected point cloud content type: " << tools::toString(coinCloud.getOriginalType());
397  return;
398  }
399  }
400 
401  saveDialog.releaseBuffer();
402  }
403  }
404  }
405 
406  template <class PointCloudT>
407  void WidgetController::storePointCloudAs(const std::string& filename, const PointCloudT& pointCloud)
408  {
409  using StoredPointT = typename PointCloudT::PointType;
410 
411  if (std::is_same<StoredPointT, PointT>())
412  {
413  pcl::io::savePCDFile(filename, pointCloud);
414  }
415  else
416  {
417  pcl::PointCloud<StoredPointT> stored;
418  pcl::copyPointCloud(pointCloud, stored);
419  pcl::io::savePCDFile(filename, stored);
420  }
421  }
422 
424  {
425  widget.configColumn->setVisible(false);
426  }
427 
429  {
430  widget.configColumn->setVisible(true);
431  }
432 }
433 
434 void visionx::WidgetController::setPointSize(double value)
435 {
436  ARMARX_VERBOSE << "Using new point size: " << value;
437  pointSize = static_cast<float>(value);
438 }
WidgetController.h
visionx::PointCloudProcessor::pointCloudHasNewData
bool pointCloudHasNewData(std::string providerName)
Returns current status for the given point cloud.
Definition: PointCloudProcessor.cpp:486
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:180
armarx::ManagedIceObject::getIceManager
IceManagerPtr getIceManager() const
Returns the IceManager.
Definition: ManagedIceObject.cpp:353
visionx::SaveDialog::setPointCloudToSave
void setPointCloudToSave(CoinPointCloud *cloud)
Definition: SaveDialog.cpp:49
visionx::armem::pointcloud::PointType
PointType
Definition: constants.h:78
visionx::PointCloudProcessor::getPointCloudFormat
MetaPointCloudFormatPtr getPointCloudFormat(std::string providerName)
Definition: PointCloudProcessor.cpp:506
visionx::PointCloudProcessor::automaticConversion
bool automaticConversion
Definition: PointCloudProcessor.h:626
visionx
ArmarX headers.
Definition: OpenPoseStressTest.h:38
CoinPointCloud.h
visionx::Manager::unregisterPointCloud
void unregisterPointCloud(const std::string &name)
Definition: Manager.cpp:46
visionx::WidgetController::newPointCloudReceived
void newPointCloudReceived(QString providerName, CoinPointCloud *cloud)
visionx::WidgetController::selectColor
void selectColor()
Definition: WidgetController.cpp:354
visionx::WidgetController::onInitPointCloudProcessor
void onInitPointCloudProcessor() override
Definition: WidgetController.cpp:70
PointCloudProvider.h
visionx::PointCloudProcessor::isPointCloudProviderKnown
bool isPointCloudProviderKnown(const std::string &providerName) const
Indicate whether the given name identifies a known point cloud provider.
Definition: PointCloudProcessor.cpp:392
visionx::tools::isLabeled
bool isLabeled(PointContentType type)
Definition: PointCloudConversions.cpp:108
visionx::WidgetController::onUnlockWidget
void onUnlockWidget() override
Definition: WidgetController.cpp:428
armarx::ArmarXWidgetController::getMainWindow
virtual QMainWindow * getMainWindow()
Returns the ArmarX MainWindow.
Definition: ArmarXWidgetController.cpp:125
visionx::CoinPointCloud::getPCLCloud
pcl::PointCloud< PointT >::ConstPtr getPCLCloud() const
Definition: CoinPointCloud.cpp:118
visionx::CoinPointCloud::getOriginalType
visionx::PointContentType getOriginalType() const
Definition: CoinPointCloud.cpp:123
segments.h
visionx::WidgetController::onDisconnectPointCloudProcessor
void onDisconnectPointCloudProcessor() override
Definition: WidgetController.cpp:84
visionx::WidgetController::refreshProviderList
void refreshProviderList()
Definition: WidgetController.cpp:281
visionx::Manager
Definition: Manager.h:37
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:926
PCLUtilities.h
visionx::WidgetController::~WidgetController
~WidgetController() override
Controller destructor.
Definition: WidgetController.cpp:56
visionx::WidgetController::onConnectPointCloudProcessor
void onConnectPointCloudProcessor() override
Definition: WidgetController.cpp:75
visionx::WidgetController::onExitPointCloudProcessor
void onExitPointCloudProcessor() override
Definition: WidgetController.cpp:123
filename
std::string filename
Definition: VisualizationRobot.cpp:83
armarx::PointCloudT
pcl::PointCloud< PointT > PointCloudT
Definition: Common.h:30
visionx::tools::toString
std::string toString(PointContentType pointContent)
Definition: PointCloudConversions.cpp:765
visionx::PointCloudProcessor::getPointClouds
int getPointClouds(const PointCloudPtrT &pointCloudPtr)
Poll PointClouds from provider.
Definition: PointCloudProcessor.h:373
visionx::WidgetController::processPointCloud
void processPointCloud(QString providerName, CoinPointCloud *cloud)
Definition: WidgetController.cpp:228
armarx::statechartmodel::eActivated
@ eActivated
Definition: SignalType.h:38
visionx::Manager::getRegisteredPointClouds
std::vector< std::string > getRegisteredPointClouds()
Definition: Manager.cpp:64
armarx::to_string
const std::string & to_string(const std::string &s)
Definition: StringHelpers.h:40
ARMARX_LOG
#define ARMARX_LOG
Definition: Logging.h:163
visionx::CoinPointCloud
Definition: CoinPointCloud.h:39
visionx::Manager::updatePointCloud
void updatePointCloud(const std::string &name, CoinPointCloud &cloud)
Definition: Manager.cpp:83
visionx::WidgetController::saveSettings
void saveSettings(QSettings *settings) override
Definition: WidgetController.cpp:65
visionx::Manager::registerPointCloud
void registerPointCloud(const std::string &name)
Definition: Manager.cpp:37
visionx::SaveDialog
Definition: SaveDialog.h:38
visionx::Manager::getCloudByName
CoinPointCloud * getCloudByName(const std::string &name)
Definition: Manager.cpp:76
PointCloudConversions.h
visionx::PointCloudProcessor::releasePointCloudProvider
void releasePointCloudProvider(std::string providerName)
Removes topic subscription and provider proxy dependency to release a point cloud provider.
Definition: PointCloudProcessor.cpp:275
visionx::SaveDialog::getResultFileName
std::string getResultFileName()
After calling the dialog, this contains the chosen file name.
Definition: SaveDialog.cpp:60
visionx::WidgetController::WidgetController
WidgetController()
Controller constructor.
Definition: WidgetController.cpp:51
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
visionx::WidgetController::savePointCloud
void savePointCloud()
Definition: WidgetController.cpp:362
IceUtil::Handle< IceGridAdmin >
visionx::WidgetController::onLockWidget
void onLockWidget() override
Definition: WidgetController.cpp:423
visionx::WidgetController::postDocking
void postDocking() override
postDocking is called after the widget has been docked into the main window.
Definition: WidgetController.cpp:127
visionx::WidgetController::pointCloudChecked
void pointCloudChecked(QListWidgetItem *item)
Definition: WidgetController.cpp:337
visionx::PointCloudProcessor::usingPointCloudProvider
void usingPointCloudProvider(std::string providerName)
Registers a delayed topic subscription and a delayed provider proxy retrieval which will be available...
Definition: PointCloudProcessor.cpp:261
visionx::WidgetController::updateProviderList
void updateProviderList(IceGrid::ObjectInfoSeq objects)
Definition: WidgetController.cpp:244
visionx::SaveDialog::releaseBuffer
void releaseBuffer()
Definition: SaveDialog.cpp:55
armarx::Logging::deactivateSpam
SpamFilterDataPtr deactivateSpam(float deactivationDurationSec=10.0f, const std::string &identifier="", bool deactivate=true) const
disables the logging for the current line for the given amount of seconds.
Definition: Logging.cpp:92
armarx::ArmarXWidgetController::getWidget
virtual QPointer< QWidget > getWidget()
getWidget returns a pointer to the a widget of this controller.
Definition: ArmarXWidgetController.cpp:54
visionx::PointCloudProcessor::getPointCloudProvider
PointCloudProviderInfo getPointCloudProvider(std::string name, bool waitForProxy=false)
Select an PointCloudProvider.
Definition: PointCloudProcessor.cpp:304
visionx::WidgetController::showPointCloudInfo
void showPointCloudInfo(QListWidgetItem *item)
Definition: WidgetController.cpp:291
visionx::WidgetController::loadSettings
void loadSettings(QSettings *settings) override
Definition: WidgetController.cpp:60
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
CoinViewer.h
visionx::WidgetController::process
void process() override
Definition: WidgetController.cpp:169