I have a transfer function that I am trying to use to filter acceleration data.
So far I have been able to use lsim with a sin wave over about 10 seconds and I'm getting the result I expect. However, I cannot work how to get data to the function in real time.
To clarify, every 0.1 seconds I am receiving an acceleration value from an external program. I need to filter the values to remove high frequency variations in the data. I need this to occur for each data point I receive as I then use the current filtered acceleration value into additional processing steps.
How do I use the transfer function in continuously and update the output value each time new data is received?
This is an example of how to do this with filter:
filter_state = []; % start with empty filter history
while not_stopped()
x = get_one_input_sample();
[y, filter_state] = filter(B, A, x, filter_state);
process_one_output_sample(y);
end;
Note that you need to use the extended form of filter, in which you pass the history of the filter from one iteration to the next using the variable filter_state. The B and A are the coefficients of your discrete filter. If your filter is continuous, you need to transform it to a discrete filter first using c2d or so. Note that if your filter is very complex, you might need to split up the filtering in several steps (e.g. one second-order-stage per filter) to avoid numerical problems.
Related
I'm trying to breakdown how bandpass function makes the filtering and stumped upon this line (after the filter is created).
y = signal.internal.filteringfcns.filterData(x,opts);
x is the data and opts has the filter structure.
I've been looking around and haven't been able to find anything about signal.internal.filteringfcns.filterData function. I compared that output with filter(opts.FilterObject,x) and they are not the same.
Next is a minimal working example (data2.txt).
load('data2.txt')
srate=64;
freqrange=[0.4 3.5];
var{1}=freqrange;
var{2}=srate;
m=numel(data2);
x=data2;
R=0.1;%10% of signal
Nr=50;
NR=min(round(m*R),Nr);%At most 50 points
x1=2*x(1)-flipud(x(2:NR+1));%maintain continuity in level and slope
x2=2*x(end)-flipud(x(end-NR:end-1));
x=[x1;x;x2];
opts=signal.internal.filteringfcns.parseAndValidateInputs(x,'bandpass',var);
opts = designFilter(opts);
xx = signal.internal.filteringfcns.filterData(x,opts);
x_fil=xx(NR+1:end-NR);
xx = filter(opts.FilterObject,x);
x_fil2=xx(NR+1:end-NR);
plot([data x_fil x_fil2])
legend('raw','filterData','filter')
Here is the plot:
And here are the psd plot of both filtered signal (filtData first).
So, any help on this ...filtData function or I doing something wrong in my analysis?
Hi again :) If you type edit signal.internal.filteringfcns.filterData, you can even look at what is inside this filterData function. You will see that this function (depending on the options opts) will either,
right zero pad the signal with N/2 zeros and call filter
call filtfilt with the signal
This is also described in the docs of bandpass. So probably this zero padding explains why your output of filter(opts.FilterObject,x) is different.
You cannot find this function described in the documentation of Matlab since it is part of the internal functions of the signal processing toolbox.
Im trying to do some calculations in a Matlab (R2015b) Simulink function block. I use a signal that gives discrete values in 1-minute intervals.
What i want to do is store the signal values of 1 day (1440 values), convert them into a vector and input it in my Matlab function for calculation (getting time between first and last value > x). All while the simulation is running.
Unit delay, and Transport delay blocks wont work because i need all the stored values at once.
Any ideas on this are much appreciated!
Thanks!
You need to add a "To Workspace" block to your simulink diagram. Setting the options as you wish will allow you to save all the outputs in a single vector. You can select the variable's name, and the default is "simout".
Then, after running the diagram, you have the variable you want in the workspace (as if you had typed it in the console). So next, you can call your function with the argument.
I am using both MATLAB and LabVIEW for Lab of course of control systems engineering and I want to implement a block diagram(system) in MATLAB and also in LabVIEW
Front panel shows "time response parametric data" which contains 6 parameters fields including settling time ,but i also need settlingMin and settlingMax which are provided/shown in MATLAB by using command stepinfo but i couldn't find a way how to get these two parameters settlingMax and settlingMin in LabVIEW.
Here is MATLAB code
clc
clear all
close all
sys1=tf([10],[1 1])
sys2=tf([1],[2 0.5])
sys_series=series(sys1,sys2)
sys_feedback=feedback(sys_series,0.1)
sys=series(540,sys_feedback)
sys_cl=feedback(sys,1,-1)
step(sys_cl)
stepinfo(sys_cl)
Download link LabVIEW VI
Comparing the help for the LabVIEW VI you are using with the help for the MATLAB function it seems obvious that MATLAB's SettlingMax is the same as LabVIEW's Peak Value in the Time Response Parametric Data cluster, while SettlingMin is the minimum value of the time response signal after Peak Time.
To get the latter value it looks as if you need to:
use CD Get Time Response Data to get the time points and response signal as DBL arrays - I assume Input and Output are both 0 since you have only one signal
use Search 1D Array with the time point array and the Peak Time value to get the array index of the peak time
use Array Subset to select the part of the response array from that index onwards (leave length unwired)
use Array Max & Min to get the minimum value of this array
I'm interested in understanding the variety of zeroes that a given function produces with the ultimate goal of identifying the what frequencies are passed in high/low pass filters. My idea is that finding the lowest value zero of a filter will identify the passband for a LPF specifically. I'm attempting to use the [hz,hp,ht] = zplane(z,p) function to do so.
The description for that function reads "returns vectors of handles to the zero lines, hz". Could someone help me with what a vector of a handle is and what I do with one to be able to find the various zeros?
For example, a simple 5-point running average filter:
runavh = (1/5) * ones(1,5);
using zplane(runavh) gives an acceptable pole/zero plot, but running the [hz,hp,ht] = zplane(z,p) function results in hz=175.1075. I don't know what this number represents and how to use it.
Many thanks.
Using the get command, you can find out things about the data.
For example, type G=get(hz) to get a list of properties of the zero lines. Then the XData is given by G.XData, i.e. X=G.XData.
Alternatively, you can only pull out the data you want
X=get(hz,'XData')
Hope that helps.
Does anyone know if it is possible to pass previous output valuess to an FIR filter in Matlab? I would like to do this because I have masses of data (>300Gb) which I would like to filter and down sample. If I use a standard [b,a] set of coefficients in a an FIR function then the first few samples will be incorrect because they depend on the initial conditions.
This is the problem because I would like to filter my large data set by taking smaller chunks of it but if I do it using the standard way then at the beginning of every chunk there will be error (which will propagate through due to it being an FIR filter).
Any ideas will be much appreciated!
filter command can take initial conditions as input and return final conditions as second output. You need to use these to filter smaller chunks of your data. For example,
b = fir1(10, 0.5);
Zi = zeros(numel(b)-1,1);
while moreData
[y Zi] = filter(b, 1, data, Zi);
end
If you have DSP System toolbox, you can also dsp.DigitalFilter System object which will manage the states for you. For example, the above code can become
b = fir1(10, 0.5);
h = dsp.DigitalFilter('TransferFunction', 'FIR (all zeros)', 'Structure', 'Direct form transposed', 'Numerator', b);
while moreData
y = step(h, data);
end
You could use the 'zi', 'zf' features of the 'filter' command:
http://www.mathworks.com/help/techdoc/ref/filter.html
This allows you to set the initial conditions of the filter.
In such cases, you can use filtfilt, which implements a zero-phase filtering, i.e., it processes the data once forward and once backward, resulting in no net delay. However, you should note that the effective filter order is double that of what is specified by b.
Here's an example from the documentation (the plot has been modified):
x=ecg(500)'+0.25*randn(500,1); %'#noisy waveform
h=fdesign.lowpass('Fp,Fst,Ap,Ast',0.15,0.2,1,60);
d=design(h,'equiripple'); %#Lowpass FIR filter
y=filtfilt(d.Numerator,1,x); %#zero-phase filtering
y1=filter(d.Numerator,1,x); %#conventional filtering
figure(1)
h=plot([x y y1]);
set(h(1),'color',[0.8,0.8,0.8])
title('Filtered Waveforms');
legend('Original waveform', 'Zero-phase Filtering','Conventional Filtering');