Speed Detection

Speed detection can be calculated using information about peaks of sensor signal and distance of each sensor.

Speed formula:

$speed = \frac{distance}{time}$

When:

  • distance is the distance between sensors (unit meters);
  • time is the time of the peak on the second sensor minus the time of respectively peak on the first sensor, and so on (unit seconds);
  • speed (unit meters/second).

Algorithm


In [1]:
from IPython.display import display
from matplotlib import pyplot as plt

import numpy as np
import pandas as pd
import peakutils
import sys

# local
sys.path.insert(0, '../')

from pywim.utils import storage
from pywim.utils.stats import iqr
%matplotlib inline

Open Raw Data File (Synthetic)


In [2]:
f = storage.open_file('../data/wim_day_001_01_20170130.h5')
dset = f[list(f.keys())[0]]
df = storage.dataset_to_dataframe(dset)

In [3]:
# information on the file
paddle = len(max(dset.attrs, key=lambda v: len(v)))

print('METADATA')
print('='*80)
for k in dset.attrs:
    print('{}:'.format(k).ljust(paddle, ' '), dset.attrs[k], sep='\t')

df.plot()
plt.show()


METADATA
================================================================================
sample_rate:         	2000
date_time:           	2017-32-30 01:32:11
site_id:             	001
lane_id:             	01
temperature:         	28.5
license_plate:       	AAA9999
calibration_constant:	[ 0.98  0.99  0.75]
sensors_distance:    	[0 1 2]
sensor_type:         	mixed
sensors_layout:      	|||
channel_configuration:	{"a0": "polymer", "a2": "polymer", "a1": "ceramic"}

Speed Estimation


In [4]:
# distance between sensors
sensors_delta_distance = np.array(dset.attrs['sensors_distance'])

# x axis: time
x = df.index.values

sensors_peak_time = []
sensors_delta_time = [None]  

for k in df.keys():
    # y axis: volts
    y = df[k].values
    
    indexes = peakutils.indexes(y, thres=0.5, min_dist=30)
    
    sensors_peak_time.append(x[indexes])
    print('\nPeak time (s) on sensor {}:'.format(k))
    print(x[indexes])

for i in range(1, len(sensors_peak_time)):
    sensors_delta_time.append(sensors_peak_time[i]-sensors_peak_time[i-1])

# the information about first sensor should be equal to the second sensor
sensors_delta_time[0] = sensors_delta_time[1]

print('\nΔtime:')
display(sensors_delta_time)

print('\nΔdistance:', sensors_delta_distance)


Peak time (s) on sensor a0:
[ 0.01153194  0.04211667  0.11180972]

Peak time (s) on sensor a1:
[ 0.03208889  0.06167083  0.13236667]

Peak time (s) on sensor a2:
[ 0.0722      0.10228333  0.17247778]

Δtime:
[array([ 0.02055694,  0.01955417,  0.02055694]),
 array([ 0.02055694,  0.01955417,  0.02055694]),
 array([ 0.04011111,  0.0406125 ,  0.04011111])]
Δdistance: [0 1 2]

In [5]:
sensors_delta_speed = []

for i in range(len(sensors_delta_distance)):
    sensors_delta_speed.append(sensors_delta_distance[i]/sensors_delta_time[i])

# the information about first sensor should be equal to the second sensor
sensors_delta_speed[0] = sensors_delta_speed[1]

print('\nΔspeed:')
display(sensors_delta_speed)


Δspeed:
[array([ 48.6453618 ,  51.13999574,  48.6453618 ]),
 array([ 48.6453618 ,  51.13999574,  48.6453618 ]),
 array([ 49.86149584,  49.24592182,  49.86149584])]

In [6]:
speed_values = np.array([])

for sensor_speeds in sensors_delta_speed[1:]:
    speed_values = np.concatenate((speed_values, sensor_speeds))

print('Speed values with rejecting outliers:')
display(speed_values)

speed = iqr.reject_outliers(pd.Series(speed_values)).mean()
print('Speed average: {} (m/s)'.format(speed))


Speed values with rejecting outliers:
array([ 48.6453618 ,  51.13999574,  48.6453618 ,  49.86149584,
        49.24592182,  49.86149584])
Speed average: 49.56660547499004 (m/s)