filename = 'DATA_MOTOR_N4SID2_4000.csv';
data = readtable(filename);
Warning: Column headers from the file were modified to make them valid MATLAB identifiers before creating variable names for the table. The original column headers are saved in the VariableDescriptions property.
Set 'VariableNamingRule' to 'preserve' to use the original column headers as table variable names.
dt = 0.001; % tiempo de muestreo
AngularSpeed = data.("AngularSpeed");
% Conversión de los datos
Varmc = 22.18; Wc = 3.27; Wmax = 4000; Varmax = 24;
Varm = (Varmc / 870) * Varm;
RPMc = Varmc * (Wmax / Varmax);
mAngularSpeed = 0.0049 * (RPMc / Wc);
AngularSpeed = 0.0049 * AngularSpeed * (RPMc / Wc);
AngularSpeed = AngularSpeed * (2 * pi / 60); % rad/s
% Graficar entradas suavizadas
% Gráfica 1: Voltaje de Armadura
fig1 = figure('Color', 'w');
plot(Varm, 'k-', 'LineWidth', 2); hold on;
xlabel('Muestras', 'Color', 'k');
ylabel('V_{arm} [V]', 'Color', 'k');
set(gca, 'XColor', 'k', 'YColor', 'k', 'GridColor', 'k', 'GridAlpha', 0.2, 'Color', 'w');
lgd1 = legend('Mediciones');
set(lgd1, 'TextColor', 'k', 'Color', 'w', 'EdgeColor', 'k');
% Gráfica 2: Velocidad Angular
fig2 = figure('Color', 'w');
plot(AngularSpeed, 'k-', 'LineWidth', 2); hold on;
xlabel('Muestras', 'Color', 'k');
ylabel('Velocidad Angular [rad/s]', 'Color', 'k');
set(gca, 'XColor', 'k', 'YColor', 'k', 'GridColor', 'k', 'GridAlpha', 0.2, 'Color', 'w');
lgd2 = legend('Mediciones');
set(lgd2, 'TextColor', 'k', 'Color', 'w', 'EdgeColor', 'k');
%% 6. Configuración de la Simulación
dt = 0.001; % Tiempo de muestreo [s]
t_step = 1.5; % Duración de cada voltaje [s]
voltajes = [10, 15, 20, 17, 23, 21, 13, 24, 19]; % Secuencia de entrada [V]
total_steps = length(voltajes);
t_total = total_steps * t_step;
% Vectores de almacenamiento
w_nl = zeros(size(time)); % Velocidad No Lineal
w_lin = zeros(size(time)); % Velocidad Lineal
V_in = zeros(size(time)); % Entrada de voltaje
% Condiciones iniciales = Punto de equilibrio
%% 7. Bucle de Simulación
% Determinar qué voltaje toca según el tiempo
current_step_index = floor(time(i) / t_step) + 1;
if current_step_index > length(voltajes)
current_step_index = length(voltajes);
V_act = voltajes(current_step_index);
% --- DINÁMICA NO LINEAL (SINDy)---
dw_nl = c1*V_act + c2*w_nl(i) + c3*V_act^2 + ...
c4*V_act*w_nl(i) + c5*w_nl(i)^2;
w_nl(i+1) = w_nl(i) + dw_nl * dt;
% --- DINÁMICA LINEAL (Aproximación realizada) ---
% dw_lin = A * (delta_w) + B * (delta_V)
dw_l = A * (w_lin(i) - w_eq) + B * (V_act - Varm);
w_lin(i+1) = w_lin(i) + dw_l * dt;
V_in(end) = V_in(end-1); % Ajuste final para gráfica
error = abs(w_nl - w_lin);
%% 8. Gráficas y Análisis
fig = figure('Color', 'w', 'Position', [300, 300, 2600, 2200]);
% Subplot 1: Voltaje de Entrada
plot(time, V_in, 'k-', 'LineWidth', 2); hold on;
yline(Varm, 'g--', 'LineWidth', 1.5);
title('Entrada', 'Color', 'k');
xlabel('Tiempo [s]', 'Color', 'k');
ylabel('V_{arm} [V]', 'Color', 'k');
set(gca, 'XColor', 'k', 'YColor', 'k', 'GridColor', 'k', 'GridAlpha', 0.2, 'Color', 'w');
lgd1 = legend('V_{entrada}', 'Entrada de Equilibrio (20V)');
set(lgd1, 'FontSize', 5, 'TextColor', 'k', 'Color', 'w', 'EdgeColor', 'k');
% Subplot 2: Comparación de Velocidades
plot(time, w_nl, 'b-', 'LineWidth', 2); hold on;
plot(time, w_lin, 'r--', 'LineWidth', 2);
title('Modelo No Lineal vs Modelo Linealizado', 'Color', 'k');
xlabel('Tiempo [s]', 'Color', 'k');
ylabel('Velocidad \omega [rad/s]', 'Color', 'k');
set(gca, 'XColor', 'k', 'YColor', 'k', 'GridColor', 'k', 'GridAlpha', 0.2, 'Color', 'w');
lgd2 = legend('Modelo No Lineal', 'Modelo Lineal');
set(lgd2, 'FontSize', 5, 'TextColor', 'k', 'Color', 'w', 'EdgeColor', 'k');
area(time, error, 'FaceColor', [1 0.8 0.8], 'EdgeColor', 'r');
title('Error Absoluto (|Real - Aprox|)', 'Color', 'k');
xlabel('Tiempo [s]', 'Color', 'k');
ylabel('Error [rad/s]', 'Color', 'k');
set(gca, 'XColor', 'k', 'YColor', 'k', 'GridColor', 'k', 'GridAlpha', 0.2, 'Color', 'w');
% Parámetros de simulación
c1 = -6.754; c2 = -1.721; c3 = 5.204; c4 = -0.060; c5 = -0.008; % Coeficientes modelo no lineal
V_eq = 20; w_eq = 343.41; % Punto de equilibrio
A_lin = -8.416; B_lin = 180.801; % Modelo linealizado
dt = 0.001; % Tiempo de muestreo [s]
t_step = 2; % Duracion de los escalones [s]
secuencia_voltajes = [20, 22, 19, 21, 18, 23, 20];
T_total = length(secuencia_voltajes) * t_step;
% Generacion de la señal de entrada
idx = floor(t(i)/t_step) + 1;
if idx > length(secuencia_voltajes), idx = length(secuencia_voltajes); end
V_in(i) = secuencia_voltajes(idx);
% Extendiendo el orden del modelo
% Estados: x = [theta; omega]
A_sys = [0, 1; 0, A_lin];
F = eye(2) + A_sys * dt; G = B_sys * dt; H = C_sys;
% ----- SECCIÓN A MODIFICAR -----
Q = diag([1e-4, 1]); % Q: Confianza en integración de theta y dinámica de w
R = 10; % R: Ruido del sensor de velocidad (ajustar si se ve muy sucio)
% ----- ----- ----- ----- -----
affine_term = -A_lin*w_eq - B_lin*V_eq; % Con este término,
% el filtro sabe que el sistema está "centrado" alrededor de 20V y 343 rad/s.
log_theta_real = zeros(size(t)); log_w_real = zeros(size(t));
log_alpha_real = zeros(size(t)); log_theta_est = zeros(size(t));
log_alpha_est = zeros(size(t)); log_y_meas = zeros(size(t));
theta_real = 0; w_real = w_eq;
% --- Dinámica No lineal ---
d_omega_real = c1*u + c2*w_real + c3*u^2 + c4*u*w_real + c5*w_real^2;
theta_real = theta_real + w_real * dt;
w_real = w_real + d_omega_real * dt;
log_theta_real(k) = theta_real;
log_alpha_real(k) = d_omega_real;
% --- Sensor de VELOCIDAD ---
ruido = 0;%% Cambiar a: 1.5 * randn(); para ver efecto ruidoso
y_meas = w_real + ruido; % Medimos w
x_pred = F*x_est + G*u + [0; affine_term*dt];
y_tilde = y_meas - H * x_pred;
x_est = x_pred + K * y_tilde;
P = (eye(2) - K * H) * P_pred;
% Corrección de simetría numérica
log_theta_est(k) = x_est(1);
log_alpha_est(k) = A_lin * x_est(2) + B_lin * u + affine_term;
% Cálculo de la Derivada Numérica de la Velocidad Medida (Aceleración Aprox)
accel_num = [0, diff(log_y_meas)/dt];
col_azul = [0 0.4470 0.7410];
col_rojo = [0.8500 0.3250 0.0980];
col_verde_claro = [0.5 0.8 0.5];
% --- FIGURA 1: Entrada y Salida ---
fig1 = figure('Color', 'w', 'Name', 'Entrada_Salida', 'Position', [50, 500, 700, 600]);
stairs(t, V_in, 'k-', 'LineWidth', 2);
title('Entrada: Voltaje de Armadura', 'Color', 'k', 'FontWeight', 'bold');
ylabel('V_{arm} [V]', 'Color', 'k');
grid on; set(gca, 'XColor', 'k', 'YColor', 'k', 'GridAlpha', 0.3, 'Color', 'w');
% 1. Velocidad Medida (Ruidosa)
plot(t, log_y_meas, 'Color', col_rojo, 'LineWidth', 2); hold on;
plot(t, log_w_real, 'Color', col_azul, 'LineWidth', 2, 'LineStyle', '--');
title('Salida: Velocidad Angular \omega', 'Color', 'k', 'FontWeight', 'bold');
ylabel('\omega [rad/s]', 'Color', 'k'); xlabel('Tiempo [s]', 'Color', 'k');
lgd1 = legend('Medición (Sensor+Ruido)', 'Real (Modelo NL)');
set(lgd1, 'TextColor', 'k', 'Color', 'w', 'EdgeColor', 'k');
grid on; set(gca, 'XColor', 'k', 'YColor', 'k', 'GridAlpha', 0.3, 'Color', 'w');
ylim([min(log_w_real)-20, max(log_w_real)+20]);
% --- FIGURA 2: Posición Estimada ---
fig2 = figure('Color', 'w', 'Name', 'Posicion', 'Position', [800, 500, 700, 800]);
plot(t, log_theta_real, 'Color', col_azul, 'LineWidth', 2); hold on;
plot(t, log_theta_est, '--', 'Color', col_rojo, 'LineWidth', 2);
title('Posición Angular Acumulada \theta (Estimada vs Real)', 'Color', 'k', 'FontWeight', 'bold');
ylabel('\theta [rad]', 'Color', 'k');
lgd2 = legend('Real', 'Estimada (KF)');
set(lgd2, 'TextColor', 'k', 'Color', 'w', 'EdgeColor', 'k', 'Location', 'northwest');
grid on; set(gca, 'XColor', 'k', 'YColor', 'k', 'GridAlpha', 0.3, 'Color', 'w');
plot(t, sin(log_theta_real), 'Color', col_azul, 'LineWidth', 1.5); hold on;
plot(t, sin(log_theta_est), '--', 'Color', col_rojo, 'LineWidth', 1.5);
title('Rotación Física (sin(\theta))', 'Color', 'k', 'FontWeight', 'bold');
ylabel('sin(\theta)', 'Color', 'k');
grid on; set(gca, 'XColor', 'k', 'YColor', 'k', 'GridAlpha', 0.3, 'Color', 'w');
% Subplot 3: ZOOM (3.8s a 4.2s)
plot(t, sin(log_theta_real), 'Color', col_azul, 'LineWidth', 2); hold on;
plot(t, sin(log_theta_est), '--', 'Color', col_rojo, 'LineWidth', 2);
title('Zoom (t = 3.8s a 4.2s)', 'Color', 'k', 'FontWeight', 'bold');
xlabel('Tiempo [s]', 'Color', 'k'); ylabel('sin(\theta)', 'Color', 'k');
grid on; set(gca, 'XColor', 'k', 'YColor', 'k', 'GridAlpha', 0.3, 'Color', 'w');
% --- FIGURA 3: Aceleración (Derivada del Sensor vs Estimada) ---
fig3 = figure('Color', 'w', 'Name', 'Aceleracion', 'Position', [50, 50, 700, 600]);
plot(t, log_alpha_real, 'Color', col_azul, 'LineWidth', 2); hold on;
plot(t, accel_num, ':', 'Color', [0 0.6 0], 'LineWidth', 1);
plot(t, log_alpha_est, '--', 'Color', col_rojo, 'LineWidth', 2);
title('Aceleración angular', 'Color', 'k', 'FontWeight', 'bold');
ylabel('\alpha [rad/s^2]', 'Color', 'k');
if max(abs(accel_num)) > 3*max(abs(log_alpha_real))
ylim([min(log_alpha_real)-300, max(log_alpha_real)+300]);
lgd3 = legend('Real', 'Derivada Numérica (d\omega_{med}/dt)', 'Estimada (KF)');
set(lgd3, 'TextColor', 'k', 'Color', 'w', 'EdgeColor', 'k');
grid on; set(gca, 'XColor', 'k', 'YColor', 'k', 'GridAlpha', 0.3, 'Color', 'w');
plot(t, log_alpha_real, 'Color', col_azul, 'LineWidth', 2); hold on;
plot(t, log_alpha_est, '--', 'Color', col_rojo, 'LineWidth', 2);
title('Sin Derivada Numérica', 'Color', 'k', 'FontWeight', 'bold');
ylabel('\alpha [rad/s^2]', 'Color', 'k'); xlabel('Tiempo [s]', 'Color', 'k');
lgd3b = legend('Real', 'Estimada (KF)');
set(lgd3b, 'TextColor', 'k', 'Color', 'w', 'EdgeColor', 'k');
grid on; set(gca, 'XColor', 'k', 'YColor', 'k', 'GridAlpha', 0.3, 'Color', 'w');