0
$\begingroup$

Rosanswers logo

I have a topic publishing a point cloud of type sensors_msgs.PointCloud2. I can subscribe to it and read it using sensors_msgs.point_cloud2.read_points function but then I get and object of type "generator". How do I access the coordinates of the points in this object? I want to write a service that checks the maximum allowed height in some specific target areas (the point cloud represents the ceiling). I am using python.


Originally posted by Mehdi. on ROS Answers with karma: 3339 on 2016-07-27

Post score: 3

$\endgroup$

3 Answers 3

0
$\begingroup$

Rosanswers logo

read_points gives you a generator (keyword 'yield'). So you can just iterate over it to find your obstacles and not crash your shiny robot

from sensor_msgs.msg import PointCloud2
from sensor_msgs import point_cloud2

def callback_pointcloud(data):
    assert isinstance(data, PointCloud2)
    gen = point_cloud2.read_points(data)
    print type(gen)
    for p in gen:
      print p  # type depends on your data type, first three entries are probably x,y,z

Originally posted by NEngelhard with karma: 3519 on 2016-07-27

This answer was ACCEPTED on the original site

Post score: 3


Original comments

Comment by Avhi on 2021-12-19:
What would be the other 3 entries ? are they RGB color values ?

Comment by bwhal on 2023-05-15:
When I use this code, it gives me an assertion error: cloud is not a sensor_msgs.msg.PointCloud2. What would be causing this and how would I fix it?

$\endgroup$
0
$\begingroup$

Rosanswers logo

After looking into the source code I found out that this read_points is a generator function that yields the next value of a cloud each time it is called. It works also as an iterator and calling it in a loop will deliver all pointcloud points:

cloud_points = []
for p in point_cloud2.read_points(pc2, field_names = ("x", "y", "z"), skip_nans=True):
    cloud_points.append(p)    

Here pc2 is my pointcloud of type sensor_msgs/PointCloud2

and cloud_points will then be a list of 3D points forming the cloud.


Originally posted by Mehdi. with karma: 3339 on 2016-07-27

This answer was NOT ACCEPTED on the original site

Post score: 2


Original comments

Comment by ozgurovic on 2017-11-14:
This would be too slow. Try this instead:

cloud_points = list(point_cloud2.read_points(cloud, skip_nans=True, field_names = ("x", "y", "z")))
$\endgroup$
0
$\begingroup$

Rosanswers logo

As of ROS2 humble there is also read_points_numpy (see here) which would give you directly a 2D NumPy array. For example:

cloud = point_cloud2.read_points_numpy(
    msg, field_names=['x', 'y', 'z', "intensity"], skip_nans=True)

Note that there also exists a read_points_list (see here) at least for galactic, foxy, and humble which would have simplified the code of the other answers.


Originally posted by Lbern with karma: 11 on 2022-09-13

This answer was NOT ACCEPTED on the original site

Post score: 1

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.