# solve in simulink using matlab function block

40 views (last 30 days)
Mikkel on 4 Sep 2014
Answered: MOHAMAD HAMIZAN on 10 Dec 2016
Hi
I have this function in .m that I would like to run in a Matlab Function block in simulink. The code runs and performs as I would like it to when I run it as a .m. But when it is put into the Matlab function block, it will not run! I use the coder.extrinsix('...') for the different special function that is not a part of simulink. Even when I do that i gives the same error code as of I had not written them.
Code
% Calculates the collision cone
coder.extrinsic('syms')
coder.extrinsic('eval')
coder.extrinsic('solve')
coder.extrinsic('max')
coder.extrinsic('min')
syms a b
V_v = 1; % Vessel Speed
O_v = 1; % Obstacle Speed
O_theta = 128*(pi/180) % Obstacle Heading
O_beta_1 = 30*(pi/180);
O_beta_2 = 42*(pi/180);
O_eta = (O_beta_1 + O_beta_2) / 2;
X = eval(solve(O_v*cos(O_theta-O_eta)-V_v*cos(a-O_eta),a));
Y = eval(solve(O_v*sin(O_theta-O_eta)-V_v*sin(b-O_eta),b));
V_r_O = max(X);
V_theta_O = min(Y);
If gives the error
• Undefined function or variable 'a'.
• Undefined function or variable 'b'.
And then it also complains about the X, Y, V_r_O and V_theta_O
• Undefined function or variable 'X'. The first assignment to a local variable determines its class.
• Undefined function or variable 'Y'. The first assignment to a local variable determines its class.
• Undefined function or variable 'V_r_O '. The first assignment to a local variable determines its class.
• Undefined function or variable 'V_theta_O'. The first assignment to a local variable determines its class.
But my understanding is that it is due to the first two errors..
How do I get this to run i Simulink??

#### 1 Comment

Mikkel on 4 Sep 2014
I'm running a version of matlab where it should be the coder.extrinsix('...') that should be valid, but I have also tried eml.extrinsix('...'), giving the same result.

Mike Hosea on 5 Sep 2014
Keep in mind that extrinsic functions are calculated by calling out to MATLAB, and what comes back is an mxArray which can't be used in the function for much of anything except passing to other extrinsic functions. There's no point in writing a function where every function is extrinsic. A better solution is to have one extrinsic function that you write. Ideally, this function should accept data (numbers) and return data (numbers), since that's what Simulink is going to want to propagate. You can test it from the MATLAB command prompt and debug it there. When you're satisfied that it works properly, then incorporate it into your MATLAB Function Block. To do so, you must pre-allocate the result before you call it. This sounds strange, but the return values from MATLAB calls are inscrutible to the compiler as is. The pre-allocation tells the compiler what the output should look like, so that it can "marshal" the data back into its own environment in a form that it can use in subsequent expressions.
So, whatever you are trying to calculate in this MATLAB Function Block in Simulink, instead write yourself a MATLAB .m file that works properly in MATLAB. Let's suppose that function is called myfun.m. Suppose myfun.m looks like this:
function [V_r_O,V_theta_O] = myfun(V_v,O_v,O_theta,O_beta_1,O_beta_2)
O_eta = (O_beta_1 + O_beta_2) / 2;
X = eval(solve(O_v*cos(O_theta-O_eta)-V_v*cos(a-O_eta),a));
Y = eval(solve(O_v*sin(O_theta-O_eta)-V_v*sin(b-O_eta),b));
V_r_O = max(X);
V_theta_O = min(Y);
Then your MATLAB function block might look like this (notice the pre-allocation of the output!)
coder.extrinsic('myfun');
V_r_O = 0;
V_theta_O = 0;
[V_r_O,V_theta_O] = myfun(V_v,O_v,O_theta,O_beta_1,O_beta_2);
where I assume the inputs here are defined my inputs to the block rather than constants as in the example above.
Note, however, that using symbolic computation is always going to be slow. That has nothing to do with the MATLAB Function Block.

Show 1 older comment
Mike Hosea on 8 Sep 2014
I'm afraid that I don't understand why you are using SOLVE in the first place, nor why you prefer, for example, an answer between pi and 2*pi for O_v*cos(O_theta-O_eta)-V_v*cos(a-O_eta) = 0 (this is the effect of using max(X)). I would have expressions there, not a call to SOLVE. ACOS and ASIN return numbers in certain ranges, so if you want the largest angle in the [0,2*pi) range that solves the equations, this number should be available directly.
Mikkel on 10 Sep 2014
I'm rather new to Matlab and Simulink, and that was the easiest way I could think of. But how would you propose to perform these calculations?
Mike Hosea on 10 Sep 2014
These equations are easy to solve by hand, but we can let MATLAB do it:
>> syms O_v O_theta O_eta V_v a b
>> solve(O_v*cos(O_theta-O_eta)-V_v*cos(a-O_eta),a)
ans =
O_eta + acos((O_v*cos(O_eta - O_theta))/V_v)
O_eta - acos((O_v*cos(O_eta - O_theta))/V_v)
>> solve(O_v*sin(O_theta-O_eta)-V_v*sin(b-O_eta),b)
ans =
O_eta - asin((O_v*sin(O_eta - O_theta))/V_v)
O_eta + pi + asin((O_v*sin(O_eta - O_theta))/V_v)
Since acos returns values in the range [0,pi], the maximum solution for a is
a = O_eta + acos((O_v*cos(O_eta - O_theta))/V_v);
ASIN returns values in the range [-pi/2,pi/2], so it is likewise not difficult to see that the minimum solution for b is
b = O_eta - asin((O_v*sin(O_eta - O_theta))/V_v);
So there, we're all done with SOLVE. Put in those two lines of code:
a = O_eta + acos((O_v*cos(O_eta - O_theta))/V_v);
b = O_eta - asin((O_v*sin(O_eta - O_theta))/V_v);
in instead of all the extrinsic stuff. There's no need for syms, coder.extrinsic, solve, or eval.

### More Answers (1)

MOHAMAD HAMIZAN on 10 Dec 2016
function [cp,h,mp,s]=thermo(T,flag)
%fonction donnant la capacité calorifique massique à pression constante, %Function giving the mass calorific capacity at constant pressure, %l'enthalpie massique, la masse molaire et l'entropie massique en unbités SI des gaz frais (C8H18-O2-N2), des gaz brûlés %The mass enthalpy, the molar mass and the mass entropy in SI units of the fresh gases (C8H18-O2-N2), the burned gases %(CO2-H2O-N2) et d'autres gaz, T est la température, flag est soit 'gf' %(CO2-H2O-N2) and other gases, T is the temperature, flag is either 'gf' %soit 'gb', soit 'co', etc... %Either 'gb' or 'co', etc. %n.B.: le carbonne est dans sa forme gazeuse (et non pas graphitique % N.B .: the carbon is in its gaseous form (and not graphitic %allotropiquement stable dans les conditions standard) % Allotropically stable under standard conditions) %respectivement gaz frais et gaz brûlés. L. Le Moyne/ISAT 28/11/09 % Respectively fresh gas and flue gas. L. Le Moyne / ISAT 28/11/09
R=8.32;
%Haute T >1000K Ahigh=[ 0.02500000E+02 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.02547162E+06 -0.04601176E+01;... %H 0.02991423E+02 0.07000644E-02 -0.05633828E-06 -0.09231578E-10 0.15827519E-14 -0.08350340E+04 -0.13551101E+01;... %H2 0.02542059E+02 -0.02755061E-03 -0.03102803E-07 0.04551067E-10 -0.04368051E-14 0.02923080E+06 0.04920308E+02;... %O 0.03697578E+02 0.06135197E-02 -0.12588420E-06 0.01775281E-09 -0.11364354E-14 -0.12339301E+04 0.03189165E+02;... %O2 0.02882730E+02 0.10139743E-02 -0.02276877E-05 0.02174683E-09 -0.05126305E-14 0.03886888E+05 0.05595712E+02;... %OH 0.02672145E+02 0.03056293E-01 -0.08730260E-05 0.12009964E-09 -0.06391618E-13 -0.02989921E+06 0.06862817E+02;... %H2O 0.03025078E+02 0.14426885E-02 -0.05630827E-05 0.10185813E-09 -0.06910951E-13 -0.14268350E+05 0.06108217E+02;... %CO 0.04453623E+02 0.03140168E-01 -0.12784105E-05 0.02393996E-08 -0.16690333E-13 -0.04896696E+06 -0.09553959E+01;... %CO2 0.02450268E+02 0.10661458E-03 -0.07465337E-06 0.01879652E-09 -0.10259839E-14 0.05611604E+06 0.04448758E+02;... %N 0.02926640E+02 0.14879768E-02 -0.05684760E-05 0.10097038E-09 -0.06753351E-13 -0.09227977E+04 0.05980528E+02;... %N2 0.03245435E+02 0.12691383E-02 -0.05015890E-05 0.09169283E-09 -0.06275419E-13 0.09800840E+05 0.06417293E+02;... %NO 2.71373590e+01 3.79004890e-02 -1.29437358e-05 2.00760372e-09 -1.16400580e-13 -4.07958177e+04 -1.23277495e+02;... %C8H8 2.55423955E+00 -3.21537724E-04 7.33792245E-07 -7.32234889E-10 2.66521446E-13 8.54438832E+04 4.53130848E+00];... %C
%Lower temperature: 300 à 1000K %a1 a2 a3 a4 a5 a6 a7 Alow=[... 0.02500000E+02 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.02547162E+06 -0.04601176E+01;... %H 0.03298124E+02 0.08249441E-02 -0.08143015E-05 -0.09475434E-09 0.04134872E-11 -0.10125209E+04 -0.03294094E+02;... %H2 0.02946428E+02 -0.16381665E-02 0.02421031E-04 -0.16028431E-08 0.03890696E-11 0.02914764E+06 0.02963995E+02;... %O 0.03212936E+02 0.11274864E-02 -0.05756150E-05 0.13138773E-08 -0.08768554E-11 -0.10052490E+04 0.06034737E+02;... %O2 0.03637266E+02 0.01850910E-02 -0.16761646E-05 0.02387202E-07 -0.08431442E-11 0.03606781E+05 0.13588605E+01;... %OH 0.03386842E+02 0.03474982E-01 -0.06354696E-04 0.06968581E-07 -0.02506588E-10 -0.03020811E+06 0.02590232E+02;... %H2O 0.03262451E+02 0.15119409E-02 -0.03881755E-04 0.05581944E-07 -0.02474951E-10 -0.14310539E+05 0.04848897E+02;... %CO 0.02275724E+02 0.09922072E-01 -0.10409113E-04 0.06866686E-07 -0.02117280E-10 -0.04837314E+06 0.10188488E+02;... %CO2 0.02503071E+02 -0.02180018E-03 0.05420529E-06 -0.05647560E-09 0.02099904E-12 0.05609890E+06 0.04167566E+02;... %N 0.03298677E+02 0.14082404E-02 -0.03963222E-04 0.05641515E-07 -0.02444854E-10 -0.10208999E+04 0.03950372E+02;... %N2 0.03376541E+02 0.12530634E-02 -0.03302750E-04 0.05217810E-07 -0.02446262E-10 0.09817961E+05 0.05829590E+02;... %NO -4.20868893e+00 1.11440581e-01 -7.91346582e-05 2.92406242e-08 -4.43743191e-12 -2.99446875e+04 4.49521701e+01;... %C8H8 2.49266888E+00 4.79889284E-05 -7.24335020E-08 3.74291029E-11 -4.87277893E-15 8.54512953E+04 4.80150373E+00];... %C
Mmol=[... 1;... %H 2;... %H2 16;... %O 32;... %O2 17;... %OH 18;... %H2O 28;... %CO 44;... %CO2 14;... %N 28;... %N2 30;... %NO 104;... %C8H8 12];... %C
if (strcmp(flag,'gf')==1) i=[4 10 12]; coeff=[(8+18/4)*1 (8+18/4)*3.76 1]; end if (strcmp(flag,'gb')==1) i=[8 6 10]; coeff=[8 18/2 3.76*(8+18/4)]; end if (strcmp(flag,'co2')==1) i=[8]; coeff=[1]; end
if (strcmp(flag,'co')==1) i=[7]; coeff=[1]; end if (strcmp(flag,'o2')==1) i=[4]; coeff=[1]; end if (strcmp(flag,'c')==1) i=[13]; coeff=[1]; end a=0; if (T>1000) a(i,:)=Ahigh(i,:); else a(i,:)=Alow(i,:); end
for j=1:length(i) cpp(j)=R*(sum(a(i(j),1:5).*T.^(0:4))); hp(j)=R*(sum(a(i(j),1:5)./(1:5).*T.^(1:5))+a(i(j),6));
mp(j)=Mmol(i(j)).*coeff(j)/sum(coeff);
end
for j=1:length(i)
sp(j)=R*(a(i(j),1)*log(T)+sum(a(i(j),2:5)./(1:4).*T.^(1:4))+a(i(j),7));
end
cp=sum(coeff(:)./sum(coeff).*cpp(:))./sum(mp)*1e3;
h=sum(coeff(:)./sum(coeff).*hp(:))./sum(mp)*1e3;
s=sum(coeff(:)./sum(coeff).*sp(:))./sum(mp)*1e3;
mp=sum(mp)*1e-3;
end
Hi, im trying to put the matlab code into the function block in simulink, but it give me the error :
Undefined function or variable 'a'. The first assignment to a local variable determines its class.
Can anyone help me how to solve this problem?