Store signal values, output as vector for function input - matlab

Im trying to do some calculations in a Matlab (R2015b) Simulink function block. I use a signal that gives discrete values in 1-minute intervals.
What i want to do is store the signal values of 1 day (1440 values), convert them into a vector and input it in my Matlab function for calculation (getting time between first and last value > x). All while the simulation is running.
Unit delay, and Transport delay blocks wont work because i need all the stored values at once.
Any ideas on this are much appreciated!
Thanks!

You need to add a "To Workspace" block to your simulink diagram. Setting the options as you wish will allow you to save all the outputs in a single vector. You can select the variable's name, and the default is "simout".
Then, after running the diagram, you have the variable you want in the workspace (as if you had typed it in the console). So next, you can call your function with the argument.

Related

Simulink - MATLAB- I have a matlab function block in Simulink with an if-statement, only one of the two actions of this if statement is executed, why?

I have the following function in a simulink block. It takes as an input the value of xi and of xihat, and assess whether xihat should be updated or not. I also want to output whether there was an update, therefore the variable update takes the value 1 if xihat is updated and -1 if it is not. When I run the Simulink programme, I get the expected values for xihat (when plotted, the data is similar to xi but with a stairs kind of appearance). However the value of up is -1 for all of the simulation time. This is not coherent with the fact that the value of xihat is updated. I have even included a disp('yes') to show when the if statement is executed. In short, when the condition is positive definite, xihat should be updated and up should be assigned 1 and only the former is executed. How is this possible?
I have tried to run this exact same function with the same data in a matlab script and it then runs perfectly and up is coherent with xihat. I have attached an image of the subsystem in which the block is located.
I also tried to change the variable name, change the order of the statements, output the conditions etc and nothing seems to help.
Simulink subsystem with MAtlab block.:

How to call simulink model(.slx) from script

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.

Simulink signal from data generated by a fcn() block

In simulink I have a function block. Basically it contains
function y=fcn(u)
if u==1
a=[0,...,1];
b=[1,...,2];
end
y=[a',b'];
%y=struct('time',a,'value',b); %Second option
I want to use these arrays as a signal. As you see I have tried two options, making an output as an array and as a structure, non of them work for me.
In short, I'd like to be able to connect a scope to the output of the function and see the signal generated by (a,b). The reason I want to do it from a Simulink block is that I can just switch between many options of signals without having to build again the model. More over, I'd prefer that if the simulation time is bigger than whatever is specified in a then the signal keeps the last value of b.
p.s. I have tried this using a From Workspace block and it works fine.

using from workspace block in simulink

how to use the "from workspace block in simulink" ?
I have tried using the from workspace block by given 10*2 matrix as input. it is appending some extra data along the data I have given .
and I have such 3 such blocks and want to know how I merge them.
Read the documentation. Simulink is time-based so the data in your From Workspace block must be as a function of time. Does your 10 x 2 matrix represent a signal as a function of time? If so, it needs to be as follows:
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.
The leftmost element of each row is the time stamp of the
value(s) in the rest of the row.
10 values isn't very much, it's likely that Simulink will need additional data points at intermediate times, if you have the Interpolate Data check box ticked. If not, "the current output equals the output at the most recent time for which data exists".
I think you may have a misunderstanding of the variables intended to be read by the FromWorkspace block.
The block expects a time series defining the value at various points in the simulation.
The From Workspace block help should point you in the right direction on this. Mathworks Help Documentation
I believe that something like the following would work for you:
>> WorkspaceVar.time=0;
>> WorkspaceVar.signals.values=zeros(10,2)
>> WorkspaceVar.signals.dimensions = [10,2]

How can I get signal dimensions in Simulink model

I have a question.
After simulate a simulink model I need to get signal dimensions of each line using MATLAB command.
I get line handles by following
line_h = find_system(gcs, 'FindAll', 'on','SearchDepth', 1, 'Type', 'Line')
then how can I get signal dimensions from line handles
** When check 'signal dimensions' in Format menu -> Port/Signal Displays
After simulate a model number of signal dimensions will show on nonscalar line.
I need to get it using MATLAB command.
Sorry for my English skill
Thank you
Alternatively, you can find the signal dimensions and signal widths of each block they originate from, using:
get_param(<block_path>,'CompiledPortDimensions')
get_param(<block_path>,'CompiledPortWidths')
Replacing <block_path> with the appropriate block path for each block of interest. The model must be compiled before you can run these commands, but since you indicate doing this after running the model, that shouldn't be a problem.
If you have a set of line handles from your find_system command you can use the following command to get the block connected to the signal.
hblkSrc = get_param(h(k),'SrcBlockHandle');
You can then use get_param(hblkSrc,'CompiledPortDimensions') as suggested by am304 to get the dimensions.
You can solve it the following way.
Enable signal logging for the desired signals (Properties). For
example set the name to custom and signalone.
If you actually don't want to log the signal, set Limit data points to last to 1, so you avoid storing unused data.
Go to SImulink preferences and enable signal logging, default output name is logsout
after simulation you'll get a dataset logsout in your workspace
now evaluate this dataset as follows:
% returns data, if data limit is set to 1 it's a coloumn
% vector with just the last value
data = logsout.get('signalone').Values.Data
you can now just use the size of this vector and you know the dimension of the signal
[~,dim]=size(data)
or in one line:
[~,dim]=size(logsout.get('signalone').Values.Data)
If you have a a lot of signals and you want to evaluate them at once, give your signals convenient output-names and use a loop for iterating through a string vector with all your signal names.
As you say you want the dimensions of "all" (are you sure?) signals I think it is more convenient to just check "Enable signal logging" in each signal property and do all further definitions in the Simulink preferences where you have a list to manage all signals.