Friday, June 12, 2009

Simulating Sensors

For many robotics tasks getting good readings from the sensors to estimate your current state is very important. The system may come to rely on the sensors so much that any hardware failure for the sensor would cause devastating consequences.

A few simple noise simulations placed into your sensor readings can help you assert that your system can handle failed sensors. But what to simulate?

There are a number of academic papers available that discuss sensor noise models, but they are typically highly detailed and specific to one sensor type.

Here is a list of common faults that you should simulate for testing analog sensors:
  • Completely on/off, this will only happen if there is a problem with the power supply, you will either get 0 or full positive, this helps to detect shorts, etc and other common failures.
    In code: sensor = 0, or sensor = high;
  • An additional DC offset, this will simulate a slowly drifting ground, you may also wish to simulate this with a slow rise/drop over a long time.
    In code : sensor+=dc_offset;
  • Inversion fault, if someone installs a sensor the wrong way round, or wires something up the wrong way.
    In code : sensor = 1-sensor;
  • Random noise, white noise is not really a very common input from the real world, but its a cheap test routine. Adding it to your signal can help determine that your filters have an appropriate noise cut-off level.
    In code : sensor = rand(); or sensor+= signed_rand();
  • Sinewave, you will find sinusoidal interfearence coming from a number of sources, such as interfearance from a nearby radio unit, micro controller, or PWM. Often higher frequency signals will be aliased and presented as a low frequency sine wave.
    In code: sensor = sensor + sin
  • Spikes/Ramps, these will sometimes occur due to the way an analog signal is read or converted to a digital form, or some rotary encoders will droop down. Poorly designed hardware filters can also be the cause.
    In code: sensor = sensor + spike, or sensor = sensor + ramp

    The last one is a little trickier to implement, but some nice common curves can help. First, the smoothstep function:

    float smoothstep(float a, float b, float x) {
    if (x if (x>=b) return 1;
    x = (x-a)/(b-a);
    return x*x * (3 - 2*x);
    }

    (I originally found this function in Texturing & Modeling: A Procedural Approach)


    The spike function:

    double spike(double t) {
    return 1/(1+150*(t-0.5)*(t-0.5));
    }

    you may wish to play with the 150x factor to make it more 'spiky'.
  • No comments: