MATLAB function Simulink: Dimension 2 is fixed on the left-hand side but varies on the right

4 ビュー (過去 30 日間)
Mohammed Alharbi
Mohammed Alharbi 2021 年 10 月 3 日
回答済み: Rishabh Singh 2021 年 10 月 6 日
Hi,
When I am using the MATLAB Function in Simulink I get the below error:
I predfined the dimensions of what the output is going to be. but I beleive the error is due using the "find" function for the "Num_phases" which always returns a variable-length vector. The maximum size of this variable array is 3 and that's why I defined it as "Num_phases = zeros(1,3)"; at the beginning of the code. Please find the code below:
I have seen that I could use "coder.varsize" function but I don't know how to use it tbh.
I removed the function and includded the inputs variables (vin,vout,ref) and put them all in a normal m.file and I don't get any error and get exactly what I want.
So can you please let me know what is the issue when I am using function block inside SIMULINK?
I am including both the Simulink file and the m.file
thanks
function [PWM_signals,phase_delay,Num_phases] = PWM_FCN(vin,vout,ref) %inputs: referance current and sensed current in each phase
Num_phases = zeros(1,3); %output phase shift
phase_delay = zeros(6,1);
PWM_signals = zeros(6,1); %output state 1 or 0
x=0;
ph=zeros(1,6);
d=zeros(1,1001);
m=zeros(1001,6);
Kcm=zeros(1001,6);
Vo=zeros(1,1001);
tol=0;
Vi=0;
inp=0;
ph = 1:6;
Vi = 1;
Vo = 0:0.001:1;
d = Vo./Vi;
m = d'*ph; % note the orientation!
Kcm = (1-(floor(m)./m)).*(1+floor(m)-m);
tol = 1e-2;
inp = vout/vin;
tmp = interp1(d,Kcm,inp);
Num_phases = find(abs(tmp-min(tmp))<tol);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Chose the phases according to the refernce current:
if (ref > 200 && ref <= 240)
x=6;
elseif (ref > 165 && ref <= 200)
x=5;
elseif (ref > 130 && ref <= 165)
x=4;
elseif (ref > 90 && ref <= 130)
x=3;
elseif (ref > 0 && ref <= 90)
x=2;
elseif ref==0
x=0;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% for 6 phases
%%%%%%%%%%%%%%5%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if x==6 || max(Num_phases)==6 && x >=3 % for very high current switch on all phases, Or switch the 6 phases if the current ripple is excellent to switch 6 phases yet the current should not be very low
PWM_signals = ones (6,1); % all phases are 1s
phase_delay(1) =0 ; phase_delay(2) =60*((1/100e3)/360) ; phase_delay(3) =120*((1/100e3)/360) ; phase_delay(4) =180*((1/100e3)/360) ; phase_delay(5) =240*((1/100e3)/360) ; phase_delay(6) =300*((1/100e3)/360) ;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% for 5 phases
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if (x > 2 && x <= 5) && (max(Num_phases) ==5) || (x == 5) && (max(Num_phases) < 5 ) % if the current is to hight to handel less the number of phases, then always swithc 5 phases
PWM_signals(1) =1 ; PWM_signals(2) =1 ; PWM_signals(3) =1 ; PWM_signals(4) =1 ; PWM_signals(5) =1 ; PWM_signals(6) =0 ; %then switch ON all the first 5 phases and switch OFF the last phase
phase_delay(1) =0 ; phase_delay(2) =72*((1/100e3)/360) ; phase_delay(3) =144*((1/100e3)/360) ; phase_delay(4) =216*((1/100e3)/360) ; phase_delay(5) =288*((1/100e3)/360) ; phase_delay(6) =0 ;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% for 4 phases
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if ((x > 2 && x <= 4) && (max(Num_phases) ==4 || sum(Num_phases)/3 ==4 )) || ((x == 4) && (max(Num_phases) < 4 )) % if the
PWM_signals(1) =1 ; PWM_signals(2) =1 ; PWM_signals(3) =1 ; PWM_signals(4) =1 ; PWM_signals(5) =0 ; PWM_signals(6) =0 ;
phase_delay(1) =0 ; phase_delay(2) =90*((1/100e3)/360) ; phase_delay(3) =180*((1/100e3)/360) ; phase_delay(4) =270*((1/100e3)/360) ; phase_delay(5) =0 ; phase_delay(6) =0 ;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% for 3 phases
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if (x > 0 && x <= 3) && (sum(Num_phases)/3 ==3) || (x == 3) && (max(Num_phases) < 3 )
PWM_signals(1) =1 ; PWM_signals(2) =1 ; PWM_signals(3) =1 ; PWM_signals(4) =0 ; PWM_signals(5) =0 ; PWM_signals(6) =0 ; phase_delay(1) =0 ; phase_delay(2) =120*((1/100e3)/360) ; phase_delay(3) =240*((1/100e3)/360) ; phase_delay(4) =0 ; phase_delay(5) =0 ; phase_delay(6) =0 ;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% for 2 phases
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if (x > 0 && x <= 2) && (sum(Num_phases)/6 == 2 || max(Num_phases) >= 4) % 2+4+6=12/2=2
PWM_signals(1) =1 ; PWM_signals(2) =1 ; PWM_signals(3) =0 ; PWM_signals(4) =0 ; PWM_signals(5) =0 ; PWM_signals(6) =0 ;
phase_delay(1) =0 ; phase_delay(2) =180*((1/100e3)/360) ; phase_delay(3) =0 ; phase_delay(4) =0 ; phase_delay(5) =0 ; phase_delay(6) =0 ;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% for 0 phases
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if ref == 0
PWM_signals = zeros (6,1);
phase_delay(1) =0 ; phase_delay(2) =0; phase_delay(3) =0; phase_delay(4) =0; phase_delay(5) =0 ; phase_delay(6) =0 ;
end

回答 (1 件)

Rishabh Singh
Rishabh Singh 2021 年 10 月 6 日
Hey Alharbi,
It seems that the error message you are receiving means variable “Num_phases” is a variable size datatype and you have implemented it as a fixed size datatype.
Suggested way around to this would be using Ports and Data Manager to set the output of function block as variable size. Go it MATLAB Function editor ->Edit Data -> Num_Phases, then tick the “Variable size”.
“Demux” block used in your Model to display the output of variable size signal is not support with the Simulink, you can modify your model using functions that are compatible with variable size signals.
Hope this helps

製品


リリース

R2018b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by