Simulink signal from data generated by a fcn() block - matlab

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.

Related

Store signal values, output as vector for function input

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.

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.

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.

S-function documentation that "S-function level-1 supports vector inputs and outputs. DOES NOT support multiple input and output ports"

I read in S-function documentation that "S-function level-1 supports vector inputs and outputs. DOES NOT support multiple input and output ports".
Does the second sentence mean the input and output dimension must be the same?
I have been using S-function level-1 to do the following:
[a1, b1] = choose_cells(c, d);
where a1 and b1 are outputs, c and d are inputs. All the variables are having a single value, except d is an array with 6 values.
Referring to the image attached, we all know that in S-function block, the input dimension must be SAME as output dimension, else we will get error, in this case, the input dimension is 7 while the output dimension is 2, so I have to include the "Terminator" blocks in the diagram for it to work perfectly, otherwise, I will get an error.
My problem is, when the system gets bigger, the array d could contain hundreds of variables, using this method, it means I would have to add hundreds of "Terminator" blocks in order to get this work, this definitely does not sound practical.
Could you please suggest me a wise way to implement this?
http://imgur.com/ib6BTTp
http://imageshack.us/content_round.php?page=done&id=4tHclZ2klaGtl66S36zY2KfO5co
Updated: actually I have been trying to convert my level-1 S-function to level-2 but I got stuck at calling another sub function at function Output(block) trying to look for other threads but to no avail, do you mind to provide related links?
My output depends on a lot processing with the inputs, this is the reason I need to call the sub-function in order to calculate and then return output values, all the examples that I can see are calculating their outputs directly in "function Output(block)", in my case I thought it is not possible.
I then tried to use Interpreted Matlab Function block but failed due to the output dimension is NOT the same as input dimension, also it does not support the return of more than ONE output................
Level-1 s-function supports single input and single output port. These ports must be vectors. But there is no restriction on the length. Input and output can have different lengths. You can use selector block to select only relevant data. You do not need to use Bus in the output.
There is also no restriction on calling other sub-functions from Output. If your sub-function is not in the same file it must be in the path or in the current directory.
If your MATLAB code is compatible with MATLAB Function block, I recommend using that block. It is simpler to setup and use.