USE UPS NEXT DAY AIR FOR ANY USA ORDER BEFORE 11AM ET *TODAY* 12/19/2014 TO GET YOUR PACKAGE IN TIME FOR XMAS - PLEASE SEE OUR SHIPPING DEADLINE NOTICE FOR MORE DETAILS!

Pothole data smoothing and detection of accelerometer data
Moderators: adafruit_support_bill, adafruit

Re: Pothole data smoothing and detection of accelerometer data

by Arctic_Eddie on Wed Feb 06, 2013 12:11 pm

Here is the continuous version. You will have to add your sensor initialization and adjust some of the #define statements. For continuous sampling, you don't need a buffer but only the sum of the previous values for the running integral. However, if you want a past history window for a running average then you will need the buffer. The buffer should hold data for twice the length of the event you want to detect. The running average will use the oldest half so that when the event is complete then the averaging window is just entering the event window.

Good luck on your project.

Code: Select all | TOGGLE FULL SIZE
// Pothole Detector V2.0 by Arctic_Eddie, 2/5/2013
// This sketch detects and processes data collected from an accelerometer on a continuous basis.
// Threshold detectors can be added which operate on the three arrays to count particular events.

// Define constants
#define SAMPLE_DELAY     200.0 // Sample delay in milliseconds, probably 20
#define GRAVITYFT_SEC   32.174 // Gravity to velocity,feet/sec
#define G_OFFSET           1.0 // Make the G reading zero for the resting state, usually 1.0 for actual use
#define G_SCALE            6.0 // If accelerometer is on +/- 3G scale
#define INCH_FOOT         12.0 // 12 inches in foot, from velocity to inch displacement calculation
#define NUM_SAMPLES         20 // Capture 6 seconds, probably 300
#define ACCEL_PIN           A0 // Use analog pin A0

// Define global veriables
uint8_t firstTime = true;             // First time through loop so initial calc not same as first rollover
uint16_t indeX    = 0;                // Pointer into data arrays
uint32_t tindeX   = 0;                // Total index counter and not reset
uint32_t dTime;                       // Clock time for startup reading
float acceleration[NUM_SAMPLES];      // Space for acceleration samples
float velocity[NUM_SAMPLES];          // Space for velocity samples
float displacement[NUM_SAMPLES];      // Space for displacement samples

// Set up system
void setup()
{
    Serial.begin( 115200 ); // Prepare the serial monitor to receive the data
   
    Serial.println( "\n\rTime, Acceleration, Velocity, Displacement" ); // Print heading

    randomSeed( analogRead( A1 ) ); // Seed the random number generator with noise
   
    // Initialize the accelerometer ****************************
   
    // Start the delay timer
    dTime = millis();
}

void loop()
{
    // Collect continuous data, calculate other values, and print results
   
    // This section is for continuous running to fill the arrays
    // Get a random value or use accelerometer reading here
    ///acceleration[indeX] = ( ( analogRead( ACCEL_PIN ) / 1024.0 ) * G_SCALE ) - G_OFFSET; // Get an acceleration reading
    acceleration[indeX] = float( random( 1025 ) - 512 ) / 1024.0; // Make it +/- 0.5G
   
    // Calculate the running sum integral for velocity and displacement
    if( indeX == 0 ) // First reading, no previous data to add to running sum
    {
        if( firstTime == true ) // Load the first position with initial data
        {
            velocity[indeX]     = acceleration[indeX] * SAMPLE_DELAY * GRAVITYFT_SEC / 1000.0;
            displacement[indeX] = velocity[indeX] * SAMPLE_DELAY * INCH_FOOT / 1000.0;
            firstTime           = false; // Prevent first time from happening again
        }
        else // Use last position, NUM_SAMPLES-1, just before rollover for accumulated values
        {
            velocity[indeX]     = ( acceleration[indeX] * SAMPLE_DELAY * GRAVITYFT_SEC / 1000.0 )
                                  + velocity[NUM_SAMPLES-1];         // The previous running sum
            displacement[indeX] = ( velocity[indeX] * SAMPLE_DELAY * INCH_FOOT / 1000.0 )
                                  + displacement[NUM_SAMPLES-1];     // The previous running sum     
        }
    }
    else // Not the first reading so add the data from the previous index
    {
        velocity[indeX]     = ( acceleration[indeX] * SAMPLE_DELAY * GRAVITYFT_SEC / 1000.0 )
                              + velocity[indeX-1];         // The running sum
        displacement[indeX] = ( velocity[indeX] * SAMPLE_DELAY * INCH_FOOT / 1000.0 )
                              + displacement[indeX-1];     // The running sum     
    }

    // Insert threshold detector, running average, and reset action here *******************
   
    // Print the results in spreadsheet readable format
    Serial.print( float( tindeX * SAMPLE_DELAY ) / 1000.0 );   // The actual time value
    Serial.print( ", " );                                      // Add a comma separator
    Serial.print( acceleration[indeX] );                       // Acceleration
    Serial.print( ", " );                                      // Add a comma separator
    Serial.print( velocity[indeX] );                           // Velocity
    Serial.print( ", " );                                      // Add a comma separator
    Serial.println( displacement[indeX] );                     // Displacement
   
    // Pause until the next interval, check clock for correct delay
    while( ( millis() - dTime ) < ( SAMPLE_DELAY * tindeX ) ) {}  // Pause here until sample interval has passed

    // Index the pointers
    tindeX++;                       // Increment the total index pointer
    indeX = ++indeX % NUM_SAMPLES;  // Increment the array indexer but cause rollover, circular buffer
}

// Supporting routines go here *********************************************
float fmap( float x, float in_min, float in_max, float out_min, float out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
Arctic_Eddie
 
Posts: 208
Joined: Tue Feb 28, 2012 6:01 pm
Location: St. Petersburg, FL

Re: Pothole data smoothing and detection of accelerometer data

by zacharoni16 on Wed Feb 06, 2013 11:10 pm

Wow thank you for all your hard work,

theres a problem though, just leaving the sensor at rest on a flat surface, the velocity and displacement term get huge and huge and huge:

Code: Select all | TOGGLE FULL SIZE
363.48, 0.00, -38.36, -86521.09
363.50, 0.01, -38.36, -86530.29
363.52, 0.00, -38.36, -86539.50
363.54, 0.00, -38.36, -86548.70
363.56, 0.00, -38.36, -86557.90
363.58, 0.00, -38.36, -86567.10
363.60, 0.00, -38.36, -86576.31
363.62, -0.01, -38.36, -86585.52
363.64, 0.00, -38.36, -86594.73
363.66, 0.00, -38.36, -86603.94
363.68, -0.01, -38.37, -86613.15
363.70, 0.00, -38.37, -86622.36
363.72, 0.00, -38.37, -86631.57
363.74, 0.00, -38.37, -86640.78
363.76, 0.00, -38.37, -86650.00
363.78, 0.00, -38.37, -86659.21
363.80, 0.00, -38.37, -86668.42
363.82, 0.00, -38.37, -86677.63
363.84, 0.00, -38.37, -86686.84
363.86, 0.00, -38.37, -86696.05
363.88, 0.00, -38.37, -86705.26
363.90, 0.00, -38.37, -86714.47
363.92, 0.00, -38.37, -86723.68
363.94, -0.01, -38.37, -86732.89
363.96, -0.01, -38.38, -86742.10
363.98, -0.01, -38.39, -86751.32
364.00, 0.00, -38.39, -86760.53
364.02, -0.01, -38.40, -86769.75
364.04, -0.01, -38.40, -86778.96
364.06, -0.01, -38.41, -86788.18
364.08, 0.00, -38.41, -86797.40
364.10, 0.00, -38.41, -86806.62
364.12, 0.00, -38.41, -86815.84
364.14, -0.01, -38.41, -86825.06
364.16, 0.00, -38.41, -86834.28
364.18, 0.00, -38.41, -86843.50
364.20, -0.01, -38.41, -86852.71
364.22, -0.02, -38.43, -86861.94
364.24, -0.01, -38.43, -86871.17
364.26, -0.01, -38.44, -86880.39
364.28, 0.00, -38.44, -86889.62
364.30, -0.01, -38.45, -86898.85
364.32, 0.00, -38.45, -86908.07
364.34, 0.00, -38.45, -86917.30
364.36, 0.00, -38.45, -86926.53
364.38, 0.00, -38.45, -86935.75
364.40, 0.00, -38.45, -86944.98
364.42, 0.01, -38.44, -86954.21
364.44, 0.00, -38.44, -86963.43
364.46, 0.00, -38.44, -86972.66
364.48, 0.00, -38.44, -86981.89
364.50, 0.00, -38.44, -86991.11
364.52, 0.00, -38.44, -87000.34
364.54, -0.01, -38.45, -87009.57
364.56, -0.01, -38.45, -87018.79
364.58, 0.00, -38.45, -87028.02
364.60, 0.00, -38.45, -87037.25
364.62, -0.01, -38.46, -87046.47
364.64, 0.00, -38.46, -87055.70
364.66, 0.00, -38.46, -87064.92
364.68, -0.01, -38.46, -87074.16
364.70, 0.00, -38.46, -87083.39
364.72, -0.01, -38.47, -87092.63
364.74, 0.00, -38.47, -87101.86
364.76, 0.00, -38.47, -87111.10
364.78, -0.01, -38.47, -87120.33
364.80, -0.01, -38.48, -87129.57
364.82, 0.00, -38.48, -87138.80
364.84, 0.00, -38.48, -87148.03
364.86, 0.00, -38.48, -87157.27
364.88, 0.00, -38.48, -87166.50
364.90, 0.00, -38.48, -87175.74
364.92, 0.00, -38.48, -87184.97
364.94, 0.01, -38.47, -87194.21
364.96, 0.00, -38.47, -87203.44
364.98, 0.00, -38.47, -87212.67
365.00, 0.00, -38.47, -87221.91
365.02, -0.01, -38.48, -87231.14
365.04, -0.01, -38.48, -87240.38
365.06, 0.00, -38.48, -87249.61
365.08, 0.00, -38.48, -87258.85
365.10, -0.01, -38.49, -87268.08
365.12, 0.00, -38.49, -87277.32
365.14, -0.01, -38.49, -87286.56
365.16, 0.00, -38.49, -87295.80
365.18, 0.00, -38.49, -87305.04
365.20, 0.00, -38.49, -87314.28
365.22, -0.01, -38.50, -87323.53
365.24, -0.01, -38.50, -87332.77
365.26, 0.00, -38.50, -87342.01
365.28, -0.01, -38.51, -87351.25
365.30, 0.00, -38.51, -87360.50
365.32, 0.00, -38.51, -87369.74
365.34, -0.01, -38.51, -87378.98
365.36, 0.00, -38.51, -87388.22
365.38, 0.00, -38.51, -87397.46
365.40, -0.01, -38.52, -87406.71
365.42, -0.01, -38.52, -87415.95
365.44, 0.00, -38.52, -87425.19
365.46, -0.01, -38.53, -87434.44
365.48, 0.00, -38.53, -87443.69
365.50, -0.01, -38.53, -87452.94
365.52, 0.00, -38.53, -87462.19
365.54, -0.01, -38.54, -87471.44
365.56, 0.01, -38.53, -87480.69
365.58, 0.00, -38.53, -87489.94
365.60, -0.01, -38.54, -87499.19
365.62, 0.00, -38.54, -87508.44
365.64, 0.00, -38.54, -87517.69
365.66, -0.01, -38.54, -87526.94
365.68, 0.00, -38.54, -87536.19
365.70, -0.01, -38.55, -87545.44
365.72, 0.00, -38.55, -87554.69
365.74, 0.00, -38.55, -87563.94
365.76, -0.01, -38.55, -87573.19
365.78, 0.00, -38.55, -87582.44
365.80, 0.00, -38.55, -87591.69
365.82, 0.00, -38.55, -87600.94
365.84, 0.00, -38.55, -87610.19
365.86, -0.01, -38.56, -87619.45
365.88, 0.00, -38.56, -87628.71
365.90, -0.01, -38.56, -87637.96
365.92, 0.00, -38.56, -87647.22
365.94, -0.01, -38.57, -87656.48
365.96, 0.00, -38.57, -87665.74
365.98, -0.01, -38.58, -87675.00
366.00, 0.00, -38.58, -87684.25
366.02, 0.00, -38.58, -87693.51
366.04, -0.01, -38.58, -87702.77
366.06, 0.00, -38.58, -87712.03
366.08, 0.00, -38.58, -87721.28
366.10, -0.01, -38.59, -87730.54
366.12, -0.01, -38.59, -87739.81
366.14, -0.01, -38.60, -87749.07
366.16, 0.00, -38.60, -87758.34
366.18, -0.02, -38.61, -87767.60
366.20, -0.01, -38.62, -87776.87
366.22, 0.00, -38.62, -87786.14
366.24, -0.01, -38.62, -87795.40
366.26, 0.00, -38.62, -87804.67
366.28, 0.00, -38.62, -87813.93
366.30, 0.00, -38.62, -87823.20
366.32, -0.01, -38.63, -87832.47
366.34, -0.01, -38.63, -87841.75
366.36, 0.00, -38.63, -87851.02
366.38, -0.01, -38.63, -87860.29
366.40, 0.00, -38.63, -87869.57
366.42, -0.01, -38.64, -87878.84
366.44, 0.01, -38.63, -87888.11
366.46, 0.00, -38.63, -87897.39
366.48, 0.00, -38.63, -87906.66
366.50, 0.00, -38.63, -87915.93
366.52, -0.01, -38.64, -87925.21
366.54, 0.00, -38.64, -87934.48
366.56, 0.00, -38.64, -87943.75
366.58, 0.01, -38.63, -87953.03
366.60, -0.01, -38.64, -87962.30
366.62, -0.01, -38.64, -87971.57
366.64, -0.01, -38.65, -87980.85
366.66, 0.00, -38.65, -87990.12
366.68, 0.00, -38.65, -87999.39
366.70, -0.01, -38.66, -88008.67
366.72, 0.00, -38.66, -88017.96
366.74, 0.00, -38.66, -88027.24
366.76, 0.00, -38.66, -88036.52
366.78, 0.00, -38.66, -88045.80
366.80, 0.00, -38.66, -88055.08
366.82, 0.00, -38.66, -88064.36
366.84, 0.00, -38.66, -88073.64
366.86, 0.00, -38.66, -88082.92
366.88, -0.01, -38.67, -88092.21
366.90, -0.01, -38.67, -88101.49
366.92, 0.01, -38.67, -88110.77
366.94, 0.00, -38.67, -88120.05
366.96, 0.00, -38.67, -88129.33
366.98, 0.00, -38.67, -88138.61
367.00, 0.00, -38.67, -88147.89
367.02, 0.00, -38.67, -88157.17
367.04, -0.01, -38.67, -88166.46
367.06, 0.00, -38.67, -88175.74
367.08, 0.00, -38.67, -88185.02
367.10, 0.00, -38.67, -88194.30
367.12, -0.01, -38.68, -88203.58
367.14, -0.01, -38.68, -88212.86
367.16, 0.00, -38.68, -88222.14
367.18, 0.01, -38.68, -88231.42





they both grow from really small to huge very fast



I was wondering what I could do about that, I was thinking before the array rolls over, to calculate the average velocity and displacement, and max displacement, but it keeps growing and growing
zacharoni16
 
Posts: 25
Joined: Thu Aug 16, 2012 6:21 pm
Location: Washinston, PA

Re: Pothole data smoothing and detection of accelerometer data

by Arctic_Eddie on Thu Feb 07, 2013 8:20 am

I noticed that also when using the random generator. Not sure why that happens other than accumulated drift and noise. A periodic reset of the arrays will probably be necessary.

PS
You could set a limit on the displacement array. When it exceeds some plus or minus value, all arrays get zeroed in their [indeX] position. On the next integration, you would be starting with a zero value which puts you back to local ground level.
Arctic_Eddie
 
Posts: 208
Joined: Tue Feb 28, 2012 6:01 pm
Location: St. Petersburg, FL

Re: Pothole data smoothing and detection of accelerometer data

by Arctic_Eddie on Thu Feb 07, 2013 1:29 pm

Including a reset test will solve the problem. In the #define section, add the first line. In the loop() section, add the second part.

Code: Select all | TOGGLE FULL SIZE
#define DRIFT_LIMIT       1000 // Reset arrays if displacement has drifted more than 1000 feet from zero

    // Insert threshold detector, running average, and reset action here *******************
   
    // Test displacement array and reset all if beyond DRIFT_LIMIT
    if( abs( displacement[indeX] ) > DRIFT_LIMIT )
    {
        acceleration[indeX] = 0.0;
        velocity[indeX]     = 0.0;
        displacement[indeX] = 0.0;
    }
Arctic_Eddie
 
Posts: 208
Joined: Tue Feb 28, 2012 6:01 pm
Location: St. Petersburg, FL

Re: Pothole data smoothing and detection of accelerometer data

by zacharoni16 on Thu Feb 07, 2013 3:00 pm

Wow sweet :), thanks for your hard work, I'll test tonight :)

I was thinking of using some kind of mechanical "floating" scale to try to see what the max displacement I could get hitting a big pothole something that is zero'ed then floats up and down in inches, so I can see where the suspension bottoms out, to set the drift limit.

The displacement is in inches, so I'm assuming anything over say 7 inches or so would bottom out the suspension and be a max value.

I'll try maybe a drift limit of 10 inches, or would it be in feet? In the example above in your code it should be 1000 inches right? from zero
zacharoni16
 
Posts: 25
Joined: Thu Aug 16, 2012 6:21 pm
Location: Washinston, PA

Re: Pothole data smoothing and detection of accelerometer data

by Arctic_Eddie on Thu Feb 07, 2013 4:38 pm

The displacement unit is inches. You could use something around 36" to allow for undulating pavement.
Arctic_Eddie
 
Posts: 208
Joined: Tue Feb 28, 2012 6:01 pm
Location: St. Petersburg, FL

Re: Pothole data smoothing and detection of accelerometer data

by zacharoni16 on Tue Feb 12, 2013 5:23 pm

Thanks for all your help man, I really appreciate it and I will keep you updated on the progress. The incremental calculation for displacement seems to be going out of control.

I decided to use a narrow band-pass filter, and take the ABS of the waveform (rectify) it and further smooth it out.

In labview the results look quite promising:

Image
zacharoni16
 
Posts: 25
Joined: Thu Aug 16, 2012 6:21 pm
Location: Washinston, PA

Re: Pothole data smoothing and detection of accelerometer data

by Arctic_Eddie on Wed Feb 13, 2013 3:28 pm

Were you able to try the periodic reset of all arrays using abs of displacement as the trigger?

The second trace is hard to see with the blue data line.
Arctic_Eddie
 
Posts: 208
Joined: Tue Feb 28, 2012 6:01 pm
Location: St. Petersburg, FL

Re: Pothole data smoothing and detection of accelerometer data

by zacharoni16 on Mon Feb 18, 2013 8:39 pm

Yeah, seems like it isn't working it keeps growing all the way up to the windup guard, 33 inches or so, :/
zacharoni16
 
Posts: 25
Joined: Thu Aug 16, 2012 6:21 pm
Location: Washinston, PA

Re: Pothole data smoothing and detection of accelerometer data

by Arctic_Eddie on Mon Feb 18, 2013 8:53 pm

I guess the next approach to try is the digital filtering you used before, at about 13Hz. Look for a burst exceeding some level and lasting several cycles. You could use the passband Butterworth 3-pole with corner frequencies of 10Hz and 15Hz. Put each new data point into the filter and evaluate the new output value for a threshold.
Arctic_Eddie
 
Posts: 208
Joined: Tue Feb 28, 2012 6:01 pm
Location: St. Petersburg, FL