How to add a parameter value to the icon of an S-function block

I'm new to S-function blocks in Simulink but I've made a working S-function block and now I want to display a value on its icon.
Right now, my Icon & Ports script looks like this:
However instead of the text 'MKF' being static, I want it to display a string from my first parameter:
disp(block.DialogPrm(1).Data.label)
Obviously this doesn't work. This is how you access parameters from within the S-function m-file.
How can I get the same variable from my S-function parameter to the icon script?
I looked in the Parameters & Dialog menu tab and it looks like this:
Does one of these contain my parameter?

 채택된 답변

Bill Tubbs
Bill Tubbs 2022년 2월 13일
편집: Bill Tubbs 2022년 2월 13일
Based on the comments in response to Benjamin's answer, here is the complete and concise answer to the question:
  1. First create a mask for the block. Right click on the block and select Mask > Edit Mask.
  2. Add the parameters you want to the mask in the Parameters & Dialog tab, in my case just one parameter called 'obs':
3. Now you can use these parameters in the Icon & Ports script. For example:
disp(obs.label)
4. And when the user double-clicks on the block they will be able to specify the parameters:
4. Finally, right click on the block and select Mask > Look Under Mask. Now add the parameters you want to pass to the S-function as a list of comma-separated names. In my case, just the one parameter 'obs':
Presumably, now the 'obs' reference is to the block's own parameter rather than an object in the MATLAB workspace as it would have been before you defined 'obs' in step 2 above.
5. These parameter(s) will now be accessible to the S-function in the usual way. For example:
% Get observer struct
obs = block.DialogPrm(1).Data;

추가 답변 (1개)

Benjamin Thompson
Benjamin Thompson 2022년 2월 10일

0 개 추천

In the Icon and Ports tab, set Run initialization to on, then anything you define in the mask workspace in the Initialization tab can be used in your drawing and display commands in Icon and Ports. See the MATLAB documentation "Mask Editor Overview" for more information. In the Initialization tab you can use the get_param commands to get parameter values.
Alternatively, use Block Annotations. Right click on a block and go to properties. Any parameters you created in your mask will also be available there for display, but it will be above or below the block rather than inside.

댓글 수: 9

Thanks, that worked. That gcb trick is barely mentioned in the documentation! Here is how I did it:
I added the following to the initialisation script:
obs_label = get_param(gcb, 'Parameters');
(Turns out Parameters is simply a char of the text entered into the Parameters dialog box on the S-function mask).
And I changed the Icon & Ports script to:
port_label('input', 1, 'u')
port_label('input', 2, 'y')
port_label('output', 1, 'xhat')
port_label('output', 2, 'yhat')
disp(obs_label)
Is that the right way to do it?
Or maybe, I should use this to make it work when there are multiple paramaters:
param_names = strsplit(get_param(gcb, 'Parameters'), ',');
obs_label = param_names{1};
This seems a bit odd. Isn't there a way to access the block workspace and get the first parameter itself, directly?
Update: In fact, this isn't what I want. This gives me the name of the MATLAB variable passed to the S-function block. What I want is the value of that variable.
Here is an example. So if you created to mask parameters p0 and p1 whose values are set by edit boxes, then add a disp statement in the icon drawing box like:
disp(['p0 is ' get_param(gcb, 'p0')]);
Then you get "p0 is 1" on your block. If this is not what you are looking for let us know. The mask controls are generally not type checking data that the user types into the edit boxes on the mask. I think your goal was to just copy the information from the mask to the block display. In the Initialization tab you can also add data type conversion stuff, data validation stuff if you don't like what was entered, etc. I added simple stuff there in my example.
With the block in question selected in Simulink, you can also test these get_param calls in the MATLAB workspace:
>> get_param(gcb, 'p0')
ans =
'1'
S-function masks have two parameters:
  • S-function name (char)
  • Parameters (char)
I can see how to get the char 'Parameters'. But what I want is the object in the base workspace which has the first name given in the Parameters parameter.
I managed to achieve it as follows in the initializion script:
param_names = strsplit(get_param(gcb, 'Parameters'), ',');
obs = evalin('base', param_names{1});
obs_label = obs.label;
Not sure if this is the most elegant way to do it but it works. As long as the object I want is always the first name in the list this should work.
What confused me is I initially thought the S-function parameter inputs would be in the block workspace somewhere. But apparently not (only their names).
You should be able to simplify your procedure for getting the value of a parameter as I have shown here and in my example. Are you setting the Name field of the parameter in the mask editor, and setting the Run initialization option in the Icon and Ports tab to On. If so, get_param should return the value of that parameter as a string, which you can then use directly in a call to disp in the Icon and Ports tab. If you are having problems post your example.
Thanks, but I think there is a misunderstanding between us. I want to use the following S-function parameter in the icon script:
block.DialogPrm(1).Data.label
Are you familiar with S-functions and S-function blocks? In your comment you show how to use a parameter from the mask. The S-function block has a pre-defined mask which I am not changing. Although it contains a parameter called 'Parameters' this does not appear to contain the value of this block parameter. Instead it seems to be a char of the text (parameter names separated by commas) specified by the user in the mask. I want to access the value of the first parameter specified.
For clarity, here is what the mask for my S-function looks like after specifying the parameter ('MKF2'):
Note that the MKF2 object actually exists in the MATLAB workspace. This is how you pass parameters to an S-function.
Yes I have built and masked many S-Functions. I now understand you are accessing the comma separated list of symbols in the Parameters edit box of the S-Function block properties. The more common approach to mask design and mask drawing is to use mask variables, and those mask variables are set by the edit boxes, check boxes, buttons, sliders, etc. that the mask designer puts into the mask. Or they are defined in the Initialization tab as internal mask workspace variables whose values are defined in some way from other mask variables.
Then, you can pass those mask variables to your S-Function in the parameters list.
So, why not use a base workspace variable? There are many cases where the base workspace is not available to your block: the model using the block may be configured to use Model Workspace only, or data dictionary only, as its extenal data source. The S-Function may be inside a masked subsystem itself.
Another consideration is the possibility of using your S-Function block more than once. What if you wanted three instances of your block and wanted to associate them with MKF1, MKF2, and MKF3 parameters in the base workspace. So you give the block a mask accepting one parameter, create three copies of that block in your model, and then change the mask parameter for each block to MKF1, MKF2, and MKF3 respectively. In the mask workspace it is always the same variable name and you reference this in your icon drawing commands as well as in the parameter list passed to the S-Function code.
Okay thanks. I think I understand what you are saying. I should forget the default mask for the S-function and create my own custom mask with appropriate input boxes for the parameter inputs (just the MKF object in this case). Then, I will be able to refer to those mask parameters directly in the icon script, right?
Obviously, the parameters still need to be available to the S-function but it sounds like there is a way to do this via the parameters list. Do I still need to specify the s-function name ("mkf_observer_sfunc") as a parameter or can this be 'hard-coded'?
I've added the observer to the mask as a parameter and I can now access it in the icon script:
Mask now looks like this:
Now I can use this in the icon script:
disp(obs.label)
However, this obs parameter is now not being passed to the S-function! (somehow the original parameter value is being passed).
Benjamin, you state above that "you can pass those mask variables to your S-Function in the parameters list."
I'm not sure how exactly. My S-function is currently using this method (described here):
% Get observer struct
obs = block.DialogPrm(1).Data;
B.t.w. Is there a tutorial on how to make a mask for an s-function block? I can't find one.
Finally figured it out! I found the answer to the last bit here.
As well as editing the mask to add your parameter to it, you need to select the "Look under mask" menu option (right click on block and look in Mask menu). This shows the default S-function mask, where you can now add the mask parameters which will be passed to the S-function:
For the benefit of others, I think I should write a concise explanation of the complete answer as a separate answer.

댓글을 달려면 로그인하십시오.

카테고리

도움말 센터File Exchange에서 Model, Block, and Port Callbacks에 대해 자세히 알아보기

제품

릴리스

R2019b

질문:

2022년 2월 10일

편집:

2022년 2월 13일

Community Treasure Hunt

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

Start Hunting!

Translated by