Is there a way to publish normals of a given point cloud in ROS?

asked 2021-11-11 05:57:39 -0600

mitselis gravatar image

updated 2021-11-15 02:35:21 -0600

Hello everyone.

I subscribe to my camera, I get the point cloud, I convert the point cloud from ROS_to_pcl and finally I use the function make_NormalEstimation() of python_pcl to get the normals. So far so good! Now I want to publish somehow these normals to a ROS topic and by publishing i mean visualizing them also in RVIZ. The python_pcl function make_NormalEstimation() returns 4 values in the form of a vector. The 3 first values are normal_x, normal_y, normal_z and he 4th value is the curvature. I want to publish and visualize the normals in RVIZ through PoseStamed messages. As far as i know a PoseStamped message needs a Pose and a Quaternion. For the Pose field i use the x, y, z of the desired point in my point cloud i want to find the normal. But when it comes for the quaternion i don't know what to use! I tried to use the returned values as they were quaternion_x, quaternion_y, quaernion_z, quaternion_w but the results where not so good...

So. my questions are:

  • How can i use the returned values of make_NormalEstimation() to create a PoseStamed message?
  • Is there a way to transform the returned values into quaternion?
  • Am i missing something about the returned values?
  • Is there another way of finding and using normals in ROS?
  • How can i generate and publish a normal in ROS? Not only it's normal_x, normal_y, normal_z values but also it's orientation.
  • Do i have to publish both it's normal_x, normal_y, normal_z and orientation or just it's normal_x, normal_y, normal_z values? And if so how will a robot know the orientation it needs to approach a point of interest?

Sorry for the chaos in my questions! I really hope they make sense!

Thanks in advance!

edit retag flag offensive close merge delete


Take a look at this prior question:

The code is in C++ though

pcl::PointCloud<pcl::PointNormal> cloud_normals_;

normalEstimation.setViewPoint(0, 0, 1.0);                                                                                                                                                                                           
normalEstimation.compute (cloud_normals_); 

int index = 0;
long temp_size = cloudFiltered->points.size();

for(unsigned int i=0; i < temp_size; i=i+20) {
// x range -35m to 35 m, y ranges -25 to 25m, z ranges 0 to 66
    cloud_normals_.points[index].x = cloudFiltered->points[i].x;
    cloud_normals_.points[index].y = cloudFiltered->points[i].y;
    cloud_normals_.points[index].z = cloudFiltered->points[i].z;
    index ++;

osilva gravatar image osilva  ( 2021-11-12 10:03:14 -0600 )edit

Thank you for your answer and sorry for my delay. Your answer was very helpful but i have some more questions so i edited my post.

mitselis gravatar image mitselis  ( 2021-11-15 02:39:33 -0600 )edit

you could also publish the normals as visualization_msgs::MarkerArray msg with each marker(normal) being an arrow.

xibeisiber gravatar image xibeisiber  ( 2021-11-15 07:37:28 -0600 )edit