Tuesday, February 19, 2013

Detecting speed bumps with accelerometer

Somebody came in from the internet some months ago and asked whether speed bumps (also called sleeping policemen) can be detected with an Android phone. You know, speed bumps like this:

I was cautious because there's a lot of traps here. Obviously the detected signal will differ depending on the form factor of the speed bump, the type of the car and even the way the phone is fixed to the car (or the lack of fixing). But I was also curious and as car-related phone applications are very fashionable today, I took the challenge. Meanwhile the guy who brought up the problem disappeared so I feel free to share what I achieved during the last one and half months.

The solution that I produced is far from perfect. First and foremost, I did not make any effort to target other phones than my trusty Nexus S. Phones which have sampling frequency of around 50 Hz in SENSOR_DELAY_FASTEST mode will work fine, significantly different sampling frequencies are not supported. It is more important, however, that I was not able to create a foolproof algorithm for the problem.

Initially I thought that some sort of rotation could be measured when the front of the car is lifted by the speed bump but I was not able to detect this rotation from the sensor signal. The car generates all sorts of vibrations and it is not easy to extract this relatively small rotation from the noisy background. So I went back to the acceleration spike which is generated when the car hits the bump and I used just the acceleration's absolute value as described in this presentation. The trouble is that this spike is pretty reminiscent of a class of other spikes like knocks, etc. For example here is a beautiful double street bump somewhere in Budapest.

One would think that signals like these could be easily detected. Now comes, however, a bumpy road with potholes, also typical in Budapest.

There are no street bumps in the second signal but the potholes generate "knocks" that are hard to distinguish from the "knocks" caused by street bumps.

There is no perfect solution to this problem, at least I could not find any. Eventually I obtained the best result by calculating the cross-correlation between the acceleration signal and a pre-recorded speed bump signal. I re-sampled this representative signal for +/- 10% of its initial frequency and calculated the cross-correlation with all the three variants (initial, +10% frequency, -10% frequency). Then I used a sliding window to calculate the power of the cross-correlation signal. This is the pre-recorded sample I used for cross-correlation:

Cross-correlating then calculating the power in a sliding window yields this signal for the double speed bump (different colors show the power of the 3 variants of the re-sampled signal):

And this is the result of the same calculation for the bumpy road:

Using a limit of about 150, the two signals can be separated and no fake bumps are detected even on the bumpy road.

Click here to download the example program.

There are a lot of problems with this approach. First, speed bumps come in all shapes and sizes and this method can detect speed bumps that are similar to the one used to generate the reference signal. Then there is the problem of the car itself. I did not have the chance to test with a lot of different cars but I bet the different suspension systems will yield drastically different signals in different car types. Anyway, I thought somebody may find this post and this post can start some thinking.


Alexander Kosenkov said...

You should consider driver's behavior too!

Almost all drivers will actually slow down in front of those bumps (it's their goal anyways). So, instead of looking just at the acceleration magnitude, check its projections too.

It might look like:
- slowing down (acceleration towards driving direction)
- stopping slowing down (common good practice to unload front wheels)
- front wheels bump and high osscilations
- rear wheels bump and lower osscilations
- car acceleration

Gabor Paller said...

Alexander: I my tests it was a suburban setting. So I drove quite slowly, say 30km/h and slowed down to about 10 km/h before the speed bumps (that I knew very well). That's a speed difference of about 20 km/h, about 5.5 m/s. But the deceleration phase took more than 1 sec - hard to estimate, let it be about 3 sec. That yields an acceleration of about 1.8 m/s^2.

I checked my samples and acceleration in random direction of about 1 m/s^2 was quite common in my samples. The car was shaking on the road because it was not perfectly smooth. In short: I was not able to extract that horizontal negative acceleration (the slowing down) from the noisy background caused by vibrations.

Maybe we can redefine the task so that we are interested only in dangerous passing of speed bumps. Then we can assume much larger deceleration and "knock".

Tejaswini Mayigowda said...


I am using LIS3DH accelerometer to detect Harsh acceleration and Harsh breaking.

The device is working for Harsh breaking perfectly but i am facing difficulty in Harsh acceleration,
With this bump,elevation's are appearing, How to remove the bump?
if i increase interrupt duration of my device i can able to detect only Harsh breaking,i cant detect HA.
Please suggest me for this problem??

Gabor Paller said...

Tejaswini, are you placing the device casually (in any position relative to the car) or do you have the possibility to fix the device to the car? E.g. usual handsfree kits fix the device in such a way that the device's Z axis points more or less to the main axis of the car (axis of driving). In this case the accelerating/braking acceleration can be measured only on the Z axis of the device and road problems (potholes, etc.) would cause acceleration only on the Y axis.

I don't understand your reference to the interrupt duration.

Sandra Johnson said...

Wow! There are way too many close calls and tragedies that could be prevented by drivers doing the right thing. Thanks for sharing your post!!
speed bumps

Ahmad Ali said...

Hi everyone can anyone give me bump detection algorithm?

Kevin said...


Amazing work with the Speed Bump detection! :)
I just have a couple of questions:
1. How did you obtain the perfect pre-recorded speed bump signal?
2. Is it possible to obtain a similar pre-recorded signal for detecting potholes, and filter out the speed bumps?

Gabor Paller said...

Hi, Kevin,

My experiments with car vibrations were summarized in this presentation (starting from slide 34) My conclusion is that road damage detection is quite possible but the general detection of speed bump is not feasible. The difference is between the two is the behavior of the driver: while road damage normally happens to driver unprepared (this means that you have a nice, strong acceleration signal which is bad news to the car's suspension system but good news for our detection algorithm), speed bump is normally approached carefully which results in a small acceleration signal which is hard to detect in the vibration cacophony of the car. Of course, if you assume that the driver gets through the speed bump with full speed, without slowing down then the situation is different but not many of us have drive permits for tanks. :-)

Regarding the capture problem, I shared some capture programs (like in this post, the post also refers to an app on Google Play that has the capture functionality). Also, I shared the data capture application I used in many of these car experiments.

Kevin said...

Thanks for the quick reply! Helped reinforce my confidence in my endeavour :)

I just have one more question, which might sound a little stupid. The pre-recorded signal that you have used, contains positive as well as negative values. However, in your application code, you take the amplitude value of the acceleration sensor (Root(x^2+y^2+z^2)) which is always a positive value, and compare it to the pre-recorded signal. Have you just taken the actual z-axis vibrations as your pre-recorded signal, or is there some other calculation I am missing? Because if I use the amplitude of the pre-recorded signal, I will always get a positive value.

Gabor Paller said...

Kevin, this issue is discussed briefly in this blog post. You are right that if the phone is fixed so that its Z axis corresponds to the vertical axis then only the Z axis should be considered. However, I took the habit in earlier experiments (mostly human movements) not to assume anything about the position of the phone because it may be positioned in any way wrt. the human body. The situation is similar in the car too. E.g. the phone may be correctly positioned so that its Z axis corresponds to the vertical axis - if the car does not tilt. If it does, then the phone's Z axis is not vertical anymore but the gravity vector always is. So I used the simplification that I look for the amplitude and don't deal with the direction of the vibration.

Karthick said...

Hi Gabor Paller Are u detecting the car acceleration using android accelerometer?

Gabor Paller said...

Karthick, the post is about vertical acceleration ("vibration") and yes, I detect this kind of acceleration using the Android accelerometer. If you are interested in the motion acceleration, I recommend the car's speedometer, click here for a post or click here for a presentation.

Harsh said...

What is bw_0_9 bw_1_0 .. in code?

Gabor Paller said...

Harsh: bw_0_9, etc. are the resampled variants of the prerecorded speed bump signal whose graph can be found in the post (below the text "This is the pre-recorded sample I used for cross-correlation"). The signal was slowed down (bw_0_9) in case the car crosses the speed bump more slowly than the case when the reference signal was recorded. bw_1_0 is the original signal and bw_1_1 is the case when the signal was sped up to simulate when the car crosses the speed bump faster. As the post says, this way of measurement is not very efficient, see the continuation of this saga here.