一个函数输出一个包含 38 个元素的向量,而 Simulink 将其作为一个元素怎么可能呢?

How can it be that a function is outputing a vector with 38 elements and Simulink takes it as one element?

在下面的 Simulink 模型中,我解释的函数输出是一个包含 38 个元素的向量。我有两个具有相同输出的函数,其中一个运行良好 (desiredtrajectory_sim.m),但另一个运行不正常 (desiredtrajectory.m)。 有什么建议么。谢谢

这是Simulink模型

function [desired_state] = desiredtrajectory_sim(in)
t = in(1);
Sf = [ 1; 2; pi/4];
dSf = [0;0;0];

Pf = [ 0.1*t; 0; 0.5*sin(0.03*pi*t) + 2; 0; 0.01*pi*t ; 0];
dPf = [ 0.1; 0; 0.5*0.03*pi*cos(0.03*pi*t); 0; 0.01*pi; 0];

pf = Sf(1); qf = Sf(2); betaf = Sf(3);
xf = Pf(1); yf = Pf(2); zf = Pf(3);
phif = Pf(4); thetaf = Pf(5); psif = Pf(6);

rf  = sqrt(pf^2 + qf^2 - 2*pf*qf*cos(betaf));         
h1 =  sqrt(0.5*(pf^2 + qf^2 - 0.5*rf^2));
h2 =  sqrt(0.5*(rf^2 + pf^2 - 0.5*qf^2));
h3 =  sqrt(0.5*(qf^2 + rf^2 - 0.5*pf^2));                   
alpha1  = acos((4*(h1^2+h2^2)-9*pf^2)/(8*h1*h2));
alpha2  = acos((4*(h1^2+h3^2)-9*qf^2)/(8*h1*h3));
Rot = RPYtoRot_ZXY(phif, thetaf, psif);
r1 = Rot*[2/3*h1;0;0];
r2 = Rot*[2/3*h2*cos(alpha1);2/3*h2*sin(alpha1);0];
r3 = Rot*[2/3*h3*cos(alpha2);-2/3*h3*sin(alpha2);0];
pos_des1 = [xf;yf;zf] + r1;
pos_des2 = [xf;yf;zf] + r2;
pos_des3 = [xf;yf;zf] + r3;

omega = [0 -sin(psif) cos(thetaf)*cos(psif);...
     0 -cos(psif) cos(thetaf)*sin(psif);...
     1     0         -sin(thetaf)]*dPf(4:6);

vel_des1 =  dPf(1:3) + cross(omega, r1);
vel_des2 =  dPf(1:3) + cross(omega, r2);
vel_des3 =  dPf(1:3) + cross(omega, r3);
acc_des = [0;0;0];

desired_state1 = [pos_des1;vel_des1;acc_des];
desired_state2 = [pos_des2;vel_des2;acc_des];
desired_state3 = [pos_des3;vel_des3;acc_des];

desired_state = [desired_state1;desired_state2;desired_state3; psif; 0; Pf; 
Sf]
size(desired_state)
end

这是 Simulink 块和错误消息 正如您所注意到的,总线只提供一个元素,而前一个总线提供 38 个元素,尽管它们具有相同的输出。

function [desired_state] = desiredtrajectory(in)%(t, pos)
tm= in(1)
pos = in(2:10);
syms t xf yf zf phif thetaf psif pf qf betaf

rf  = sqrt(pf^2+qf^2-2*pf*qf*cos(betaf));

              h1 =  sqrt(0.5*(pf^2+qf^2-0.5*rf^2));
              h2 =  sqrt(0.5*(rf^2+pf^2-0.5*qf^2));
              h3 =  sqrt(0.5*(qf^2+rf^2-0.5*pf^2));

alf1  = acos((4*(h1^2+h2^2)-9*pf^2)/(8*h1*h2));
alf2  = acos((4*(h1^2+h3^2)-9*qf^2)/(8*h1*h3)); 

Rot = RPYtoRot_ZXY(phif, thetaf, psif);
eps = [Rot*[2/3;0;0]+[xf;yf;zf]
   Rot*[2/3*h2*cos(alf1);2/3*h2*sin(alf1);0]+[xf;yf;zf]
   Rot*[2/3*h2*cos(alf2);-2/3*h3*sin(alf2);0]+[xf;yf;zf]];

 X  = [ xf yf zf phif thetaf psif pf qf betaf];

 Sf = [ 1; 2; pi/4];
 dSf = [0;0;0];

Pf = [ 0.1*t; 0; 0.5*sin(0.03*pi*t) + 2; 0; 0.01*pi*t ; 0];
dPf = [ 0.1; 0; 0.5*0.03*pi*cos(0.03*pi*t); 0; 0.01*pi; 0];

qd = [Pf; Sf];
qddot = [dPf; dSf];

jac = jacobian(eps,X);
%%%%%%%%%%%%%
pf = Sf(1); qf = Sf(2); betaf = Sf(3);
xf = Pf(1); yf = Pf(2); zf = Pf(3);
phif = Pf(4); thetaf = Pf(5); psif = Pf(6);

x1=pos(1);
y1=pos(2);
z1=pos(3);
x2=pos(4);
y2=pos(5);
z2=pos(6);
x3=pos(7);
y3=pos(8);
z3=pos(9);

qpf=[(x1+x2+x3)/3;...
 (y1+y2+y3)/3;...
 (z1+z2+z3)/3;...
 atan2((2*z1/3-z2/3-z3/3),(2*y1/3-y2/3-y3/3)); ...
 -atan2((2*z1/3-z2/3-z3/3),(2*x1/3-x2/3-x3/3)); ...
 atan2((2*y1/3-y2/3-y3/3),(2*x1/3-x2/3-x3/3))];

 qsf=[sqrt((x1-x2)^2+(y1-y2)^2+(z1-z2)^2); ...
 sqrt((x1-x3)^2+(y1-y3)^2+(z1-z3)^2); ...
 acos((pf^2+qf^2-rf^2)/(2*pf*qf))];

 q = [qpf;qsf];
 %%%%%%%%%%%%%
 %%%pos_desired%%%%%%%
 pos_des =  eval(eps);
 pos_des =subs(pos_des,t,tm);
 jacval  =  eval(jac);

 qd = eval(qd);%subs(qd,t,tm);
 q  = eval(q);
 qe = qd - q;
 qddot = eval(qddot);%subs(qddot,t,tm);
 kappa=0.2*eye(9);
 qrefdot = qddot + kappa*qe;

 vel_des = jacval*qrefdot;
 vel_des = subs(vel_des,t,tm);
 acc_des = zeros(3,1);

 yaw = 0;
 yawdot = 0;
 % =================== Your code ends here ===================

 desired_state1 = [pos_des(1:3);vel_des(1:3);acc_des];
 desired_state2 = [pos_des(4:6);vel_des(4:6);acc_des];
 desired_state3 = [pos_des(7:9);vel_des(7:9);acc_des];
 Pf = subs(Pf,t,tm);
 Sf = subs(Sf,t,tm);
 format short
 digits(3);
 desired_state = vpa([desired_state1;desired_state2;desired_state3; psif; 0; 
 Pf; Sf])
 size(desired_state)
 end

第二张图片显示第二个函数的输出是一个标量 - 块输出的维度是 1 - 而不是你认为的 38。

也就是说,您的函数不会提供与您认为相同的输出。

错误是因为 Selector 块期望它们的输入是 38 维,而它们不是。

要确定为什么您认为正在发生的事情实际上并不是正在发生的事情,您可以使用编辑器在 m 代码、运行 模型中设置一个断点,然后单步执行代码以确定为什么它会在您期望它以其他方式输出时给出标量输出。

另一种方法是 运行 使用伪造的输入数据从 MATLAB 命令行运行您的函数。像

tmp = desiredtrajectory(randn(10,1))

在这里很合适。

答案是desiredtrajectory输出desired_state,这是一个符号变量。是的,它包含一个 38 元素向量,但 Simulink 将对象本身视为标量。

但真正的问题是您不能将符号变量传播到 Simulink 信号中。您需要输出为数字向量。

克服这个问题的一种方法是把线

desired_state = double(desired_state);

在文件末尾将符号对象转换为双精度型,它将有 38 个元素。

(但是不清楚你为什么首先使用符号数学,我建议如果你不使用它会更好,当然效率更高。)