Projet

Général

Profil

Modélisation de la batterie » modele_2rc.m

Mustapha Lahmer, 10/01/2025 14:58

 
clear all;
clc;


% --- Charger les données du tableau Excel ---
opts = detectImportOptions('Log1.xlsx');
opts.VariableNamingRule = 'preserve';
data = readtable('Log1.xlsx', opts);

% --- Initialisation des données ---
dt = 0.2; % Intervalle de temps (secondes)
I = data.Current; % Courant (A)
V_meas = data.Voltage; % Tension mesurée (V)

% Tableau OCV-SOC
soc_table = ([100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0]) / 100;
ocv_table = [4.1269, 4.0825, 4.0515, 3.9422, 3.8545, 3.7481, ...
3.6186, 3.5414, 3.44, 3.2358, 2.7565];

% Paramètres de la batterie
Q_nom = 18000; % Capacité nominale (Coulombs)
soc_initial = 0.6466; % SOC initial (100 %)
soc = soc_initial + cumsum(I) * dt / Q_nom; % Calcul du SOC
soc(soc < 0) = 0; % Limiter SoC à 0 %
soc(soc > 1) = 1; % Limiter SoC à 100 %

% Interpolation pour V_OC
Voc = interp1(soc_table, ocv_table, soc, 'linear', 'extrap');

% --- Initialisation des paramètres ---
% Initialisation des paramètres
params = [0.023, 0.05985, 7345.99, 0.0068, 1073.25]; % [R0, R1, C1, R2, C2]
lb = [0.025, 0.05, 500, 0.005, 500];% Limites inférieures
ub = [0.1, 0.06, 7350, 0.007, 1100];% Limites supérieures


t = (0:length(I)-1)' * dt; % Vecteur temps (colonne)

% --- Fonction pour le modèle 2RC avec mise à jour exponentielle ---
model_2RC = @(params, Voc, I, dt) ...
calculate_vsim(params, Voc, I, dt);

% --- Boucle d'identification récursive ---
max_iterations = 10; % Limite de sécurité pour convergence
tolerance = 1e-2;
learning_rate = 0.01; % Taux d'apprentissage pour la correction des paramètres
prev_params = params;
error_history = zeros(max_iterations, 1); % Pour tracer les erreurs

for iter = 1:max_iterations
% Étape 1 : Simulation de la tension prédite
V_sim = model_2RC(prev_params, Voc, I, dt);
% Étape 2 : Calcul de l'erreur de prédiction
error = V_meas - V_sim; % \Delta Z


error_norm = norm(error);
error_history(iter) = error_norm;
% Étape 3 : Ajustement des paramètres
params_opt = lsqcurvefit(@(params, t) model_2RC(params, Voc, I, dt), ...
prev_params, t, V_meas, lb, ub);

% Étape 4 : Correction des paramètres en fonction de l'erreur
params_opt(1) = params_opt(1) + learning_rate * mean(error) * sign(params_opt(1)); % Mise à jour de R0
params_opt(2) = params_opt(2) + learning_rate * mean(error) * sign(params_opt(2)); % Mise à jour de R1
params_opt(3) = params_opt(3) + learning_rate * mean(error) * sign(params_opt(3)); % Mise à jour de C1
params_opt(4) = params_opt(4) + learning_rate * mean(error) * sign(params_opt(4)); % Mise à jour de R2
params_opt(5) = params_opt(5) + learning_rate * mean(error) * sign(params_opt(5)); % Mise à jour de C2
% Vérification de convergence
if norm(params_opt - prev_params) < tolerance
fprintf('Convergence atteinte à l''itération %d\n', iter);
break;
end
% Ajout de la vérification sur la variation de l'erreur
if iter > 1 && abs(error_history(iter) - error_history(iter-1)) < 1e-1
fprintf('Convergence atteinte après %d itérations.\n', iter);
break;
end

% Mise à jour pour l'itération suivante
prev_params = params_opt;
% Affichage des résultats intermédiaires
fprintf('Itération %d : R0 = %.4f, R1 = %.4f, C1 = %.4f, R2 = %.4f, C2 = %.4f\n', ...
iter, params_opt(1), params_opt(2), params_opt(3), params_opt(4), params_opt(5));
end

% --- Résultats finaux ---
R0 = params_opt(1);
R1 = params_opt(2);
C1 = params_opt(3);
R2 = params_opt(4);
C2 = params_opt(5);

% Calcul des constantes de temps
tau1 = R1 * C1; % Constante de temps RC1
tau2 = R2 * C2; % Constante de temps RC2

fprintf('Paramètres finaux estimés :\n');
fprintf('R0 = %.4f Ω\n', R0);
fprintf('R1 = %.4f Ω\n', R1);
fprintf('C1 = %.4f F\n', C1);
fprintf('R2 = %.4f Ω\n', R2);
fprintf('C2 = %.4f F\n', C2);
fprintf('Tau1 = %.4f s, Tau2 = %.4f s\n', tau1, tau2);

% --- Visualisation des résultats ---
figure;
plot(t, V_meas, 'b', 'LineWidth', 1.5); hold on;
plot(t, V_sim, 'r--', 'LineWidth', 1.5);
xlabel('Temps (s)');
ylabel('Tension (V)');
legend('Tension mesurée', 'Tension simulée');
title('Comparaison des tensions mesurée et simulée après identification');
grid on;

figure;
plot(t, V_meas, 'b', 'LineWidth', 1.5); hold on;
plot(t, Voc, 'g--', 'LineWidth', 1.5);
plot(t, V_sim, 'r:', 'LineWidth', 1.5);
xlabel('Temps (s)');
ylabel('Tension (V)');
legend('Tension mesurée', 'Tension OCV', 'Tension simulée');
title('Décomposition des tensions simulées');
grid on;

% Calcul et affichage de l'erreur au fil du temps
figure;
plot(t, error, 'm', 'LineWidth', 1.5);
xlabel('Temps (s)');
ylabel('Erreur (V)');
title('Erreur entre la tension mesurée et simulée');
grid on;


% --- Fonction de calcul de la tension simulée ---
function V_sim = calculate_vsim(params, Voc, I, dt)
% Initialisation des tensions dynamiques
V_RC1 = 0; % Tension initiale sur RC1
V_RC2 = 0; % Tension initiale sur RC2
V_sim = zeros(size(I)); % Tension simulée

for k = 2:length(I)
% Mise à jour exponentielle pour RC1 et RC2
V_RC1 = params(2) * (1 - exp(-dt / (params(2) * params(3)))) * I(k);
V_RC2 = params(4) * (1 - exp(-dt / (params(4) * params(5)))) * I(k);
% Tension simulée
V_sim(k) = Voc(k) - params(1) * I(k) - V_RC1 - V_RC2;
end
end
    (1-1/1)