I want to detect jerk from accelerator data i.e. values beyond 1.57 m/s^2, but due to the high frequency nature of the sensor (400 values per second), it gives multiple jerks instead of one. How can I solve this?
I do not need more jerk updates as it gives many false positives. If accelerometer value breaches 1.57m/s^2 and comes back below it I consider that a jerk.
Problem that I want to solve is build a android app that uses accelerometer data to detect faults on railway tracks.
I am resorting to someone's advise and doing bandpass filtering and then Hilbert transform on the data then use find peaks function , is this correct approach if so how to proceed further ; if not do suggest one.
Multiple peaks is what i mean i.e. multiple local maximas instead of one.
I am building a mobile based real time accelerometer Oscillation Monitoring System.
The csv of all data contains x,y,z accelerometer value,jerk time in UTC,latitude , longitude of real time train journey: https://drive.google.com/file/d/1k47ScyTRr7tr9ZCbSPfHdYApCy53s0E7/view?usp=sharing
The plots are in form of html which are exported from plotly kindly download them and them open on remote machine.
Plot of raw accelerometer data :https://drive.google.com/file/d/1cuJhjrpvvvN1BIDIxn_tBeo2Yyn4Blab/view?usp=sharing
The first step,is a bandpass filter between 0.3 to 12 Hz (Plot):
def bandpass(signal): fs = 380 lowcut = 0.3 highercut = 12.0 nyq = 0.5 * fs low = lowcut/nyq high = highercut/nyq order = 2 b , a = scipy.signal.butter(order,[low,high],'bandpass',analog=False) y = scipy.signal.filtfilt(b,a,signal,axis=0) return(y)
Followed by an envelope detector,of which I have compared RMS and Hilbert(Plot): https://drive.google.com/file/d/19cL8kZuh5hvB0AW5zKAKZy0uTBlaMVJS/view?usp=sharing
def hilbert_transform(x, N=None, axis=-1): x = np.asarray(x) if np.iscomplexobj(x): raise ValueError("x must be real.") if N is None: N = x.shape[axis] if N <= 0: raise ValueError("N must be positive.") Xf = fft(x, N, axis=axis) h = np.zeros(N, dtype=Xf.dtype) if N % 2 == 0: h = h[N // 2] = 1 h[1:N // 2] = 2 else: h = 1 h[1:(N + 1) // 2] = 2 if x.ndim > 1: print("Hello World") ind = [np.newaxis] * x.ndim ind[axis] = slice(None) h = h[tuple(ind)] x = ifft(Xf * h, axis=axis) return x
def window_rms(a, window_size): a2 = np.power(a,2) window = np.ones(window_size)/float(window_size) return np.sqrt(np.convolve(a2, window, 'valid'))
I need to build a jerk detector, by merging the envelope of several peaks caused by an event (Any value above 1.57 m/s^2 is considered a peak).
Last part is where I am getting stuck.
I have tried peak detection of scipy , have not got right result.
plt.rcParams["figure.figsize"] = (20,12) # plt.plot(x) # For zooming # plt.ylim(4500, 5000) plt.plot(envelope2) plt.axhline(1.57) peaks, _ = find_peaks(envelope2, prominence =1.57) # BEST! plt.plot(peaks, envelope2[peaks], "xr") plt.legend(['RMS'], loc='upper left') plt.show()
Used zero crossing
zero_crosses_rate = np.nonzero(np.diff(envelope > 1.57)) print(zero_crosses_rate,envelope[zero_crosses_rate]) # printing original list print("The original list : " + str(zero_crosses_rate)) # Using list slicing # Separating odd and even index elements odd = zero_crosses_rate[::2] even = zero_crosses_rate[1::2] # print result print(odd) print(envelope2[odd]) print(even) print(envelope2[even]) print("even bigger then odd that is considered jerk")
Also use modified Zscore , same could not understand, so could not work with it.
All in all consider me a lay man willing to follow guidance and learn with open mind seeking help.