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>
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 =
101 if (virtualRobotReaderPlugin->isAvailable())
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);
176 arviz.commit({layer});
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";
254 Eigen::Matrix4f globalSensorPose = Eigen::Matrix4f::Identity();
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();
int Label(int n[], int size, int *curLabel, MiscLib::Vector< std::pair< int, size_t > > *labels)
#define ARMARX_CHECK_NOT_EMPTY(c)
armarx::viz::Client arviz
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Property< PropertyType > getProperty(const std::string &name)
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.
PluginT * addPlugin(const std::string prefix="", ParamsT &&... params)
std::string getName() const
Retrieve name of object.
std::string prefix
Prefix of the properties such as namespace, domain, component name, etc.
PropertyDefinition< PropertyType > & defineOptionalProperty(const std::string &name, PropertyType defaultValue, const std::string &description="", PropertyDefinitionBase::PropertyConstness constness=PropertyDefinitionBase::eConstant)
bool synchronizeRobot(VirtualRobot::Robot &robot, const armem::Time ×tamp) const
Synchronize both the platform pose and the joint values of a virtual robot, according to the robot st...
static Duration MicroSeconds(std::int64_t microSeconds)
Constructs a duration in microseconds.
PointCloud & pointSizeInPixels(float s)
PointCloud & pointCloud(const PointCloudT &cloud)
Draw a point cloud.
PointCloud & checkFinite(bool enabled=true)
Enable or disable checking whether points are finite when adding them (disabled by default).
PointCloudProcessorPropertyDefinitions(std::string prefix)
int getPointClouds(const PointCloudPtrT &pointCloudPtr)
Poll PointClouds from provider.
MetaPointCloudFormatPtr getPointCloudFormat(std::string providerName)
bool waitForPointClouds(int milliseconds=1000)
Wait for new PointClouds.
std::vector< std::string > getPointCloudProviderNames() const
Get the names of providers for which usingPointCloudProvider() has been called.
Property definitions of PointCloudToArViz.
PointCloudToArVizPropertyDefinitions(std::string prefix)
virtual void setPointSizeInPixels(float pointSizeInPixels, const Ice::Current &=Ice::emptyCurrent) override
void RemoteGui_update() override
virtual void setCustomTransform(const armarx::PoseBasePtr &transform, const Ice::Current &=Ice::emptyCurrent) override
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
void onExitPointCloudProcessor() override
void onConnectPointCloudProcessor() override
void onDisconnectPointCloudProcessor() override
void onInitPointCloudProcessor() override
void createRemoteGuiTab()
std::string getDefaultName() const override
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
#define ARMARX_INFO
The normal logging level.
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
#define ARMARX_VERBOSE
The logging level for verbose information.
std::string const GlobalFrame
Variable of the global coordinate system.
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
void RemoteGui_startRunningTask()
void RemoteGui_createTab(std::string const &name, RemoteGui::Client::Widget const &rootWidget, RemoteGui::Client::Tab *tab)
GridLayout & add(Widget const &child, Pos pos, Span span=Span{1, 1})
void add(ElementT const &element)