In Simulink, is it possible to send data to workspace in real-time using the 'ToWorkspace' block?

Hello everyone,
I have a large simulink model. In this model I calculate certain variables that are essentially [1x1] constants. For example, I analyze an electrocardiogram recording to count the number of heart cycles: num_cycles.
I would then like to use such constants like num_cycles in various other blocks like selectors and Matlab function blocks to fix the size of various variable size signals.
Now, if such constants would be defined in the workspace, I could just type num_cycles or whatever in the Simulink selector block, or in the output size of the Matlab Function's explorer. I have tried using the block "ToWorkspace" to do this. However, this block only sends data to workspace once the simulation in stopped or paused.
My question is: is there any way to send variables to the workspace immediately so that they can be accessed by future blocks as if they were workspace variables?
Thank you,
Rafael

1 Comment

I don’t think you can do this. Please post here if you find a solution.
However, the answer may be in your question. Did you read the doc on “variable size signals”?

Sign in to comment.

 Accepted Answer

9 Comments

This.
A bit more workflow info:
  • Create a Simulink.Signal object called 'num_cycles' in a Data Dictionary and link it to your model.
  • Use a Data Store Write block to write to 'num_cycles'
  • Use Data Store Read blocks to read from 'num_cycles', or in Stateflow charts and MATLAB Functions, add a variable object and change 'Scope' to be 'Data Store Memory' in the Model Explorer.
This way you will be able to read and write to num_cycles as a global variable. You can type expressions such as:
num_cycles = num_cycles + 1;
So you can read and write in one expression.
Hi Walter and Jonas,
Thanks for the answers!
I had no idea about data stores, I'll give this a long read.
I'll get back to you when I've played around a bit.
Rafael
Alright, so I spent the day reading and trying this out.
I learned a lot but it didn't really work I'm afraid.
I think I didn't explain myself too well, or maybe I have not properly understood what I learned.
The main problem here I'm trying to address is signal sizes. I would like to be able to specify the width of signals in the model based on values calculated in the same model.
I used the num_cycles as an example for such a value.
I followed the workflow instructions suggested by Jonas:
  1. I created num_cycles as a Simulink.Signal object in a data dictionary and linked it to the model.
  2. I wrote to num_cycles in the model as soon as I had calculated it.
The idea is that I could then try 2 different strategies:
a) 3. In the model explorer of a Matlab Function block whose output dimensions I wanted to define using num_cycles, I added a new datum 'num_cycles' in their model explorer and set the scope to Date Store Memory.
I then used num_cycles in the definition of a Matlab Function block's model explorer output size and do something like:
If I did this, inside the Matlab Function block code I could play around with num_cycles and do stuff like num_cycles = num_cycles +1. However, I cannot use num_cycles to define the ouput size/dimensions like in the above figure. If I tried, I would get the following error:
Size computation for 'my_matlab_function_block' failed. Size definition is referring to the value of 'num_cycles' which is not a constant, or a constant initialized from workspace.
Alternatively I also tried...
b) 3. Using a selector block with num_cycles in the dialogue box to essentially convert a variable-size input signal with an artificially large size, to a fixed-size signal with a tight size that I know as a result of the model's calculations (i.e. num_cycles):
If I try to run this, I get the following error:
For dimensions 1, parameter 'Indices' in '.../Selector': invalid setting in '.../Selector' for parameter 'Indices'.
It doesn't like num_cycles.
Now,for both these strategies, if num_cycles were defined in the base workspace, this would work. The problem is that Simulink will only "look at" the base workspace num_cycles at the start, during compilation, when defining signal widths. Hence, I would first need to predefine it anyhow before compiling the Simulink model to e.g. num_cycles = 1.If I then change the value in the base workspace using assignin() or similar after I calculate the number of cycles in the Simulink model, it will not matter because the num_cycles in the selector index definition will be the original one (i.e. 1) and not the one calculated during execution.
Like Ameer Hamza suggested in another answer, maybe its just not possible to define signal dimensions 'on-the-fly' like that.
Thoughts? Thanks by the way!
For option b), use num_cycles to generate an external index input to the selector block, with the Index Option set to one of the port options, not dialog as you have above. Open sldemo_varsize_basic for an example.
Hi Paul,
I tried that and to be honest I'm not really sure if it's worked or not.
I did the following:
The input signal 'heart_cycle_idx' is variable size and specified as [175000x1]. These are the dimensions I specified for it in the model explorer.
The data store 'num_cycles' is 240. Hence, only the first 240 elements of 'heart_cycle_idx' are meaningful - the rest is nonesense/undefined. I want to use the selector to only consider these meaningful first 240 elements.
As we can see, the model runs, but the output of the selector block still appears as a variable signal having dimensions [175000x1] (I should think it would be a fixed signal of dimensions [240x1]).
However, if I then use the Width block to calculate the width of the selector's output, it shows from the second display that its 240 - the correct number.
So I'm scratching my head a bit wondering what's going on here.
As far as I understand, what you're seeing is what is expected. You allocated space for a 175000 element signal, and that space is allocated statically. That is, the output of your selector block will always have 175000 elements, which you'll see if you send the output of the selector block into a ToWorkspace block. However, at each time step only the first num_cycle elements in that signal are valid and usable, and elemennt 241:175000 will be filled with nan values in the workspace. But internal to the diagram that signal will have an effective width of num_cycle at each time time step. So if you add a scalar to that signal, the scalar is added to the first num_cycle elements, whatever num_cycle may be. If you haven't already, check out the demo sldemo_varsize_basic. Keep in mind that not all blocks support variable size signals.
Ahh, I see now. I'll work with this. Thanks for all your answers!

Sign in to comment.

More Answers (1)

2 Comments

Hi Ameer,
This is the first thing I tired.
I used a wrapped Matlab function (declaring it extrinsic to code-generation) inside a Matalb Function block to then use assignin() to pass the variables to the workspace.
Initially, I thought this had worked - the variables had been passed to the workspace correctly. However, the problem is that if I use these variables to define signal sizes or whatever, I need to have them defined at the start, while the simulink model is compiling. I could do this by predefining some dummy variable (e.g. num_cycles = 0) in Matlab, and then running the Simulink model. This variable would then be overwritten in the model with assignin( ) with the correct number of cycles. The problem is that the various blocks that make use of num_cycles will only consider the initial declaration (num_cycles = 0) which I guess is done during compilation. Future changes in this workspace variable during execution will not be reflected in the Simulink model, which will still think that num_cycles = 0.
Thanks anyhow,
Rafael
I think that changing the parameters of a compiled model using values from the base workspace is not possible. You can read these values using extrensic(), but using them to changing the signal dimensions might require the re-compilation of the model.

Sign in to comment.

Categories

Find more on General Applications in Help Center and File Exchange

Products

Release

R2020b

Asked:

on 25 Oct 2020

Edited:

on 27 Oct 2020

Community Treasure Hunt

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

Start Hunting!