Reducing a robot’s sensitivity to false negatives from the rangefinder

I’ve just had an interesting discussion with Richard Hayes concerning the problems some RoboSumo teams are having with false negative readings from the HC-SR04 rangefinder. When used to detect the presence of a nearby object (such as a robot opponent), this sensor seems to be quite sensitive to a number of factors including:

  • How close the object is to the measurement “axis” of the ultrasonic sensor. In other words, is the target object directly in front of the sensor or slightly to one side?
  • What material the reflecting surface is made of. A hard flat surface seems to be detected more reliably.
  • The angle of the reflecting surface. If the surface is perpendicular to the direction of propagation of the incident ultrasound beam, that seems to be ideal. However, if the surface is at an angle, it may not be sensed at all.

Anyway, in the course of my conversation with Richard, we discussed the following approach to overcoming the problem of false negatives.

  1. Create a variable called “dc” which stands for distance counter.
  2. Each time you get a positive reading from the rangefinder (i.e. a short distance, indicating the presence of an object), increase the value of dc to a certain number N (such as 10 for example).
  3. Each time you get a negative reading from the rangefinder (i.e. a long distance), decrease the value of dc by 1 unless it is already zero.
  4. Whenever dc is greater than zero, your robot should be in attack mode because your opponent is probably straight ahead.
  5. Whenever dc equals zero, your robot should be in search mode because your opponent probably isn’t straight ahead.

In my example below, I set N equal to 10, which means that:

  • Only one positive reading is required to switch from SEARCH to ATTACK,
  • But 10 negative readings in a row are required to switch from ATTACK to SEARCH.

The following diagram illustrates how the robot responds to positive and negative readings when N=10.

search_attack

So the robot remains very sensitive to positive readings, but becomes much less sensitive to negative readings. The higher the value of N, the more negative readings in a row will be required to switch from ATTACK mode to SEARCH mode.

In a previous post, I discussed one approach for interfacing this sensor to an MSP430 microcontroller. The example program below is based on the second example from that earlier post, which placed the rangefinder code in a separate function.

//
// RoboSlam Example: Rangefinder example
// Code is for MSP430G2452 or MSP430G2553
// Written by Ted Burke - Last updated 20-3-2015
//
// This version aims to reduce the effect of false
// negatives from the rangefinder.
//
 
#include <msp430.h>
 
// function prototype
int distance();
 
// main function
int main( void )
{
    // disable watchdog timer to prevent time out reset
    WDTCTL = WDTPW + WDTHOLD;
 
    // configure digital inputs and outputs
    P1DIR = 0b00001000;   // Port 1 outputs: P1.3 (trig)
    P2DIR = 0b00111000;   // Port 2 outputs: P2.3 (LED), P2.4-5 (motor)
 
    int d;         // distance
    int dc = 0;    // distance counter
    int state = 1; // state variable
    
    // Main loop implements simple state machine
    while(1)
    {
        // Measure distance using rangfinder
        d = distance();
        
        // Update distance counter
        if (d < 30) dc = 10;          // positive reading sets dc to 10
        else if (dc > 0) dc = dc - 1; // negative reading reduces dc by 1
        
        if (state == 1)      // STATE 1: SPIN
        {
            // left motor forward, right motor reverse
            P2OUT = 0b00001001;
            
            // change state?
            if (dc > 0) state = 2;
        }
        else if (state == 2) // STATE 2: ATTACK
        {
            // left motor forward, right motor forward
            P2OUT = 0b00000101;
            
            // change state?
            if (dc == 0) state = 1;
        }
    }
}

//
// This function measures distance in cm using the rangefinder.
// It assumes TRIG is P1.3 and ECHO is P1.2.
//
int distance()
{
    // Send 20us trigger pulse
    P1OUT |= BIT3;
    __delay_cycles(20);
    P1OUT &= ~BIT3;
     
    // Wait for start of echo pulse
    while((P1IN & BIT2) == 0);
     
    // Measure how long the pulse is
    int d = 0;
    while((P1IN & BIT2) > 0)
    {
        // The following delay was worked out by trial and error
        // so that d counts up in steps corresponding to 1cm
        __delay_cycles(30);
        d = d + 1;
        if (d >= 400) break;
    }
    
    // Leave 100ms for any ultrasound reflections to die away
    __delay_cycles(100000);
    
    // Pass the measured distance back to the calling function
    return d;
}
Advertisements
This entry was posted in Uncategorized. Bookmark the permalink.

One Response to Reducing a robot’s sensitivity to false negatives from the rangefinder

  1. Pingback: RoboSumo: Day Ten | cathalfitzie58

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s