VoxelGridMappingProvider.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * @package RobotComponents::ArmarXObjects::VoxelGridMappingProvider
17 * @author Mirko Waechter ( mirko dot waechter at kit dot edu )
18 * @date 2018
19 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
22
24
26
27#include <pcl/common/transforms.h>
28#include <pcl/filters/approximate_voxel_grid.h>
29#include <pcl/filters/frustum_culling.h>
30#include <pcl/filters/passthrough.h>
31#include <pcl/filters/uniform_sampling.h>
32#include <pcl/filters/voxel_grid.h>
33#include <pcl/io/pcd_io.h>
34#include <pcl/point_types.h>
35
39
42
43//#include <RobotComponents/components/MotionPlanning/CSpace/SimoxCSpace.h>
44#include <VirtualRobot/CollisionDetection/CDManager.h>
45#include <VirtualRobot/CollisionDetection/CollisionChecker.h>
46#include <VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.h>
47#include <VirtualRobot/Visualization/TriMeshUtils.h>
48
50#include <VisionX/interface/components/Calibration.h>
51
52#include <MotionPlanning/CSpace/CSpaceSampled.h>
53#include <MotionPlanning/Planner/BiRrt.h>
54#include <MotionPlanning/PostProcessing/ShortcutProcessor.h>
55
56
57using namespace armarx;
58
59namespace visionx
60{
64
65 std::string
67 {
68 return "VoxelGridMappingProvider";
69 }
70
71 std::string
76
83
84 void
86 {
87 skipper.reset(
88 new IceReportSkipper(getProperty<float>("PointCloudStorageFrequency").getValue()));
89 cycleKeeper.reset(new CycleUtil(1000.0f / getProperty<float>("UpdateRate").getValue()));
90 providerName = getProperty<std::string>("providerName").getValue();
91 sourceFrameName = getProperty<std::string>("sourceFrameName").getValue();
93 gridLeafSize = getProperty<float>("GridSize");
94
96 accumulatedPointCloud.reset(new pcl::PointCloud<PointType>());
97 if (!getProperty<std::string>("PointCloudLoadFilepath").getValue().empty())
98 {
99 ARMARX_INFO << "Loading pointcloud from "
100 << getProperty<std::string>("PointCloudLoadFilepath").getValue();
101 pcl::io::loadPCDFile(getProperty<std::string>("PointCloudLoadFilepath"),
103 }
104 }
105
106 void
108 {
109 if (getProperty<std::string>("RobotStateComponentName").getValue() != "")
110 {
112 getProperty<std::string>("RobotStateComponentName").getValue());
114 robotStateComponent, VirtualRobot::RobotIO::RobotDescription::eCollisionModel);
115 robotPool.reset(new RobotPool(localRobot, 3));
116 }
117 dd = getTopic<DebugDrawerInterfacePrx>("DebugDrawerUpdates");
118 collectingPointClouds = getProperty<bool>("ActivateOnStartUp");
119 octtree.reset(new pcl::octree::OctreePointCloud<PointType>(gridLeafSize));
120
121 if (sourceFrameName.empty())
122 {
123
124 visionx::ReferenceFrameInterfacePrx proxy =
126 if (proxy)
127 {
128 sourceFrameName = proxy->getReferenceFrame();
129 ARMARX_INFO << "source frame name is " << sourceFrameName;
130 }
131 }
132
134 }
135
136 void
140
141 void
143 {
144 auto limits = Split(getProperty<std::string>("BoundingBox").getValue(), ";", true);
145 int i = 0;
146 ARMARX_CHECK_EQUAL(limits.size(), 3);
147 for (auto& pos : limits)
148 {
149 auto posVec = Split<float>(pos, ",", true);
150 ARMARX_CHECK_EQUAL(posVec.size(), 2);
151 croppingMin(i) = posVec.at(0);
152 croppingMax(i) = posVec.at(1);
153 i++;
154 }
155 }
156
157 void
159 {
160
161 typename pcl::PointCloud<PointType>::Ptr inputCloudPtr(new pcl::PointCloud<PointType>());
162 typename pcl::PointCloud<PointType>::Ptr downsampledTransformedInputCloudPtr(
163 new pcl::PointCloud<PointType>());
164 typename pcl::PointCloud<PointType>::Ptr outputCloudPtr(new pcl::PointCloud<PointType>());
165
167 {
168 ARMARX_DEBUG << deactivateSpam(10) << "Pointcloud processing is disabled";
169 usleep(10000);
170 return;
171 }
172 if (!waitForPointClouds(providerName, 10000))
173 {
174 ARMARX_INFO << "Timeout or error while waiting for point cloud data" << flush;
175 return;
176 }
177 else
178 {
179 getPointClouds(providerName, inputCloudPtr);
180 }
181 TIMING_START(FullCalc);
182
183 ARMARX_INFO << "Got cloud of size: " << inputCloudPtr->size();
184 auto localRobot = robotPool->getRobot();
185 visionx::MetaPointCloudFormatPtr format = getPointCloudFormat(providerName);
186 ARMARX_INFO << deactivateSpam(1) << "pc timestamp: "
187 << IceUtil::Time::microSeconds(format->timeProvided).toDateTime();
189 {
191 localRobot, robotStateComponent, format->timeProvided))
192 {
194 << "failed to sync robot to timestamp! conversion to globalpose "
195 "will fail! aborting";
196 return;
197 }
198 }
199
200 Eigen::Matrix4f transform = Eigen::Matrix4f::Identity();
201 // Eigen::Matrix4f sourceFrameGlobalPose = Eigen::Matrix4f::Identity();
202 if (robotStateComponent && sourceFrameName != "Global")
203 {
204 transform = localRobot->getRobotNode(sourceFrameName)->getGlobalPose();
205 }
206
207 Eigen::Matrix4f cam2robot;
208 cam2robot << 0, 0, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1;
209 // .. read or fill the source cloud
210 pcl::FrustumCulling<PointType> fc;
211 fc.setInputCloud(inputCloudPtr);
212 fc.setNegative(false);
213 fc.setVerticalFOV(35);
214 fc.setHorizontalFOV(45);
215 fc.setNearPlaneDistance(0.0);
216 fc.setFarPlaneDistance(3500);
217
218 fc.setCameraPose(cam2robot);
219
220 fc.filter(*outputCloudPtr);
221 ARMARX_INFO << "size before frustrum culling: " << inputCloudPtr->size()
222 << " size after: " << outputCloudPtr->size();
223 inputCloudPtr.swap(outputCloudPtr);
224
225 ARMARX_INFO << "Robot camera transform is: " << transform;
226 // float N = 0.001f;
227 // transform (0,0) = transform (0,0) * N;
228 // transform (1,1) = transform (1,1) * N;
229 // transform (2,2) = transform (2,2) * N;
230 TIMING_START(PCl_TRANSFORM);
231 // Transform to intermediate cropping frame
232 pcl::transformPointCloud(*inputCloudPtr, *outputCloudPtr, transform);
233 outputCloudPtr.swap(inputCloudPtr);
234 TIMING_END(PCl_TRANSFORM);
235
236 TIMING_START(PCL_FILTER);
237 // // assumes that z axis goes up in robot's root frame
238 pcl::PassThrough<PointType> pass;
239
240
241 pass.setInputCloud(inputCloudPtr);
242 pass.setFilterFieldName("z");
243 pass.setFilterLimits(croppingMin(2), croppingMax(2));
244 pass.filter(*outputCloudPtr);
245 outputCloudPtr.swap(inputCloudPtr);
246
247 pass.setInputCloud(inputCloudPtr);
248 pass.setFilterFieldName("x");
249 pass.setFilterLimits(croppingMin(0), croppingMax(0));
250 pass.filter(*outputCloudPtr);
251 outputCloudPtr.swap(inputCloudPtr);
252
253 pass.setInputCloud(inputCloudPtr);
254 pass.setFilterFieldName("y");
255 pass.setFilterLimits(croppingMin(1), croppingMax(1));
256 pass.filter(*outputCloudPtr);
257 outputCloudPtr.swap(inputCloudPtr);
258 TIMING_END(PCL_FILTER);
259
260
261 TIMING_START(PCl_DOWNSAMPLING);
262 gridLeafSize = getProperty<float>("GridSize");
263 pcl::VoxelGrid<PointType> grid;
264 grid.setMinimumPointsNumberPerVoxel(
265 getProperty<int>("MinimumPointNumberPerVoxel").getValue());
266 // grid.setDownsampleAllData(false);
267 grid.setLeafSize(gridLeafSize, gridLeafSize, gridLeafSize);
268 grid.setInputCloud(inputCloudPtr);
269 grid.filter(*outputCloudPtr);
270 ARMARX_VERBOSE << "Got cloud of size: " << inputCloudPtr->size()
271 << " after downsampling: " << outputCloudPtr->size();
272 outputCloudPtr.swap(inputCloudPtr);
273
274
275 if (!lastPointCloud)
276 {
277 lastPointCloud.reset(new Cloud());
278 }
279 // {
280 // *inputCloudPtr += *lastPointCloud;
281
282 // pcl::VoxelGrid<PointType> grid;
283 // grid.setMinimumPointsNumberPerVoxel(2);
284 // // grid.setDownsampleAllData(false);
285 // grid.setLeafSize(gridLeafSize, gridLeafSize, gridLeafSize);
286 // grid.setInputCloud(inputCloudPtr);
287 // grid.filter(*outputCloudPtr);
288 // ARMARX_VERBOSE << "Cloud size after removing of temporal points (e.g. flickering): " << outputCloudPtr->size();
289 // outputCloudPtr.swap(inputCloudPtr);
290 // lastPointCloud = downsampledTransformedInputCloudPtr;
291 // }
292
293
294 TIMING_END(PCl_DOWNSAMPLING);
295
296 // Eigen::Matrix4f transformScaleUp = Eigen::Matrix4f::Identity();
297 // float N2 = 1000.f;
298 // transformScaleUp (0,0) = transformScaleUp (0,0) * N2;
299 // transformScaleUp (1,1) = transformScaleUp (1,1) * N2;
300 // transformScaleUp (2,2) = transformScaleUp (2,2) * N2;
301
302 // pcl::transformPointCloud(*inputCloudPtr, *outputCloudPtr, transformScaleUp);
303 // outputCloudPtr.swap(inputCloudPtr);
304
305
306 typename pcl::PointCloud<PointType>::Ptr occludedPoints(new pcl::PointCloud<PointType>());
307 typename pcl::PointCloud<PointType>::Ptr oldPointsInView(new pcl::PointCloud<PointType>());
308 {
309 TIMING_START(PCL_FrustumCulling);
310 std::unique_lock lock(dataMutex);
311 Eigen::Matrix4f cam2robot;
312 cam2robot << 0, 0, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1;
313 // .. read or fill the source cloud
314 pcl::FrustumCulling<PointType> fc;
315 fc.setInputCloud(accumulatedPointCloud);
316 fc.setNegative(false);
317 fc.setVerticalFOV(40);
318 fc.setHorizontalFOV(50);
319 fc.setNearPlaneDistance(0.0);
320 fc.setFarPlaneDistance(2500);
321
322 fc.setCameraPose(transform * cam2robot);
323
324 fc.filter(*oldPointsInView);
325
326
327 fc.setNegative(true);
328 fc.filter(*outputCloudPtr);
329 outputCloudPtr.swap(accumulatedPointCloud);
330 TIMING_END(PCL_FrustumCulling);
331
332
333 TIMING_START(OCCLUSION);
334 Eigen::Vector3f cameraPos = transform.block<3, 1>(0, 3);
335 for (auto& p : *oldPointsInView)
336 {
337 Eigen::Vector3f currentPoint(
338 p._PointXYZRGBA::x, p._PointXYZRGBA::y, p._PointXYZRGBA::z);
339 VirtualRobot::MathTools::BaseLine<Eigen::Vector3f> line(transform.block<3, 1>(0, 3),
340 currentPoint - cameraPos);
341 float distP1 = (currentPoint - cameraPos).norm();
342 for (auto& p2pcl : *inputCloudPtr)
343 {
344 Eigen::Vector3f p2(
345 p2pcl._PointXYZRGBA::x, p2pcl._PointXYZRGBA::y, p2pcl._PointXYZRGBA::z);
346 float distP2 = (cameraPos - p2).norm();
347 if (distP1 > distP2)
348 {
349 auto distance = VirtualRobot::MathTools::distPointLine(line, p2);
352 {
353 auto newP = p;
354 // newP._PointXYZRGBA::r = 255;
355 // newP._PointXYZRGBA::g = 0;
356 // newP._PointXYZRGBA::b = 0;
357 occludedPoints->push_back(newP);
358 break;
359 }
360 }
361 }
362 }
363 TIMING_END(OCCLUSION);
364
365 TIMING_START(RemoveRobotVoxels);
366 inputCloudPtr = removeRobotVoxels(inputCloudPtr, localRobot, gridLeafSize);
367 ARMARX_VERBOSE << "Size after removal of robot voxels: " << inputCloudPtr->size();
368 TIMING_END(RemoveRobotVoxels);
369
370 TIMING_START(Accumulation);
371 // octtree->setInputCloud(inputCloudPtr);
372 // octtree->addPointsFromInputCloud();
373 // octtree->setInputCloud(occludedPoints);
374 // octtree->addPointsFromInputCloud();
375
376 *accumulatedPointCloud += *inputCloudPtr;
377 *accumulatedPointCloud += *occludedPoints;
378
379
380 *accumulatedPointCloud += *occludedPoints;
381 ARMARX_VERBOSE << "Accumulated pc size: " << accumulatedPointCloud->size()
382 << " new point count: " << inputCloudPtr->size()
383 << " number of occluded points: " << occludedPoints->size();
384 TIMING_END(Accumulation);
385 TIMING_START(Downsampling2);
386 // filter again to remove duplicated points
387
388 pcl::VoxelGrid<PointType> grid2;
389 grid2.setLeafSize(gridLeafSize, gridLeafSize, gridLeafSize);
390 grid2.setInputCloud(accumulatedPointCloud);
391 grid2.filter(*outputCloudPtr);
392 outputCloudPtr.swap(accumulatedPointCloud);
393 ARMARX_VERBOSE << "Accumulated pc size after grid filtering: "
394 << accumulatedPointCloud->size() << " " << VAROUT(gridLeafSize);
395 TIMING_END(Downsampling2);
396
397
399
400 TIMING_START(PREPARATION);
401
402 // std::map<Eigen::Vector3i, int> grid;
403 std::vector<VirtualRobot::VisualizationFactory::Color> gridColors;
404 gridPositions.reserve(accumulatedPointCloud->size());
405 gridColors.reserve(accumulatedPointCloud->size());
406
407 DebugDrawerTriMesh ddTriMesh;
408
409 this->gridPositions.clear();
410 this->gridPositions.reserve(accumulatedPointCloud->size());
411 // pcl::octree::OctreePointCloud<PointType>::AlignedPointTVector points;
412 // octtree->getOccupiedVoxelCenters(points);
413 for (auto& p : *accumulatedPointCloud)
414 {
415 if (!std::isnan(p._PointXYZRGBA::x) && !std::isnan(p._PointXYZRGBA::y) &&
416 !std::isnan(p._PointXYZRGBA::z))
417 {
418
419 this->gridPositions.push_back(
420 {p._PointXYZRGBA::x, p._PointXYZRGBA::y, p._PointXYZRGBA::z});
421 gridColors.push_back(
422 VirtualRobot::VisualizationFactory::Color(p._PointXYZRGBA::r / 255.f,
423 p._PointXYZRGBA::g / 255.f,
424 p._PointXYZRGBA::b / 255.f,
425 0.8));
426 }
427 }
428 TIMING_END(PREPARATION);
429
430 std::vector<Eigen::Vector3f> gridPositionsEigen = armarx::transform(
431 this->gridPositions,
432 +[](const Vector3f& p) -> Eigen::Vector3f {
433 return {p.e0, p.e1, p.e2};
434 });
435
436
437 ARMARX_INFO << VAROUT(gridPositionsEigen.size());
438
439 TIMING_START(MESHING);
440
441 gridMesh = VirtualRobot::TriMeshUtils::CreateSparseBoxGrid(
442 Eigen::Matrix4f::Identity(),
443 gridPositionsEigen,
447 VirtualRobot::VisualizationFactory::Color::Blue(),
448 gridColors);
450 TIMING_END(MESHING);
451 TIMING_START(VISU);
452 // DebugDrawer24BitColoredPointCloud ddPC;
453 // visionx::tools::convertFromPCLToDebugDrawer(accumulatedPointCloud, ddPC, visionx::tools::eConvertAsColors);
454 // dd->set24BitColoredPointCloudVisu("VoxelGrid", "PointCloud", ddPC);
455 // ARMARX_INFO << "Sending point cloud to debug drawer - size: " << ddTriMesh.faces.size() << " first: " << ddTriMesh.vertices.at(0).x << ", " << ddTriMesh.vertices.at(0).y << ", " << ddTriMesh.vertices.at(0).z;
456 dd->setTriMeshVisu("VoxelGrid", "PointCloudCollisionGrid", ddTriMesh);
457 TIMING_END(VISU);
458 }
459
460
461 if (accumulatedPointCloud->size() > 0 && skipper->checkFrequency("SavingPCD") &&
462 !getProperty<std::string>("PointCloudStoreFilepath").getValue().empty())
463 {
464 std::unique_lock lock(dataMutex);
465 ARMARX_INFO << "Saving point cloud to "
466 << getProperty<std::string>("PointCloudStoreFilepath").getValue();
467 pcl::io::savePCDFile(getProperty<std::string>("PointCloudStoreFilepath").getValue(),
469 }
470 TIMING_END(FullCalc);
471
472
473 cycleKeeper->waitForCycleDuration();
474 }
475
478 const VirtualRobot::RobotPtr& robot,
479 float distanceThreshold)
480 {
481 CloudPtr result(new Cloud());
482 VirtualRobot::CDManager cdm;
483 auto colModels = robot->getCollisionModels();
484 auto collisionChecker = robot->getCollisionChecker();
485 for (auto& p : *cloud)
486 {
487 bool collisionFound = false;
488 for (auto& colModel : colModels)
489 {
490 Eigen::Vector3f pEigen(p._PointXYZRGBA::x, p._PointXYZRGBA::y, p._PointXYZRGBA::z);
491 if (collisionChecker->checkCollision(colModel, pEigen, distanceThreshold))
492 {
493 collisionFound = true;
494 break;
495 }
496 }
497 if (!collisionFound)
498 {
499 result->push_back(p);
500 }
501 }
502 return result;
503 }
504
505 Vector3fSeq
507 {
508 std::unique_lock lock(dataMutex);
509 return gridPositions;
510 }
511
512 Ice::Float
513 VoxelGridMappingProvider::getGridSize(const Ice::Current&) const
514 {
515 return gridLeafSize;
516 }
517
518 void
523
524 void
529
530 void
532 {
533 std::unique_lock lock(dataMutex);
534 ARMARX_INFO << "Clearing voxel grid";
535 accumulatedPointCloud->clear();
536 }
537
538 void
540 const std::set<std::string>& changedProperties)
541 {
542 if (changedProperties.count("BoundingBox"))
543 {
545 }
546 }
547
549} // namespace visionx
#define ARMARX_REGISTER_COMPONENT_EXECUTABLE(ComponentT, applicationName)
Definition Decoupled.h:29
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition Logging.cpp:75
#define VAROUT(x)
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition Component.cpp:90
Property< PropertyType > getProperty(const std::string &name)
This util class helps with keeping a cycle time during a control cycle.
Definition CycleUtil.h:41
static DebugDrawerTriMesh convertTriMesh(const VirtualRobot::TriMeshModel &trimesh)
TopicProxyType getTopic(const std::string &name)
Returns a proxy of the specified topic.
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
static VirtualRobot::RobotPtr createLocalCloneFromFile(RobotStateComponentInterfacePrx robotStatePrx, VirtualRobot::RobotIO::RobotDescription loadMode=VirtualRobot::RobotIO::eFull)
This is a convenience function for createLocalClone, which automatically gets the filename from the R...
static bool synchronizeLocalCloneToTimestamp(VirtualRobot::RobotPtr robot, RobotStateComponentInterfacePrx robotStatePrx, Ice::Long timestamp)
Synchronizes a local robot to a robot state at timestamp.
This class holds a pool of local VirtualRobots for multi threaded applications that can be requested ...
Definition RobotPool.h:41
void enableResultPointClouds(std::string resultProviderName="")
Enables visualization.
int getPointClouds(const PointCloudPtrT &pointCloudPtr)
Poll PointClouds from provider.
MetaPointCloudFormatPtr getPointCloudFormat(std::string providerName)
void usingPointCloudProvider(std::string providerName)
Registers a delayed topic subscription and a delayed provider proxy retrieval which will be available...
bool waitForPointClouds(int milliseconds=1000)
Wait for new PointClouds.
void provideResultPointClouds(const PointCloudPtrT &pointClouds, std::string providerName="")
sends result PointClouds for visualization
Brief description of class VoxelGridMappingProvider.
std::unique_ptr< armarx::IceReportSkipper > skipper
pcl::octree::OctreePointCloud< PointType >::Ptr octtree
void componentPropertiesUpdated(const std::set< std::string > &changedProperties) override
Implement this function if you would like to react to changes in the properties.
std::pair< armarx::Vector3fSeq, std::vector< VirtualRobot::VisualizationFactory::Color > > removeRobotVoxels(const armarx::Vector3fSeq &gridPoints, std::vector< VirtualRobot::VisualizationFactory::Color > const &gridColors, const VirtualRobot::RobotPtr &robot, float distanceThreshold)
void startCollectingPointClouds(const Ice::Current &) override
void reset(const Ice::Current &) override
armarx::Vector3fSeq getFilledGridPositions(const Ice::Current &) const override
::Ice::Float getGridSize(const ::Ice::Current &=Ice::emptyCurrent) const override
void stopCollectingPointClouds(const Ice::Current &) override
void process() override
Process the vision component.
armarx::DebugDrawerInterfacePrx dd
void onExitPointCloudProcessor() override
Exit the ImapeProcessor component.
void onConnectPointCloudProcessor() override
Implement this method in the PointCloudProcessor in order execute parts when the component is fully i...
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
VirtualRobot::TriMeshModelPtr gridMesh
std::unique_ptr< armarx::CycleUtil > cycleKeeper
armarx::RobotStateComponentInterfacePrx robotStateComponent
void onInitPointCloudProcessor() override
Setup the vision component.
std::string getDefaultName() const override
Retrieve default name of component.
#define ARMARX_CHECK_GREATER_EQUAL(lhs, rhs)
This macro evaluates whether lhs is greater or equal (>=) rhs and if it turns out to be false it will...
#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...
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:184
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
#define TIMING_START(name)
Helper macro to do timing tests.
Definition TimeUtil.h:289
#define TIMING_END(name)
Prints duration.
Definition TimeUtil.h:306
std::shared_ptr< class Robot > RobotPtr
Definition Bus.h:19
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::vector< std::string > Split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
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:351
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
const LogSender::manipulator flush
Definition LogSender.h:251
ArmarX headers.
double norm(const Point &a)
Definition point.hpp:102
double distance(const Point &a, const Point &b)
Definition point.hpp:95