115 líneas
3.6 KiB
Matlab
Original Blame Histórico

Este archivo contiene caracteres Unicode ambiguos

Este archivo contiene caracteres Unicode que pueden confundirse con otros caracteres. Si crees que esto es intencional, puedes ignorar esta advertencia. Usa el botón de Escape para revelarlos.

% === Problem 3a: Effect of Noise on Parameter Estimation ===
clear; close all;
% True system parameters
m = 0.75;
L = 1.25;
c = 0.15;
g = 9.81;
mL2_true = m * L^2;
mgL_true = m * g * L;
theta_true = [mL2_true; c; mgL_true];
% Load clean data
data = readtable('output/problem1_data.csv');
t = data.t;
q_clean = data.q;
u = data.u;
Ts = t(2) - t(1);
N = length(t);
% Derivatives from clean q
dq_clean = zeros(N,1);
ddq_clean = zeros(N,1);
for k = 2:N-1
dq_clean(k) = (q_clean(k+1) - q_clean(k-1)) / (2*Ts);
ddq_clean(k) = (q_clean(k+1) - 2*q_clean(k) + q_clean(k-1)) / Ts^2;
end
% LS estimation on clean data
X_clean = [ddq_clean, dq_clean, q_clean];
theta_hat_clean = (X_clean' * X_clean) \ (X_clean' * u);
rel_error_clean = abs((theta_hat_clean - theta_true) ./ theta_true) * 100;
% Reconstruct q̂_clean
q_hat_clean = zeros(N, 1);
dq_hat_clean = zeros(N, 1);
q_hat_clean(1) = q_clean(1);
dq_hat_clean(1) = dq_clean(1);
for k = 2:N
ddq_hat_clean_k = (1/theta_hat_clean(1)) * ...
(u(k-1) - theta_hat_clean(2)*dq_clean(k-1) - theta_hat_clean(3)*q_clean(k-1));
dq_hat_clean(k) = dq_hat_clean(k-1) + Ts * ddq_hat_clean_k;
q_hat_clean(k) = q_hat_clean(k-1) + Ts * dq_hat_clean(k-1);
end
% === Loop over noise levels ===
noise_levels = [0.001, 0.0025];
for i = 1:length(noise_levels)
noise_std = noise_levels(i);
q_noisy = q_clean + noise_std * randn(size(q_clean));
% Derivatives from noisy q
dq_noisy = zeros(N,1);
ddq_noisy = zeros(N,1);
for k = 2:N-1
dq_noisy(k) = (q_noisy(k+1) - q_noisy(k-1)) / (2*Ts);
ddq_noisy(k) = (q_noisy(k+1) - 2*q_noisy(k) + q_noisy(k-1)) / Ts^2;
end
% LS estimation on noisy data
X_noisy = [ddq_noisy, dq_noisy, q_noisy];
theta_hat_noisy = (X_noisy' * X_noisy) \ (X_noisy' * u);
rel_error_noisy = abs((theta_hat_noisy - theta_true) ./ theta_true) * 100;
% Reconstruct q̂_noisy
q_hat_noisy = zeros(N,1);
dq_hat_noisy = zeros(N,1);
q_hat_noisy(1) = q_noisy(1);
dq_hat_noisy(1) = dq_noisy(1);
for k = 2:N
ddq_hat_noisy_k = (1/theta_hat_noisy(1)) * ...
(u(k-1) - theta_hat_noisy(2)*dq_noisy(k-1) - theta_hat_noisy(3)*q_noisy(k-1));
dq_hat_noisy(k) = dq_hat_noisy(k-1) + Ts * ddq_hat_noisy_k;
q_hat_noisy(k) = q_hat_noisy(k-1) + Ts * dq_hat_noisy(k-1);
end
% Print results
fprintf('\n--- Noise std = %.4f ---\n', noise_std);
fprintf('Clean: mL2=%.4f (%.2f%%), c=%.4f (%.2f%%), mgL=%.4f (%.2f%%)\n', ...
theta_hat_clean(1), rel_error_clean(1), ...
theta_hat_clean(2), rel_error_clean(2), ...
theta_hat_clean(3), rel_error_clean(3));
fprintf('Noisy: mL2=%.4f (%.2f%%), c=%.4f (%.2f%%), mgL=%.4f (%.2f%%)\n', ...
theta_hat_noisy(1), rel_error_noisy(1), ...
theta_hat_noisy(2), rel_error_noisy(2), ...
theta_hat_noisy(3), rel_error_noisy(3));
% === Combined plot ===
figure('Name', sprintf('Noise std = %.4f', noise_std), 'Position', [100, 100, 1000, 800]);
subplot(2,1,1);
plot(t, q_clean, 'b', ...
t, q_hat_clean, 'g--', ...
t, q_hat_noisy, 'r:');
legend('Actual q(t)', 'Estimated (clean)', 'Estimated (noisy)');
title(sprintf('Estimated Output (σ = %.4f)', noise_std));
ylabel('q(t) [rad]');
grid on;
subplot(2,1,2);
bar([rel_error_clean, rel_error_noisy]);
set(gca, 'XTickLabel', {'mL^2', 'c', 'mgL'});
legend({'No Noise', sprintf('With Noise (σ=%.4f)', noise_std)}, 'Location', 'northwest');
ylabel('Relative Error [%]');
title('Estimation Error');
grid on;
% Save figure
filename = sprintf('output/Prob3a_NoiseStd%.4f.png', noise_std);
saveas(gcf, filename);
end