0
$\begingroup$

Rosanswers logo

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?

-Adi


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

Post score: 0


Original comments

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.

$\endgroup$

2 Answers 2

0
$\begingroup$

Rosanswers logo

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

$\endgroup$
0
$\begingroup$

Rosanswers logo

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


Original comments

Comment by FRK on 2018-12-05:
Thank you for sharing your code. However, I am wondering whats the difference between your minVal and msg->range_min?

Comment by fabritya on 2018-12-15:
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.

Comment by fabritya on 2018-12-15:
minVal is the actual minimum value from the ranges which are within the msg->range_max and msg->range_min range

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.