# Minimum distance from laser scanner data

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;
}
}
ROS_INFO_STREAM(msg->ranges[800]);
ROS_INFO_STREAM((double)msg->ranges[minIndex]);


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?

Originally posted by fabritya on ROS Answers with karma: 13 on 2018-07-11

Post score: 0

Comment by Delb on 2018-07-12:
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.

Comment by Delb on 2018-07-12:
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.

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.

Originally posted by PeteBlackerThe3rd with karma: 9529 on 2018-07-12

This answer was NOT ACCEPTED on the original site

Post score: 1

Hello,

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]); }


Thanks

Originally posted by fabritya with karma: 13 on 2018-07-16

This answer was NOT ACCEPTED on the original site

Post score: 1