Untitled

 avatar
unknown
matlab
10 months ago
4.8 kB
17
Indexable
SoC = 0.55; % initial guess SoC, actual initial SoC is approx. 0.9
syms pc nc i x y z;
syms pc32 real;
syms xhat [32 1] real;

% Approximate negative electrode lithium concentration from positive
% electrode concentration
csn = @(z) (theta0_n + ((z - theta0_p*Cmx_p) / ((theta100_p - theta0_p) * Cmx_p)) * (theta100_n - theta0_n));

equilibrium = @(xhat) matCp*(expm(A*Ttime)*xhat); % Takes positive electrode concentrations (nx1)
Equnew = @(xhat)(6/((n+1)*(n+2)*(2*n+3)))*sum((0:n+1).^2*xhat); % Another way to calculate
SoCfunc = @(equilibrium) (equilibrium - conmax_p)/(conmin_p - conmax_p); % SoC from equilibrium

%% Curve fitting instead of lookup table
p1 = 185.1;
p2 = -699.1;
p3 = 1070;
p4 = -853.3;
p5 = 380;
p6 = -93.95;
p7 = 12.79;
p8 = 2.703;
vocvfunc = @(x) p1*(SoCfunc(equilibrium(x)))^7 + p2*(SoCfunc(equilibrium(x)))^6 + ...
                  p3*(SoCfunc(equilibrium(x)))^5 + p4*(SoCfunc(equilibrium(x)))^4 + ...
                  p5*(SoCfunc(equilibrium(x)))^3 + p6*(SoCfunc(equilibrium(x)))^2 + ...
                  p7*(SoCfunc(equilibrium(x))) + p8;

%% Lookup table
matching_vocv_func = @(SoCfunc) vocv(find(abs(socv - SoCfunc) == min(abs(socv - SoCfunc)), 1));

% Voltage of battery is sum of these two, pc is positive electrode lithium
% concentration, VBnew1 needs pc(32) only, only pc(32) is passed to 1 but
% entire PC for VBnew2
VBnew1 = @(pc,i) (gain2*Tt/(alp_n*F))*asinh(i/(2*an*An*Ln*(kn * sqrt(Ce0*(csn(pc)*Cmx_n).*(Cmx_n-(csn(pc)*Cmx_n)))))) + ...
                 (gain2*Tt/(alp_p*F))*asinh((i)/(2*ap*Ap*Lp*(kp * sqrt(Ce0*pc.*(Cmx_p-pc))))) + Rf*i ; % removed
VBnew2 = @(pc) Kgn*(csn(pc(32))-csn(equilibrium(pc)))-Kgp*(pc(32)-equilibrium(pc)) + matching_vocv_func(SoCfunc(equilibrium(pc)));

xhat_sym = sym('xhat', [32, 1]);

%% This section for making partial derivatives of Vocv function, used for lookup table and Equilibrium

% Define symbolic variables
x = sym('x', [32, 1]);

% Define the function vocvfunc
y = SoCfunc(equilibrium(x));

vocvfunc = p1*y^7 + p2*y^6 + p3*y^5 + p4*y^4 + p5*y^3 + p6*y^2 + p7*y + p8;

derivatives = jacobian(vocvfunc, x);
% taken partial derivative of equilibrium terms of voltage equation
equilibrium_sym = Equnew(xhat_sym);

VBnew2_sym = -Kgn * csn(equilibrium_sym) + Kgp * equilibrium_sym;

for idx = 1:32
    dVBnew2_dpc(idx) = diff(VBnew2_sym, xhat_sym(idx));
end
%%

% Partial derivative of terms that only depend on pc(32)
Vb1 = @(pc,i) (gain2*Tt/(alp_n*F))*asinh(i/(2*an*An*Ln*(kn * sqrt(Ce0*(csn(pc)*Cmx_n).*(Cmx_n-(csn(pc)*Cmx_n)))))) + ...
              (gain2*Tt/(alp_p*F))*asinh((i)/(2*ap*Ap*Lp*(kp * sqrt(Ce0*pc.*(Cmx_p-pc))))) + Rf*i ;
Vb2 = @(pc) Kgn*csn(pc)-Kgp*(pc);

dvb1 = diff(Vb1,pc);
dvb2 = diff(Vb2,pc);
%% Constants and initialization

num_steps = 1000; % Number of time steps
dt = 1; % Time step size (1 second)
xp = zeros(length(num_steps),n+2);
xn = zeros(length(num_steps),n+2);
xp(1,:) = (conmax_p - SoC *(conmax_p-conmin_p)) ; %initial conditions
xn(1,:)=conmin_n + SoC *(conmax_n-conmin_n);        %initial conditions
Ttime = 100;    % equilibrium setlling time
ppp = eye(size(matAp))*0.5; %covariance matrix P initial cond

A = matAp; 
B = matBp;

x_hat_history = zeros(length(xp(1,:)), num_steps);
P_history = zeros(length(xp(1,:)), length(xp(1,:)), num_steps);
Equ = zeros(num_steps,1);
SoCeorig = zeros(num_steps,1);
% Initialize state estimate and error covariance
x_hat = xp(1,:)';
P = ppp;
Q = eye(diag(n+2))*2; % Process noise covariance
R = 100;  % Measurement noise covariance


for k = 1:num_steps
    % Define control input and measurement at time step k
    u = i_cell(k); % Control input at time step k
    yy = v_cell(k); % Measurement at time step k


    % Prediction step
    x_hat_pred = x_hat + dt * (A * x_hat + B * -u);

    x_hat_pred_history(k) = x_hat_pred(32);



vestimated(k) = VBnew1(x_hat_pred(32),u) + VBnew2(x_hat_pred);

% All partial derivatives of lookup table in 32x1 matrix
derivative_values_num = double(subs(derivatives, x, x_hat_pred));

%Last jacobian term of state 32
cmatrix(k,1)= double(subs(Vb2,{pc},{x_hat_pred(32)}))+double(subs(Vb1,{pc,i},{x_hat_pred(32),u})) + derivative_values_num(32) ;

%Complete jacobian matrix
    C = [double(dVBnew2_dpc(1:n+1))+derivative_values_num(1:n+1) double(dVBnew2_dpc(n+2))+cmatrix(k,1)];

    %finding kalman gain
    [P_pred,KK,~] = icare(A,C',Q,R);
      K=KK';
 
errr(k) = yy - vestimated(k); %Error output 


x_hat = x_hat_pred +  K * (errr(k))*Cmx_p;


    % Store the state estimate and error covariance etc
    x_hat_history(:, k) = x_hat;
    P_history(:, :, k) = P;
    khistory(:,k) = K;
    csnhistory(k)=csn(x_hat(32));

    %Find equilibrium
    Equ(k)= matCp*(expm(A*Ttime)*x_hat);

    %Find SoC
    SoCeorig(k) = (conmax_p- Equ(k))/(conmax_p-conmin_p);


end
Editor is loading...
Leave a Comment