Coder Social home page Coder Social logo

Comments (6)

paulbovbel avatar paulbovbel commented on August 18, 2024

Thanks, this is interesting and I'll try to investigate sometime soon. If you have a suggested fix, a PR would be very welcome!

from pointcloud_to_laserscan.

paulbovbel avatar paulbovbel commented on August 18, 2024

Reading your RA question, I think angle_max being inclusive should be the standard assumption, however it may help to clarify that in the message definition with a PR to sensor_msgs. Making the number of readings one larger would follow as the solution.

from pointcloud_to_laserscan.

moooeeeep avatar moooeeeep commented on August 18, 2024

I think this is not so straight-forward, as you are dealing with some sort of histogram here (non-zero width bins), instead of actual rays.

Obviously you could just add one to the calculated size. But then you'd have a mostly useless top bin, when you have angle_min = -PI, angle_max = PI because std::atan2 wraps to the negative range for anything above angle_max itself, so its bin would likely be empty all the time.

Also you'd probably want to perform the check whether or not to skip a point based on the calculated bin index, instead of the actual angle, to take into account the non-zero bin width. For the same reason it might make sense to "correct" the angles that are assigned to the message after using them to set up the bin ranges from the user configuration. On the one hand to fix the case where the angle range is not divisible by the bin width, but also to let the "rays" point to the center of each bin (e.g., size = (angle_max - angle_min) / angle_increment + 1, angle_min = angle_min + angle_increment/2, angle_max = angle_min + (size - 1) * angle_increment).

In conclusion, this seems not so straight-forward and unfortunately I don't have a PR I could submit right now.

angle_max being inclusive indeed seems sensible but I don't want to imagine how many applications would break if one changed the message definition now.

from pointcloud_to_laserscan.

moooeeeep avatar moooeeeep commented on August 18, 2024

I added a PR to address this issue.

from pointcloud_to_laserscan.

paulbovbel avatar paulbovbel commented on August 18, 2024

I've turned this every which way and I'm not sure I've come up with a consistently good answer to this problem. The current behaviour of pointcloud_to_laserscan is definitely naive when it comes to range and bucket assignments.

I think we have to fallback to how the LaserScan is defined in relation to a 'real' LIDAR sensor. If the FOV of a hardware LIDAR is 2pi, I would expect [min, max] angle to be [-pi, pi], and I would expect there to be a ray return at [min, max] inclusive. So that means we have size = (angle_max - angle_min) / angle_increment + 1.

Now, how should pointcloud_to_laserscan translate a pointcloud into this format? The tricky thing is that for a hardware LIDAR, each return has a negligible FOV, and therefore a small obstacle could actually 'slip' through the cracks between rays. This is not what we try to do here, since I believe users generally want to capture all information in a pointcloud regardless of size. In the practical case, this probably leads to all sorts of questionable behaviour when this 'laserscan' is then used in say, the navigation stack. A user probably wants to make sure that angle_increment * range_max ~= costmap_cell_width, otherwise you'll get weird aliasing issues. Moving on...

If we assume each bucket captures an equal angle_increment, the min and max bucket will capture obstacles angle_increment / 2 outside of the defined FOV, which won't do. I believe this means that the min and max buckets should have a a half-increment so that we don't violate the defined FOV.


So this brings us to:

from pointcloud_to_laserscan.

moooeeeep avatar moooeeeep commented on August 18, 2024

The way I addressed this in my PR, is by maintaining separately the valid angle range (currently with an exclusive upper bound: [angle_lower_bound, angle_upper_bound)) and the ray angles that belong to each of the buckets (inclusive max: [angle_min, angle_max]). The former can be specified directly by the user config, the latter are then calculated based on either the number of buckets or the desired angle increment here.

For example, when we configure an angle range of [-180°, 180°) and an angle increment of 90°, we receive four buckets. In the LaserScan message, the corresponding angles will then point to the center of each bin: -135°, -45°, 45°, 135°. Similarly, when we configure an angle range of [-180°, 180°) and a ranges_size of four, we receive an angle increment of 90° and the same angles in the output message.

So far, I did not add an option to directly configure the output angles and the increment that will appear in the LaserScan message and expand the valid angle range from that. Not sure if anyone would need this.

Also, as already indicated, in my implementation, the upper bound of the angle range is currently exclusive, for not having to check that edge case in the index calculation here. While this shouldn't make a difference for a 360° scan, this might become a problem when an entire column of the input cloud is ignored because the user specified the exact maximum angle of their sensor as an upper bound in the value range. Not sure how floating point accuracy (transforming spherical to Cartesian to polar coordinates) will mess up this exact boundary anyways though.

from pointcloud_to_laserscan.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.