Issues with creating a frequency weighting filter for a iso-standard
이전 댓글 표시
Hello! I want to mention in the beginning that i am new to signal processing with MATLAB.
I am currently working on weighting a vibration simulation and some acceleration data. The standard I am using for the weighting gives the filter functions using the Laplace variable. The three functions that are used are a high pass & low pass filter, and lastly an a-v transition filter (pic included)

For this the band limiting i use butterworth filters, which i think should be equal to the first function. For the transfer function i use the bilinear tool to get filter coefficients using the info from the standard, and then i filter the signal using all three filters.
It is worth mentioning that the simulation i use gives a displacement value (time series) where i use FFT and thereafter differentiate twice in fourier domain to get a acceleration value. After that i weigh the signal with the weighting filter below. Am i doing this in the correct order? Lastly i convert to dB and plot and this is the result:

I am pretty sure that the filter fails at weighing correctly according to the standard. For example, the weighting factor that is multiplied with the acceleration at f = 100 Hz should be 0.160, and in the plot they are almost the same.
Here is the code:
function filtered_signal=Wh_weighting(acceleration_signal,Fs)
%Purpose: to weight an acceleration signal with Wh weighting, for hand arm
%vibrations
%Input: The time series acceleration signal and the sampling frequency of
%the signal
%Output: The filtered signal using Wh filtering according to ISO 8041 and
%Iso 5349
%Constants from SS_EN_ISO_8041_1_2017 page 12 table 3 Wh
f1=10^.8;
w1=2*pi*f1;
f2=10^3.1;
w2=2*pi*f2;
f3=100/2/pi;
f4=f3;
Q1=1/sqrt(2);
Q2=Q1;
Q4=0.64;
w3=2*pi*f3;
w4=2*pi*f4;
%The nyquist limit
nyqusit_limit=Fs/2;
%A second order highpass filter for band limiting of the signal, b1 and a1
%are coefficients of the highpass filter transfer function in z domain.
[b1,a1]=butter(2,f1/nyqusit_limit,'high');
%A second order lowpass filter for band limiting of the signal. b2 and a2
%are coefficients of the lowpass filter transfer function in z domain.
[b2,a2]=butter(2,f2/nyqusit_limit,'low');%low pass filter
%Frequency weighting filter
%This filter uses the coeffcients described in ISO 5349-1 (commented is ISO 8041) equation (3) in S
%domain and transforms its coeeficients to z-domain using the bilinear
%transform. So A3 and B3 are s-domain coeffcients and a3 and b3 are
%z-domain coefficients.
%B3=[1/w3 1];
B3 = [2*pi*f4^2 f3*(2*pi*f4)^2];
%A3=[1/w4/w4 1/Q4/w4 1];
A3 = [f3 2*pi*f4*f3/Q4 f3*(2*pi*f4)^2];
[b3,a3]=bilinear(B3,A3,Fs);%a-v transition filter
%Here the signal is filtered several times by different filter to give an
%overall filtering.
%the input signal is first filtered with the low pass filter
filtered_signal=filter(b2,a2,acceleration_signal);
% the output of line 44 is then filtered again with the highpass filter
filtered_signal=filter(b1,a1,filtered_signal);
%lastly the signal is filtered with the frequency weighting filter
filtered_signal=filter(b3,a3,filtered_signal);
%filtered_signal=filter(b3,a3,acceleration_time_series_signal);
% rms(filtered_signal) gives the declaration value a_hw for a mono axial
% vibration
end
Am i implementing this totaly wrong maybe?
Thank you in advance for any help received :)
댓글 수: 12
I cannot easily follow the code, or determine what relationship
have to ‘Fs’.
have to ‘Fs’. f1=10^.8;
w1=2*pi*f1;
f2=10^3.1;
w2=2*pi*f2;
f3=100/2/pi;
f4=f3;
Q1=1/sqrt(2);
Q2=Q1;
Q4=0.64;
w3=2*pi*f3;
w4=2*pi*f4;
Fs = 65536; % Using Plots For Reference, Assuming Nyquist Freq = 250
B3 = [2*pi*f4^2 f3*(2*pi*f4)^2];
%A3=[1/w4/w4 1/Q4/w4 1];
A3 = [f3 2*pi*f4*f3/Q4 f3*(2*pi*f4)^2];
[b3,a3]=bilinear(B3,A3,Fs);%a-v transition filter
figure
freqz(B3, A3, 2^16, Fs)
I am not posting this as an nswer becausse I am not certain that I understand the question.
EDIT — (16 Apr 2023 at 21:06)
Corrected ‘Fs’, and re-ran code.
.
Elias Jakobsson
2023년 4월 16일
Star Strider
2023년 4월 16일
The bliniear approach appears to be appropriate and the implementation correct, however I fail to understand the rest of it.
Most filters do not amplify (some active filters may amplify, although that is not common practice) so the filtered signals have magnitudes that are never greater than the filter passbands.
I find it interesting that what appear to be the orange magnitude functions end at different frequencies (perhaps 105 to 175 Hz) while the frequency of the blue signals go out to 250 Hz. That indicates to me that the filters are not created with the same sampling frequency as the signal (assuming that the frequency upper limits are the Nyquist frequencies of the various filters and signals).
I am not certain that your approach is wrong, simply that the filters and signals may be inconsistent in the sampling frequencies used to create the filters. The sampling frequencies supplied to the filters need to be consistent with the sampling frequencies of the signals they are to work with for the filters to operate correctly.
Elias Jakobsson
2023년 4월 16일
Star Strider
2023년 4월 16일
I do not see anything wrong with the posted code. The lowpass call to create ‘filtered_signal’ is appropriate, although I prefer 'ImpulseResponse','iir' to design an efficient elliptic filter.
My concern is that
and
must be supplied with the same sampling frequency as the signal they are being used to filter. That value of ‘Fs’ needs to be derived from the sampling frequency of each signal in order for the filters to work correctly with it. (If all the signals have the same sampling frequency, then one filter design will work for all of them.)
must be supplied with the same sampling frequency as the signal they are being used to filter. That value of ‘Fs’ needs to be derived from the sampling frequency of each signal in order for the filters to work correctly with it. (If all the signals have the same sampling frequency, then one filter design will work for all of them.) If the signal sampling frequency — the consecutive sampling inteervals — are not constant, use the resample function to make them constant. (This is required for most signal processing techniques, the only exception I am aware of being the nufft function.) Then use that sampling frequency to design the filters and use those filters to process the resampled signals.
.
Elias Jakobsson
2023년 4월 16일
Star Strider
2023년 4월 17일
The resample function works in the time domain, so you have to use the time domain vectors with it. I am not certain what those are here, however that needs to be done first.
[sr,tr] = resample(s,t,Fs); % ‘s’ & ‘t’ Are The Original Signal & Time Vectors, ‘sr’ & ‘tr’ Are The Resampled Versions
Then, do all the signal processing (fft, filtering, and anything else) on the resampled signals.
.
Elias Jakobsson
2023년 4월 17일
Star Strider
2023년 4월 17일
I am not certain what the plots are. It could help to plot the original signal fft, the filter Bode plots, and the frequency domain of the filtered signal. I still do not understand what you are doing with respect to designing the filters in the context of the signals.
Elias Jakobsson
2023년 4월 17일
편집: Elias Jakobsson
2023년 4월 17일
Star Strider
2023년 4월 17일
Your explanation helps. I still have a problem with the filtered signal plots, since in the filter passband the signal should be the same as the unfiltered signal. Only in the stopbands should it be different, and significantly attenuated. That does not appear to be the situation, if I understand the plots correctly.
The Bode plots produced by the freqz function show the magnitude and phase response of the filter at the plotted frequencies. They should be the same as the filter design parameters, essentially being a ‘quality control¹ for the filter design.
Elias Jakobsson
2023년 4월 17일
편집: Elias Jakobsson
2023년 4월 17일
답변 (1개)
Star Strider
2023년 4월 17일
0 개 추천
The sampling frequency can be anything that you determine to be appropriate for the system you are integrating. The highest frequency in the signal (and I do not know what that is) should be less than the Nyquist frequency, creating the sampling frequency to be at least 2.5 times the highest frequency in the signal, and higher if possible.
Since you are creating your data with an ode45 (or similar functions) integration of your system, the easiest way to create consistent sampling intervals (the inverse of the sampling frequency) is to define ‘tspan’ as a vector of more than two elements. For example to create a time vector from 0 to 1000 seconds (or whatever time span you are using) with a sampling frequency of 5000, something like this will work:
Fs = 5000; % Sampling Frequency (Hz)
Tlen = 1000; % Signal Length (sec)
tspan = linspace(0, Tlen*Fs, Tlen*Fs+1)/Fs; % ‘tspan’ Vector
The integration will still be adaptive, however the results will be interpolated and will only be reported at the times corresponding to the multiple-element ‘tspan’ vector. There will likely be no need to do any resampling.
Now that you have the signal and a specific sampling frequency for it, all the filters can be created with that sampling frequency. They should then produce the result you want. The passbands and stopbands can be defined with respect to the Nyquist frequency (and they all must be less than the Nyquist frequency) so for example using this sampling frequency (5000):
Fn = Fs/2; % Nyquist Frequency
BandpassFreqs = [100 250]/Fn; % Normalised Frequencies
I am posting this as an answer because it might actually be the solution to this problem.
.
댓글 수: 4
Elias Jakobsson
2023년 4월 17일
The Control System Toolbox makes defining and realising these filters straightforward.
Returning too the original definitions —

I copied that to here for convenience.
Coding the filters are then straightforward —
format long
Fs=65536; %Sample rate
Fn = Fs/2;
f1=6.310/Fn; % Normalise The Frequency By The Nyquist Frequency
w1=2*pi*f1;
f2=1258.9/Fn; % Normalise The Frequency By The Nyquist Frequency
w2=2*pi*f2;
f3=15.915/Fn; % Normalise The Frequencies By The Nyquist Frequency
f4=f3;
Q1=1/sqrt(2);
Q2=Q1;
Q4=0.64;
w3=2*pi*f3;
w4=2*pi*f4;
K = 1;
Ts = 1/Fs; % Sampling Interval
opts = bodeoptions; % For The 'bodeplot' Plots
opts.FreqUnits = 'Hz';
s = tf('s');
Hb = (s^2*pi^2*f2^2) / ((s^2 + 2*pi*f1*s/Q1 + 4*pi^2*f1^2)*(s^2 + 2*pi*f2*s/Q1 + 4*pi^2*f2^2))
figure
bodeplot(Hb, opts)
grid
Hbz = c2d(Hb, Ts, 'tustin')
Hbzn = Hbz.Numerator
Hbzd = Hbz.Denominator
Hw = ((s + 2*pi*f3)*2*pi*K*f4^2) / ((s^2 + 2*pi*f4*s/Q2 + 4*pi^2*f4^2)*f3)
figure
bodeplot(Hw, opts)
grid
Hwz = c2d(Hw, Ts, 'tustin')
Hwzn = Hwz.Numerator
Hwzd = Hwz.Denominator
If you have the Control System Toolbox, you can run this code offline. If you do not have it, and if you want to change anything in my code, you can run it here in a Comment, and then once the post is submitted, you can copy the numerator and denominator vectors from it (as you can here, after I post this). You can then delete that Comment if you want to. I did my best to proofread this, however there could still be errors that I did not catch, so please check it.
Use these numerator and denominator vectors inside the square brackets (copy the square brackets as well and ignore the curly braces) as the transfer function vectors for the Signal Processing Toolbox filters. No further processing should be necessary for them. (The 'tustin' method is the same as the 'bililnear' method.)
.
Elias Jakobsson
2023년 4월 18일
The sampling frequency may be too high to produce reliable filters. Is that high a sampling frequency absolutely required, or is it possible to use perhaps a tenth of that?
Although the Control System Toolbox bodeplot plots were encouraging, I am not happy with the way the filters are transferring to the discrete domain, so i tried with the Symbolic Math Toolbox as well to see if I could improve on the result.
I am unfortunately not encouraged —
Fs=65536; %Sample rate
Fn = Fs/2;
f1=6.310/Fn; % Normalise The Frequency By The Nyquist Frequency
w1=2*pi*f1;
f2=1258.9/Fn; % Normalise The Frequency By The Nyquist Frequency
w2=2*pi*f2;
f3=15.915/Fn; % Normalise The Frequencies By The Nyquist Frequency
f4=f3;
Q1=1/sqrt(2);
Q2=Q1;
Q4=0.64;
w3=2*pi*f3;
w4=2*pi*f4;
K = 1;
Ts = 1/Fs;
acceleration_signal = randn(Fs*5,1);
% s = tf('s');
syms s
Hb = (s^2*pi^2*f2^2) / ((s^2 + 2*pi*f1*s/Q1 + 4*pi^2*f1^2)*(s^2 + 2*pi*f2*s/Q1 + 4*pi^2*f2^2));
Hb = simplify(Hb, 500)
[Hbn,Hbd] = numden(Hb)
Hbn = double(sym2poly(Hbn))
Hbd = double(sym2poly(Hbd))
[B1,A1] = bilinear(Hbn,Hbd,Fs)
figure
freqz(B1,A1, 2^16, Fs)
set(subplot(2,1,1), 'XLim',[0 2])
set(subplot(2,1,2), 'XLim',[0 2])
Hw = ((s + 2*pi*f3)*2*pi*K*f4^2) / ((s^2 + 2*pi*f4*s/Q2 + 4*pi^2*f4^2)*f3);
Hw = simplify(Hw, 500)
[Hwn,Hwd] = numden(Hw)
Hwn = double(sym2poly(Hwn))
Hwd = double(sym2poly(Hwd))
[B3,A3] = bilinear(Hwn,Hwd,Fs)
figure
freqz(B3,A3, 2^16, Fs)
set(subplot(2,1,1), 'XLim',[0 2])
set(subplot(2,1,2), 'XLim',[0 2])
return % Stop Here
Hbz = c2d(Hb, Ts, 'tustin');
Hbzn = Hbz.Numerator;
Hbznv = cell2mat(Hbzn);
Hbzd = Hbz.Denominator;
Hbzdv = cell2mat(Hbzd);
Hw = ((s + 2*pi*f3)*2*pi*K*f4^2) / ((s^2 + 2*pi*f4*s/Q2 + 4*pi^2*f4^2)*f3);
Hwz = c2d(Hw, Ts, 'tustin');
Hwzn = Hwz.Numerator;
Hwznv = cell2mat(Hwzn);
Hwzd = Hwz.Denominator;
Hwzdv = cell2mat(Hwzd);
% I made them into vectors directly with cell2mat
B1 = Hbznv;
A1 = Hbzdv;
B3 = Hwznv;
A3 = Hwzdv;
[sos1,g1] = tf2sos(B1,A1)
[sos3,g3] = tf2sos(B3,A3)
figure
freqz(B1,A1, 2^16, Fs)
set(subplot(2,1,1), 'XLim',[0 2])
set(subplot(2,1,2), 'XLim',[0 2])
figure
freqz(sos1, 2^16, Fs)
set(subplot(2,1,1), 'XLim',[0 2])
set(subplot(2,1,2), 'XLim',[0 2])
figure
freqz(B3,A3, 2^16, Fs)
figure
freqz(sos3, 2^16, Fs)
filtered_signal=filtfilt(sos1,g1,acceleration_signal);
filtered_signal=filtfilt(sos3,g3,filtered_signal);
I need to be away for a while. I will return to this later.
.
카테고리
도움말 센터 및 File Exchange에서 Multirate Signal Processing에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!









