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;