You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

117 lines
3.2 KiB

  1. %
  2. % Problem 1b: Lyapunov-based Parameter Estimation
  3. %
  4. clear
  5. % True system parameters
  6. m_true = 1.315;
  7. b_true = 0.225;
  8. k_true = 0.725;
  9. % Simulation parameters
  10. Ts = 0.001;
  11. T_total = 40;
  12. t = 0:Ts:T_total;
  13. N = length(t);
  14. % Gamma setup
  15. gamma = 0.66;
  16. fprintf('Using gamma = %.4f (Lyapunov Based Estimation)\n', gamma);
  17. % Define sine input only (as per problem statement)
  18. u = 2.5 * sin(t);
  19. % Simulate the true system
  20. x = zeros(1, N);
  21. dx = zeros(1, N);
  22. ddx = zeros(1, N);
  23. x(1) = 0; dx(1) = 0;
  24. for k = 1:N-1
  25. f = @(x_, dx_, u_) (1/m_true) * (u_ - b_true * dx_ - k_true * x_);
  26. k1 = f(x(k), dx(k), u(k));
  27. k2 = f(x(k) + Ts/2 * dx(k), dx(k) + Ts/2 * k1, u(k));
  28. k3 = f(x(k) + Ts/2 * dx(k), dx(k) + Ts/2 * k2, u(k));
  29. k4 = f(x(k) + Ts * dx(k), dx(k) + Ts * k3, u(k));
  30. ddx(k) = k1;
  31. dx(k+1) = dx(k) + Ts/6 * (k1 + 2*k2 + 2*k3 + k4);
  32. x(k+1) = x(k) + Ts * dx(k);
  33. end
  34. ddx(1:end-1) = diff(dx) / Ts;
  35. ddx(end) = ddx(end-1);
  36. % Estimation using Lyapunov structure
  37. phi_all = [ddx; dx; x]; % shape: [3 x N]
  38. theta_hat = zeros(3, N);
  39. theta_hat(:, 1) = [1; 1; 1];
  40. for k = 1:N-1
  41. phi = phi_all(:,k);
  42. y = u(k);
  43. y_hat = theta_hat(:,k)' * phi;
  44. e = y - y_hat;
  45. theta_hat(:,k+1) = theta_hat(:,k) + Ts * gamma * e * phi;
  46. end
  47. % Final estimates
  48. fprintf('\nFinal estimates:\n');
  49. fprintf('Estimated m: %.4f, b: %.4f, k: %.4f\n', theta_hat(1,end), theta_hat(2,end), theta_hat(3,end));
  50. % Plot results
  51. figure('Name', 'Lyapunov Estimation (notes form)', 'Position', [100, 100, 1280, 860]);
  52. sgtitle(sprintf('Input: sine | Gamma = %.3f | Lyapunov', gamma), 'FontWeight', 'bold');
  53. subplot(3,1,1);
  54. plot(t, theta_hat(1,:), 'b', 'LineWidth', 1.5);
  55. ylabel('$$\hat{m}(t)$$ [kg]', 'Interpreter', 'latex');
  56. grid on; title('Εκτίμηση μάζας');
  57. subplot(3,1,2);
  58. plot(t, theta_hat(2,:), 'r', 'LineWidth', 1.5);
  59. ylabel('$$\hat{b}(t)$$ [Ns/m]', 'Interpreter', 'latex');
  60. grid on; title('Εκτίμηση απόσβεσης');
  61. subplot(3,1,3);
  62. plot(t, theta_hat(3,:), 'k', 'LineWidth', 1.5);
  63. ylabel('$$\hat{k}(t)$$ [N/m]', 'Interpreter', 'latex');
  64. xlabel('t [sec]');
  65. grid on; title('Εκτίμηση ελαστικότητας');
  66. if ~exist('output', 'dir')
  67. mkdir('output');
  68. end
  69. saveas(gcf, sprintf('output/Prob1b_lyapunov_gamma%.3f_%ds.png', gamma, T_total));
  70. % Reconstruct estimated output x_hat(t)
  71. x_hat = zeros(1, N);
  72. dx_hat = zeros(1, N);
  73. dx_hat(1) = 0;
  74. for k = 1:N-1
  75. m_hat = theta_hat(1,k);
  76. b_hat = theta_hat(2,k);
  77. k_hat = theta_hat(3,k);
  78. ddx_hat = (u(k) - b_hat * dx_hat(k) - k_hat * x_hat(k)) / m_hat;
  79. dx_hat(k+1) = dx_hat(k) + Ts * ddx_hat;
  80. x_hat(k+1) = x_hat(k) + Ts * dx_hat(k);
  81. end
  82. e_x = x - x_hat;
  83. % Plot extra figure with x, x_hat and e_x
  84. figure('Name', 'System Response vs Estimation', 'Position', [100, 100, 1280, 860]);
  85. sgtitle(sprintf('System Response and Error | Gamma = %.3f', gamma), 'FontWeight', 'bold');
  86. subplot(2,1,1);
  87. plot(t, x, 'b', t, x_hat, '--r', 'LineWidth', 1.5);
  88. legend('x(t)', 'x_{hat}(t)', 'Location', 'Best');
  89. ylabel('Θέση [m]');
  90. grid on; title('Αντίδραση Συστήματος και Εκτίμηση');
  91. subplot(2,1,2);
  92. plot(t, e_x, 'k', 'LineWidth', 1.5);
  93. ylabel('e_x(t)');
  94. grid on; title('Σφάλμα θέσης: x(t) - x_{hat}(t)');
  95. saveas(gcf, sprintf('output/Prob1b_extrastates_gamma%.3f_%ds.png', gamma, T_total));