'Could not determine the size of this expression' in simulink function block
2 views (last 30 days)
Show older comments
George West
on 12 Apr 2024
Answered: Fangjun Jiang
on 12 Apr 2024
When running my Simulink simulation i am faced with an error with regards to the code in my function block. The error is:
Error:Could not determine the size of this expression.
Function 'Model Predictive Control ' (#52.3574.3583), line 94, column 49:
"1:i_value"
In the first snippet the phase in which MATLAB says is causing the error is the underlined part: 'H(i_value,1:i_value)'
The loop of code in which this error is highlighted is as follows:
i=1; %i is the level
while (i<=p)
minK = min(Kbest, 2^(i-1));
for j = 1:2:minK*2
for C = u_min:u_max
i_value = i;
Ucand(i,j+C) = C;
Ucand(p+1,j+C) = (H(i_value,1:i_value)*Ucand(1:i_value,j+C) - U_bar_unc(i_value))^2 + Ucand(p+1,j+C);
Niter=Niter+1;
end
end
Ucand = sortrows(Ucand',p+1)';
minK = min(Kbest, 2^i);
l = 1; j = 1;
while j <= minK*2
if Ucand(p+1,l) > 0
Ucand_aux(:,j+0) = Ucand(:,l);
Ucand_aux(:,j+1) = Ucand(:,l);
j = j + 2;
end
l = l + 1;
end
Ucand = Ucand_aux;
i=i+1;
end
The matrix H is of size (6,6) and the value of p is 6. This means the while loops is for values of i from 1:6 so the indexing doesnt exceed the limits of the matrices, so i am unsure as to the problem.
The rest of the code is as follows (to clarify the variables and matrices used within the loop):
function [U_op,Niter,Rs2_o]=MPCFunctionDraft(Vc,i_filter,vref,Vdc,Ts,Lfilter,Cfilter, u_min, u_max, p, Kbest, A, B, D, Np, lambda)
% In order to call "cont2dis" function
coder.extrinsic('cont2dis');
coder.extrinsic('MPC_Matrices_l');
persistent Aq Bq Bdq Vc1 Vc_old if_old UpsilonT Gamma lSTE W_inv H Rr
% Initialize variables and get the parameters of the Discrete model based on Ts
if isempty(Vc1), Vc1 = 0 + 1j*0; end
if isempty(Vc_old), Vc_old = 0 + 1j*0; end
if isempty(if_old), if_old = 0 + 1j*0; end
if isempty(Aq) && isempty(Bq) && isempty(Bdq)
Aq = zeros(2); Bq = zeros(2,1); Bdq = zeros(2,1);
% Call "cont2dis" function
[Aq, Bq, Bdq] = cont2dis(Ts,Lfilter,Cfilter);
end
if isempty(UpsilonT) && isempty(Gamma) && isempty(lSTE) && isempty(W_inv) && isempty(H) && isempty (Rr)
UpsilonT = zeros(6,4); Gamma = zeros(4,6); lSTE = zeros(6,3); W_inv = zeros(6,6); H = zeros(6,6); Rr = zeros(2,2);
% Call "MPC_Matrices_l" function
[UpsilonT,Gamma,lSTE,W_inv,H] = MPC_Matrices_l(A,B,D,Np,lambda);
end
% To generate the switching states matrix
states = [1 0 0;
1 1 0
0 1 0
0 1 1
0 0 1
1 0 1
1 1 1];
a = exp(1j*(2*pi/3));
% Read current measurements at sampling instant k
ifk = i_filter;
Vck = Vc;
% Equation of io(k-1) = if(k-1)-(c/Ts)(vc(k)-vc(k-1)).
io1 = if_old - (Cfilter/Ts)*(Vck - Vc_old);
% Store the measured current for the next iteration
if_old = ifk;
Vc_old = Vck;
%% Vo Reference
Vo_xy_ref = [vref; vref]; % Vo reference in alpha-beta
%% Output sequences
Yref=complex(zeros(4,1)); %(4,1)
Yref(1:2,1)=Rr*Vo_xy_ref; % Construct output reference sequence
for k=3:2:4
row_i=k;
row_f=k+1;
Yref(row_i:row_f,:)=Rr*Yref(row_i-2:row_f-2,:);
end
% FOR loop to find the best switch in the next instant and its corresponding V(i)
for k = 1:7
s = states(k,:);
sw = (2/3)*(s(1)+a*s(2)+a^2*s(3));
Vi = Vdc*sw;
% Output Voltage Prediction at instant k+1
Vc1 = Aq(2,1)*ifk + Aq(2,2)*Vck + Bq(2)*Vi + Bdq(2)*io1;
%% System state
Vo_xy = [Vc1; Vc1];
Io_xy = [ifk ifk]';
Ii_xy = [io1; io1]; % Approximate filter current
x_k = [Ii_xy ; Vo_xy; Io_xy]; % System state variables
%% Unconstrained solution calculation
% Initialize variables
F_k=zeros(p,1);
Niter=0.0; % Count nodes
uabc_k_1 = [0 0 0]'; % Assume previous state is 0 0 0
F_k=UpsilonT*(Gamma*x_k-Yref)-lSTE*uabc_k_1;
U_unc=-W_inv*F_k;
U_bar_unc = H*U_unc; % Center of the sphere in the transformed space
%Initialize SDA matrices
Niter=0;
Ucand=complex(zeros(p+1,2*Kbest));
Ucand_aux=complex(zeros(p+1,2*Kbest));
U_op=zeros(p,1);
i=1; %i is the level
while (i<=p)
minK = min(Kbest, 2^(i-1));
for j = 1:2:minK*2
for C = u_min:u_max
i_value = i;
Ucand(i,j+C) = C;
Ucand(p+1,j+C) = (H(i_value,1:i_value)*Ucand(1:i_value,j+C) - U_bar_unc(i_value))^2 + Ucand(p+1,j+C);
Niter=Niter+1;
end
end
Ucand = sortrows(Ucand',p+1)';
minK = min(Kbest, 2^i);
l = 1; j = 1;
while j <= minK*2
if Ucand(p+1,l) > 0
Ucand_aux(:,j+0) = Ucand(:,l);
Ucand_aux(:,j+1) = Ucand(:,l);
j = j + 2;
end
l = l + 1;
end
Ucand = Ucand_aux;
i=i+1;
end
end
Rs2_o = Ucand(p+1,1);
U_op = real(Ucand(1:p,1));
end
Any suggestions would be much appreciated.
0 Comments
Accepted Answer
Fangjun Jiang
on 12 Apr 2024
In general, it is better to specify the size (number of rows and columns) of all the inputs, outputs and parameters that are used by the MATLAB Function block inside a Simulink model.
In MATLAB, it is not a problem. But in Simulink, it prefers any data to be a fixed size. Variable size data is allowed but it's very tricky to use.
You have pre-allocate the size of variable UpsilonT = zeros(6,4); Gamma = zeros(4,6); lSTE = zeros(6,3); W_inv = zeros(6,6. That is good. I wonder if you clicked "Edit Data" in the code editor and specify the size of inputs and outputs.
Also, you seem to have complex number. It's better to not to use i or j as a variable name then.
0 Comments
More Answers (0)
See Also
Categories
Find more on Array and Matrix Mathematics in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!