How to create if-then logic in simulink? - matlab

I have a written code and a program in matlab, but I want to do the same think in simulink. I am stuck at the if-then part of the program which I can't figure out.
I tried using the "If" block, but then I didn't know how to say "then alfa=0". After trying to research it I saw many different ways to do conditional statements and now I'm very confused.
if(vb-y(2))*y(3)<0
alfa=0
end
if y(3)<zba && (vb-y(2))*y(3)>=0
alfa=0
end
if zba<y(3) && y(3)<zmax && (vb-y(2))*y(3)>=0
alfa=0.5*(sin(pi*(y(3)-(zmax+zba)/2)/(zmax-zba))+1)
end
if zmax<y(3) && (vb-y(2))*y(3)>=0
alfa=1
end
I basically need this made in simulink. If someone could just start it out for me or explain the proper way to do this I'd be very thankful.

I believe this can be done in the following way: Choose the if-block to implement your condition, and for the then and else-block, you choose an if-action-block. The if block decides which of these two if-action blocks will be evaluated at every timestep and the following merge-block integrates both individual outputs into one combined signal (alfa in your case) again. The image shows the first if-then of your code (assuming else alfa=1. In case of no else, the else-output can be disabled in the block-properties).
Since the if-block supports elseif expressions as a comma separated list, I suggest you use this for your 2nd, 3rd and 4th if's, which means that you will most likely need additional if-action blocks, and more inputs for the merge-block. Also for the elseif expressions, you'll need to change your && to & which should be fine. a && b only evaluates b if a is true, a & b always evaluates both.

Related

How to insert page break through the program in maple?

How should we insert a page break via the code itself in maple program ?
Not insert page break? of menu
As I want to insert the page break as the code runs and with other outputs. In maple code.
Let's suppose that you have the following PutGraph procedure defined and available.
(You could define it in the Startup Code region of your Document/Worksheet. Or you could define it in your Maple initialization file. Or you could define it and store it in a .mla Library archive within your libname path. Or you could simply define it at the start of any Document/Worksheet in which you want to utilize it. I leave that choice to you.)
Then you can utilize this Putgraph procedure instead of DrawGraph, with the extra effect that it inserts a pagebreak right before the inlined plot of the Graph.
It also accepts a 2D or 3D plot as its argument. And if its argument is a Graph then you can also pass additional arguments that would normally be accepted by DrawGraph.
The restriction is that you can only effectively use one such call to this implementation of PutGraph per Execution Group or Document Block. If you want it done otherwise then you will have to show me explicitly how you need to call it once for multiple insertions. If you want specific behaviour then you will have to describe it adequately.
Here's the procedure, as 1D Maple notation code:
PutGraph:=proc(GG::{Graph,specfunc({PLOT,PLOT3D})})
local T,xml;
uses DocumentTools,DocumentTools:-Layout,GraphTheory;
if GG::Graph then
T:=DrawGraph(GG,_rest);
else T:=GG; end if;
xml:=Worksheet(Group(Input(Textfield(InlinePlot(T)))));
InsertContent(subsindets(xml,'specfunc(anything,_XML_Input)',
u->':-_XML_Input'(':-_XML_Pagebreak'(),
op(u))));
return NULL;
end proc:
Here's some example of calling it. (I'll mention again: it needs to be called at most once per Execution Group or Document Block. If you put it more than once in the same Execution Group/Block then only the last instance will work as intended.)
G1 := GraphTheory:-RandomGraphs:-RandomGraph(6,degree=3):
Now, in its own Execution Group/Document Block,
PutGraph(G1);
You can have something else appear before the next page break, or several things like text, other input/output, etc.
somethingelse;
And now, in its own Execution Group/Block,
PutGraph(G1,showlabels);
And so on,
somethingelse;
PutGraph(G1,showweights);
somethingelse;
P := GraphTheory:-DrawGraph(G1):
PutGraph(P);
somethingelse;

Cannot solving error while using SelectOutputOut block

I am still a beginner at modeling anylogic. I am currently using the selectOutputOut block to create the different routes of agent flow (the agent named product). I already created a function for choosing the output and already inputted the type SelectOutputOut for returning values.
I simply followed the SelectOutputN example from AnyLogic example model. However, there is an error "This method must return a result of type SelectOutputOut" which I really do not know how to fix.
If you have any solutions, please help me.
Thanks in advance.
Here are the images
at the very end of the choosingOutput function body write return null;
The problem is that you only have "else if" statements, you need to either write an else statement to cover all the possibilities, or return something at the very end (in case all the ifs are false)
It will also work if your last if, instead of writing if else(agent.product == TypeC), you just write else

set initial conditions in matlab function block (simulink)

I'm currently trying to learn some basis for a bigger project that will make a massive use of simulink.
Right now, I would like to code my own simulink block whith a feedback. It means that one of the inputs is also the output (with a 'memory' block between them to ensure everything goes right!).
My code looks like
function out = func(cmd,in)
if in == 0 && cmd == 1
out = 1;
elseif in == 1 && cmd == 0
out = 0;
else
disp('error')
end
As I said, 'in' is linked to 'out'. Unfortunatly, it is required to set an initial value for out otherwise I get some errors. Of course I can't do it in the code like that :
out = 0;
In that case, the value 'out' is set to 0 at each time step.
Have you any advice to do it ? I've read that S-functions and flag could be used, but I have no idea how it works.
Your function gets called during model initialization (t=0), and the value of out will be calculated based on the value of cmd and in value at t=0.
Hence you need to make sure cmd and in are initialized correctly you shouldn't be setting a value explicitly for out.
If you really need to (which you won't) then the simplest thing to do is use an Initial Condition block after this block.
Note that the above is only applicable to a block that has no states, as with your example. For your bigger project, you may have custom written blocks with states, in which case the approach to setting initial conditions for the states is different depending on whether you are using a MATLAB Function block or an S-Function.
Finally, note that if you want an error to be thrown then throw an error in the usual MATLAB way. Using disp as you are doing doesn't stop the simulation, but you haven't set a value for out, which is bad coding.
Well, I think that I've solve that issue. I put it here, I could help someone else
by adding a clock and initialize out with an if statement if time <=0 out = ...
However, it requires to add an extra input, which is not very convinient. Maybe someone could tell me how to solve that.
do the if properly and terminate it by else out = in;
I belive that was the main problem here. I've also placed my matlab-function block in a subsystem with a mask that initializes in and cmd.
Thanks again for your help, it helped a lot.
However, my problem is still unsolved since the statement if t<0 doesn't work for some reason.

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.

Debugging loops

For some current projects, I'm working with several data structures that are pretty large (in the area of 10K elements). To be able to access this data in lists, I need to use loops and iterators, which can be a pain when the problem area is in the latter half of the list.
So I find myself spending alot of time with my finger on the F8 button in Eclipse's debugger to loop through each element of an iterating loop. This gets worse when have to step through that particular section several times to get an idea why the code is reacting a particular way.
If one has a general idea how many times a loop is to execute before a problem area is hit, is there a way to set a loop breakpoint to execute up to that point then pause?
Use conditional breakpoints.
http://wiki.eclipse.org/FAQ_How_do_I_set_a_conditional_breakpoint%3F
I believe there's a better way to do this, but you can create a trivial block of code in the loop that only executes at a certain iteration, and put the breakpoint inside of it.
if (loopIndex == 1000) {
int number = 14; //Break here
}
Using this as an example:
for(int i=0;i<10000;i++){
System.out.println(i);
}
Set a breakpoint on the print line, then right click on it and select Breakpoint Properties.... From here you can set a condition to trigger the breakpoint. This is the similar to a conditional you would have in an if-statement. If you wanted to trigger the breakpoint when i equals 6000, check the Conditional box and try this: