How to implement a modified transfer function? - simulink

my field is not that much related to, but I need to build a model-based simulation in simulink. The model has a transfer modified function as follows:
r(s)/q(s)=t/(t*s+1)
I know the basics, however, to implement this, I got into question, whether I have to use a Gain block with value of t before and after a transfer function like this 1/(s+1), or it should be implemented in another fashion? As t is not a constant. Thanks.

Firstly note that t/(t*s + 1) is equivalent to 1/(s+(1/t)). In both cases t > 0 or the system is unstable or ill-defined.
If t was constant then you could use a Transfer Function block, which is the equivalent of the first of the following implementations. Since t is not constant, you cannot use a Transfer Function block, but you can use the second implementation shown below.

Related

Alternatives to global variables: persistent variables and nested functions in MATLAB

First, I have had a look at this excellent article already.
I have a MATLAB script, called sdp. I have another MATLAB script called track. I run track after sdp, as track uses some of the outputs from sdp. To run track I need to call a function called action many many times. I have action defined as a function in a separate MATLAB file. Each call of this action has some inputs, say x1,x2,x3, but x2,x3are just "data" which will never change. They were the same in sdp, same in track, and will remain the same in action. Here, x2,x3 are huge matrices. And there are many of them (think like x2,x3,...x10)
The lame way is to define x2,x3 as global in sdp and then in track, so I can call action with only x1. But this slows down my performance incredibly. How can I call action again and again with only x1 such that it remembers what x2,x3 are? Each call is very fast, and if I do this inline for example, it is super fast.
Perhaps I can use some persistent variables. But I don't understand exactly if they are applicable to my example. I don't know how to use them exactly either.
Have a look at object oriented programming in Matlab. Make an action object where you assign the member variables x2 ... to the results from sdp. You can then call a method of action with only x1. Think of the object as a function with state, where the state information in your case are the constant results of sdp.
Another way to do this would be to use a functional approach where you pass action to track as a function handle, where it can operate on the variables of track.
Passing large matrices in MATLAB is efficient. Semantically it uses call-by-value, but it's implemented as call-by-reference until modified. Wrap all the unchanging parameters in a struct of parameters and pass it around.
params.x2 = 1;
params.x3 = [17 39];
params.minimum_velocity = 19;
action('advance', params);
You've already discovered that globals don't perform well. Don't worry about the syntactic sugar of hiding variables somewhere... there are advantages to clearly seeing where the inputs come from, and performance will be good.
This approach also makes it easy to add new data members, or even auxiliary metadata, like a description of the run, the time it was executed, etc. The structs can be combined into arrays to describe multiple runs with different parameters.

Use exist to check if Simulink-Block has parameter 'SampleTime'

I want to write a function that automatically changes the parameter SampleTime of all blocks in my model to a specific value. I can use find_system to find all blocks and then I can loop through all blocks and use set_param('Blockpath','SampleTime','0.001'). But if I do this and the block does not have a parameter called SampleTime, it'll make my program crash.
So my question is how can I find out if the parameter exists before setting it? I tried something like exist(['blockpath','/SampleTime']), but it didn't do what I expected. Any ideas?
You can use get_param('blockpath','ObjectParameters') to get a struct with all parameters and then use isfield to check if you can find SampleTime.
I think what you are doing is not a good idea. In typical simulink models, you have the sample time set only at very few places, running all other models with inherited sample time. In most cases, it is not a problem to change these few places.
If you have to many blocks or you frequently change the sample time, better use a workspace variable or a mask parameter. Set all blocks to to have sample time x and put x=0.01 in your base work space to set it for all blocks.
Building on #Daniel's answer, if you really must do this, which for reasons given in the comments to #Daniel's answer is a bad idea, then the simplest approach is
% Define the new value as a string
>> newSampleTime = '10';
% Find all blocks in the model
>> allBlocks = find_system(gcs);
% Identify the blocks that have a SampleTime property
>> blockIdx = cellfun(#(c)isfield(get_param(c,'ObjectParameters'),'SampleTime'),allBlocks);
% Change the sample time
>> cellfun(#(c)set_param(c,'SampleTime',newSampleTime),allBlocks(blockIdx));

Loading Variables into Functions from Structs in Matlab

Say I have a project which is comprised of:
A main script that handles all of the running of my simulation
Several smaller functions
A couple of structs containing the data
Within the script I will be accessing the functions many times within for loops (some over a thousand times within the minute long simulation). Each function is also looking for data contained with a struct files as part of their calculations, which are usually parameters that are fixed over the course of the simulation, however need to be varied manually between runs to observe the effects.
As typically these functions form the bulk of the runtime I'm trying to save time, as my simulation can't quite run at real-time as it stands (the ultimate goal), and I lose alot of time passing variables/parameters around functions. So I've had three ideas to try and do this:
Load the structs in the main simulation, then pass each variable in turn to the function in the form of a large argument (the current solution).
Load the structs every time the function is called.
Define the structs as global variables.
In terms of both the efficiency of the system (most relevent as the project develops), and possibly as I'm no expert programmer from a "good practise" perspective what is the best solution for this? Is there another option that I have not considered?
As mentioned above in the comments - the 1st item is best one.
Have you used the profiler to find out where you code takes most of its time?
profile on
% run your code
profile viewer
Note: if you are modifying your input struct in your child functions -> this will take more time, but if you are just referencing them then that should not be a problem.
Matlab does what's known as a "lazy copy" when passing arguments between functions. This means that it passes a pointer to the data to the function, rather than creating a new instance of that data, which is very efficient memory- and speed-wise. However, if you make any alteration to that data inside the subroutine, then it has to make a new instance of that argument so as to not overwrite the argument's value in the main function. Your response to matlabgui indicates you're doing just that. So, the subroutine may be making an entire new struct every time it's called, even though it's only modifying a small part of that struct's values.
If your subroutine is altering a small part of the array, then your best bet is to just pass that small part to it, then assign your outputs. For instance,
[modified_array] = somesubroutine(struct.original_array);
struct.original_array=modified_array;
You can also do this in just one line. Conceptually, the less data you pass to the subroutine, the smaller the memory footprint is. I'd also recommend reading up on in-place operations, as it relates to this.
Also, as a general rule, don't use global variables in Matlab. I have not personally experienced, nor read of an instance in which they were genuinely faster.

Determining direct-feedthrough paths without compilation/execution

I am currently working on a tool written in M-Script that executes a set of checks on a given simulink model. This tool does not compile/execute the model, I'm using find_system and get_param to retrieve all the information I need in order to run the routines of my tool.
I've reached a point where I need to determine whether a certain block has direct-feedthrough or not. I am not entirely sure how to do this. Two possible solutions come to mind:
A property might store this information and might be accessible via get_param. After investigating this, I could not find any such property.
Some block types have direct-feedthrough (Sum, Logic, ...), some other do not (Unit Delay, Integrator), so I could use the block type to determine whether a block has direct-feedthrough or not. Since I'm not an experienced Simulink modeller, I'm not sure if its possible to tell whether a block has direct-feedthrough by solely looking at its block type. Also, this would require a lookup table including all Simulink block types. An impossible task, since additional block types might get added to Simulink via third party modules.
Any help or pointers to possible solutions are greatly appreciated.
after some further research...
There is an "official solution" by Matlab:
just download the linked m-file
It shows that my idea was not that bad ;)
and for the record, my idea:
I think it's doable quite easily. I cannot present you some code yet, but I'll see what I can do. My idea is the following:
programatically create a new model
Add a Constant source block and a Terminator
add the Block you want to get to know the direct feedthrough ability in the middle
add_lines
run the simulation and log the states, which will give you the xout variable in the workspace.
If there is direct feedthrough the vector is empty, otherwise not.
probably you need to include some try/catch error catching for special cases
This way you can analyse a block for direct feedthrough by just migrating it to another model, without compiling your actual main model. It's not the fastest solution, but I can not imagine that performance matters that much for you.
Here we go, this script works fine for my examples:
function feedthrough = hasfeedthrough( input )
% get block path
blockinfo = find_system('simulink','Name',input);
blockpath = blockinfo{1};
% create new system
new_system('feed');
open_system('feed');
% add test model elements
src = add_block('simulink/Sources/Constant','feed/Constant');
src_ports = get_param(src,'PortHandles');
src_out = src_ports.Outport;
dest = add_block('simulink/Sinks/To Workspace','feed/simout');
dest_ports = get_param(dest,'PortHandles');
dest_in = dest_ports.Inport;
test = add_block(blockpath,'feed/test');
test_ports = get_param(test,'PortHandles');
test_in = test_ports.Inport;
test_out = test_ports.Outport;
add_line('feed',src_out,test_in);
add_line('feed',test_out,dest_in);
% setup simulation
set_param('feed','StopTime','0.1');
set_param('feed','Solver','ode3');
set_param('feed','FixedStep','0.05');
set_param('feed','SaveState','on');
% run simulation and get states
sim('feed');
% if condition for blocks like state space
feedthrough = isempty(xout);
if ~feedthrough
a = simout.data;
if ~any(a == xout);
feedthrough = ~feedthrough;
end
end
delete system
close_system('feed',1)
delete('feed');
end
When enter for example 'Gain' it will return 1, when you enter 'Integrator' it will return 0.
Execution time on my ancient machine is 1.3sec, not that bad.
Things you probably still have to do:
add another parameter, to define whether the block is continuous or discrete time and set the solver accordingly.
test some "extraordinary" blocks, maybe it's not working for everything. Also I haven implemented anything which could deal with logic, but actually the constant is 1 so it should work as well.
Just try out everything, at least it's a good base for you to work on.
A famous exception is the StateSpace Block which can have direct feedthrough AND states. But there are not sooo much standard blocks with this "behaviour". If you also have to deal with third party blocks you could get into some trouble, I have to admit that.
possible solution for the state space: if one compares xout with yout than one can find another indicator for direct feedthrough: if there is, the vectors are not equal. If so, than they are equal. Just an example, but I can imagine that it is possible to find more general ways to test things like that.
besides the added simout block above one needs the condition:
% if condition for blocks like state space
feedthrough = isempty(xout);
if ~feedthrough
a = simout.data;
if ~any(a == xout);
feedthrough = ~feedthrough;
end
end
From the documentation:
Tip
To determine if a block has direct feedthrough:
Double-click the
block. The block parameter dialog box opens.
Click the Help button in
the block parameter dialog box. The block reference page opens.
Scroll
to the Characteristics section of the block reference page, which
lists whether or not that block has direct feedthrough.
I couldn't find a programmatic equivalent though...
Based on a similar approach to the one by #thewaywewalk, you could set up a temporary model that contains an algebraic loop, similar to,
(Note that you would replace the State-Space block with any block that you want to test.)
Then set the diagnostics to error out if there is an algebraic loop,
If an error occurs when the model is compiled
>> modelname([],[],[],'compile');
(and you should check that it is the Algebraic Loop error that has occured), then the block has direct feed though.
If no error occurs then the block does not have direct feed though.
At this point you would need to terminate the model using
>> modelname([],[],[],'term');
If the block has multiple inports or outprts then you'll need to iterate over all combinations of them.

Software in the Loop mode with Modelica

How to implement Software in the Loop for control systems design with Modelica (OpenModelica, jModelica) for a plant and C/C++ routine for a controller. What approaches you can suggest?
I thought external C Functions would help but seems they have some restrictions such that they should obey reference transparancy property ie return the same values for the same inputs (should not have internal states).
In that case, the issue with calling external C functions does not apply. It is true that Modelica restricts the use of functions in the continuous equations such that the function must return the same value for the same arguments. In those cases, you must find a way to pass the state into the function and have it return the new state (if you want to satisfy this "purity" requirement). This is obviously quite tedious to do with C code (you would have to pass in the state, assign all state variables (probably globals) run your code, then extract the values of all the state variables and return them).
Fortunately for you, you don't need to worry about this. The reason is because your function only needs to be called from within a when clause. If you are triggering your when clause based on time (e.g. using the sample(...) function), I'm pretty sure you are guaranteed that the function will only be invoked once at each time.
Basically, your setup would be something like this:
algorithm
when sample(0, sample_rate) then
u := controllerEvaluation(x, y, t);
end when;
In this way, you can pass time, the necessary states, x, and inputs, y (or u, depending on your perspective), into the controller and you get back the controller command to the plant, u.
In this context, the when clause is a representation of your scheduler and because it doesn't include any state events (like you would have, for example, with a tooth wheel encoder or other asynchronous interrupt) the simulator can schedule all these function invocations without any risk of having to repeat them.