Robotics StackExchange | Archived questions

Efficient way to send a new large pointcloud (100.000+ Points)

Hi,

I have pointers to arrays for x, y, z and intensity data. Now I want to create a Pointcloud message from it but I'm missing the correct idea to this efficiently. I have ~100.000 Points @~30Hz+ that need to be sent in an appropriate time. Right now I'm creating a point with x,y,z data and push it into my point cloud in each iteration (100.000+...) which is quite time-consuming. I would be really happy if you could point me in the right direction on how to do this with the least amount of computation time. Is there a way to handle it without copying any data?

Thanks for your help! :)

Here is a simplified version of the code I'm using:

typedef pcl::PointCloud<pcl::PointXYZ> PointCloud;
PointCloud::Ptr cloud(new PointCloud);
    for(int i = 0; i < (size = 100000) ; i++)
    {
        pcl::PointXYZ point;
        basic_points.x = x[i];
        basic_points.y = y[i];
        basic_points.z = z[i];
        new_pointcloud->points.push_back(point);
    }
cloud->points = new_pointcloud->points;

Asked by bjajo on 2020-01-21 16:06:03 UTC

Comments

My solution was to do it this way:

typedef pcl::PointCloud<pcl::PointXYZ> PointCloud; 
PointCloud::Ptr cloud(new PointCloud);
    for(int i = 0; i < (size = 100000) ; i++)
    {
        cloud->points[i].x = x[i];
        cloud->points[i].y = y[i];
        cloud->points[i].z = z[i];
    }

Asked by bjajo on 2020-01-23 15:44:10 UTC

Answers

Where are you trying to publish it to?

One option that will help with reducing the copies and serialization is if you use intraprocess communication by means of Nodelets vs nodes. http://wiki.ros.org/nodelet Its a slightly different API but everything should be pretty straight forward. When you load multiple nodelets into a nodelet manager, they will communicate over intraprocess communication (ei shared ptr) and not serialize and deserialize the messages.

I'd also recommend making use of the type masquerading to reduce even further the number of copies you make from conversions.

Side note: ROS2 will do this faster and better in concept. I might recommend if you're throwing around that much information, you may want to consider moving to Eloquent.

Asked by stevemacenski on 2020-01-21 17:45:24 UTC

Comments

Thanks for your answer, interesting point! i'll have a look into that. But I think a major problem is my way to create the actual Pointcloud. Do you have any advice there?

  typedef pcl::PointCloud<pcl::PointXYZ> PointCloud;
  PointCloud::Ptr cloud(new PointCloud);
        for(int i = 0; i < (size = 100000) ; i++)
        {
            pcl::PointXYZ point;
            basic_points.x = x[i];
            basic_points.y = y[i];
            basic_points.z = z[i];
            new_pointcloud->points.push_back(point);
        }
 cloud->points = new_pointcloud->points;

Asked by bjajo on 2020-01-22 03:18:56 UTC

What is x, y, z? It seems they are just vectors of values, which is all the PointXYZ is as well.

Asked by stevemacenski on 2020-01-22 13:22:59 UTC

Exactly these are arrays containing my point cloud data. Do you have any suggestions on how to do this operation more efficient? :)

Asked by bjajo on 2020-01-22 15:03:21 UTC

Where did the arrays come from? Would it be possible to populate the pointcloud directly rather than these arrays?

Asked by stevemacenski on 2020-01-22 15:23:18 UTC

It is actually a callback to another process and I get these pointers back. Changing that will require some serious rework.

Asked by bjajo on 2020-01-22 16:03:07 UTC