| [yh, B, A, errors]=hand_arm_time_fil(y, Fs, B, A, settling_time, resample_filter)
|
function [yh, B, A, errors]=hand_arm_time_fil(y, Fs, B, A, settling_time, resample_filter)
% % hand_arm_time_fil: Calculates the hand arm vibrations filter coefficients and returns the filtered time record
% %
% % Syntax;
% %
% % [yh, B, A, errors]=hand_arm_time_fil(y, Fs, B, A, settling_time, resample_filter)
% %
% % ********************************************************************
% %
% % Description
% %
% % Calculates the hand arm vibrations filter coefficients and returns the
% % filtered time record.
% %
% %
% % There are two options for the downsampling filters to optimize
% % performance for continuous signals or for impulsive signals.
% % For continuous noise the time domain does not have significant
% % impulses; however, for impulsive time records there are often very
% % large impulses with distinctive peaks.
% %
% % There are two antialiasing filters and interpolation schemes available.
% % The first program is the built-in Matlab "resample" progam which
% % uses a Kaiser window fir filter for antialising and uses an unknown
% % interpolation method. The second program available for downsampling
% % is bessel_down_sample which uses a Bessel filter for antialiasing
% % and uses interp with the cubic spline option for interpolation.
% %
% % The resample function has good antialising up to the Nyquist frequency;
% % however, it has significant ringing effect when there are impulses.
% % The bessel_down_sample function has good antialising; however, there is
% % excessive attenuation near the Nyquist frequency.
% % The bessel_down_sample function experiences no ringing due to impulses
% % so it is very useful for peak estimation.
% %
% %
% % The input and output variables are described in more detail in the
% % sections below respectively.
% %
% %
% % ********************************************************************
% %
% % Input Variables
% %
% % y=randn(10000, 10) % multichannel input time record in (Pa).
% % % Processsing assumes that y has more channels
% % % than time record samples.
% % % default is y=randn(10000, 10);
% %
% % Fs=50000; % (Hz) sampling rate in Hz.
% % % default is 50000 Hz.
% %
% % B is an array of feedforward filter coefficients for the hand arm vibration
% %
% % A is an array of feedback filter coefficients for the hand arm vibration
% % % frequency weighting filter.
% % % default is B=1; A=1; The program recalculates
% % % B and A if the input values are not numeric,
% % % are empty, or have a length less than 4.
% %
% % settling_time=0.1; % (seconds) is the time it takes the filter to
% % % settle (seconds).
% % % default is settling_time=0.1;
% %
% % resample_filter=1; % type of filter to use when resamling
% % % 1 resample function Kaiser window fir filter
% % % 2 Bessel filter
% % % otherwise resample function Kaiser window fir
% % % filter
% % % default is resample_filter=1; (Kaiser window)
% %
% % ********************************************************************
% %
% % Output Variables
% %
% % yh is the time record which has been filtered by the hand arm
% % vibration frequency filter.
% %
% % B is an array of feedforward filter coefficients for hand arm
% % vibration frequency weighting filter.
% %
% % A is an array of feedback filter coefficients for hand arm
% % vibration frequency weighting filter.
% %
% % errors indicates whether the resampled sampling rate is within the
% % tolerance of 5000 Hz. Within tolerance 0 is output.
% % outside of tolerance 1 is output.
% %
% % **********************************************************************
%
%
% Example='1';
%
% % An exaple with 1 channels of vibrations data
%
% y=randn(1, 50000);
% Fs=10000;
% B=1;
% A=1;
% settling_time=1;
%
% [yh, B, A, errors]=hand_arm_time_fil(y, Fs, B, A, settling_time);
%
% % Plot the results
% t_vibs=1/Fs*(0:(50000-1));
% subplot(2,1,1);
% plot(t_vibs, y);
% title('Unweighted Time Record');
% hold on;
% subplot(2,1,2);
% plot(t_vibs, yh);
% title('Weighted Time Record');
%
% % ********************************************************************
% %
% % This program requires the Matlab Signal Processing Toolbox
% %
% %
% % List of Dependent Subprograms for
% % hand_arm_time_fil
% %
% % FEX ID# is the File ID on the Matlab Central File Exchange
% %
% %
% % Program Name Author FEX ID#
% % 1) bessel_antialias Edward L. Zechmann
% % 2) bessel_digital Edward L. Zechmann
% % 3) bessel_down_sample Edward L. Zechmann
% % 4) convert_double Edward L. Zechmann
% % 5) filter_settling_data3 Edward L. Zechmann
% % 6) geospace Edward L. Zechmann
% % 7) get_p_q2 Edward L. Zechmann
% % 8) hand_arm_fil Edward L. Zechmann
% % 9) LMSloc Alexandros Leontitsis 801
% % 10) match_height_and_slopes2 Edward L. Zechmann
% % 11) remove_filter_settling_data Edward L. Zechmann
% % 12) resample_interp3 Edward L. Zechmann
% % 13) rms_val Edward L. Zechmann
% % 14) sub_mean2 Edward L. Zechmann
% %
% %
% % ********************************************************************
% %
% % Program Modified by Edward L. Zechmann
% %
% % created June 2007
% %
% % modified 3 September 2008 Updated comments
% %
% % modified 10 December 2008 Upgraded to include
% % filter settling and resampling.
% %
% % modified 16 December 2008 Use convolution to simplify filter
% % coefficients (B1, B2, A1, A2) into
% % arrays B and A.
% %
% % Finished modifications to support
% % filter settling and resampling.
% %
% % modified 19 December 2008 Updated comments
% %
% % modified 5 January 2009 Added sub_mean to remove running
% % average using a a number of averages
% % per second at one-half the lowest
% % frequency band of interest(1 Hz).
% %
% % modified 9 October 2009 Updated Comments
% %
% % modified 9 July 2010 Added an option to resample using a
% % Bessel Filter. Updated comments.
% %
% % modified 4 August 2010 Updated Comments
% %
% %
% %
% %
% % ********************************************************************
% %
% % Please Feel Free to Modify This Program
% %
% % See Also: hand_arm_fil, vibs_calc_hand_arm
% %
if nargin < 1 || isempty(y) || ~isnumeric(y)
y=randn(10, 10000);
end
if nargin < 2 || isempty(Fs) || ~isnumeric(Fs)
Fs=10000;
end
if nargin < 3 || isempty(B) || ~isnumeric(B)
B=1;
end
if nargin < 4 || isempty(A) || ~isnumeric(A)
A=1;
end
% Hand-arm vibrations require a longer filter settling time than for sound
% because the important frequencies are at least an order of magnitude
% lower.
if (nargin < 5 || isempty(settling_time)) || ~isnumeric(settling_time)
settling_time=1;
end
if (nargin < 6 || isempty(resample_filter)) || ~isnumeric(resample_filter)
resample_filter=1;
end
if ~isequal(resample_filter, 2)
resample_filter=1;
end
% Remove the running average from the signal.
% The number of averages per second can be about one-tenth the lowest
% frequency to resolve. For hand-arm vibrations, the lowest frequency to
% resolve according to ISO 5349-1 is 1.0 Hz
[y]=sub_mean2(y, Fs, 0);
% % ********************************************************************
% %
% set the flag for indicating whether to resample
flag0=0;
max_freq=60000;
min_freq=5000;
if Fs <= max_freq
p=1;
q=1;
Fsn=Fs;
errors=0;
else
[Fsn, p, q, errors]=get_p_q2(Fs, max_freq, min_freq);
end
if ~isequal(Fsn, Fs)
flag0=1;
end
% % ********************************************************************
% %
[num_samples, num_channels]=size(y);
% set the flag for indicating whether to transpose
flag1=0;
% Transpose the data so that the filters act along the time records
% not along the channels.
if num_samples < num_channels
flag1=1;
y=y';
[num_samples, num_channels]=size(y);
end
if (nargin < 4) || (logical(length(B) < 4) || logical(length(A) < 4)) || logical(~isnumeric(B) || ~isnumeric(A))
[B, A]=hand_arm_fil(Fsn);
end
% % ********************************************************************
%
% Downsample the data to a reasonable sampling rate to keep the hand arm
% vibrations filters as stable as possible.
if isequal(flag0, 1)
% Adding filter settling data
num_data_pts=num_samples;
[y11, num_settle_pts]=filter_settling_data3(Fs, y(:, 1), settling_time);
% Downsampling
if isequal(resample_filter, 1)
buf=resample(y11, p, q);
else
[buf]=bessel_down_sample(y11, Fs, Fs*p/q, settling_time);
end
% removing filter settling data
[buf]=remove_filter_settling_data(buf, q/p, num_settle_pts, num_data_pts, 0);
n2=length(buf);
y2=zeros(n2, num_channels);
y2(:, 1)=buf;
clear('buf');
if num_channels > 1
for e1=2:num_channels;
% Adding filter settling data
[y11, num_settle_pts]=filter_settling_data3(Fs, y(:, e1), settling_time);
% Downsampling
if isequal(resample_filter, 1)
buf=resample(y11, p, q);
else
[buf]=bessel_down_sample(y11, Fs, Fs*p/q, settling_time);
end
% removing filter settling data
[buf]=remove_filter_settling_data(buf, q/p, num_settle_pts, num_data_pts, 0);
y2(:, e1)=buf;
end
end
else
y2=y;
end
clear('y');
% % ********************************************************************
%
% Apply the hand-arm weighting filters to each channel of data
yh=zeros(size(y2));
for e1=1:num_channels;
% Adding filter settling data
num_data_pts=length(y2(:, e1));
[y11, num_settle_pts]=filter_settling_data3(Fsn, y2(:, e1), settling_time);
% Apply the hand-arm vibrations filters
buf = real(filter(B, A, y11 ));
% Remove the settling data from the time record.
[buf]=remove_filter_settling_data(buf, 1, num_settle_pts, num_data_pts, 2);
yh(:, e1)=buf;
end
% % ********************************************************************
%
% Resample if necessary so the output has the same size as the input
if isequal(flag0, 1)
% Adding filter settling data
num_data_pts=length(yh(:, 1));
[y11, num_settle_pts]=filter_settling_data3(Fs, yh(:, 1), settling_time);
% Upsampling
if isequal(resample_filter, 1)
buf=resample(y11, q, p);
else
t_in=q/p*1/Fs*(-1+(1:length(y11)));
[buf]=resample_interp3(y11, t_in, 1/Fs);
[buf]=bessel_antialias(buf, Fs, Fs/2.5, settling_time);
end
% removing filter settling data
[buf]=remove_filter_settling_data(buf, q/p, num_settle_pts, num_data_pts, 1);
num_samples2=length(buf);
yhh=zeros(num_samples2, num_channels);
yhh(:, 1)=buf;
clear('buf');
if num_channels > 1
for e1=2:num_channels;
% Adding filter settling data
num_data_pts=length(yh(:, 1));
[y11, num_settle_pts]=filter_settling_data3(Fs, yh(:, e1), settling_time);
% Upsampling
if isequal(resample_filter, 1)
buf=resample(y11, q, p);
else
t_in=q/p*1/Fs*(-1+(1:length(y11)));
[buf]=resample_interp3(y11, t_in, 1/Fs);
[buf]=bessel_antialias(buf, Fs, Fs/2.5, settling_time);
end
% removing filter settling data
[buf]=remove_filter_settling_data(buf, q/p, num_settle_pts, num_data_pts, 1);
yhh(:, e1)=buf;
end
end
else
yhh=yh;
end
clear('yh');
% % ********************************************************************
%
% Append the data to the output variable
if isequal(flag0, 1)
if num_samples2 > num_samples
num_samples2=num_samples;
end
yh=yhh(1:num_samples2, 1:num_channels);
else
yh=yhh(1:num_samples, 1:num_channels);
end
% % ********************************************************************
%
% Output yh must have the same size as the original input matrix y.
% Transpose yh if necessary.
if isequal(flag1, 1)
yh=yh';
end
|
|