01-18-2015 10:10 PM
I need to compute a smoother derivative signal for a hardware control system. More specifically, I need to implement velocity control with feedback from a differentiated measured position signal.
I would like to use a moving average of about 20-50 data points, and take the derivative of that smoothed signal over that time (at ~35kHz, about 0.5ms~1.5ms.
I use LabView real time almost daily, but I only do a little bit of FPGA coding. Nothing I've tried so far works on the FPGA. Can someone refer me to some example code for a moving average derivative? I have seen example code for computing a derivative with ~3~5 data points, but not with anything higher.
Thanks!
01-19-2015 02:12 PM - edited 01-19-2015 02:14 PM
Basically you need to maintain a circular buffer with the last 50 values of your signal. If you have to access all values in the history. If you are doing a simple moving average, look at this
that's a 64 point moving average of a fixed point number. You need to size accumulator's FXP correctly based on number history length.
If you want a better way to get the derivative, do some research on the Savitski-Golay filter, which is in LabVIEW. The beauty of it is you can use it to get a less noisy derivative, and use to get the 1st, 2nd, nth derivative easily. I have used it to great success in real-time code. To implement in FPGA you will prob need to use block memory though.
01-19-2015 04:42 PM
Or you could just use a regular IIR filter, and just set the degree of smoothing through the filter time constant. You can play around with the exact filter design (Chebychev,/Butterworth, their order) to trade off phase shift against complexity, which you might find useful since using within a feedback control loop. Might be worth you reading up on IIR vs FIR (Wikipedia has some useful pointers) as which is best depends upon your application.
01-19-2015 09:58 PM
IME to remove enough noise to get smooth derivative data, the amount of averaging has to be so high, or the cutoff freq of your IRR lowpass filter so low, that in the process you also remove a lot of your derivative information, thereby making your derivative signal useless again. More averaging slows the response of the signal, giving you a derivative that is too slow and delayed from the real system.
I found the SV filter to be a good way way out of this predicament... your mileage may vary.