I hope I'll be able to explain it enough.

First, I think it's important to look at the LaserScan message. The first part after the header gives you the min and max angle + the distance between each measurement.

So imagine a circle with a midpoint. The midpoint is your `lidar_link`

so it has a 'front' (the direction of the x axis). The front is your 0 rad.

If you have a `min_angle`

of pi (-90 degrees, I'm going to stick with degrees from here on, but it's actually rads) you know where to start. Your `float32[] ranges`

is a list of ranges. The first range is at -90 degrees. If your `angle_increment`

is 1 degree, then the second range is at -89 the third at -88 etc.

That's kinda like one of those hand fans where each of the blades is 1 range.

In a way, that means the `LaserScan`

message is not really 2D. It's a list of 1D lengths that you make 2D by plotting them out on a circle.

Now for pointclouds. If somebody has more experience with them, please correct me. However, I have always understood it as being an actual 2(or3)D pointcloud.

Looking back at the `lidar_link`

(or `pointcloud_link`

if you will), it doesn't just have a 'front'. It has an x, y and z axis. It is a 3D origin. If you have a point `(2, 0, 1)`

that's a point 2 meter in front of the link and 1 meter up. A pointcloud uses a grid to express each point.

Now for the final part of your question, how the conversion works. If you've got a lidar message, basically have vectors with a magnitude and length (hopefully khanacademy helps explaining what I mean). In the link I posted, they went from a point (a,b) to a magnitude and direction. However, for a lidar to pointcloud conversion you would of course do the opposite. You go from a magnitude and direction to a coordinate.

I hope this helped you a bit with understanding the difference.