Search code examples
matlabmatrix3dsimulinkmatlab-coder

3D Matrix as output of a Matlab Function in a Simulink model


I have the following problem.

I have a SIMULINK model and in this model I have a block: Matlab Function, the following http://it.mathworks.com/help/simulink/slref/matlabfunction.html

To my function I have in input :

  • a vector (N x 1)
  • a constant (1 X 1)

In output I would like to have a 3D Matrix, so a matrix R with dimensions (3 X 3 X N).

But I get the following error:

Data 'R' (#41) is inferred as a variable size matrix, while its specified
type is something else.
Component: MATLAB Function | Category: Coder error

Could you please help me?

The function in the block is the following :

function R = fcn(u,n_robots)

% u is the vector of the quaternions.
% If there are 2 robots involved the u will look like this:
% u=[w1 x1 y1 z1 w2 x2 y2 z2]'
%#eml
assert(n_robots<10);
% Initialization of the variables. If you remove this it won't work because
% code generation doesn't support dynamic changing size variables.
w=zeros(n_robots,1);
x=zeros(n_robots,1);
y=zeros(n_robots,1);
z=zeros(n_robots,1);
n=zeros(n_robots,1);

Rxx=zeros(n_robots,1);
Rxy=zeros(n_robots,1);
Rxz=zeros(n_robots,1);
Ryx=zeros(n_robots,1);
Ryy=zeros(n_robots,1);
Ryz=zeros(n_robots,1);
Rzx=zeros(n_robots,1);
Rzy=zeros(n_robots,1);
Rzz=zeros(n_robots,1);

R=zeros(3,3,n_robots);

for i=0:n_robots-1

    w(i+1) = u( 1+3*i );
    x(i+1) = u( 2+3*i );
    y(i+1) = u( 3+3*i );
    z(i+1) = u( 4+3*i );

    n(i+1) = sqrt(x(i+1)*x(i+1) + y(i+1)*y(i+1) + z(i+1)*z(i+1) + w(i+1)*w(i+1));

    x(i+1) = x(i+1)/ n(i+1);
    y(i+1) = y(i+1)/ n(i+1);
    z(i+1) = z(i+1)/ n(i+1);
    w(i+1) = w(i+1)/ n(i+1);

    Rxx(i+1) = 1 - 2*(y(i+1)^2 + z(i+1)^2);
    Rxy(i+1) = 2*(x(i+1)*y(i+1) - z(i+1)*w(i+1));
    Rxz(i+1) = 2*(x(i+1)*z(i+1) + y(i+1)*w(i+1));

    Ryx(i+1) = 2*(x(i+1)*y(i+1) + z(i+1)*w(i+1));
    Ryy(i+1) = 1 - 2*(x(i+1)^2 + z(i+1)^2);
    Ryz(i+1) = 2*(y(i+1)*z(i+1) - x(i+1)*w(i+1) );

    Rzx(i+1) = 2*(x(i+1)*z(i+1) - y(i+1)*w(i+1) );
    Rzy(i+1) = 2*(y(i+1)*z(i+1) + x(i+1)*w(i+1) );
    Rzz(i+1) = 1 - 2 *(x(i+1)^2 + y(i+1)^2);

    R(:,:,i+1) = [
        Rxx(i+1),    Rxy(i+1),    Rxz(i+1);
        Ryx(i+1),    Ryy(i+1),    Ryz(i+1);
        Rzx(i+1),    Rzy(i+1),    Rzz(i+1)];
end

Solution

  • You may need to parameterise your whole model so you can repeat simulation with different numbers of robots and collect the results.

    Either that, or figure out a max number of robots and make sure all variables are set to the maximum capacity - fill the space unused by robots with 0 or -1 or NaN to mark it as unused (whatever's appropriate for you.