I need help with running a Simulink model with the data from MATLAB workspace contained in structures. Below is a very simplified use-case of what I would like to do
Use Case :
I have a structure in MATLAB workspace called "data_in", and it has two fields x, and y which are vectors. I have a simulink model with two Inports named x and y.
This is what I would like to to :
a. Read the name of the Inports from the Simlunk Model. In this case it would be x and y
b. Programmatically assign the data from the structure - "data_in" to the ports "x" and "y" in the Simulink model. The structure "data_in" contains two vectors "x" and "y" to be mapped to Simulink Inports
The above use case is a very simplified scenario. The model that I intend to use can have 100 inports, and thus I do not want to use "From Workspace" block, as it would be impractical for me to add 100s of them
How can I handle such a situation in Simulink. I am a little more than a beginner in MATLAB and Simulink. So, a detailed answer would help me a lot
If I get correctly your question, and the inputs are time-variables, you may use From Workspace and call your initialization script by InitFcn in Callbacks.
assuming you have an initialization script named init_script:
put in InitFcn this: init_script; so as you run Simulink that script is run first.
assume this is your timeseries in init_script:
ts = timeseries(randn(10,2),'Name','TS');
put ts in the From Workspace:
But if these are not time variant vectors do the same and use constant block instead, inside its value field put the vectors' name and again put the script that contains these vectors in InitFcn in Callbacks:
X = randi(10,6,1);
Y = randi(10,6,1);
then do the operations you need:
so the To Workspace block named as simout will give you:
simout.Data(:,:,1)
ans =
14
9
16
16
10
3
and finally, if you have lots of those vectors and components, you can create them easily from Matlab Workspace:
my_struct.x = randn(6,1);my_struct.y = randn(6,1);
new_system('myModel')
open_system('myModel')
pos = [10 10 20 30]
for i =1:10
add_block('built-in/Inport',['myModel' '/In1'],'Position',pos);
add_block('built-in/Constant',['myModel' strcat('/Cx', num2str(i))],'Position',pos+2);
add_block('built-in/Constant',['myModel' strcat('/Cy', num2str(i))],'Position',pos+i);
pos = pos + 1;
X_vector = my_st.x
set_param(strcat('myModel/Cx', num2str(i)),'Value', X_vector)
Y_vector = my_st.x
set_param(strcat('myModel/Cy', num2str(i)),'Value', Y_vector)
....
of course this for loop code is here to give you the idea, and in reality will be more complex and you will know how to handle it the best.
Related
Hello I'm building a exe from a simulink model and in order to do that I pass the inputs to it through a .mat file.
My question is, since in my model is present a "for each" block, how can I store the data in the .mat file? Normally (without the for each block) I would store the input as a constant vector in the workspace (see the upper part of the simulink model) and it will handle automatically how to pass the data during the simulation time. But in my case, since I want to export as .exe and pass the input programmatically, I need the input as .mat file and the presence of the "for each" block screw up the building the vector time (since is unclear how to combine time vector with data vector inside the .mat file because is unclear to simulink which data take at a given simulation time.
Thank you for any help!
It's not really clear what the specific problem you are having is.
In your upper diagram, the model will run when you have a variable
>> input = 1:3;
If you turn on Display->Signals & Ports->Signal Dimensions then you'll see that the signal coming out of the Constant block has a dimension of 3.
For the lower diagram, create a variable in MATLAB, that since it will be used in a From File block, must adhere to the specifications required for that block, which means the first row is a time vector, so
>> t = [0 10]
t =
0 10
>> u = [1 1;2 2;3 3]
u =
1 1
2 2
3 3
>> tu = [t;u]
tu =
0 10
1 1
2 2
3 3
And then save this variable to your file,
>> save input tu
Now the signal coming out of the From File block will also be of dimension 3.
Change the values of t and u to suit your specific problem.
I'm a super beginner in Simulink models and control systems.
I have .slx Simulink model for drone dynamics system.
It takes in two inputs (roll cmd, pitch cmd) and outputs velocity x, velocity y, position x, and position y.
From here, it seems like I can open the system by calling
open_system('myModel.slx', 'loadable');
But how do I put inputs and get output values?
Is there a way I can do this in a gui?
EDIT:
Here is the full layout of my model:
When I did
roll_CMD=10;
pitch_CMD=20;
I got a warning saying:
Input port 1 of 'SimpleDroneDynamics/...' is not connected.
How do I feed inputs using port numbers?
How do I get outputs with port numbers? I tried
[vx, vy, px, py] = sim('SimpleDroneDynamics.slx');
and got an error saying
Number of left-hand side argument doesn't match block diagram...
Is there a way to continuously feed inputs at every time step? This being controller module, I think I'm supposed to feed in different values based on output position and velocity.
EDIT2:
I'm using Matlab2017a
About the first two points of your question:
In simulink:
For the inputs you can use a constant block and when you double click the input block you can assign a value, which can be a workspace variable.
To get the outputs to your workspace you can use the simout block (make sure to put Save format to array).
Connect inputs to your simulink model
Connect outputs of your simulink model to the simout blocks.
MATLAB script
clc;
clear all;
roll = 10;
pitch = 20;
sim('/path_to_simulinkmodel.slx')
time = simout(:,1);
velocity_X = simout(:,2);
velocity_Y = simout(:,3);
position_X = simout(:,4);
position_Y = simout(:,5);
About the third point of your question
You can define the duration of your simulation in the block diagram editor. You can put a variable which is defined in the calling script. There are multiple ways of achieving time dependent input variables:
One option I personally don't recommend is using a for-loop and calling the simulink model with a different value of roll and pitch
for i = 1:numberOfTimesteps
roll = ...
...
sim('simulinkModel.slx')
end
A second and more efficient approach is changing the constant blocks to other source blocks like ramp signals or sinusoid signals
First of all Simulink model use main Matlab workspace. So you can change your variables values at command window (or just at your script) and run Simulink model.
There are several ways to initialize this constants for Simulink. One more useful way is to create script containing all your variables and load it at Simulink model starts. You can do it by adding script name in Simulink/Model Explorer/Callbacks. (There are different callbacks - on Loading, on Starting and etc.). Read more about this: here.
Now you can run your simulation using sim function:
sim('name_of_model')
name_of_model must contain path if model is not in the active MATLAB folder (active folder you can see in your matlab window just under the main menu).
There are different properties of sim function, read about them in help this can be useful for you. By the way: you can change some parameters of your model using sim. You even can find any block in your model and change it's properties. Read more about sim and about finding current blocks. Interesting that the last solution give you ability to change parameters during the simulation!
About getting output. After you run simulation you get tout variable in main workspace. It is an array of timesteps. But if you add outport block (like at my image) you also get another variable in workspace yout. yout is an Datasets. It contain all your outports values. For 2 outports for example:
yout
yout =
Simulink.SimulationData.Dataset
Package: Simulink.SimulationData
Characteristics:
Name: 'yout'
Total Elements: 2
Elements:
1 : ''
2 : ''
Get the values of any of outports:
yout.get(1).Values
it is a timeseries data type, so:
yout.get(1).Values.Time - give you times
yout.get(2).Values.Data - give you values of this outport at each time
We have one more method to take output values:
[t,x,y] = sim('model_name')
it returns double arrays. t- time array, y - matrix of all outports values (it already double and contain only values without times, but for each simulation time!)
So now you can create common Matlab GUI and work at this variables! There is no any difficulties. You can read more about GUI for Simulink here.
I have a .mat file which has a structure loaded into the Workspace. I have created a simulink model and want to Import the signals from the Workspace. What should be the Input value for the Data Parameter of the 'From Workspace' block. The Name of the structure is Measurements, the Signal Name is B_cal and it has further elements as time,name, Units and value. I know that the structures can be accessed by somewhat like this command :
Measurements.B_cal.value
But i am unable to set the Input Parameters. Could anyone help me with this ?
There are some limitation to use structures through the FromWorkspace block:
A MATLAB expression that evaluates to one of the following:
A MATLAB timeseries object
A structure of MATLAB timeseries objects
A two-dimensional matrix:
The first element of each matrix row is a time stamp.
The rest of each row is a scalar or vector of signal values.
A structure, with or without time, which contains:
1) A signals.values field, which contains a vector of signal values
2) An optional signals.dimensions array, which contains the dimensions of the signal
3) An optional time vector, which contains time stamps
More useful information you can find in help.
So in your case you can use different methods. I'll give some examples:
1) define your struct in necessary format:
t = (1:10)'; %'
v = [6 9 3 1 7 0 7 3 8 1]'; %'
measure.time = t;
measure.signals.values = v;
Important moment here: t andv must be a columns! rows will not work!
If you need to use several rows of data use multidimensional v and add
measure.signals.dimentions = size(v,2);
2) You can see ths time field is an optional. If you do not have it you need to set Sample time in block other than 0 and, clear Interpolate Data, Set Form output after final data value by to a value other than Extrapolation. Furthermore, you need to define time field:
mystruct.time = [];
3) If you don't want to change your structure, you can use next:
t = (1:10)'; %'
and set this in Data of FromWorkspace block: [t, Measurements.B_cal.value].
4) There are some useful methods: use timeseries or just matrix. But it's not really your case if you need to use your structure.
I'm using a lot of MATLAB for a Control class and something is really bumming me out. They want us to use a lot of Simulink even though I find the visual representation not that helpful and the interface between Simulink and MATLAB scripts hard to figure out in general.
So I have a model and I have added scopes for sinks which can save data directly to the workspace when ran from Simulink. However when I use the command sim in the script to directly use the model according to some parameters (stopTime, solving method, etc.) the results are buried in an object which is poorly documented to say the least so say I have:
simout = sim('lab','StopTime','100','Solver','ode1','FixedStep','2');
Now I have an object in my workspace but to access the data I want I need to go 3, hell 4 layers deep sometimes in the members of simout. My first question is :
Is there a way to access directly or at least know what those members are without using the tedious use of who.
I don't want to compile code to access its documentation! And help is not really helpful for those situations.
Why doesn't the Simulink model save the data when invoked like prescribed in the sink properties. I know that the line of code I mentioned overides some of the simulink block prescriptions (e.g. the solving method used).
How to know how simulink models interact with matlab scripts, granted I am a noob in coding in general, but the documentation doesn't really tell me what are the formal definitions of the model and the way it is used in matlab. I am scared at some points the default settings of 'sim' will overide some settings I set up in an earlier model which would prove to be a nasty buisiness to debug.
TL;DR Is there a quick way to access deeply buried members of an object? For example right now I have to do:
simout = sim('lab','StopTime','100','Solver','ode1','FixedStep','2');
who(simout)
ScopeData = (simout.get('ScopeData'))
signals = (ScopeData.signals)
time = (ScopeData.time)
Can I do something more C-ish of the sort of (Simout->ScopeData).signals?
And finally, why is the MATLAB suite presented like it was an app for day-traders when it is used a lot by EE people who in general need to know their coding? Why are libraries with headers and good documentation for what you are importing in your code (e.g. boost, string etc.) not used? This last option might be less pretty by hiding the mechanics, but to be able to write code properly I feel like I have to know most of the underlying mechanics of the code.
Invariably when most people start off using MATLAB or Simulink, they hate it. The main reasons I see for this is people are taught MATLAB very poorly which prevents them from understanding the power of MATLAB and when it should be used.
Before I get into describing how the MATLAB workspace, m files and Simulink are all related let's first define what each of those is separately and a few of the things you can do with them.
The MATLAB Workspace
The MATLAB workspace contains all of the variables you have created in MATLAB either explicitly via the command window or implicitly through running a .m file (don't worry I'll come back to these). The simplest method to add a variable to the MATLAB workspace is to directly type into the command window like
>> A = 1
A =
1
which adds the variable A to the workspace and assigns it a value of 1. Even simpler though is to simple type 1 like
>> 1
ans =
1
which adds the variable ans to the workspace with a value of 1. The default workspace variable for any command executed by MATLAB that is not explicitly assigned to a variable is ans.
The workspace browser in MATLAB displays information about all of the variables currently in the workspace. For instance if we were to execute, in the command window,
>> A = 5;
>> B = [6 8];
>> C = [3 6 7; 9 11 12];
>> D = eye(max(size(C)));
the workspace browser would look something like
Some Helpful Workspace Commands
The save and clear commands are helpful commands that work with the MATLAB workspace. save lets you save variables from the workspace to a file whilst clear lets you remove variables from the workspace, thus freeing up memory. clear all will clear every variable from the workspace.
m Files
An m-file (or script file) is a simple text file with a .m file extension. In it you type MATLAB commands which can be executed sequentially by executing just the m-file in the command window. For instance, lets copy our commands from above and paste them into an m-file called mfile_test.m. Now lets add the command C - A to the bottom of the m-file (note do not append a ; after the command). We can execute this m-file from the command window and see the output of all of commands within it executed sequentially
>> mfile_test.m
ans =
-2 1 2
4 6 7
m Files and Functions
m files can also contain functions. For instance we could write a function that calculates the area and circumference of a circle like
function [A, C] = circle(r)
A = pi*r*r;
C = 2*pi*r;
end
and put it in an m-file called circle.m. We could then use this like
>> circle(5)
ans =
78.5398
where ans now holds the area of a circle with a radius of 5 or
>> [A, C] = circle(5)
A =
78.5398
C =
31.4159
where A holds the area of the circle and C the circumference.
Simulink Models
Simulink is a graphical tool that can be used to model various different types of systems as well as modelling dynamic system behaviour. Simulink is closely embedded into the MATLAB ecosystem which adds additional power to it (again I'll come back to this later when describing the similarities).
Simulink models contain blocks which all exhibit different behaviour. There is also the functionality to create your own Simulink blocks should you need. Models in Simulink are made by connecting blocks of different kinds to emulate the system you want to model.
Simulink is quite extensive and I don't recommend learning it on your own. The best way to learn Simulink is invariably as part of a course, Control Systems or Systems Analysis type courses are ideal for this purpose. For that reason I'm not going to dwell on it for much longer here.
How are the MATLAB Workspace, m Files and Simulink all Related?
Well, the MATLAB workspace is available to both m files and Simulink. Variables in the MATLAB workspace can be used in both m files and Simulink.
m files that contain only scripts (and not functions) will write every variable created in them to the MATLAB workspace. m files that contain only functions won't write any of the new variables used in those functions to the MATLAB workspace. The only way a function will alter variables in the MATLAB workspace is by assigning an output value to ans or if you explicitly declare output arguments when calling the function.
Simulink and the MATLAB workspace have a very similar relationship to m files and the MATLAB workspace. Any variable in the MATLAB workspace is available for use in Simulink (in any part, including configuration). For instance in the below configuration I use the MATLAB workspace variables start_time, stop_time and step_time to set up the parameters of model. Typically I would define these in an m-file before I run my Simulink model with sim(). This is how we can relate all 3 together.
Simulink can write variables to the MATLAB workspace by adding output arguments to the sim() command. However, as you've found this can be quite nasty to navigate and extract what you really want! A better approach would be to use the Data Import/Export options in Simulink coupled with a To Workspace block to grab the outputs that you are concerned with so that you can ignore everything else.
Below I have a screenshot of the Simulink Data Import/Export pane. You can see there are options in here for us to send variables to the MATLAB workspace. Typically, the most common you would need is tout which will be a range given by start_time:step_time:stop_time from the earlier configuration pane. Other areas that would be of primary interest in this screen would be xInitial and xout which are used in Root Locus analysis.
However, all that aside one of the best blocks in Simulink is the To Workspace block. This block can be used to store variables directly in the MATLAB workspace and is one of the keys to being able to link MATLAB and Simulink. You get the power of Simulink but the computational and plotting abilities of MATLAB. I've included a screenshot of it below as well as a typical configuration I would use. The default Save Format for this block is Timeseries, however, I recommend changing this to Array as it will make your life much easier.
OK, where was I? I feel like I'm giving a lecture instead of writing an answer!
A Practical Explanation
Simulink Model
So now let's put everything we've learned into practice with a simple example. First we are going to create a simple Simulink model like this
Now we'll set up our configuration for this, as before for the Solver section
We'll also untick Limit data points to last: in the Data Import/Export section
And, that's it. Our simple Simulink model has been created and setup. For the purposes of this answer, I'm saving mine as stackoverflow_model.slx.
MATLAB Script
Now we'll create simple MATLAB script (m-file) called stackoverflow_script.m that will set up the necessary variables for our Simulink model by adding them to the MATLAB workspace. We'll then call our Simulink model and check what new variables it added to the workspace. And, finally we'll generate a simple plot to show the benefits of this approach.
So here is the MATLAB script
% Script developed to describe the relationship between the MATLAB
% workspace, m-files and Simulink
close all
clear all
% Initialise variables
start_time = 0;
stop_time = 10;
step_time = (stop_time - start_time) / 1000; % Creates 1000 + 1 points
% Choose k
k = 60;
% Execute Simulink model
sim('stackoverflow_model');
whos % To display variables returned from Simulink
% Plot results
figure;
plot(tout, yout, 'r');
title('Sample Plot');
xlabel('Time (s)');
ylabel('Output');
Putting it All Together
Now we execute this script in the command window with stackoverflow_script and sit back and marvel at the POWER of MATLAB and Simulink combined.
>> stackoverflow_script
Name Size Bytes Class Attributes
k 1x1 8 double
start_time 1x1 8 double
step_time 1x1 8 double
stop_time 1x1 8 double
tout 1001x1 8008 double
yout 1001x1 8008 double
We can see from the output above that all of the variables Simulink needs (k, start_time, step_time and stop_time) are all in the MATLAB workspace. We can also see that Simulink adds 2 new variables to the MATLAB workspace tout and yout which are simple 1001x1 vectors of doubles. No nasty structs to navigate.
And finally, this produces a nice plot
And so that concludes our whistle stop tour through MATLAB, m files and Simulink! I hope you've enjoyed it as much as I did writing it!
P.S. I haven't checked this for spelling or grammar mistakes so edits are very much welcome ;)
General
Well to put it short workspace is the variable-environement you are working in. If you run a script, your workspace is 'base', which is the same the console uses. So Matlab does have different environements, one is a kind of included environement known as path, the other one is for variables, known as workspace.
Simulink uses a different one, which prevents shadowing variable names I guess.
To check check members in the current workspace use who
To write members to another workspace use assignin
To run something in a specified workspace use evalin
Your Questions
1.
Who lists all the variables in the current workspace you don't need it for the thing you wanna do.
The whole simulink documentation isn't that good...
2.
It does...
3.
If you run a script and define variables they are defined in the base workspace. When you specify a variable in simulink by just entering its name (for example a), it does load it from the base workspace (hence this way arround no problems).
The other way arround is to either use the given export blocks, or specify export values in your own blocks by either using global or assignin.
4.
If you open the scope block and hit the options-buttion (the little gear), you can select an export option. You can aswell specify the type you wan't to use. You seem to use the struct with time option, which is the one with the most lvls, I'd suggest to use the array-type if your problem is just the fact that it is a struct.
You can also just use the Outputblock to specify the export type and name.
So I'd go with:
sim('modelname');
signals=ScopeData.signals;
time=ScopeData.time;
Or when specified as an array:
sim('modelname');
signals=ScopeData(:,2);
time=ScopeData(:,1);
In the example above I don't specify the way the model is run, however you can also specify it as you posted.
I would like to use jtraj to specify a trajectory in a Simulink model. Below are what I attempted to retrieve in the command prompt:
Q0 = [1 1 0];
Q1 = [1+0.5*cos(2*20) 1+0.5*sin(2*20) 0];
t = 0:0.1:20;
[Q, Qd, Qdd] = jtraj(Q0, Q1, t);
However, I don't know how to include such trajectory data in the Simulink model easily. Any comments?
Thanks in advance.
If I understand your question correctly, you want to import some time-dependent data as a signal in a Simulink model, correct? There are two ways you can do this,
Using a root inport, and then importing the data using the Input field on the Data Import/Export page of the configuration parameters. See the documentation for more information.
Use a From Workspace block to import the data from the base workspace.
i think there is some ways:
you can write your data to m-file (for example by test.m name)
then befor running simulink model, you can run this m-file,
in this case you can use Constant block whit variable's name that exists to workspace.