Projet

Général

Profil

programme comptage modifié » coulomb_modifie.m

Mustapha Lahmer, 25/01/2025 21:53

 
clear all;
clc;

% --- Charger les données du tableau Excel ---
% Remplacez 'data.xlsx' par le chemin vers votre fichier Excel
% Chargement des données depuis un fichier Excel
opts = detectImportOptions('test1_Log.xlsx');
opts.VariableNamingRule = 'preserve';
data = readtable('test1_Log.xlsx', opts);


% --- Données d'entrée ---
% Tableau OCV-SOC
soc_table = [100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0] / 100; % SOC en fraction
ocv_table = [4.1269, 4.0825, 4.0515, 3.9422, 3.8545, 3.7481, ...
3.6186, 3.5414, 3.44, 3.2358, 2.7565]; % Tensions OCV (V)

% Paramètres du modèle 2RC
%params.R0 = 0.023;
%params.R1 = 0.007296;
%params.C1 = 3814.045;
%params.R2 = 0.002747;
%params.C2 = 1265.502;

params.R0 = 0.023 ;
params.R1 = 0.05985;
params.C1 = 7345.99;
params.R2 = 0.0068;
params.C2 = 1073.25;
params.C_b = 18000; % Capacité de la batterie en coulombs (Ah * 3600)

% Données d'échantillonnage
dt = 0.2; % Temps d'échantillonnage en secondes
soc_init = 0.872; % SOC initial (en fraction)

I = data.Current; % Courant en ampères
V_measured = data.Voltage; % Tension mesurée en volts

% --- Initialisations ---
n = length(I); % Nombre de points de données
SOC_coulomb = zeros(n, 1); % SOC estimé par comptage de Coulomb
SOC_corrige = zeros(n, 1); % SOC corrigé par la méthode modifiée
SOC_coulomb(1) = soc_init; % Initialisation SOC initial
SOC_corrige(1) = soc_init; % Initialisation SOC initial corrigé
V_OCV = zeros(n, 1); % Tension OCV estimée
V_R1 = 0; % Tension initiale sur le premier réseau RC
V_R2 = 0; % Tension initiale sur le deuxième réseau RC
SOC_OCV = zeros(n, 1); % SOC estimé par la tension OCV
I_c_real = zeros(n, 1); % Courant corrigé réel
errors_SOC = zeros(n, 1); % Erreur entre SOC_OCV et SOC_Coulomb


% --- Étape 1 : Simulation pas à pas pour OCV, SOC Coulomb et I_c_real ---
for k = 1:n
% Mise à jour des tensions dynamiques (modèle 2RC)
%V_R1 = V_R1 + (dt / (params.R1 * params.C1)) * (params.R1 * I(k) - V_R1);
%V_R2 = V_R2 + (dt / (params.R2 * params.C2)) * (params.R2 * I(k) - V_R2);
V_R1 = exp(-dt / (params.R1 * params.C1)) * V_R1 + params.R1 * (1 - exp(-dt / (params.R1 * params.C1))) * I(k); % Mise à jour de la tension V_RC1 en utilisant une équation exponentielle
V_R2 = exp(-dt / (params.R2 * params.C2)) * V_R2 + params.R2 * (1 - exp(-dt / (params.R2 * params.C2))) * I(k); % Mise à jour de la tension V_RC2 en utilisant une équation exponentielle

% Estimation de la tension OCV
V_OCV(k) = V_measured(k) + params.R0 * I(k) + V_R1 + V_R2;

% Estimation du SOC à partir de V_OCV (interpolation SOC-OCV)
SOC_OCV(k) = interp1(ocv_table, soc_table, V_OCV(k), 'linear', 'extrap');

% Calcul du SOC par comptage de Coulomb
if k > 1
SOC_coulomb(k) = SOC_coulomb(k-1) + (I(k) * dt) / params.C_b;
% Limitation du SOC entre 0 % et 100 %
if SOC_coulomb(k) > 1
SOC_coulomb(k) = 1;
elseif SOC_coulomb(k) < 0
SOC_coulomb(k) = 0;
end
end

% Calcul de l'erreur entre SOC_OCV et SOC_Coulomb
errors_SOC(k) = SOC_OCV(k) - SOC_coulomb(k);

% Calcul du courant corrigé réel I_c_real
I_c_real(k) = I(k) + errors_SOC(k)*2; % profil (charge et decharge ou bien seulement charge)
%I_c_real(k) = I(k) + errors_SOC(k)*4; % profil decharge
end

% --- Étape 2 : Interpolation pour déterminer les coefficients k2, k1, k0 ---
coeffs = polyfit(I, I_c_real, 2); % Ajustement quadratique entre I et I_c_real
k2 = coeffs(1);
k1 = coeffs(2);
k0 = coeffs(3);

% --- Étape 3 : Calcul du courant corrigé I_c avec les coefficients ---
I_c = k2 * I.^2 + k1 * I + k0;

% --- Étape 4 : Calcul du SOC corrigé avec la méthode modifiée ---
for k = 2:n
SOC_corrige(k) = SOC_corrige(k-1) + (I_c(k) * dt) / params.C_b;
% Limitation du SOC corrigé entre 0 % et 100 %
if SOC_corrige(k) > 1
SOC_corrige(k) = 1;
elseif SOC_corrige(k) < 0
SOC_corrige(k) = 0;
end
end
% --- Calcul de l'erreur RMSE ---
% RMSE pour la méthode classique (Coulomb)
rmse_coulomb = sqrt(mean((SOC_OCV - SOC_coulomb).^2));

% RMSE pour la méthode modifiée (Coulomb modifié)
rmse_corrige = sqrt(mean((SOC_OCV - SOC_corrige).^2));


% Conversion en pourcentage des estimations de l'EKF (entre 0 et 100 %)
SOC_corrige = SOC_corrige * 100; % Conversion en pourcentage

% Méthode Coulomb Counting
SOC_coulomb = SOC_coulomb * 100;
SOC_OCV = SOC_OCV * 100;
% Affichage des résultats complets avec SoC Coulomb après calcul
for k = 1:n
fprintf('Étape %d: Courant = %.4f A, SoC estimé SOC_corrige = %.4f%%, SoC estimé Coulomb = %.4f%%\n', ...
k, I(k), SOC_corrige(k), SOC_coulomb(k));
end



% --- Résultats ---
disp('Coefficients déterminés par interpolation quadratique :');
disp(['k2 = ', num2str(k2)]);
disp(['k1 = ', num2str(k1)]);
disp(['k0 = ', num2str(k0)]);

% Afficher les résultats
disp('Erreur RMSE :');
disp(['Méthode Coulomb classique : ', num2str(rmse_coulomb)]);
disp(['Méthode Coulomb modifiée : ', num2str(rmse_corrige)]);


% --- Tracés --

% SOC estimés
figure;
plot(1:n, SOC_coulomb, '--', 'LineWidth', 1.5);
hold on;
plot(1:n, SOC_corrige, ':', 'LineWidth', 1.5);
xlabel('Temps (échantillons)');
ylabel('SOC (%)');
title('Coulomb et Coulomb corrigée');
legend('SOC Coulomb', 'SOC Corrigé');
grid on;

% Courant corrigé vs mesuré
figure;
plot(1:n, I, '--', 'LineWidth', 1.5);
hold on;
plot(1:n, I_c, 'LineWidth', 1.5);
xlabel('Temps (échantillons)');
ylabel('Courant (A)');
title('Courant mesuré et corrigé');
legend('I mesuré', 'I corrigé');
grid on;

    (1-1/1)