How to calculate differential of scattered data?
10 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Ying Wu
el 15 de Dic. de 2022
Hi, I have time sertis of two signals, one is y, one is Cl, and I'd like to calculate the first and second derivative of these two signals.
Now I use the following code (the dataset has been attached):
dy = gradient(y)./gradient(time);
dCl = gradient(Cl)./gradient(time);
ddy = gradient(dy)./gradient(time);
ddCl = gradient(dCl)./gradient(time);
But when I use the data to plot phase-plane, the results look weird.
X1 = [y, dy, ddy];
X2 = [Cl, dCl, ddCl];
figure(1)
patch([X1(:,1);nan], ...
[X1(:,2);nan], ...
[X1(:,3);nan], ...
[X1(:,1)+X1(:,2);nan],...
'EdgeColor','interp','Marker','none','MarkerFaceColor','flat','LineWidth',0.8,'FaceAlpha',1);
view(3);
figure(2)
patch([X2(:,1);nan], ...
[X2(:,2);nan], ...
[X2(:,3);nan], ...
[X2(:,1)+X2(:,2);nan],...
'EdgeColor','interp','Marker','none','MarkerFaceColor','flat','LineWidth',0.8,'FaceAlpha',1);
view(3);
I'd like to determine the intersection between curve of y-dy (down figure) or Cl-dCl (up figure) with z=0 plane, but the ddCl varies above and below frequently around z=0, so the intersection cannot be identified, like figures attached.
Is there any problem during the data processing procedure?
Thanks!
1 comentario
Askic V
el 15 de Dic. de 2022
Well, you need to use some kind of filter. If you just do first order approximation of derivation (also called the Euler method), it will just increase the noise in the data.
Please have a look at this small example:
dt = 0.1; % step size (sec)
t_dur = 10; % total t_dur
t = 0:dt:t_dur;
y_pure = sin(t);
std_dev = 0.1;
y_noise = y_pure + std_dev*randn(size(t));
subplot(4,1,1)
plot(t,y_pure)
title('Pure signal')
dy= gradient(y_pure)./gradient(t);
subplot(4,1,2)
plot(t,dy)
title('Derivation of pure signal');
subplot(4,1,3)
plot(t,y_noise)
title('Signal with noise');
dy_noise = gradient(y_noise)./gradient(t);
subplot(4,1,4)
plot(t,dy_noise)
title('Derivation of noisy signal');
As you can see, you are amost not able to recognize that the last signal is cos(t).
So if the data contains noise (and most likely it is always the case), some kind of filtering must be applied.
I think most propriate for these applications would be kalman filtering, but I hope some more experience will jump to help.
Respuesta aceptada
Askic V
el 15 de Dic. de 2022
Editada: Askic V
el 15 de Dic. de 2022
Okay, here's what I do in order to avoid calculating derivation on the discrete data, especially when I know that they represent position, velocity and acceleration.
In fact, I used very similar code (Kalman filter implementation), when I had real measured position values (using MDT sensors), but I needed to calculate velocity and acceleration in order to use feed forward control.
dt = 0.1; % step size (sec)
t_dur = 15; % total t_dur
t = 0:dt:t_dur;
y_pure = sin(t);
dy_pure = cos(t);
ddy_pure = -sin(t);
std_dev = 0.05; % Std. deviation of Gauss noise
y_noise = y_pure + std_dev*randn(size(t)); % add noise to the signal
% Calculate velocity and acceleration
% using gradient or diff on the discrete data
dy_noise = gradient(y_noise)./gradient(t);
ddy_noise = gradient(dy_noise)./gradient(t);
dt = 0.1; % step size (sec)
t_dur = 15; % total t_dur
t = 0:dt:t_dur;
y_pure = sin(t);
dy_pure = cos(t);
ddy_pure = -sin(t);
std_dev = 0.05; % Std. deviation of Gauss noise
y_noise = y_pure + std_dev*randn(size(t)); % add noise to the signal
% Calculate velocity and acceleration
% using gradient or diff on the discrete data
dy_noise = gradient(y_noise)./gradient(t);
ddy_noise = gradient(dy_noise)./gradient(t);
% plot data
subplot(3,1,1)
plot(t,y_pure);
hold on
plot(t,y_noise,'r')
legend('pure signal', 'noisy signal');
subplot(3,1,2)
plot(t,dy_pure)
hold on
plot(t, dy_noise)
legend('pure velocity', 'calculated (noisy) velocity');
subplot(3,1,3)
plot(t,ddy_pure)
hold on
plot(t,ddy_noise)
legend('pure acc', 'calculated (noisy) acc');
% Now implement and apply Kalman filter
T = dt;
% State space model of a system
% dx/dt = A*x, y = C*x;
A = [1 T T^2/2
0 1 T;
0 0 1];
C = [1 0 0];
% process variance
Q = 0.1*[T^4/4 T^3/2 T^2/2;
T^3/2 T^2 T;
T^2/2 T 1];
% sensor noise variance
R = std_dev^2;
% initial state estimate variance
P0 = [ 1 0 0
0 1 0
0 0 1];
% Initial value of state vector
% x(1) - position
% x(2) - velocity
% x(3)- accelerartion
x = [0;1;1];
% Design filter
P = P0;
N = length(y_noise);
xhat_array = zeros(3, N);
for i = 1:N
xp = A*x;
Pp = A*P*A' + Q;
S = C*Pp*C' + R;
K = Pp*C' / S;
residual = y_noise(i) - C*xp;
x = xp+K*residual;
P = Pp - K*C*Pp;
xhat_array(:,i) = x;
end
figure
subplot(2,1,1)
% Plot noisy velocity
plot(t, dy_noise)
hold on
% Plot filtered velocity
plot(t, xhat_array(2,:),'r');
% Plot ideal velocity
plot(t, dy_pure,'g');
legend('Noisy velocity', 'Filered velocity', 'Ideal velocity');
% Plot noisy acceleration
subplot(2,1,2);
plot(t, ddy_noise)
hold on
% Plot filtered acceleration
plot(t, xhat_array(3,:),'r');
hold on
% Plot ideal acceleration (pure)
plot(t, ddy_pure,'g');
legend('Noisy acc', 'Est./Filt. acc', 'Ideal acc.');
Basically, instead of calculating derivatives using the Euler method (or by definition), you should use estimation techniques such as Kalman filtering. Kalman filter is optimal linear state estimator. You can see from the example, how even small amount of noise on the original data can practically totally corrupt the calculated derivations (especially second derivation i.e. acceleration).
Derivations always tend to amplify the noise.
If you're interested I suggest searching for prof. Dan Simon and his excellent book "Optimal State Estimation".
I hope this will be useful to you (and probably others).
4 comentarios
Más respuestas (0)
Ver también
Categorías
Más información sobre Vibration Analysis en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!