Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sensor_msgs_py.point_cloud2 functions treat numpy arrays as having shape (width, height) #236

Open
jdlangs opened this issue Dec 14, 2023 · 3 comments
Assignees

Comments

@jdlangs
Copy link
Contributor

jdlangs commented Dec 14, 2023

I'm not sure if this is really a problem or just a different convention but it was something that surprised me that I had to work around. I see that for organized clouds both the read_points and create_cloud functions have logic that treat the input/output ndarray of having a shape where the cloud width is the first index (rows), and the cloud height is the second (columns). I suppose it works if you always follow that convention but I think most other code will treat it with the opposite convention and some axes swapping is necessary.

I think pretty much only the bits I linked would have to be changed to make the switch. @Flova what are your thoughts as the original PR author?

@jdlangs
Copy link
Contributor Author

jdlangs commented Jan 19, 2024

So I originally thought this was just a relatively harmless swapping of axes, but now I'm seeing it's creating issues with the point order in organized clouds. Specifically, I'm trying to read point clouds with the following structure:

PointCloud2:
  height:  1544
  width:  2064
  fields:
     sensor_msgs.msg.PointField(name='x', offset=0, datatype=7, count=1)
     sensor_msgs.msg.PointField(name='y', offset=4, datatype=7, count=1)
     sensor_msgs.msg.PointField(name='z', offset=8, datatype=7, count=1)
     sensor_msgs.msg.PointField(name='normal_x', offset=16, datatype=7, count=1)
     sensor_msgs.msg.PointField(name='normal_y', offset=20, datatype=7, count=1)
     sensor_msgs.msg.PointField(name='normal_z', offset=24, datatype=7, count=1)
     sensor_msgs.msg.PointField(name='curvature', offset=32, datatype=7, count=1)
  is_bigend:  False
  is_dense:  True
  point_step:  48
  row_step:  99072
  num_bytes:  152967168

When I call read_points, I get an array of shape (2064,1544) as expected. However, when I try to index the points in a 2D region, I find they are out of order. Switch the argument order in the call to reshape inside read_points fixes this and lets me access a contiguous region of the organized cloud.

@mjcarroll
Copy link
Member

I agree that it seems transposed. Would you be able to open a PR with the fix and maybe a unit test so that we can prevent regression in the future?

@jdlangs
Copy link
Contributor Author

jdlangs commented Jan 22, 2024

Yes, the fix is simple enough so I'll go ahead with a PR. It will probably be sometime next week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants