Level 2 Matlab中的Simulink块错误S-Function:Simulink.RunTimeBlock回调不存在的

时间:2016-02-24 19:40:18

标签: matlab simulink s-function

我正在Simulink中编写2级Matlab S-Function。在尝试构建时,我收到以下错误:

Reference to non-existent field 'SetPreCompInpPortInfoToDynamic'

我的设置功能的第一位是:

function setup(block)

% Register number of ports
block.NumInputPorts  = 4;
block.NumOutputPorts = 3;

% Setup port properties to be inherited or dynamic
block.SetPreCompInpPortInfoToDynamic;
block.SetPreCompOutPortInfoToDynamic;

% Override input port properties
for i=1:block.NumInputPorts
block.InputPort(i).Dimensions        = 1;
block.InputPort(i).DatatypeID  = 0;  % double
block.InputPort(i).Complexity  = 'Real';
block.InputPort(i).DirectFeedthrough = false;
end

构建工作正常,将值赋值给block(传递给我的S函数的对象)。它只会在引用block的回调时窒息。 这让我认为block作为一种不同类型的对象而不是RunTimeBlock对象传递给我的S-Function,但我不确定。

我尝试直接将Simulink.RunTimeBlock导入到该函数中,但它没有任何区别。

以前在几个地方(这里是一个)问过这个问题: http://mathforum.org/kb/message.jspa?messageID=7049610

但是,我无法找到答案的任何地方。

非常感谢任何帮助。

根据评论的要求: 我的模型图片(这很简单,因为我只是先测试S函数):

picture of model

完整的S-Function代码(注意它很长,但更新函数只包含大量的数学运算):

function Canfield_S_Function(block)

import Simulink.RunTimeBlock;
%MSFUNTMPL_BASIC A Template for a Level-2 MATLAB S-Function
%   The MATLAB S-function is written as a MATLAB function with the
%   same name as the S-function. Replace 'msfuntmpl_basic' with the 
%   name of your S-function.
%
%   It should be noted that the MATLAB S-function is very similar
%   to Level-2 C-Mex S-functions. You should be able to get more
%   information for each of the block methods by referring to the
%   documentation for C-Mex S-functions.
%
%   Copyright 2003-2010 The MathWorks, Inc.

%%
%% The setup method is used to set up the basic attributes of the
%% S-function such as ports, parameters, etc. Do not add any other
%% calls to the main body of the function.
%%
setup(block);

%endfunction

%% Function: setup ===================================================
%% Abstract:
%%   Set up the basic characteristics of the S-function block such as:
%%   - Input ports
%%   - Output ports
%%   - Dialog parameters
%%   - Options
%%
%%   Required         : Yes
%%   C-Mex counterpart: mdlInitializeSizes
%%
function setup(block)

% Register number of ports
block.NumInputPorts  = 4;
block.NumOutputPorts = 3;

% Setup port properties to be inherited or dynamic
block.SetPreCompInpPortInfoToDynamic;
block.SetPreCompOutPortInfoToDynamic;

% Override input port properties
for i=1:block.NumInputPorts
block.InputPort(i).Dimensions        = 1;
block.InputPort(i).DatatypeID  = 0;  % double
block.InputPort(i).Complexity  = 'Real';
block.InputPort(i).DirectFeedthrough = false;
end

% Override output port properties
for j=1:block.NumOutputPorts
block.OutputPort(j).Dimensions       = 1;
block.OutputPort(j).DatatypeID  = 0; % double
block.OutputPort(j).Complexity  = 'Real';
end

% Register parameters
block.NumDialogPrms     = 4;

% Register sample times
%  [0 offset]            : Continuous sample time
%  [positive_num offset] : Discrete sample time
%
%  [-1, 0]               : Inherited sample time
%  [-2, 0]               : Variable sample time
block.SampleTimes = [-1 0];

% Specify the block simStateCompliance. The allowed values are:
%    'UnknownSimState', < The default setting; warn and assume DefaultSimState
%    'DefaultSimState', < Same sim state as a built-in block
%    'HasNoSimState',   < No sim state
%    'CustomSimState',  < Has GetSimState and SetSimState methods
%    'DisallowSimState' < Error out when saving or restoring the model sim state
block.SimStateCompliance = 'DefaultSimState';

%% -----------------------------------------------------------------
%% The MATLAB S-function uses an internal registry for all
%% block methods. You should register all relevant methods
%% (optional and required) as illustrated below. You may choose
%% any suitable name for the methods and implement these methods
%% as local functions within the same file. See comments
%% provided for each function for more information.
%% -----------------------------------------------------------------

block.RegBlockMethod('PostPropagationSetup',    @DoPostPropSetup);
block.RegBlockMethod('InitializeConditions',    @InitializeConditions);
%block.RegBlockMethod('Start',                  @Start);
block.RegBlockMethod('Outputs',                 @Outputs);     % Required
block.RegBlockMethod('Update',                  @Update);
%block.RegBlockMethod('Derivatives',            @Derivatives);
%block.RegBlockMethod('Terminate',              @Terminate); % Required

end setup

%%
%% PostPropagationSetup:
%%   Functionality    : Setup work areas and state variables. Can
%%                      also register run-time methods here
%%   Required         : No
%%   C-Mex counterpart: mdlSetWorkWidths
%%
function DoPostPropSetup(block)
block.NumDworks = 4;

  block.Dwork(1).Name            = 'x1';
  block.Dwork(1).Dimensions      = 1;
  block.Dwork(1).DatatypeID      = 0;      % double
  block.Dwork(1).Complexity      = 'Real'; % real
  block.Dwork(1).UsedAsDiscState = true;

  block.Dwork(2).Name            = 'x2';
  block.Dwork(2).Dimensions      = 1;
  block.Dwork(2).DatatypeID      = 0;      % double
  block.Dwork(2).Complexity      = 'Real'; % real
  block.Dwork(2).UsedAsDiscState = true;

  block.Dwork(3).Name            = 'x3';
  block.Dwork(3).Dimensions      = 1;
  block.Dwork(3).DatatypeID      = 0;      % double
  block.Dwork(3).Complexity      = 'Real'; % real
  block.Dwork(3).UsedAsDiscState = true;

  block.Dwork(4).Name            = 'x4';
  block.Dwork(4).Dimensions      = 1;
  block.Dwork(4).DatatypeID      = 0;      % double
  block.Dwork(4).Complexity      = 'Real'; % real
  block.Dwork(4).UsedAsDiscState = true;

end DoPostPropSetup


%%
%% InitializeConditions:
%%   Functionality    : Called at the start of simulation and if it is 
%%                      present in an enabled subsystem configured to reset 
%%                      states, it will be called when the enabled subsystem
%%                      restarts execution to reset the states.
%%   Required         : No
%%   C-MEX counterpart: mdlInitializeConditions
%%
function InitializeConditions(block)

block.Dwork(1).Data = block.DialogPrm(1).Data;
block.Dwork(2).Data = block.DialogPrm(2).Data;
block.Dwork(3).Data = block.DialogPrm(3).Data;
block.Dwork(4).Data = block.DialogPrm(4).Data;

end InitializeConditions

%%
%% Outputs:
%%   Functionality    : Called to generate block outputs in
%%                      simulation step
%%   Required         : Yes
%%   C-MEX counterpart: mdlOutputs
%%
function Outputs(block)

block.OutputPort(1).Data = block.Dwork(1).Data;
block.OutputPort(2).Data = block.Dwork(2).Data;
block.OutputPort(3).Data = block.Dwork(3).Data;

end Outputs



%%
%% Update:
%%   Functionality    : Called to update discrete states
%%                      during simulation step
%%   Required         : No
%%   C-MEX counterpart: mdlUpdate
%%

function Update(block)

%specify a pointing vector and plunge distance, convert vector to unit
%vector
tVec = [block.InputPort(1).Data,block.InputPort(2).Data,block.InputPort(3).Data]; %pointing vector
tVec = tVec/norm(tVec);

plunge = block.InputPort(4).Data; %plunge dist

%find the bending vector and angle
u_Bend = cross(tVec, [0,0,1])/norm(cross(tVec, [0,0,1]));
phi = acos(dot(tVec, [0,0,1]));

%Find coordinates of distal revolutes about wrist center when joint is at rest
rev_Dist = 3.17200333; %Distance from plate center
arm_L = 5.1; %arm length
d1p = [0;rev_Dist; plunge];
d2p = [rev_Dist*cos(30);-1*rev_Dist*sin(30);plunge];
d3p = [-1*rev_Dist*cos(30);-1*rev_Dist*sin(30);plunge];

nu = 1-cos(phi);
c = cos(phi);
s = sin(phi);

%Transformation matrix: convert at-rest distal revolutes to pointed distal
%revolutes
R = [u_Bend(1)*u_Bend(1)*nu+c, u_Bend(1)*u_Bend(2)*nu-u_Bend(3)*s, u_Bend(2)*u_Bend(3)*nu+u_Bend(2)*s; ...
     u_Bend(1)*u_Bend(2)*nu+u_Bend(3)*s, u_Bend(2)*u_Bend(2)*nu+c, u_Bend(2)*u_Bend(3)*nu-u_Bend(1)*s; ...
     u_Bend(1)*u_Bend(3)*nu-u_Bend(2)*s, u_Bend(2)*u_Bend(3)*nu+u_Bend(1)*s, u_Bend(3)*u_Bend(3)*nu+c];

d1 = R*d1p;
d2 = R*d2p;
d3 = R*d3p;

%find points on the midplane between the basal and distal plates
p1 = (d1+[0;rev_Dist; 0])/2;
p2 = (d2+[rev_Dist*cos(30);-1*rev_Dist*sin(30);0])/2;
p3 = (d3+[-1*rev_Dist*cos(30);-1*rev_Dist*sin(30);0])/2;

%find the midplane equation using those points
N = cross((p2-p1), (p3-p1)); %set of first three plane coefficients
D = -1*dot(N, p1);
midplane = [N; D];

%Find equations of the 3 planes that the basal arms revolve in
%--arm 1--
b1_1= [0;rev_Dist;0];%position of basal revolute
b1_2= [0;0;0];%center of basal plate
b1_3= [0;rev_Dist;1];%one unit above basal revolute

Nb1 = cross((b1_2-b1_1), (b1_3-b1_1));
Db1 = -1*dot(Nb1, b1_1);
cplane1 = [Nb1; Db1];

%--arm 2--
b2_1= [rev_Dist*cos(30);-1*rev_Dist*sin(30);0];%position of basal revolute
b2_2= [0;0;0];%center of basal plate
b2_3= [rev_Dist*cos(30);-1*rev_Dist*sin(30);1];%one unit above basal revolute

Nb2 = cross((b2_2-b2_1), (b2_3-b2_1));
Db2 = -1*dot(Nb2, b2_1);
cplane2 = [Nb2; Db2];

%--arm 3--
b3_1= [-1*rev_Dist*cos(30);-1*rev_Dist*sin(30);0];%position of basal revolute
b3_2= [0;0;0];%center of basal plate
b3_3= [-1*rev_Dist*cos(30);-1*rev_Dist*sin(30);1];%one unit above basal revolute

Nb3 = cross((b3_2-b3_1), (b3_3-b3_1));
Db3 = -1*dot(Nb3, b3_1);
cplane3 = [Nb3; Db3];


%Solve for the 3 intersection points of the basal and distal arms

%solution is obtained from the intersection of the midplane, armplane and
%the circle that the end of the basal arm traces
%-----------------------------------------------------------------------------
    function F = plane1(x1)

    F(1) = x1(1)*cplane1(1)+x1(2)*cplane1(2)+x1(3)*cplane1(3)+cplane1(4);
    F(2) = x1(1)*midplane(1)+x1(2)*midplane(2)+x1(3)*midplane(3)+midplane(4);
    F(3) = (x1(1)-b1_1(1))^2+(x1(2)-b1_1(2))^2+(x1(3)-b1_1(3))^2-arm_L^2;
    end

fun1 = @plane1;
x0_1 = [0,0,0];
POI1 = fsolve(fun1,x0_1);
%------------------------------------------------------------------------------
    function F = plane2(x1)

    F(1) = x1(1)*cplane2(1)+x1(2)*cplane2(2)+x1(3)*cplane2(3)+cplane2(4);
    F(2) = x1(1)*midplane(1)+x1(2)*midplane(2)+x1(3)*midplane(3)+midplane(4);
    F(3) = (x1(1)-b2_1(1))^2+(x1(2)-b2_1(2))^2+(x1(3)-b2_1(3))^2-arm_L^2;
    end

fun2 = @plane2;
x0_2 = [0,0,0];
POI2 = fsolve(fun2,x0_2);
%-------------------------------------------------------------------------------
    function F = plane3(x1)

    F(1) = x1(1)*cplane3(1)+x1(2)*cplane3(2)+x1(3)*cplane3(3)+cplane3(4);
    F(2) = x1(1)*midplane(1)+x1(2)*midplane(2)+x1(3)*midplane(3)+midplane(4);
    F(3) = (x1(1)-b3_1(1))^2+(x1(2)-b3_1(2))^2+(x1(3)-b3_1(3))^2-arm_L^2;
    end

fun3 = @plane3;
x0_3 = [0,0,0];
POI3 = fsolve(fun3,x0_3);
%--------------------------------------------------------------------------------

%there will be 2 solutions for each point corresponding to bending in and
%bending out. We need to filter these to just bending out.
m1=[max(POI1(1)); max(POI1(2)); max(POI1(3))];
m2=[max(POI2(1)); max(POI2(2)); max(POI2(3))];
m3=[max(POI3(1)); max(POI3(2)); max(POI3(3))];

%with midplane points, find turning angles of basal joints
q=[0;0;1];%q is a reference vector to measure theta from. Vertical reference was chosen here

%Find turning angle using the dot product of the basal arm vector and the
%reference vector
theta1=eval(acos(dot(m1-b1_1, q)/norm(m1-b1_1)));
theta2=eval(acos(dot(m2-b2_1, q)/norm(m2-b2_1)));
theta3=eval(acos(dot(m3-b3_1, q)/norm(m3-b3_1)));

thetadeg = (180/pi).*[theta1; theta2; theta3];



block.Dwork(1).Data = thetadeg(1);
block.Dwork(2).Data = thetadeg(2);
block.Dwork(3).Data = thetadeg(3);

end Update


%%
%% Terminate:
%%   Functionality    : Called at the end of simulation for cleanup
%%   Required         : Yes
%%   C-MEX counterpart: mdlTerminate
%%



function Terminate(block)
end Terminate

end

0 个答案:

没有答案