3D-матрица как вывод функции Matlab в модели Simulink

У меня следующая проблема.

У меня есть модель SIMULINK, и в этой модели у меня есть блок: функция Matlab, следующий http://it.mathworks.com/help/simulink/slref/matlabfunction.html

Для моей функции у меня есть ввод:

  • вектор (N x 1)
  • константа (1 х 1)

На выходе я хотел бы иметь 3D-матрицу, поэтому матрица R с размерами (3 X 3 X N).

Но я получаю следующую ошибку:

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

Не могли бы вы мне помочь?

Функция в блоке следующая:

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

person desmond13    schedule 25.11.2014    source источник
comment
Я считаю, что вы не можете сделать размер выходной переменной в simulink. Размер R ДОЛЖЕН всегда быть одинаковым, поэтому он должен быть независимым от n_robots.   -  person Ander Biguri    schedule 25.11.2014
comment
Как определяется выход R в диспетчере портов и данных? Я не уверен, что блоки MATLAB Function поддерживают сигналы переменного размера, что и есть R. Проверьте uk.mathworks.com /help/simulink/ug/.   -  person am304    schedule 25.11.2014
comment
Что вы можете сделать (и это будет лучше), так это создать функцию для КАЖДОГО робота, а затем поместить такое количество функциональных блоков в модель.   -  person Ander Biguri    schedule 25.11.2014
comment
Я не могу этого сделать, потому что в будущем у меня будет N роботов, и мне нужно, чтобы программа была максимально параметризована.   -  person desmond13    schedule 25.11.2014


Ответы (2)


Возможно, вам придется параметризовать всю вашу модель, чтобы вы могли повторить моделирование с другим количеством роботов и собрать результаты.

Либо так, либо определите максимальное количество роботов и убедитесь, что все переменные установлены на максимальную вместимость — заполните пространство, не используемое роботами, 0 или -1 или NaN, чтобы пометить его как неиспользуемое (в зависимости от того, что вам подходит.

person James    schedule 25.11.2014

Я согласен с тем, что ответ @James, параметризующий модель с размером, идеален. Вы можете объявить n_robots как ненастраиваемый параметр для функционального блока MATLAB, и тогда значение будет считаться постоянным во время каждой симуляции. Это, в свою очередь, сделало бы R фиксированным размером во время каждой симуляции. Однако значение может быть изменено между симуляциями для обработки другого количества роботов.

Однако для полноты вы можете установить выходной сигнал R в переменный размер. В редакторе функциональных блоков MATLAB нажмите «Редактировать данные». Найдите и выберите запись для R. Установите флажок «Размер переменной» и введите соответствующие верхние границы. [3,3,10] кажется достаточным из вашего кода.

Дополнительную информацию об использовании данных переменного размера с функциональным блоком MATLAB можно найти по адресу:

http://www.mathworks.com/help/simulink/variable-size-data.html

person Ryan Livingston    schedule 03.12.2014
comment
Итак, если я не ошибаюсь, вы говорите мне оставить n_robots как настраиваемый, R как переменный размер и указать верхние границы R? Спасибо за ответ - person desmond13; 04.12.2014
comment
@minidiable, по моим наблюдениям, то, что вы упомянули, возможно. Однако, если n_robots не меняется ни в одном прогоне вашей симуляции, может быть, имеет больше смысла сделать его ненастраиваемым и оставить R фиксированным размером? - person Ryan Livingston; 04.12.2014
comment
Да. Теперь я уверен, что n_robots не меняется во время определенной симуляции. Это, безусловно, меняется между различными симуляциями, но это не должно быть проблемой, если я установлю n_robots как ненастраиваемый. - person desmond13; 04.12.2014