How to refresh global variable in simulink - matlab

I have simple transfer function in simulink.
Where I want to change values of A and B depending on some conditions during simulation.
So I created this block
Where inside I am trying to set params but i dont know how.
set_param('mySimulation/myBlock','den',A);
set_param('mySimulation/myBlock','num',B);
I am getting error
TransferFcn block does not have a parameter named 'den'
I tried many different names but cant find one that is correct. Please what is correct name? Or how else should I change A and B during simulation?

Related

Anylogic - New Beginner: Action charts How to return visable the variables?

I am new to anylogic and need to create an actionchart for my master thesis. I know how to set it up and all but I don't know how I can see if the algorithm worked. I tried to use statistics where I choose my used variables but this shows me always the initial value.
This is what I tried to do: Just a first easy algorithm. I have a variable "test" with initial value 0. I have created an action chart with a "for loop" (for i=0;i<10;i++). And in the loop I have placed a code-block with test=test+1;.
And I have placed outside of the loop a return-block where I return "test".
So this action chart should just add 1 for every loop to my variable test. At a result the value should be 10.
When I am running this there are no errors but also no results. The Statistic block only shows the value 0. And now I don't know what I am doing wrong. Is the error in the action chart or at the statistics?
I have searched in Google and read "anylogic in three days" and was searching at the anylogic help.pages... I havn't found a solution so I thought that maybe someone knows what I am doing wrong.
I rebuilt the example you describe, and I am getting an action chart that returns the value 10. I also added a statistics block and associated it with the value of test, and it shows a value of 10. Is it possible that you are just never calling the action chart (analogous to calling a function), therefore it never executes?
In general, I would avoid action charts, as I have found it is just easier to write and maintain code in the AnyLogic functions or Advanced Java area.

Add inports & outports to Simulink C Mex S-Function mask

I am trying to amend the example given here for creating a dynamic masked subsystem, where I want to dynamically change the number of imports and outports to an S-Function.
I have a very simple S-Function implemented in C (it's the timestwo example in the documentation) and for which I wish the user to be able to define the number of inputs and number of outputs in a mask. The intention is then, within the S Function, to manipulate the received input values and write to the output values. The S-Function will eventually do some quite complicated stuff and I need multiple instances of it in Simulink, hence why I want it defined in a library.
I have put the S-Function into a library and unlocked it by choosing Diagram->Unlock Library.
I have defined 2 variables, numInports and numOutports in the Parameters & Dialog pane of the mask editing window.
I then add the following to the Initialization pane:
blocks = find_system(gcb,...
'LookUnderMasks','on',...
'FollowLinks','on',...
'RegExp', 'on',...
'BlockType', 'port');
if ~isempty(blocks)
Simulink.SubSystem.deleteContents(gcb);
end
for n=0:(numInports - 1)
label = sprintf('/In%d', n);
add_block('built-in/Inport',[gcb,label]);
end
for n=0:(numOutports - 1)
label = sprintf('/Out%d', n);
add_block('built-in/Outport',[gcb,label]);
end
The intention is for the initialisation to delete all imports and outports when the parameters are changed, then recreate them. I then save the model within the library.
The find_system() command should find and delete all blocks with port in the type, as suggested here and here.
I have created a model that uses this library model S Function implementation. However, when I update the parameters, I get the error:
Error in 'MyModel/MyLibrarySFunction': Initialization commands cannot be evaluated. Caused by:
A new block named 'MyModel/MyLibrarySFunction/In0' cannot be added.
Can anybody please advise what is going wrong here?
EDIT:
The documentation for find_system() has all as a valid parameter value, not the on I used and which was in the documentation example, but this seems to have no effect when I change it. I added:
msg = sprintf('Num blocks: %d', numel(blocks));
disp(msg);
just after the find_system() call and get 0 for the number of blocks found, so I guess the problem may be that In0 is not deleted and hence I am trying to reinsert it.

How to update variable in From workspace block during runtime

I have a sample model(shown below) which consist of a from workspace block. It contains a workspace variable variable1(timeseries signal). I am changing the data of variable1 during simulation but model is not updating the current value of variable1. It's update only when I stop and restart the simulation but I want it to update during runtime only. Can anyone help me in handling this problem?
This is not really how Simulink is designed to work, so there's no easy way to do this. Simulink only checks only checks the workspace for values during model initialization at the start of the simulation. The best thing to do is to use set_param, as in:
set_param('untitled/From Workspace',' VariableName','variable1'); % put the correct path to your block
This is not changing anything in how the block is parameterised, but forces Simulink to parameterise the block with the new values of variable1. Because variable1 is a timeseries object, I am not sure how well this will work, but it's worth a try.
For more details, see this discussion on MATLAB Central.

Simulink: What happens when subsystems are initialized?

I've been having a lot of trouble getting simulink's block callbacks to run, and the documentation is woefully inadequate and disorganized. It seems that I'm misunderstanding multiple points of how Simulink compiles models, but since StackOverflow dislikes multi-part questions, I will post them one at a time.
The situation: I have a library of components, each of which is a virtual subsystem whose parameters are defined through the masks. Block A has Parameter a which is sent to the base workspace using the 'assignin' command.
Next, the block B has a parameter b which is initialized in the Initialization tab of the mask.
Finally, the StartFcn callback of the block B runs a script which needs to reference both a and b to calculate c. In the script, I reference a simply as a because it's in the 'base' workspace, and I reference b using get_param(gcb,'b').
Now, this last command works when the parameter b is a user input (so it's a constant value). But in my case, this b is calculated using other parameters in the Initialization tab. And for some reason, in the script, this parameter is always zero.
I added a display within the block B to see what these values are, and they are clearly non-zero.
Can someone please explain why the script cannot seem to get the real value of the areas out of the block?
You can get the masked workspace variable using getworkspacevariable

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.