The actual measurement of a laser scanner is the distance. So ideally you should be able to go through the code of the driver and publish that data into a custom message. Performance wise, that is the best option.
However, let me give you a simpler solution.
For your reference, this is the PointCloud2 message definition. Essentially, the large array data
contains x,y,z location of the points in the point cloud. All you need to do is to parse the data array, obtain x,y,z for each point and then calculate the euclidean distance where (0,0,0) is the location of the sensor / frame.
The parsing logic is simple. Your message has height
1, width
811 and point_step
16. You can verify the numbers by checking
width*point_step == row_step*height
The fields
give you information about parsing the data. Each group of 16 numbers in the array data
gives you x,y,z and intensity for a single point in the point cloud. First 1-4 numbers represent x as a 32 bit float, 5-8 represents y, 9-12 represents z, 13-16 represents the intensity. All you then need to do is convert the data to 32 bit float in little endian.
Libraries should exist where all this is done. However, if you are into reinventing the wheel or couldn't find one, this will get you home.
Originally posted by janindu with karma: 849 on 2019-03-24
This answer was ACCEPTED on the original site
Post score: 4
Original comments
Comment by tracsat on 2019-03-24:
Ah ok this makes a lot of sense thank you! I had come to a similar conclusion after reading through a bunch of blog posts but I was getting stuck on the float32 part - I was not aware that a float32 could be represented this way.
Thank you for the link for converting to a float32. I notice the solution that was taken says that it assumes that the data is not little endian, however I believe my data is. Is there a way around this? This is my first time encountering endian so I am not sure how much of an issue it may be.
Thanks again!
Comment by janindu on 2019-03-24:
In little endian, the bytes are ordered in reverse compared to big endian. So all you have to do is to follow the same implementation but use the bytes in reverse order.
Comment by tracsat on 2019-03-24:
Ok that makes a lot of sense thank you!
I just have one more thing if you don't mind. I noticed that the solution uses a special datatype they have to define 'uchar'. Would I also need this? Or would a simple int type work?
Thanks
Comment by janindu on 2019-03-24:
uchar is simply unsigned char type data. Even though the name says char it's essentially a numeric variable. Its size is 8 bits so can take values from 0-255. int, on the other hand, is 32 bits in size at least. So you can't represent 4 bytes (you can, but that's a headache) using int variable. unsigned char is a fundamental data type in C++ so I don't see any reason not to use it. Ref : Data Types in C++
Comment by tracsat on 2019-03-24:
Thanks that makes a lot of sense. I was not aware that uchar was a fundamental type.
Comment by gvdhoorn on 2019-03-25:\
Libraries should exist where all this is done. However, if you are into reinventing the wheel or couldn't find one
+1 to this. Manually converting or iterating over PointCloud messages is not needed. Just use one of the conversion functions available.
Comment by Petros ADLATUS on 2022-05-20:
@janindu may I could add a short question to the saving with little endian format?