How to use classes as Simulink lvl 2-M S-function custom-blocks?

2 ビュー (過去 30 日間)
Erwin Torreao Dassen
Erwin Torreao Dassen 2013 年 1 月 15 日
I'm developing a Simulink model that has to access our library of Matlab classes. Although it should be, as of now, AFAIK, Simulink has no support for M-file S-functions that are classes instead of a bunch of functions. Anyway, I found a way to have an object available to the S-function and use it as a bridge. Details follow. The issue I am having is when calling methods in the object.
In the Simulink model I have a custom lvl 2-M S-funtion block configured as the code below shows. As you can see, in certain call-back functions I have lines that get a 'UserData' parameter from the runtime simulink block handle. Since 'UserData' can be anything I use it store an object. This is accomplished by adding
object_wrapper = someclass(param)
set_param(gcb,'UserData',object_wrapper)
in the InitFcn call-back in the Block properties dialog. The S-function is as follows (I only posted the setup and outputs function since the other registered call-backs are similar):
% Sfunction_wrapper
function Sfunction_wrapper(block)
setup(block);
end
function setup(block)
% Register number of ports
block.NumInputPorts = 1;
block.NumOutputPorts = 2;
% Setup port properties to be inherited or dynamic
block.SetPreCompInpPortInfoToDynamic;
block.SetPreCompOutPortInfoToDynamic;
% Override input port properties
block.InputPort(1).DatatypeID = 0; % double
block.InputPort(1).Complexity = 'Real';
block.InputPort(1).DirectFeedthrough = false;
% Override output port properties
block.OutputPort(1).DatatypeID = 0; % double
block.OutputPort(1).Complexity = 'Real';
block.OutputPort(2).DatatypeID = 0; % double
block.OutputPort(2).Complexity = 'Real';
block.SampleTimes = [1/20000 0];
block.RegBlockMethod('InitializeConditions', @InitializeConditions);
block.RegBlockMethod('Start', @Start);
block.RegBlockMethod('Outputs', @Outputs);
block.RegBlockMethod('Update', @Update);
block.RegBlockMethod('Terminate', @Terminate);
block.RegBlockMethod('SetInputPortSamplingMode', @SetInputPortSamplingMode);
end
function Outputs(block)
% Forward the call to the wrapper
wrapper_mainBlock = get_param(block.BlockHandle,'UserData');
wrapper_mainBlock.outputs(block);
end
% Similar functions for startup,etc,...
function SetInputPortSamplingMode(block,idx,fd)
block.InputPort(idx).SamplingMode = fd;
block.OutputPort(1).SamplingMode = fd;
block.OutputPort(2).SamplingMode = fd;
end
The main point is in the Outputs function where I forward the calculation to the object wrapper. The idea is that inside the corresponding class I have easy access to all the library we have already developed and mainly to instantiated data (states) that can be of any type, contrary to DVectors wich can be only numerical. This would be a good enough solution except for the the following error I keep getting and I don't know why except that it could be something scope related??
Error while running output in someclass.m -> too many arguments... (stack trace)
The signature of the method is used correctly as you can see above. (This is not exactly the error message since I edited the code above.
Any ideas?
Kind regards,
Erwin
  3 件のコメント
Kaustubha Govind
Kaustubha Govind 2013 年 1 月 15 日
Is that the exact error that you see? It is an error about too many input arguments, or output arguments? Are you able to set a breakpoint at the line:
wrapper_mainBlock.outputs(block);
and step into someclass.m?
Erwin Torreao Dassen
Erwin Torreao Dassen 2013 年 1 月 15 日
編集済み: Erwin Torreao Dassen 2013 年 1 月 15 日
The error about too many arguments was solved. Apparently it was related to changing the class file while the model had some hidden instances of the old version of the class (matlab doesn't see these variables).
I got this behaviour corrected for good by adding
delete(get_param(gcb,'UserData');
to the StopFcn callback.
With respect to the other problem (that of data/state persistence) I made someclass to be a handle class (subclassing the handle class), and now I got persistence!
So things appear to be solved!

サインインしてコメントする。

採用された回答

Erwin Torreao Dassen
Erwin Torreao Dassen 2013 年 1 月 15 日
Solved in the comments above.
Main points:
1) someclass has to be a subclass of handle class so as to have data persistence.
2) Add a delete call to someclass in the StopFcn block callback function so as to really remove old instances from memory while developing. You get weird errors if you don't...

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeSimulink Functions についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by