error in Function output: cannot be of MATLAB type

Hello,
I develop a function to input four components, which allows for a signal blocking over time according to a codition, I proceed as follows:
function [y1,y2] = fcn(u)
%#codegen
coder.extrinsic('degtorad');
coder.extrinsic('radtodeg');
Az=0;
El=0;
In=0;
Or=0;
Azk =degtorad( u(1));
Elk= degtorad(u(2));
Ink=degtorad(u(3));
Ork=degtorad(u(4));
Az = [Az ; Azk];
El= [El ; Elk];
In=[In; Ink];
Or=[Or; Ork];
n=size(Az,1);
if (n==1)
j=1;
end
X2=cos(El(n))*cos(Az(n));
X3=sin(Az(n))*cos(El(n));
I=cos(In(j))*sin(El(n))-sin(In(n))*X2*cos(Or(j))-sin(In(j))*X3*sin(Or(j));
if (0.9<I && I<=1)
y1=radtodeg(In(j));
y2=radtodeg(Or(j));
else
j=n-1;
I=cos(In(j))*sin(El(n))-sin(In(n))*X2*cos(Or(j))-sin(In(j))*X3*sin(Or(j));
y1=radtodeg(In(j));
y2=radtodeg(Or(j));
end
when i run it, i have this error:
Function output 'y1' and 'y2' cannot be of MATLAB type.
can u help me to resolve it?

Réponses (1)

Walter Roberson
Walter Roberson le 23 Mai 2015

0 votes

http://www.mathworks.com/help/simulink/ug/calling-matlab-functions.html and scan down to "Converting mxArrays to Known Types"
In summary: initialize y1 and y2 to 0 before assigning values to them that are the outputs of function calls.

8 commentaires

thank's for ure repply, I've initialized to 0, but the error still exist
Initialize before the "if" so that the initialization is done for both branches. If the problem still persists please post your revised code.
Notice that your code does not initialize j unless n==1, but you can prove that n will never be 1 (because it is size(Az,1) and Az is [0;degtorad(u(1))] and thus must always have at least two entries)
studentU
studentU le 23 Mai 2015
Modifié(e) : Walter Roberson le 23 Mai 2015
this is the latest code
function [y1, y2] = fcn(u)
%#codegen
coder.extrinsic('degtorad');
coder.extrinsic('radtodeg');
Az=0;
El=0;
In=0;
Or=0;
n=2;
y1=0;
y2=0;
Azk =degtorad( u(1));
Elk= degtorad(u(2));
Ink=degtorad(u(3));
Ork=degtorad(u(4));
Az = [Az ; Azk];
El= [El ; Elk];
In=[In; Ink];
Or=[Or; Ork];
n=size(Az,1);
if (n==1)
k=1;
end
X2=cos(El(n))*cos(Az(n));
X3=sin(Az(n))*cos(El(n));
I=cos(In(k))*sin(El(n))-sin(In(n))*X2*cos(Or(k))-sin(In(k))*X3*sin(Or(k));
if (0.9<I && I<=1)
y1=radtodeg(In(k));
y2=radtodeg(Or(k));
else
if (n>1)
k=n-1;
I=cos(In(k))*sin(El(n))-sin(In(n))*X2*cos(Or(k))-sin(In(k))*X3*sin(Or(k));
y1=radtodeg(In(k));
y2=radtodeg(Or(k));
end
end
Do not expand elements dynamically. You have lines like
Az = [Az ; Azk];
which attempt to expand the scalar value Az into a vector. Either just code
Az = [0; Azk];
or if you have reason to have the 0 in a named variable (plausible) then give it a different name such as
Az_init = 0;
and then later
Az = [Az_init; Azk];
The same applies for the other variables.
studentU
studentU le 23 Mai 2015
Modifié(e) : studentU le 23 Mai 2015
I am looking to recover the sets of values of Az until the condition is true, in your example I have of crushing Az values is I would always the present value of az and 0
If you need to store an unknown number of values in Simulink, then there are a few approaches.
The first approach is to put a maximum limit on the number of elements to be stored, and initialize the vectors accordingly. As you go, you keep track of how many elements have actually been used. At any one time, you then use subscript indexing like Az(1:numused) to refer to the portion that is meaningful. Eventually you will either finish normally or you will get to the limit of the maximum number of elements you allocated and you need to stop processing. Then for all of the values that are being returned as signals, just before returning, assign to them the subset that was actually used, such as
Az = Az(1:numused);
This is okay because in Simulink you can shrink an array but you cannot grow it larger than you initialized it.
The second approach is like the first in having hard-coded vector sizes, but does not require that the variable be initialized to its longest possible value and does not require that you subscript by the number of elements currently in use. Simulink effectively does those things for you if you set up the variable using coder.varsize
The third approach is to use dynamic memory allocation. I think this might involve using coder.varsize as well, but I am not able to access the documentation as I do not have the license or software support agreement. You could try looking starting at http://www.mathworks.com/help/fixedpoint/ug/minimize-dynamic-memory-allocation.html
thank you Roberson for repply,
i used the second approch, i've add at the begining coder.varsize('Az','El','In','Or'); but it generates this error:
Variable 'k' is undefined on some execution paths.
I can not declare the k before, if (n == 1) because I want the exchange k values if I declare, it will take the initial value each TE

Connectez-vous pour commenter.

Question posée :

le 23 Mai 2015

Commenté :

le 24 Mai 2015

Community Treasure Hunt

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

Start Hunting!

Translated by