Error in using variable from MATLAB workspace to Simulink?

In my case I have one model file of Simulink. So when for the first time I run the model and I send one signal which I named as "Fs" in the "To Workspace" block. Then I use this "Fs" from the matlab workspace to calculate 'Rate of change of this Frequency signal' using matlab script. I have named the rate of change of frequency as variable "avg_rocof". Now I wanted to use this "avg_rocof" variable in my Simulink model using "FromWorkspace" block. But when I run the model I get the following above error
" Invalid matrix variable specified as workspace input in 'IEEE_14_Bus_System_SM_FFR/From Workspace'. The matrix data must be a real, double, have two dimensions, and at least two columns. The first column must contain time values and the remaining columns the data values. Matrix values cannot be Inf or NaN.
Anyone please assist in this problem?

 Accepted Answer

When you use "From Workspace", the variable must have at least two columns. The first column will be treated as time.
If you are trying to import a value that is not logically a "signal" that varies in time, then there are a small number of possibilities:
  • it is a signal, just a constant signal; in that case use 0 as the first column (time); and configure From Workspace to "hold" the signal; OR
  • it is something you want to treat as a global variable or datastore variable; OR
  • it is something you want to use as a parameter (for example gain for a block)
If you are wanting to do global variables or parameters, then see https://www.mathworks.com/matlabcentral/answers/1653710-global-variable-in-simulink#comment_2009495 where I show how to construct those from the MATLAB level. There are some tricks involved

14 Comments

How to implement this possibility......
"it is a signal, just a constant signal; in that case use 0 as the first column (time); and configure From Workspace to "hold" the signal;"
One way can be as I run the model once get the "Fs" signal value and then using the script I calculate 'avg_rocof". Finally, when I get value of 'avg_rocof" as a scalar value , I simply use a constant block in the simulink and run again the model and I think its one way.
But can you please tell me how to do it using the 1ST Possibility you mentioned above???
avg_rocof_to_import = [0, avg_rocof];
now From Workspace avg_rocof_to_import
@Walter Roberson Thank you very much , it works now. Really appreciate your thorough response.
@Walter Roberson, what is the point advising this, instead of a Constant block?
In order to change a constant block value from the MATLAB level, there are two ways to proceed:
  • know the complete paths to all occurances of the constant block that should use the same value, and set_param() each of them to the new numeric value; or
  • define the value of the constant blocks in terms of a name, and use the kinds of techniques I linked to in order define the name as a param (in which case you do not need to know the paths to any blocks)
Either one requires that the value be "pushed" into Simulink.
Some people prefer to write in terms of From Workspace, which "pull" workspace variables into Simulink, but have the disadvantage that the variable has to be structured with time as the first column.
I suppose these days you might be able to construct a Simulink "Signal" object at the MATLAB level; I have not looked into that. It is probably a "push" technique as well.
I suspect that most people who are thinking about transferring a value from the MATLAB level to the Simulink level do not think about constant blocks; if they do, doing it properly is still more work then using From Workspace. I would tend to expect that Constant Block are more efficient.
Maybe I'm missing something, but for simple cases changing the value of Constant block from the Matlab workspace needn't be so difficult. As @Fangjun Jiang suggests, just make the parameter in the "Constant value" field a variable name, like "cvalue" (no quotes when entering in the block field) and then in the Matlab workspace assign to that
>> cvalue = 5 % or whatever
All block parameters that are set as "cvalue" will then take on the value of 5 when the simulation runs. There are, of course, other approaches, but this approach is the simplest and sounds like it's all that the OP needs, at least to get started.
Having said that, I am confused by one thing. The workflow described by the OP is:
  1. run simulation and send Fs to workspace
  2. from Fs compute the value of a new variable called avg_rocof
  3. run the simulation again using the value of avg_rocof
My question is, what value of avg_rocof is used in Step 1 and how does it get into the simulation? Or is there some structural change to the simulation after step 1 and before step 3?
The error message in the question is caused by the incorrect data format provided to the "From Workspace" block. But once the OP clarified his question, it is clear that a Constant block shall be used. There is no advantage to use the [0 value] trick to make the "From Workspace" block serve as a "Constant" block. In fact, there are only disadvantages.
Simulink models and Simulink blocks use variables directly from workspace. This should be a foundermental knowledge for a Simulink user. The OP didn't know this. He thought "From Workspace" should be used to read the variable from the workspace, since he has used "To Workspace" to save the signal logging to the workspace. This is the root cause of the problem.
@Walter Roberson, I would suggest not to bring in unnecessary topcis. They make the Answer complicated. Rather than being helpful, they overwhelm the reader.
  1. There is no need to mention global variable or datastore variable.
  2. There is no need to mention set_param(). The need for it would be the same, if using Constant block or "From Workspace" block.
  3. There is no need to explain the difference between "push" and "pull", if there are any.
  4. Signal object is irrevelant. It is used to define signal property, not to import value.
I used to "know" that values in the workspace were automatically used in Simulink. But then I went looking for documentation of that "fact", and what I found was documentation that says that the only way to resolve values is through DataStore. And indeed when I referrenced a name in a block, Simulink popped up a request to resolve the name through a datastore, incuding the option to create a new global datastore variable.
What you indicate might be fundemental knowledge for Simulink users, but it does not match anything I found documented. And, frankly, that fundamental knowledge does not match the results of my experiments.
I have, historically, observed Simulink resolving a variable from the workspace of a calling MATLAB function, but only under restricted circumstances involving some block initializations that I was not able to categorize properly. Initial value settings... sometimes. Mask initialization callbacks. But it failed in other cases.
Here is documentation of that "fact" that block parameters can be specified as variables and the value of the variable can be set in the Matlab base workspace (among other options): Block Parameters and Share and Reuse Blcok Parameter Values by Creaing Variables
I've never had Simulink pop up a request to resolve a name through a DataStore, but that's just me and my applications.
I'm really quite surprised that such an approach doesn't match the result of your experiments. What happens if you do the following (I did this in 2021b):
  1. Open simulink
  2. Create a blank model
  3. Create a block diagram with a Constant block feeding a To Workspace block
  4. Double click the Constant block, specify cvalue as the block parameter for "Constant value"
  5. Click OK on the Block Paramters for the Constant block
  6. At the matlab command prompt, assign a value to cvalue ">> cvalue = 6.23"
  7. Simulate the model by clicking the Run button
  8. After the simulation is complete, what does this command show: >> out.simout.Data
Thank you for the reference, @Paul
I notice there that the documentation specifically refers to the base workspace. I don't think I tested base workspace, as part of what I "knew" (from observing discussions) was that Simulink was supposed to look in the workspace of the calling function or in the base workspace, but the discussions had been vague as to which was to be used. If I recall correctly at one point a few years ago the rules about caller / base changed. Also I had absorbed that there was a configuration parameter for From Workspace that could tell it explicitly whether to use caller or base, but that option appears to be removed a couple of years ago.
Maybe you're referring to what happens when executing a model by calling sim from within a Matlab function that is called from a script or the command line like any other function. For example, in 2021b calling this function from the command line
function out = temp
out = sim('untitled');
end
runs the simulation 'untitled' and pulls in block parameter values, like cvalue above, from the base workspace. If I clear cvalue from the base workspace I get:
>> out = temp;
Error using temp
Invalid setting in 'untitled/Constant' for parameter 'Value'.
Caused by:
Error using temp
Error evaluating parameter 'Value' in 'untitled/Constant'
Error using temp
Unrecognized function or variable 'cvalue'.
Error using temp
Variable 'cvalue' has been deleted from base workspace.
Suggested Actions:
Undo the deletion. - Fix
Load a file into base workspace. - Fix
Create a new variable. - Fix
The error message indicates that Simulink was looking for cvalue in the base workspace but couldn't find it (it would have looked in the model workspace first, but it's not there either).
In older versions of Simulink, the sim command had a Name/Value option called 'SrcWorkspace' that could be used to tell Simulink to pull variables in from the 'current' workspace, which would be the function workspace of temp in this example. Check this doc page from 2017b. However, that feature is no longer supported (and was recommended against as far back as 2009b apparently). AFAIK, one has to use the Simulink.SimulationInput paradigm if calling sim from inside a function and wanting to set the values of simulation block parameters from inside the calling function (as opposed to doing something like evalin to the base workspace, yech.)
I'm quite certain that no version of Simulink would never have looked in the workspace of the function that calls sim absent the use of the SrcWorkspace directive, so don't know why such discussions would have been vague.
This doc page Symbol Resolution explains the process. However, that page contains the line:
"Except when simulation occurs via the sim command, the search order is:"
And I cannot find anywhere what the exceptions are for the sim command. Not on that page, and not on the doc page for sim. Oh well.
Also, while on this topic, a block parameter can be any Matlab expression, such as a function call, that evaluates to an appropriate value for the parameter (as discused on the linked Symbol Resolution page). For example, with the Constant block, instead of cvalue as the block parameter, we could enter something like
nchoosek(5,3) % my parameter
The % is treated as a comment symbol as normal. In fact, we could even have
nchoosek(param1,param2) % my parameter
and then Simulink will look for variables param1 and param2 using its normal workspace resolution.
I didn't expect the comments went that long but it was really a good discussion.
@Paul, it is good that you brought up the case where sim() is called inside a MATLAB .m function. It covers almost all the aspects regarding workspace.
  • Regarding auto prompt to create variables, (e.g. in R2022b)
When you add a new DataStoreRead block to a model and specify a variable but the variable does not exist yet, there is a red highlight at the block indicating an error. Click that error or update the model, there will be a "Fix" button. Click it and it will prompt to create the variable. The "visibility" could be the model or "global data store". If model, then a DataStoreMemory block will be added at the root level, which means the data store can be accessed anywhere in the model. If "global data store", a signal object will be created in the base workspace. The signal object is to declare the variable and its properties, not to import values. A different opened model can also utilize this variable thus "global".
When the block is different, e.g. a Constant block, the prompt will be slightly different.
  • Regarding workspace
Base workspace is by far the most commonly used, although a model always has its own "model workspace", which proceeds the base workspace in terms of loading value for variables.
Function workspace behaves the same as in MATLAB.
There is also a mask workspace for a block with a mask.
Searching those terms should lead to the document.
  • Regarding Simulink fundamentals document
I start as
doc, Simulink, Simulink Environment Fundamentals, Simulink Concepts, Simulink Models
On that page, there are images showing blocks using variables, and in the "Data" section, there are documents explaining base workspace.
It seems that these fundamentals are buried too deep. I wish the workspace variable is mentioned in Simulink, Get Started, Tutorials section.
My recollection is that at some point in the past, while testing/fixing code people had posted, that Simulink did read variables from the calling function workspace. It might well have been before R2017b.
Much more recently, I have observed Simulink prompting to create a variable even though there was no DataStoreRead . I encountered the behaviour when I was building the code I linked to above -- one of my goals for that code was to create the objects at the MATLAB level in such a way that Simulink would not pop up such prompts.
I can't say that I've used Simulink in every release, but I'm pretty sure that running a model using the sim command (which is what I think you're talking about here, correct me if I'm wrong) was never supposed to use variables from the calling workspace by default. Hence the need for the 'SrcWorkspace' Name/Value parameter, which defaults to 'base' and always has as far as I can remember.
I do not doubt that Simulink might prompt to create a variable (never experienced that myself). However, if that happened in the context of developing the code referenced in this link, then that is a different issue. That Answer thread referenced this doc page Share Data Globally. However, that doc page is talking about using "global data with a MATLAB Function block," which is a different concept than using variables to define block parameters, which is what we've been talking about in this Answer thread, whether for the Constant block or the From Workspace block.

Sign in to comment.

More Answers (1)

The error message has explained the problem. Maybe you are not familar with the usage. Double click the "From Workspace" block, click Help to open the document. There should be some example models. You can look into the example models to figure out the proper format for importing your "avg_rocof" data.
Basically, if avg_rocof=rand(10,1), a column vector, then you need to construct a column time vector, e.g. t=(0:0.1:0.9)'
then the data for the "From Workspace" block should be [t;avg_rocof]

3 Comments

Thanks for replying.
My 'avg_rocof' data is as shown in the figure that I have attached. It's ' -0.2762 ' 1x1 double .
Now, do I need to construct a column vector in the same script where I am calculating 'avg_rocof'?
And the data name [t;avg_rocof] in the "For Workspace" cannot be entered as it doesn't accept variable name like that.
This is my script for calculating 'avg_rocof'.
f = Fs.signals.values; % frequency signal
Dt = 20e-6; % sampling step size
R = 0; % rocof initialisation
for k = 196002:1:316002
R = R + (f(k)- f(k-1))/Dt;
end
avg_rocof = R / (316002-196002);
display(avg_rocof);
avg_rocof is a scalar value, not a vector?? 'Rate of change of this Frequency signal' sounds like a time-varying signal, not a single value.
But, if you are just take the average value, like the name indicates, then you can use a Constant block, not the "From Workspace" block. Specify the Constant value as avg_rocof.
@Fangjun Jiang Thank you for your valuable comments and help.

Sign in to comment.

Categories

Community Treasure Hunt

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

Start Hunting!