Reputation: 337
I have a program that connects to a bluetooth accelerometer and reads that data to determine motion in real time and I'm trying to figure out how to smooth out the noise so I can better represent the motion. I found a scipy function for a butterworth filter (pardon my ignorance on filters) but it seems like it only works when you have the whole plot as it looks at the points before and after to smooth noise. How can I smooth out noise dynamically? Here's my code:
def animator():
global xyz
fig = plt.figure()
xyz_mot = fig.add_subplot(111, projection = "3d")
xyz_mot.set_title("Motion")
xyz_mot.set_xlim3d(-100, 100)
xyz_mot.set_ylim3d(-100, 100)
xyz_mot.set_zlim3d(-100, 100)
xyz = xyz_mot.scatter(0,0,0)
ani = FuncAnimation(fig, updateAni, frames=2, interval=50)
fig.show()
def updateAni(i):
t = float(time_data[-1] / 1000)**2
xmot[0] = .5 * acceleration_data[-1].x * t
ymot[0] = .5 * acceleration_data[-1].y * t
zmot[0] = .5 * acceleration_data[-1].z * t
xyz._offsets3d = (xmot, ymot, zmot)
#print("X Motion: " + str(xmot) + ", Y Motion: " + str(ymot))
#print(time_data[-1])
The accelerometer data and time data are being added to the arrays acceleration_data
and time_data
from another thread. Is there a matplotlib/some other library function to smooth noise? Any help is appreciated
Upvotes: 2
Views: 296
Reputation: 11075
Instead of adding the raw acceleration data to acceleration_data
from your secondary thread, I'd filter the data there by using a buffer to constantly take the average of the last several measurements. Without your code for the thread, I can only give you some pseudo-code, but this should give you an idea of how it would work.:
import collections
def thread_func():
buf = collections.deque(maxlen=10) #take the average of up to the last 10 samples
while True:
accel = bluetooth_device.read()
buf.append(accel)
if buf: #may want to make sure the buffer isn't empty first to prevent devide by 0
acceleration_data.append(sum(buf)/len(buf))
Upvotes: 1
Reputation: 1032
Look at running data through an exponential averaging or moving average filter. The exponential average allows you to trade off averaging verse speed with alpha parameter. Filter the raw data from the accelerometer before adding to the output array.
The following snippet implements simple exponential avererager
avg = alpha * x + (1 - alpha) * x_prev
x_prev = x
buffer.append(avg)
Upvotes: 2