115 linhas
3.6 KiB
Matlab
Original Anotar Histórico

This file contains ambiguous Unicode characters

Este arquivo contém caracteres Unicode que podem ser confundidos com outros caracteres. Se você acha que isso é intencional, pode ignorar esse aviso com segurança. Use o botão Escapar para revelá-los invisible_runes_line=`Esta linha tem caracteres unicode invisíveis

% === 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