Ask Your Question

Minimum distance from laser scanner data.

asked 2018-07-11 22:55:53 -0600

fabritya gravatar image

I have been trying to get the minimum distance from laser scan data. My code is as follows: Here, "msg" is the "const sensor_msgs::LaserScan::ConstPtr &msg" from the callback.

int minIndex = 540;
int maxIndex = 1080;
for (int i = minIndex + 1; i < maxIndex; i++)
    if (((msg->ranges[i] <= msg->ranges[minIndex]))&& msg->ranges[i] > 0)
        minIndex = i;

Now, I checked the stream for these values, and got these:

[ INFO] [1531360195.851970761, 15.721000000]: 3.42491
[ INFO] [1531360195.895046530, 15.754000000]: 3.42411
[ INFO] [1531360195.922127253, 15.774000000]: 3.41909
[ INFO] [1531360195.958390861, 15.802000000]: 3.42099
[ INFO] [1531360195.982909709, 15.822000000]: 3.42179
[ INFO] [1531360196.011697987, 15.846000000]: 3.42434

If we look at the third and fourth value, the third value is lower than the minimum I found. I randomly chose index 800, but I guess it is enough to prove that my code has some problem. Also, i keep getting the index 540, which is my first value as the minimum value.

My guess is that the laser scan data coming in is float32, but the check is somehow truncating that value to a fixed digit rounded off value. or is it due to the subscription rate, my values may be overwritten?


edit retag flag offensive close merge delete


First, you should add text in the ROS_INFO it's easier to understand the outputs. Secondly, where are you executing this code ? Is it inside the callback ? If not then it's possible that the msg->ranges[] is updated during the for loop leading to those kind of errors.

Delb gravatar image Delb  ( 2018-07-12 05:29:10 -0600 )edit

You should save in another variable ranges_temp = msg->ranges and then execute the for loop so that you are sure the variable ranges_temp won't be updated during the loop.

Delb gravatar image Delb  ( 2018-07-12 05:33:40 -0600 )edit

2 Answers

Sort by ยป oldest newest most voted

answered 2018-07-16 15:58:45 -0600

fabritya gravatar image


Thank you all for your comments. I incorporated your suggestions and my code definitely looks cleaner. For anyone else reading this, I did execute this piece of code in the callback.

Also, the code was working as required and it was my own naivety that caused the problem. My laser scanner distances were recorded in the clockwise direction and hence my array would have the values I needed on the left half 0-540 index. The reason I was getting 540 index all the time was because 540 was in fact the closest obstacle to my robot. My lesson here is to just make sure to understand the way the laser scans are recorded.

void LeftClosestObstacle::messageCallback(const sensor_msgs::LaserScan::ConstPtr &msg) {
    int size = msg->ranges.size();
    int minIndex = 0;
    int maxIndex = 540; //0 to 540 for left side minimum distance
    int closestIndex = -1;
    double minVal = 999; //values are between 0.2 and 30 meters for my scanner

    for (int i = minIndex; i < maxIndex; i++)
        if ((msg->ranges[i] <= minVal) && (msg->ranges[i] >= msg->range_min) && (msg->ranges[i] <= msg->range_max))
            minVal = msg->ranges[i];
            closestIndex = i;
    ROS_INFO_STREAM("Min ---" << msg->ranges[closestIndex]); }


edit flag offensive delete link more


Thank you for sharing your code. However, I am wondering whats the difference between your minVal and msg->range_min?

FRK gravatar image FRK  ( 2018-12-05 04:56:34 -0600 )edit

msg->range_min is the minimum possible range of the laser scanner, the check is done so that the distance values obtained are within the given range for example 0-30m. If you see the rostopic echo for the ranges, sometimes the ranges are out of range when laser hits are not obtained.

fabritya gravatar image fabritya  ( 2018-12-15 02:06:32 -0600 )edit

minVal is the actual minimum value from the ranges which are within the msg->range_max and msg->range_min range

fabritya gravatar image fabritya  ( 2018-12-15 02:08:06 -0600 )edit

answered 2018-07-12 08:01:45 -0600

We need to see more of your code to know what's really going on here. But there's a few things I can spot straight away.

Also, i keep getting the index 540, which is my first value as the minimum value : Your loop starts at 541 but your initial closest value at index 540. So if this is invalid i.e. zero, or closer than any other values in the range you're testing then the if statement will never be true. This explains why index 540 comes up so often.

You're also not handling the possibility there are no valid depth samples in the range 540 - 1080, this would also result in an index of 540 being reported.

A note on coding style : you're using the variable minIndex to represent two different things at different points in your code, this is very bad practice. I recommend using a separate variable called closestIndex instead, setting this to an initial impossible value like -1 would allow you to detect when there are no valid samples.

You should use the range_min and range_max values from the laser scan message to check a sample is valid, not simply check it's greater than zero. This may work for some sensors and drivers but will not work in all systems.

I'll second @Delb using ROS_INFO with some extra information so you know what the numbers being printed out mean would be really helpful.

Hope this helps.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower


Asked: 2018-07-11 22:55:53 -0600

Seen: 1,203 times

Last updated: Jul 12 '18