25 #include <pcl/common/transforms.h>
26 #include <pcl/impl/point_types.hpp>
27 #include <pcl/point_types.h>
29 #include <SimoxUtility/math/convert/mat4f_to_pos.h>
30 #include <SimoxUtility/math/convert/mat4f_to_rpy.h>
31 #include <SimoxUtility/math/convert/pos_rpy_to_mat4f.h>
47 defineOptionalProperty<int>(
48 "ProviderWaitMs", 100,
"Time to wait for each point cloud provider [ms].");
58 params.pointSizeInPixels,
"viz.pointSizeInPixels",
"The point size in pixels.");
59 defs->optional(params.checkFinite,
61 "Enable to check points for being finite. "
62 "\nEnable this option if the drawn point cloud causes the screen to become "
64 defs->optional(params.labeled,
66 "If true and point cloud is labeled, draw colors according to labels.");
67 defs->optional(params.alsoVisualizeNode,
69 "If true also the node's coordinate systems is shown.");
71 defs->optional(params.robotName,
"robotName",
"");
73 params.pointCloudNodeName,
75 " If the point cloud header does not provide a frame id, this info is used.");
88 return "PointCloudToArViz";
94 params.providerWaitTime =
95 IceUtil::Time::milliSeconds(getProperty<int>(
"ProviderWaitMs").getValue());
103 robot = virtualRobotReaderPlugin->
get().
getRobot(params.robotName);
128 static_cast<int>(params.providerWaitTime.toMilliSeconds())))
130 auto it = cache.find(providerName);
131 if (it == cache.end())
139 std::scoped_lock lock(paramMutex);
140 params = this->params;
147 std::optional<PointCloudToArViz::OriginInfo> originInfo;
151 pcl::PointCloud<pcl::PointXYZRGBL>::Ptr inputCloud(
152 new pcl::PointCloud<pcl::PointXYZRGBL>);
154 originInfo = applyCustomTransform(*inputCloud);
155 vizCloud.
pointCloud(*inputCloud, params.labeled);
159 pcl::PointCloud<pcl::PointXYZRGBA>::Ptr inputCloud(
160 new pcl::PointCloud<pcl::PointXYZRGBA>);
162 originInfo = applyCustomTransform(*inputCloud);
167 if (params.alsoVisualizeNode && originInfo.has_value())
170 originPose.pose(originInfo->pose);
172 layer.
add(originPose);
180 ARMARX_VERBOSE <<
"Timeout waiting for point cloud provider " << providerName
189 std::scoped_lock lock(paramMutex);
190 params.pointSizeInPixels = pointSizeInPixels;
207 template <
class Po
intT>
208 std::optional<PointCloudToArViz::OriginInfo>
209 PointCloudToArViz::applyCustomTransform(pcl::PointCloud<PointT>& pointCloud)
215 <<
"The robot reader plugin is deactivated. Won't transform point cloud";
221 std::scoped_lock lock(robotMutex);
226 const auto pointCloudNodeName = [&]() -> std::string
229 if (not pointCloud.header.frame_id.empty())
231 return pointCloud.header.frame_id;
237 <<
"The point cloud header does not provide a frame_id. Using property instead";
240 <<
"The `pointCloudNodeName` property must be provided as the point cloud "
242 "frame id is not set!";
244 return params.pointCloudNodeName;
250 <<
"The robot is not available. Won't transform point cloud";
258 std::scoped_lock lock(robotMutex);
260 const auto node = robot->getRobotNode(pointCloudNodeName);
262 <<
"No robot node with name `" << pointCloudNodeName <<
"`";
263 globalSensorPose = node->getGlobalPose();
266 pcl::transformPointCloud(pointCloud, pointCloud, globalSensorPose);
268 else if (not localTransformationNodeName.empty())
271 <<
"Local transformation node cannot be set as point cloud is in global "
277 return OriginInfo{.name = pointCloudNodeName, .pose = globalSensorPose};
288 tab.checkFinite.
setName(
"Check Finite");
289 tab.checkFinite.setValue(params.checkFinite);
291 tab.pointSizeInPixels.setName(
"Point Size [pixels]");
292 tab.pointSizeInPixels.setDecimals(2);
293 tab.pointSizeInPixels.setRange(0, 100);
294 tab.pointSizeInPixels.setSteps(100);
295 tab.pointSizeInPixels.setValue(params.pointSizeInPixels);
297 tab.labeled.setName(
"Color by Labels");
298 tab.labeled.setValue(params.labeled);
300 grid.
add(
Label(tab.checkFinite.getName()), {row, 0}).
add(tab.checkFinite, {row, 1});
302 grid.
add(
Label(tab.pointSizeInPixels.getName()), {row, 0})
303 .
add(tab.pointSizeInPixels, {row, 1});
305 grid.
add(
Label(tab.labeled.getName()), {row, 0}).
add(tab.labeled, {row, 1});
308 tab.localTransformationNode =
ComboBox();
309 tab.localTransformationNode.addOption(
"");
310 for (
const std::string& nodeName : robot->getRobotNodeNames())
312 tab.localTransformationNode.addOption(nodeName);
314 grid.
add(
Label(
"Local node: "), {row, 0}).add(tab.localTransformationNode, {row, 1});
317 auto createFloatSpinBox = [&](
float min,
float max,
float value)
320 spinBox.setRange(
min,
max);
321 spinBox.setValue(
value);
322 tab.transfSpinBoxes.push_back(spinBox);
327 grid.
add(
Label(
"Transformation: "), {row, col++})
328 .add(
Label(
"x"), {row, col++})
329 .add(createFloatSpinBox(-5000, 5000, 0), {row, col++})
330 .add(
Label(
"y"), {row, col++})
331 .add(createFloatSpinBox(-5000, 5000, 0), {row, col++})
332 .add(
Label(
"z"), {row, col++})
333 .add(createFloatSpinBox(-5000, 5000, 0), {row, col++})
334 .add(
Label(
"roll"), {row, col++})
335 .add(createFloatSpinBox(-
M_PI,
M_PI, 0), {row, col++})
336 .add(
Label(
"pitch"), {row, col++})
337 .add(createFloatSpinBox(-
M_PI,
M_PI, 0), {row, col++})
338 .add(
Label(
"yaw"), {row, col++})
339 .add(createFloatSpinBox(-
M_PI,
M_PI, 0), {row, col++});
349 std::scoped_lock lock(paramMutex);
350 if (tab.checkFinite.hasValueChanged())
352 params.checkFinite = tab.checkFinite.getValue();
354 if (tab.pointSizeInPixels.hasValueChanged())
356 params.pointSizeInPixels = tab.pointSizeInPixels.getValue();
358 if (tab.labeled.hasValueChanged())
360 params.labeled = tab.labeled.getValue();
363 if (tab.localTransformationNode.hasValueChanged())
365 localTransformationNodeName = tab.localTransformationNode.getValue();
367 if (not localTransformationNodeName.empty())
369 const auto localTransf =
370 robot->getRobotNode(localTransformationNodeName)->getLocalTransformation();
371 const Eigen::Vector3f pos = simox::math::mat4f_to_pos(localTransf);
372 const Eigen::Vector3f rpy = simox::math::mat4f_to_rpy(localTransf);
374 for (
unsigned int i = 0; i < 3; i++)
376 tab.transfSpinBoxes.at(i).setValue(pos[i]);
378 for (
unsigned int i = 0; i < 3; i++)
380 tab.transfSpinBoxes.at(i + 3).setValue(rpy[i]);
386 for (
auto& spinBox : tab.transfSpinBoxes)
388 if (spinBox.hasValueChanged())
396 std::scoped_lock lock(robotMutex);
398 auto localTransformation =
399 simox::math::pos_rpy_to_mat4f(tab.transfSpinBoxes.at(0).getValue(),
400 tab.transfSpinBoxes.at(1).getValue(),
401 tab.transfSpinBoxes.at(2).getValue(),
402 tab.transfSpinBoxes.at(3).getValue(),
403 tab.transfSpinBoxes.at(4).getValue(),
404 tab.transfSpinBoxes.at(5).getValue());
406 robot->getRobotNode(localTransformationNodeName)
407 ->setLocalTransformation(localTransformation);
410 ARMARX_INFO <<
"Updating localTransformation of " +
411 tab.localTransformationNode.getName() +
" to "
412 << localTransformation.matrix();