PointCloudFilter.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::ArmarXObjects::PointCloudFilter
19  * @author Markus Grotz ( markus dot grotz at kit dot edu )
20  * @date 2016
21  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22  * GNU General Public License
23  */
24 
25 #include "PointCloudFilter.h"
26 
27 #include <pcl/common/colors.h>
28 #include <pcl/surface/convex_hull.h>
29 #include <pcl/filters/statistical_outlier_removal.h>
30 
31 #include <VirtualRobot/CollisionDetection/CollisionModel.h>
32 #include <VirtualRobot/math/Helpers.h>
33 #include <VirtualRobot/MathTools.h>
34 #include <SimoxUtility/math/convert/mat4f_to_rpy.h>
35 #include <SimoxUtility/math/convert/mat4f_to_pos.h>
36 #include <SimoxUtility/math/convert/pos_rpy_to_mat4f.h>
37 
39 
42 
45 
47 
48 
49 using namespace armarx;
50 
51 namespace visionx
52 {
53 
54  PointCloudFilterPropertyDefinitions::PointCloudFilterPropertyDefinitions(std::string prefix) :
56  {
57  defineOptionalProperty<std::string>("RobotStateComponentName", "RobotStateComponent",
58  "Name of the robot state component.");
59 
60  defineOptionalProperty<bool>("sourceFrameNameAuto", true,
61  "If enabled, try to get and use source frame name from point cloud provider.");
62  defineOptionalProperty<std::string>("sourceFrameName", "DepthCamera", "The source frame name.");
63  defineOptionalProperty<std::string>("targetFrameName", "Global", "The target frame name.");
64 
65  defineOptionalProperty<std::string>("PointCloudFormat", "XYZRGBA", "Format of the input and output point cloud (XYZRGBA, XYZL, XYZRGBL).");
66 
67  defineOptionalProperty<bool>("EnableDownsampling", true, "Enable/disable downsampling.");
68  defineOptionalProperty<float>("leafSize", 5.0f, "The voxel grid leaf size.");
69 
70 
71  defineOptionalProperty<bool>("StatisticalOutlierRemoval_enabled", false, "Enable StatisticalOutlierRemoval (pre downsampling)");
72  defineOptionalProperty<int>("StatisticalOutlierRemoval_MeanK", 50,
73  "(pcl parameter) number of nearest neighbors to use for mean distance estimation. ");
74  defineOptionalProperty<float>("StatisticalOutlierRemoval_StddevMulThresh", 1,
75  "(pcl parameter) standard deviation multiplier for the distance threshold calculation. ");
76 
77  defineOptionalProperty<bool>("EnableCropping", true, "Enable/disable cropping.");
78  defineOptionalPropertyVector<Eigen::Vector3f>("minPoint", Eigen::Vector3f(-1000.0f, -1000.0f, 0.0f),
79  "Minimal point of cropping box.", ',');
80  defineOptionalPropertyVector<Eigen::Vector3f>("maxPoint", Eigen::Vector3f(4800.0f, 11500.0f, 1800.0f),
81  "Maximal point of cropping box.", ',');
82  defineOptionalPropertyVector<Eigen::Vector3f>("rpy", {0, 0, 0},
83  "Roll, Pitch and Yaw applied to the points in the croping frame", ',');
84 
85  defineOptionalPropertyVector<Eigen::Vector3f>("ProviderFrameTranslation", Eigen::Vector3f(0.0f, 0.0f, 0.0f), "", ',');
86  defineOptionalPropertyVector<Eigen::Vector3f>("ProviderFrameRotation", Eigen::Vector3f(0.0f, 0.0f, 0.0f), "", ',');
87 
88  defineOptionalProperty<std::string>("croppingFrame", "Global", "The coordinate frame in which cropping is applied.");
89 
90  defineOptionalProperty<bool>("applyCollisionModelFilter", true,
91  "Discard points that appear to belong to the robot itself.");
92 
93  defineOptionalProperty<std::string>("RemoteGuiName", "RemoteGuiProvider", "Name of the remote GUI provider");
94 
95  defineOptionalProperty<bool>("reportCloudOutsideOfCroppingArea", false,
96  "If cropping is enabled, the points outside of the area are reported in a separate cloud");
97  }
98 
99 
101  {
102  return "PointCloudFilter";
103  }
104 
105  std::string PointCloudFilter::getReferenceFrame(const Ice::Current&)
106  {
107  std::unique_lock lock(parametersMutex);
108  return parameters.targetFrameName;
109  }
110 
112  const Vector3BasePtr& min, const Vector3BasePtr& max,
113  const std::string& frame, const Ice::Current&)
114  {
115  std::unique_lock lock(parametersMutex);
116  parameters.croppingEnabled = true;
117  parameters.croppingMinPoint = Vector3Ptr::dynamicCast(min)->toEigen();
118  parameters.croppingMaxPoint = Vector3Ptr::dynamicCast(max)->toEigen();
119  parameters.croppingFrameName = frame;
120  }
121 
123  {
124  getProperty(pointCloudFormat, "PointCloudFormat");
125 
126 
127  getProperty(parameters.sourceFrameName, "sourceFrameName");
128  getProperty(parameters.targetFrameName, "targetFrameName");
129 
130  getProperty(parameters.croppingEnabled, "EnableCropping");
131  getProperty(parameters.croppingFrameName, "croppingFrame");
132  getProperty(parameters.croppingMinPoint, "minPoint");
133  getProperty(parameters.croppingMaxPoint, "maxPoint");
134  getProperty(parameters.croppingRPY, "rpy");
135 
136  getProperty(parameters.downsamplingEnabled, "EnableDownsampling");
137  getProperty(parameters.gridLeafSize, "leafSize");
138 
139  getProperty(parameters.statisticalOutlierRemoval.enabled, "StatisticalOutlierRemoval_enabled");
140  getProperty(parameters.statisticalOutlierRemoval.meanK, "StatisticalOutlierRemoval_MeanK");
141  getProperty(parameters.statisticalOutlierRemoval.stddevMulThresh, "StatisticalOutlierRemoval_StddevMulThresh");
142 
143  {
144  parameters.providerFrameTransformation = simox::math::pos_rpy_to_mat4f(
145  getProperty<Eigen::Vector3f>("ProviderFrameTranslation").getValue(),
146  getProperty<Eigen::Vector3f>("ProviderFrameRotation").getValue()
147  );
148  }
149 
150  std::string robotStateComponentName = getProperty<std::string>("RobotStateComponentName");
151  if (!robotStateComponentName.empty())
152  {
153  usingProxyFromProperty("RobotStateComponentName");
154  }
155  else
156  {
157  ARMARX_INFO << "No RobotStateComponent configured, not performing any point cloud transformations.";
158  }
159 
160  getProperty(parameters.applyCollisionModelFilter, "applyCollisionModelFilter");
161  getProperty(parameters.reportCloudOutsideOfCroppingArea, "reportCloudOutsideOfCroppingArea");
162  if (parameters.applyCollisionModelFilter && robotStateComponentName.empty())
163  {
164  ARMARX_WARNING << "Collision model filter activated, but no RobotStateComponent configured, deactivating collision model filtering";
165  parameters.applyCollisionModelFilter = false;
166  }
167 
168  debugDrawer.setLayer(getName());
169  debugDrawer.offeringTopic(*this);
170  debugDrawer.setEnabled(false);
171  }
172 
174  {
175  const std::string robotStateComponentName = getProperty<std::string>("RobotStateComponentName");
176  if (!robotStateComponentName.empty())
177  {
178  getProxy(robotStateComponent, robotStateComponentName);
179  localRobot = RemoteRobot::createLocalCloneFromFile(
180  robotStateComponent, VirtualRobot::RobotIO::RobotDescription::eStructure);
181  }
182 
183  {
184  const std::vector<std::string> providerNames = getPointCloudProviderNames();
185  ARMARX_CHECK_EQUAL(providerNames.size(), 1);
186 
187  this->providerSourceFrameName = getPointCloudFrame(providerNames.front());
188  if (getProperty<bool>("sourceFrameNameAuto") && !providerSourceFrameName.empty())
189  {
190  ARMARX_INFO << "Using source frame '" << providerSourceFrameName << "' from provider '" << providerNames.front() << "'.";
191  this->parameters.sourceFrameName = providerSourceFrameName;
192  }
193  }
194 
195  if (pointCloudFormat == "XYZRGBA")
196  {
197  enableResultPointClouds<pcl::PointXYZRGBA>(getName() + "Result");
198  enableResultPointClouds<pcl::PointXYZRGBA>(getName() + "Outside");
199  }
200  else if (pointCloudFormat == "XYZL")
201  {
202  enableResultPointClouds<pcl::PointXYZL>(getName() + "Result");
203  enableResultPointClouds<pcl::PointXYZL>(getName() + "Outside");
204  }
205  else if (pointCloudFormat == "XYZRGBL")
206  {
207  enableResultPointClouds<pcl::PointXYZRGBL>(getName() + "Result");
208  enableResultPointClouds<pcl::PointXYZRGBL>(getName() + "Outside");
209  }
210  else
211  {
212  ARMARX_ERROR << "Could not initialize point cloud, because format '" << pointCloudFormat << "' is unknown."
213  << "\nKnown formats are: XYZL, XYZRGBA, XYZGBL.";
214  }
215 
216  getProxyFromProperty(remoteGui, "RemoteGuiName", false, "", false);
217  if (remoteGui)
218  {
219  remoteGuiCreate();
220  remoteGuiTask = new armarx::SimpleRunningTask<>(
221  [this]()
222  {
223  this->remoteGuiRun();
224  }, "RemoteGuiTask");
225  remoteGuiTask->start();
226  }
227 
228  debugDrawer.getTopic(*this);
229  // Clear the layer (disregarding whether debug drawer is enabled).
230  debugDrawer.getTopic()->clearLayer(debugDrawer.getLayer());
231  }
232 
234  {
235 
236  }
237 
239  {
240  if (pointCloudFormat == "XYZRGBA")
241  {
242  processPointCloud<pcl::PointXYZRGBA>();
243  }
244  else if (pointCloudFormat == "XYZL")
245  {
246  processPointCloud<pcl::PointXYZL>();
247  }
248  else if (pointCloudFormat == "XYZRGBL")
249  {
250  processPointCloud<pcl::PointXYZRGBL>();
251  }
252  else
253  {
254  ARMARX_ERROR << "Could not process point cloud, because format '" << pointCloudFormat << "' is unknown."
255  << "\nKnown formats are: XYZL, XYZRGBA, XYZRGBL.";
256  }
257  }
258 
260  {
261  if (remoteGuiTask)
262  {
263  remoteGuiTask->stop();
264  remoteGuiTask = nullptr;
265  }
266  if (remoteGui)
267  {
268  remoteGui->removeTab(getName());
269  }
270  }
271 
272 
273  static std::string toUpper(const std::string& string)
274  {
275  std::string upper;
276  std::transform(string.begin(), string.end(), std::back_inserter(upper), ::toupper);
277  return upper;
278  }
279 
280  template <typename PointT>
282  {
283  using PointCloudPtr = typename pcl::PointCloud<PointT>::Ptr;
284 
285  // Get current parameters.
286  Parameters params;
287  {
288  std::unique_lock lock(parametersMutex);
289  params = this->parameters;
290  }
291 
292  // Only input cloud manages frame.
293  FramedPointCloud<PointT> inputCloud(params.sourceFrameName);
294  PointCloudPtr tempCloud(new pcl::PointCloud<PointT>());
295  FramedPointCloud<PointT> outsideCloud(params.sourceFrameName);
296 
297  if (waitForPointClouds(10000))
298  {
299  getPointClouds(inputCloud.cloud);
300  }
301  else
302  {
303  ARMARX_VERBOSE << "Timeout or error while waiting for point cloud data.";
304  return;
305  }
306 
307  const uint32_t originalWidth = inputCloud.cloud->width;
308  const uint32_t originalHeight = inputCloud.cloud->height;
309 
310  // Synchronize robot.
311  if (robotStateComponent)
312  {
313  // visionx::MetaPointCloudFormatPtr format = getPointCloudFormat(providerName);
314  // Use timestamp from point cloud instead of format->timeProvided
315 
316  long timestampMicroseconds = static_cast<long>(inputCloud.cloud->header.stamp);
317  // RemoteRobot::synchronizeLocalCloneToTimestamp(localRobot, robotStateComponent, timestampMicroseconds);
318  (void) timestampMicroseconds;
319  RemoteRobot::synchronizeLocalClone(localRobot, robotStateComponent);
320  }
321 
322  if (params.statisticalOutlierRemoval.enabled)
323  {
324  // Perform downsampling.
325  ARMARX_DEBUG << "statisticalOutlierRemoval ...";
326  pcl::StatisticalOutlierRemoval<PointT> sor;
327  sor.setMeanK(params.statisticalOutlierRemoval.meanK);
328  sor.setStddevMulThresh(params.statisticalOutlierRemoval.stddevMulThresh);
329 
330  sor.setInputCloud(inputCloud.cloud);
331  tempCloud->clear();
332  sor.filter(*tempCloud);
333  tempCloud.swap(inputCloud.cloud);
334  }
335 
336  if (params.downsamplingEnabled)
337  {
338  // Perform downsampling.
339  ARMARX_DEBUG << "Downsample ...";
340  pcl::ApproximateVoxelGrid<PointT> grid;
341  grid.setLeafSize(params.gridLeafSize, params.gridLeafSize, params.gridLeafSize);
342  grid.setInputCloud(inputCloud.cloud);
343 
344  tempCloud->clear();
345  grid.filter(*tempCloud);
346 
347  tempCloud.swap(inputCloud.cloud);
348  }
349 
350  drawFrame(inputCloud.getFramedPose(localRobot), "source");
351 
352  ARMARX_DEBUG << "transformBy\n" << params.providerFrameTransformation;
353  inputCloud.transformBy(params.providerFrameTransformation);
354 
355 
356  if (params.croppingEnabled)
357  {
358  try
359  {
360  // Transform to cropping frame.
361  changePointCloudFrame(inputCloud, "cropping", params.croppingFrameName);
362  }
363  catch (const armarx::LocalException& e)
364  {
365  ARMARX_ERROR << deactivateSpam(5) << "Caught armarx::LocalException (stopping processing).\n" << e.what();
366  return;
367  }
368 
369 
370  // Perform cropping.
371  ARMARX_DEBUG << "Crop ...";
372 
373  tempCloud->clear();
374  outsideCloud.cloud->clear();
375  outsideCloud.setFrameWithoutTransformation(inputCloud.getFrame());
376  const Eigen::Matrix3f transform = VirtualRobot::MathTools::rpy2eigen3f(params.croppingRPY).inverse();
377  for (const auto& p : inputCloud.cloud->points)
378  {
379  const Eigen::Vector3f transfed = transform * Eigen::Vector3f{p.x, p.y, p.z};
380  if (
381  transfed(0) >= params.croppingMinPoint(0) && transfed(0) <= params.croppingMaxPoint(0) &&
382  transfed(1) >= params.croppingMinPoint(1) && transfed(1) <= params.croppingMaxPoint(1) &&
383  transfed(2) >= params.croppingMinPoint(2) && transfed(2) <= params.croppingMaxPoint(2))
384  {
385  tempCloud->push_back(p);
386  }
387  else if (params.reportCloudOutsideOfCroppingArea)
388  {
389  outsideCloud.cloud->push_back(p);
390  }
391  }
392  tempCloud.swap(inputCloud.cloud);
393  }
394 
395  if (debugDrawer.enabled())
396  {
397  // Draw crop box.
398  Eigen::Matrix32f aabb;
399  aabb.col(0) = params.croppingMinPoint;
400  aabb.col(1) = params.croppingMaxPoint;
401  debugDrawer.drawBoxEdges(
402  "cropBox", aabb,
403  inputCloud.getGlobalPose(localRobot) * VirtualRobot::MathTools::rpy2eigen4f(params.croppingRPY));
404  }
405  else
406  {
407  debugDrawer.removeboxEdges("cropBox");
408  }
409 
410  const bool collisionModelFilterEnabled = params.applyCollisionModelFilter && robotStateComponent;
411  if (collisionModelFilterEnabled)
412  {
413  // This requires inputCloud to be in global frame.
414  changePointCloudFrame(inputCloud, "collision model filter", armarx::GlobalFrame);
415  if (params.reportCloudOutsideOfCroppingArea)
416  {
417  changePointCloudFrame(outsideCloud, "collision model filter", armarx::GlobalFrame);
418  }
419 
420  ARMARX_DEBUG << "Apply collision model filter ...";
421 
422  PointCloudPtr collisionCloudPtr(new pcl::PointCloud<PointT>());
423 
424  for (VirtualRobot::CollisionModelPtr collisionModel : localRobot->getCollisionModels())
425  {
426  std::vector<Eigen::Vector3f> vertices = collisionModel->getModelVeticesGlobal();
427 
428  pcl::PointCloud<PointT> hullCloud;
429  hullCloud.width = static_cast<uint32_t>(vertices.size());
430  hullCloud.height = 1;
431  hullCloud.points.resize(vertices.size());
432  for (size_t i = 0; i < vertices.size(); ++i)
433  {
434  hullCloud.points[i].getVector3fMap() = vertices[i].cast<float>();
435  }
436 
437  (*collisionCloudPtr) += hullCloud;
438  }
439 
440  pcl::ConvexHull<PointT> hull;
441  hull.setInputCloud(collisionCloudPtr);
442  hull.setDimension(3);
443 
444  std::vector<pcl::Vertices> polygons;
445  PointCloudPtr surfaceHull(new pcl::PointCloud<PointT>);
446  hull.reconstruct(*surfaceHull, polygons);
447 
448  pcl::CropHull<PointT> cropHull;
449  cropHull.setDim(3);
450  cropHull.setHullIndices(polygons);
451  cropHull.setHullCloud(surfaceHull);
452  cropHull.setCropOutside(false); // Remove points inside hull.
453  cropHull.setInputCloud(inputCloud.cloud);
454 
455  tempCloud->clear();
456  cropHull.filter(*tempCloud);
457 
458  tempCloud.swap(inputCloud.cloud);
459 
460  if (params.reportCloudOutsideOfCroppingArea)
461  {
462  cropHull.setInputCloud(outsideCloud.cloud);
463  tempCloud->clear();
464  cropHull.filter(*tempCloud);
465  tempCloud.swap(outsideCloud.cloud);
466  }
467 
468  }
469 
470  // Transform to target.
471  try
472  {
473  // Transform to target frame.
474  changePointCloudFrame(inputCloud, "target", params.targetFrameName);
475  if (params.reportCloudOutsideOfCroppingArea)
476  {
477  changePointCloudFrame(outsideCloud, "collision model filter", params.targetFrameName);
478  }
479  }
480  catch (const armarx::LocalException& e)
481  {
482  ARMARX_ERROR << deactivateSpam(5) << "Caught armarx::LocalException (stopping processing).\n" << e.what();
483  return;
484  }
485 
486  // Provide result.
487  PointCloudPtr resultCloud = inputCloud.cloud;
488 
490  << "Input cloud " << originalWidth << " x " << originalHeight
491  << " --> Filtered cloud " << resultCloud->width << " x " << resultCloud->height;
492 
493  provideResultPointClouds(getName() + "Result", resultCloud);
494  provideResultPointClouds(getName() + "Outside", outsideCloud.cloud);
495  }
496 
497 
498  void PointCloudFilter::drawFrame(const FramedPose& frame, const std::string& role)
499  {
500  if (debugDrawer.enabled())
501  {
502  debugDrawer.drawPose(toUpper(role) + " (" + frame.getFrame() + ")", frame.toEigen());
503  }
504  }
505 
506 
507 
508  template<typename PointT>
509  void PointCloudFilter::changePointCloudFrame(FramedPointCloud<PointT>& pointCloud,
510  const std::string& role, const std::string& frame)
511  {
512  ARMARX_DEBUG << "Transform from " << pointCloud.getFrame()
513  << " to " << toUpper(role) << " (" << frame << ")";
514  pointCloud.changeFrame(frame, localRobot);
515  drawFrame(pointCloud.getFramedPose(localRobot), role);
516  }
517 
518 
520  {
522  }
523 
524 
525  void PointCloudFilter::remoteGuiCreate()
526  {
527  using namespace armarx::RemoteGui;
528 
529  const auto& p = parameters;
530 
531  auto rootLayout = makeVBoxLayout();
532 
533  // Misc
534  {
535  rootLayout.addChild(
536  makeSimpleGridLayout().cols(2)
537  .addChild(makeTextLabel("Source Frame: "))
538  .addChild(makeHBoxLayout()
539  .addChild(makeCheckBox("SourceFrameAutoEnabled")
540  .label("Auto").value(getProperty<bool>("sourceFrameNameAuto")))
541  .addChild(makeComboBox("SourceFrame")
542  .addOptions({armarx::GlobalFrame, "root"})
543  .addOptions(localRobot->getRobotNodeNames())
544  .value(p.sourceFrameName)))
545 
546  .addChild(makeTextLabel("Target Frame: "))
547  .addChild(makeComboBox("TargetFrame")
548  .options({armarx::GlobalFrame, "root"})
549  .addOptions(localRobot->getRobotNodeNames())
550  .value(p.targetFrameName))
551 
552  .addChild(makeTextLabel("StatisticalOutlierRemoval: "))
553  .addChild(makeHBoxLayout()
554  .addChild(makeCheckBox("StatisticalOutlierRemoval_enabled")
555  .label("Enabled").value(p.statisticalOutlierRemoval.enabled))
556  .addChild(makeTextLabel("MeanK"))
557  .addChild(makeIntSpinBox("StatisticalOutlierRemoval_MeanK")
558  .min(1).max(1000).value(p.statisticalOutlierRemoval.meanK))
559  .addChild(makeTextLabel("StddevMulThresh"))
560  .addChild(makeFloatSpinBox("StatisticalOutlierRemoval_StddevMulThresh")
561  .min(0.001f).max(100.f).decimals(3).value(p.statisticalOutlierRemoval.stddevMulThresh)))
562 
563  .addChild(makeTextLabel("Downsampling: "))
564  .addChild(makeHBoxLayout()
565  .addChild(makeCheckBox("DownsamplingEnabled")
566  .label("Enabled").value(p.downsamplingEnabled))
567  .addChild(makeTextLabel("Grid Leaf Size: "))
568  .addChild(makeFloatSpinBox("DownsamplingGridLeafSize")
569  .min(0.1f).max(1000.f).decimals(1).value(p.gridLeafSize)))
570 
571  .addChild(makeTextLabel("Collision Model Filter: "))
572  .addChild(makeCheckBox("CollisionModelFilterEnabled")
573  .label("Enabled").value(p.applyCollisionModelFilter))
574  );
575  }
576 
577  //transform
578  {
579  const Eigen::Vector3f pos = simox::math::mat4f_to_pos(p.providerFrameTransformation);
580  const Eigen::Vector3f rpy = simox::math::mat4f_to_rpy(p.providerFrameTransformation);
581 
582  rootLayout.addChild(
583  makeGroupBox("Transform").addChild(
584  makeSimpleGridLayout().cols(2)
585  .addTextLabel("XYC")
586  .addChild(makeVector3fSpinBoxes("transform.XYC").value(pos).min(-10000).max(10000).decimals(3))
587  .addTextLabel("RPY")
588  .addChild(makeVector3fSpinBoxes("transform.RPY").value(rpy).min(-2 * M_PI).max(2 * M_PI).decimals(3))
589  ));
590  }
591 
592  // Cropping
593  {
594  auto cropGroupLayout = makeVBoxLayout();
595 
596  WidgetPtr frameLabel = makeTextLabel("Frame: ");
597  WidgetPtr minLabel = makeTextLabel("Minimum: ");
598  WidgetPtr maxLabel = makeTextLabel("Maximum: ");
599  WidgetPtr rpyLabel = makeTextLabel("Roll / Pitch / Yaw: ");
600 
601  WidgetPtr enabledCheckBox = makeCheckBox("CropEnabled").value(p.croppingEnabled).label("Enabled");
602  WidgetPtr reportAllBox = makeCheckBox("reportCloudOutsideOfCroppingArea").value(p.reportCloudOutsideOfCroppingArea).label("Report points outside");
603 
604  WidgetPtr frameLine = makeComboBox("CropFrame")
605  .options({armarx::GlobalFrame, "root"})
606  .addOptions(localRobot->getRobotNodeNames())
607  .value(p.croppingFrameName);
608  WidgetPtr minVector3Spin = makeVector3fSpinBoxes("CropMin").value(p.croppingMinPoint)
609  .min(-100000).max(100000);
610  WidgetPtr maxVector3Spin = makeVector3fSpinBoxes("CropMax").value(p.croppingMaxPoint)
611  .min(-100000).max(100000);
612  WidgetPtr rpyVector3Spin = makeVector3fSpinBoxes("CropRPY").value(p.croppingRPY)
613  .min(-M_PI).max(M_PI).decimals(3);
614 
615  cropGroupLayout.addChild(makeSimpleGridLayout().cols(2)
616  .children(
617  {
618  enabledCheckBox, reportAllBox,
619  frameLabel, frameLine,
620  minLabel, minVector3Spin,
621  maxLabel, maxVector3Spin,
622  rpyLabel, rpyVector3Spin
623  }));
624 
625  rootLayout.addChild(makeGroupBox("CropGroup")
626  .label("Cropping").child(cropGroupLayout));
627  }
628 
629  // Visualization
630  {
631  auto visuGroupLayout = makeVBoxLayout();
632 
633  WidgetPtr enabledCheckBox = makeCheckBox("VisuEnabled")
634  .label("Enabled").value(debugDrawer.enabled());
635 
636  visuGroupLayout.addChild(makeSimpleGridLayout().cols(2)
637  .addChild(enabledCheckBox));
638 
639  rootLayout.addChild(makeGroupBox("VisuGroup")
640  .label("Visualization").child(visuGroupLayout));
641  }
642 
643 
644  const std::string tabName = getName();
645  remoteGui->createTab(tabName, rootLayout);
646  remoteGuiTab = armarx::RemoteGui::TabProxy(remoteGui, tabName);
647  }
648 
649 
650  void PointCloudFilter::remoteGuiRun()
651  {
652  int cycleDurationMs = 50;
653  CycleUtil c(cycleDurationMs);
654  while (!remoteGuiTask->isStopped())
655  {
656  remoteGuiTab.receiveUpdates();
657 
658  remoteGuiUpdate(remoteGuiTab);
659 
660  remoteGuiTab.sendUpdates();
661  c.waitForCycleDuration();
662  }
663  }
664 
665 
666  void PointCloudFilter::remoteGuiUpdate(RemoteGui::TabProxy& tab)
667  {
668  using namespace armarx::RemoteGui;
669 
670  {
671  std::unique_lock lock(parametersMutex);
672 
673  // Frames
674  ValueProxy<std::string> sourceFrame = tab.getValue<std::string>("SourceFrame");
675 
676  if (tab.getValue<bool>("SourceFrameAutoEnabled").get())
677  {
678  parameters.sourceFrameName = this->providerSourceFrameName;
679  sourceFrame.set(parameters.sourceFrameName);
680  // sourceFrame.setDisabled(true); // Seems not to do the right thing.
681  }
682  else
683  {
684  parameters.sourceFrameName = sourceFrame.get();
685  // sourceFrame.setDisabled(false); // Seems not to do the right thing.
686  }
687 
688  tab.getValue(parameters.targetFrameName, "TargetFrame");
689 
690  // Misc
691  tab.getValue(parameters.downsamplingEnabled, "DownsamplingEnabled");
692  tab.getValue(parameters.gridLeafSize, "DownsamplingGridLeafSize");
693  tab.getValue(parameters.applyCollisionModelFilter, "CollisionModelFilterEnabled");
694  tab.getValue(parameters.reportCloudOutsideOfCroppingArea, "reportCloudOutsideOfCroppingArea");
695  tab.getValue(parameters.statisticalOutlierRemoval.enabled, "StatisticalOutlierRemoval_enabled");
696  tab.getValue(parameters.statisticalOutlierRemoval.meanK, "StatisticalOutlierRemoval_MeanK");
697  tab.getValue(parameters.statisticalOutlierRemoval.stddevMulThresh, "StatisticalOutlierRemoval_StddevMulThresh");
698 
699  // Cropping
700  tab.getValue(parameters.croppingEnabled, "CropEnabled");
701  tab.getValue(parameters.croppingFrameName, "CropFrame");
702  tab.getValue(parameters.croppingMinPoint, "CropMin");
703  tab.getValue(parameters.croppingMaxPoint, "CropMax");
704  tab.getValue(parameters.croppingRPY, "CropRPY");
705 
706  parameters.providerFrameTransformation = simox::math::pos_rpy_to_mat4f(
707  tab.getValue<Eigen::Vector3f>("transform.XYC").get(),
708  tab.getValue<Eigen::Vector3f>("transform.RPY").get()
709  );
710 
711  }
712 
713  // Visu
714  bool visuEnabled = tab.getValue<bool>("VisuEnabled").get();
715  if (!visuEnabled)
716  {
717  // This will clear the layer if the visualization was enabled before.
718  debugDrawer.clearLayer(false);
719  }
720  // This has to come *after* clearing.
721  debugDrawer.setEnabled(visuEnabled);
722 
723  }
724 
725 
726 }
armarx::SimpleRunningTask
Usage:
Definition: TaskUtil.h:70
RemoteRobot.h
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:180
visionx::FramedPointCloud::getFramedPose
armarx::FramedPose getFramedPose(const std::string &agentName) const
Get the current pose as FramedPose.
Definition: FramedPointCloud.h:76
armarx::DebugDrawerTopic::offeringTopic
void offeringTopic(ManagedIceObject &component, const std::string &topicNameOverride="") const
Call offeringTopic([topicName]) on the given component.
Definition: DebugDrawerTopic.cpp:73
visionx::PointCloudFilter::onInitPointCloudProcessor
virtual void onInitPointCloudProcessor() override
Definition: PointCloudFilter.cpp:122
armarx::WidgetDescription::makeGroupBox
GroupBoxPtr makeGroupBox(std::string label, WidgetPtr child, bool framed)
Definition: DefaultWidgetDescriptions.cpp:105
armarx::RemoteGui::makeVector3fSpinBoxes
detail::Vector3fSpinBoxesBuilder makeVector3fSpinBoxes(std::string const &name, float limpos=1000)
Definition: Vector3fWidgets.h:113
visionx
ArmarX headers.
Definition: OpenPoseStressTest.h:38
armarx::DebugDrawerTopic::enabled
bool enabled() const
Indicate whether visualization is enabled, i.e. a topic is set and enabled flag is set.
Definition: DebugDrawerTopic.cpp:68
armarx::FramedPose
The FramedPose class.
Definition: FramedPose.h:258
armarx::RemoteGui
Definition: LightweightRemoteGuiComponentPlugin.h:30
visionx::PointCloudFilter::setCroppingParameters
virtual void setCroppingParameters(const armarx::Vector3BasePtr &min, const armarx::Vector3BasePtr &max, const std::string &frame, const Ice::Current &=Ice::emptyCurrent) override
Definition: PointCloudFilter.cpp:111
armarx::DebugDrawerTopic::removeboxEdges
void removeboxEdges(const VisuID &id)
Remove box edges (as a line set).
Definition: DebugDrawerTopic.cpp:335
WidgetBuilder.h
armarx::RemoteGui::detail::Vector3fSpinBoxesBuilder::decimals
Vector3fSpinBoxesBuilder & decimals(const Eigen::Vector3i decimals)
Definition: Vector3fWidgets.h:91
armarx::GlobalFrame
const std::string GlobalFrame
Definition: FramedPose.h:62
armarx::WidgetDescription::makeHBoxLayout
HBoxLayoutPtr makeHBoxLayout(std::vector< WidgetPtr > elements)
Definition: DefaultWidgetDescriptions.cpp:30
FramedPointCloud.h
visionx::FramedPointCloud::getGlobalPose
Eigen::Matrix4f getGlobalPose(const VirtualRobot::RobotPtr &robot) const
Get the current global pose.
Definition: FramedPointCloud.h:86
armarx::CycleUtil
This util class helps with keeping a cycle time during a control cycle.
Definition: CycleUtil.h:40
armarx::Component::usingProxyFromProperty
bool usingProxyFromProperty(const std::string &propertyName, const std::string &endpoints="")
Use a proxy whose name is specified by the given property.
Definition: Component.cpp:167
armarx::RemoteGui::detail::SimpleGridLayoutBuilder::addChild
SimpleGridLayoutBuilder & addChild(WidgetPtr const &child, int colspan)
Definition: LayoutWidgets.h:121
Storage.h
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
visionx::FramedPointCloud::setFrameWithoutTransformation
void setFrameWithoutTransformation(const std::string &f)
Definition: FramedPointCloud.h:70
visionx::PointCloudFilter::processPointCloud
void processPointCloud()
Definition: PointCloudFilter.cpp:281
armarx::RemoteGui::makeTextLabel
detail::LabelBuilder makeTextLabel(std::string const &text)
Definition: StaticWidgets.h:22
visionx::PointCloudFilter::getReferenceFrame
virtual std::string getReferenceFrame(const Ice::Current &=Ice::emptyCurrent) override
Definition: PointCloudFilter.cpp:105
PointCloudFilter.h
armarx::RemoteGui::detail::Vector3fMinMaxMixin::min
Derived & min(float v)
Definition: Vector3fWidgets.h:22
armarx::RemoteGui::ValueProxy::get
T get() const
Definition: WidgetProxy.h:288
armarx::aron::type::PointCloudPtr
std::shared_ptr< class PointCloud > PointCloudPtr
Definition: forward_declarations.h:23
visionx::PointCloudProcessor::getPointCloudFrame
std::string getPointCloudFrame(const std::string &providerName, const std::string &defaultFrame="")
Get the reference frame of the point cloud by given provider.
Definition: PointCloudProcessor.cpp:559
armarx::RemoteGui::makeSimpleGridLayout
detail::SimpleGridLayoutBuilder makeSimpleGridLayout(std::string const &name="")
Definition: LayoutWidgets.h:235
visionx::FramedPointCloud::getFrame
std::string getFrame() const
Get the current frame.
Definition: FramedPointCloud.h:66
armarx::WidgetDescription::makeFloatSpinBox
FloatSpinBoxPtr makeFloatSpinBox(std::string name, float min, float max, float defaultValue, int steps, int decimals)
Definition: DefaultWidgetDescriptions.cpp:172
armarx::DebugDrawerTopic::getLayer
const std::string & getLayer() const
Get the default layer (used if no layer is passed to a method).
Definition: DebugDrawerTopic.cpp:83
armarx::RemoteGui::TabProxy
Definition: WidgetProxy.h:17
armarx::Component::getProxyFromProperty
ProxyType getProxyFromProperty(const std::string &propertyName, bool addToDependencies=false, const std::string &endpoints="", bool throwOnProxyError=true)
Get a proxy whose name is specified by the given property.
Definition: Component.h:236
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:926
armarx::RemoteGui::TabProxy::receiveUpdates
void receiveUpdates()
Definition: WidgetProxy.h:131
visionx::PointCloudProcessor::provideResultPointClouds
void provideResultPointClouds(const PointCloudPtrT &pointClouds, std::string providerName="")
sends result PointClouds for visualization
Definition: PointCloudProcessor.h:286
M_PI
#define M_PI
Definition: MathTools.h:17
FramedPose.h
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:177
visionx::PointCloudProcessor::waitForPointClouds
bool waitForPointClouds(int milliseconds=1000)
Wait for new PointClouds.
Definition: PointCloudProcessor.cpp:433
visionx::FramedPointCloud::cloud
PointCloudPtrT cloud
The point cloud.
Definition: FramedPointCloud.h:105
armarx::Pose::toEigen
virtual Eigen::Matrix4f toEigen() const
Definition: Pose.cpp:334
visionx::PointCloudFilter::process
virtual void process() override
Definition: PointCloudFilter.cpp:238
armarx::RemoteGui::detail::ValueMixin::value
Derived & value(ValueT const &value)
Definition: Basic.h:77
max
T max(T t1, T t2)
Definition: gdiam.h:48
visionx::PointCloudFilter::createPropertyDefinitions
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
Definition: PointCloudFilter.cpp:519
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:189
visionx::PointCloudProcessorPropertyDefinitions
Properties of PointCloudProcessor.
Definition: PointCloudProcessor.h:173
visionx::PointCloudProcessor::getPointClouds
int getPointClouds(const PointCloudPtrT &pointCloudPtr)
Poll PointClouds from provider.
Definition: PointCloudProcessor.h:373
armarx::WidgetDescription::makeIntSpinBox
IntSpinBoxPtr makeIntSpinBox(std::string name, int min, int max, int defaultValue)
Definition: DefaultWidgetDescriptions.cpp:162
armarx::RemoteGui::detail::ComboBoxBuilder::options
ComboBoxBuilder & options(std::vector< std::string > const &options)
Definition: StringWidgets.h:20
visionx::PointCloudFilter::onExitPointCloudProcessor
virtual void onExitPointCloudProcessor() override
Definition: PointCloudFilter.cpp:233
visionx::FramedPointCloud
A point cloud which keeps track of its reference coordinate frame and allows changing frames using ar...
Definition: PointCloudFilter.h:59
armarx::WidgetDescription::WidgetPtr
::IceInternal::Handle<::armarx::WidgetDescription::Widget > WidgetPtr
Definition: NJointControllerBase.h:66
armarx::RemoteGui::TabProxy::getValue
ValueProxy< T > getValue(std::string const &name)
Definition: WidgetProxy.h:161
CycleUtil.h
armarx::RemoteGui::ValueProxy::set
void set(std::atomic< T1 > const &value)
Definition: WidgetProxy.h:323
visionx::PointCloudFilter::onConnectPointCloudProcessor
virtual void onConnectPointCloudProcessor() override
Definition: PointCloudFilter.cpp:173
armarx::Component::getConfigIdentifier
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition: Component.cpp:74
armarx::DebugDrawerTopic::drawPose
void drawPose(const VisuID &id, const Eigen::Matrix4f &pose, bool ignoreLengthScale=false)
Draw a pose (with the preset scale).
Definition: DebugDrawerTopic.cpp:586
visionx::PointCloudFilter::onDisconnectPointCloudProcessor
virtual void onDisconnectPointCloudProcessor() override
Definition: PointCloudFilter.cpp:259
GfxTL::Matrix3f
MatrixXX< 3, 3, float > Matrix3f
Definition: MatrixXX.h:600
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
armarx::PropertyUser::getProperty
Property< PropertyType > getProperty(const std::string &name)
Property creation and retrieval.
Definition: PropertyUser.h:179
armarx::DebugDrawerTopic::setLayer
void setLayer(const std::string &layer)
Set the default layer (used if no layer is passed to a method).
Definition: DebugDrawerTopic.cpp:88
armarx::DebugDrawerTopic::drawBoxEdges
void drawBoxEdges(const VisuID &id, const Eigen::Vector3f &position, const Eigen::Quaternionf &orientation, const Eigen::Vector3f &extents, float width=DEFAULTS.boxEdgesWidth, const DrawColor &color=DEFAULTS.boxEdgesColor, bool ignoreLengthScale=false)
Draw box edges (as a line set).
Definition: DebugDrawerTopic.cpp:225
IceUtil::Handle< class PropertyDefinitionContainer >
armarx::transform
auto transform(const Container< InputT, Alloc > &in, OutputT(*func)(InputT const &)) -> Container< OutputT, typename std::allocator_traits< Alloc >::template rebind_alloc< OutputT > >
Convenience function (with less typing) to transform a container of type InputT into the same contain...
Definition: algorithm.h:315
visionx::FramedPointCloud::transformBy
void transformBy(const Eigen::Matrix4f &transform)
Definition: FramedPointCloud.h:98
armarx::WidgetDescription::makeCheckBox
CheckBoxPtr makeCheckBox(std::string name, bool defaultValue, std::string label)
Definition: DefaultWidgetDescriptions.cpp:145
visionx::PointCloudFilter::getDefaultName
virtual std::string getDefaultName() const override
Definition: PointCloudFilter.cpp:100
armarx::RemoteGui::TabProxy::sendUpdates
void sendUpdates()
Definition: WidgetProxy.h:146
armarx::RemoteGui::makeComboBox
detail::ComboBoxBuilder makeComboBox(std::string const &name)
Definition: StringWidgets.h:58
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
Eigen::Matrix
Definition: EigenForwardDeclarations.h:27
armarx::ManagedIceObject::getName
std::string getName() const
Retrieve name of object.
Definition: ManagedIceObject.cpp:107
armarx::RemoteGui::detail::Vector3fMinMaxMixin::max
Derived & max(float v)
Definition: Vector3fWidgets.h:31
armarx::FramedPose::getFrame
std::string getFrame() const
Definition: FramedPose.cpp:393
min
T min(T t1, T t2)
Definition: gdiam.h:42
ARMARX_CHECK_EQUAL
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
Definition: ExpressionException.h:130
armarx::DebugDrawerTopic::getTopic
DebugDrawerInterfacePrx getTopic() const
Get the topic.
Definition: DebugDrawerTopic.cpp:58
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
armarx::PropertyDefinitionsPtr
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
Definition: forward_declarations.h:34
armarx::RemoteGui::ValueProxy
Definition: WidgetProxy.h:13
armarx::DebugDrawerTopic::setEnabled
void setEnabled(bool enabled)
Set whether drawing is enabled.
Definition: DebugDrawerTopic.cpp:63
visionx::PointCloudFilterPropertyDefinitions
Definition: PointCloudFilter.h:63
armarx::WidgetDescription::makeVBoxLayout
VBoxLayoutPtr makeVBoxLayout(std::vector< WidgetPtr > elements)
Definition: DefaultWidgetDescriptions.cpp:37
armarx::ManagedIceObject::getProxy
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
Definition: ManagedIceObject.cpp:393
visionx::PointCloudProcessor::getPointCloudProviderNames
std::vector< std::string > getPointCloudProviderNames() const
Get the names of providers for which usingPointCloudProvider() has been called.
Definition: PointCloudProcessor.cpp:381
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28