Reset state of continuous blocks (e.g., transfer function) in Simulink - simulink

How I can reset the state of a transfer function block in Simulink (i.e., reset back to the initial conditions)?
For example, in an electrical network, this would correspond to reset capacitors/inductors to zero (or an initial state), for example through switches.
I tried using an "Enabled Subsystem" and placing the Transfer Fcn block there but it seems that the state is not reset when Enable changes ...

By default an enabled subsystem holds the states from one enable to the next. However they may be reset by opening the Enable Block within the subsystem, and changing the States when enabling property to reset.
If you need to reset the states during an enable (rather than at the start of it) then you will need to construct your transfer function using individual integrator blocks (and gains; and summation, etc) and use their reset functionality.

Related

Can I change a block parameter using another block for conditional execution?

I'm wondering whether it is possible to change a block parameter in Simulink (or the value of one saved as a variable) using a different block to enable conditional execution. What I would like to do is have a certain block parameter (in this case, Counter) run during the simulation with an initial value, and have it change to a different value if a certain condition is satisfied.
Ultimately, what I would like to get out of this is to get a Counter block to stop running upon the satisfaction of that condition.
I'm pretty new to Simulink, but I'll detail some of the stuff I've tried so far:
Dashboard switches (Slider, Knob etc.) - I know they're used to
change tunable parameters of blocks, but they cannot be linked to
other blocked and can be only be controlled manually.
Matlab Function block - didn't seem to work, I'm obviously missing something.
Is it maybe possible to disable a certain block/link when that condition is met? That would be a straight forward approach, but I'm not sure it can be implemented in Simulink. Any help would be appreciated!
So to meet your ultimate goal have you considered to place your counter in an enabled subsytem?
Whenever the requirements are met to stop the counter you simply disable the subsystem and the counter will stop.
On the output port of that enabled subsystem you will have the options to preserve the last value or reset it to certain one.

Can an event based task in Codesys trigger on a falling edge?

I am currently working on a project that incorporates an EStop circuit. The EStop circuit transmits a 'normally on' (TRUE) signal under normal circumstances. When the EStop button is pressed the signal drops out and becomes FALSE. The digital signal is just for me to catch so I can potentially issue a 'one-shot' command (controlled stop), in the brief period, before connection to all motors and systems fault out.
I have tried configuring an event based task under 'Task Configurations' using the digital EStop output (seemed like the most ideal use case). However the 'event' conditions require a Boolean variable and will only trigger on a rising edge instance. Because my EStop signal is normally 'on' (TRUE) this will not work for me unless I can somehow invert the conditions of the event.
I understand I can incorporate the functionality I am looking for within my main task using an if statement and an inverter, but it seems silly there seems to be no option to invert the conditions of the event.
If what I am asking for is possible please let me know. If anyone can confirm it is NOT possible I will also accept that answer.

Dynamically adjusting arrival rate in source

the basic idea behind the modeling issue is a breakdown of a production machine.
I would like to model this by setting the arrival rate (simply arrivals per second) to zero (Source.rate = 0). After the machine is repaired, the arrival rate is set to its actual value again (e.g., Source.rate = 5). While the first command does the job, the second does not seem to have any effect, i.e. new agents are not created.
The segment of the model is rather simple: Source --> Select Output (decision about breakdown) --> true: go on in production; false: delay (repair machine) --> go on in production.
Source.rate = 0 is called at the out port (false) of "breakdown" and Source.rate = 5 at the out port of "repair".
https://i.stack.imgur.com/hqGoI.png
Of cause, this issue might be modeled differently (e.g., using hold with disabled "forced pushing"), however, it is not clear for me why my approach does not work.
Thanks in advance!
Instead of using source.rate=5; use source.set_rate(5);
To expand on Felipe's answer with an explanation:
Instead of using source.rate=5; use source.set_rate(5);
rate is effectively a Parameter (in the AnyLogic sense) of the Source block. (All AnyLogic's Process Modeling blocks are actually themselves Agents developed by AnyLogic, and thus with Parameters, Variables, etc.)
You can set an AnyLogic Parameter directly (via just assigning a value as you did), but they also all have a set_<parameter name> method (function) which should really always be used instead because this triggers any internal on-change logic for this Parameter. It is only this triggered logic (internal to the Source block) which causes the Source to 're-evaluate' the rate properly.
(You can use on-change logic for Parameters in your own models, and need to do so when altering a parameter requires some 'adjustments' to the rest of the model; i.e., in situations where the change doesn't 'just work' due to other bits of the model reading the new value after the change point.)
I don't know why your model doesn't work (maybe more details of your model is needed), but a simple solution which I tested and worked, is as below:
You can set the source's "Type of arrival" to "calls of inject() function", add an event to your model and set its "Trigger type" to "Rate" and set its rate value to 5. Then in action code of the event use below code:
if(yourCondition)
{
source.inject(1);
}
I hope it helps you.

Get the handle of a block calling an Interpreted Matlab Function

I am using Simulink to model a waste recycling plant out of a number of masked blocks that I created, representing sorting steps, buffers etc. Each module (that is, a masked block) has a failure probability, modeled using Discrete Events. If a failure event occurs, a triggered subsystem calls an Interpreted Matlab Function ("outside" of simulink). This function is supposed to set a parameter status of the masked block representing the module that failed as well as the upstream modules' status to 0 (because obviously, everything upstream has to stop as well or the material will just pile up).
`set_param(gcb, 'status', num2str(status));
PortConnectivity = get_param(gcb,'PortConnectivity');
sources = PortConnectivity.SrcBlock;`
Basically, this will be looped until I reach a block with no own Source Block.
This all works quite well, except for one problem: The gcb command gives me the block path to the last block I highlighted manually, and not to the block that called the Interpreted Matlab function. Is there any way to get the calling block's handle (which I would use with it's Parents parameter to access the Mask's status)? (A similar question has been asked here, with no results...)
I hope you get my problem - I'll be happy to elaborate if anything's unclear; I am not claiming to be a Simulink expert, so sorry for maybe using wrong terminology.
Ok, for everyone stumbling upon this:
For the mask that contains the caller of the Matlab Interpreted Function, in the mask editor I define a parameter 'this_block' (turn visibility off), that I initialize in the Initialisation pane using
parent = get_param(gcb,'Parent');
set_param(gcb, 'this_block','Parent')
Since this masked block (responsible for modelling the failure and its upstream communication) is itself used in another masked block also present in the library (responsible for modeling the module's behaviour), I also had to check "Allow library blocks to modify it's contents" in the mask editor Inititlization pane of the parent's mask. The parameter 'this_block' is then handed over as one of the input arguments of the called function (in my case, status_communication(u, this_block)).

Which method is generally used to communicate between programs in Structured Text

I am maintaining a project for a PLC written in ST. To implement a new feature I need to let cyclic program A know when an event happened in cyclic program B.
How is this generally done in ST? Do I simply use global variables or is there a different method? If I use global variables, how are these then protected from concurrent modification?
I use the X20 PLCs from B&R Automation.
Asynchronous communication is tricky.
So imagine a global A_DONE initialized to false, with B inspecting it occasionally. A runs, and sets A_DONE. B can react to this event... but what does it do if it needs to handle another event?
If you believe that the event that tells A to signal A_DONE occurs only long after B sees A_DONE, B can simply reset A_DONE to false (assuming this always happens before the next A_DONE event) and the cycle can repeat.
If A_DONE can occur "again" while B is handling the results of seeing A_DONE, B cannot just reset A_DONE: you might get a timing splinter in which B reads A_DONE, A sets A_DONE again and B then clears A_DONE; now you've lost an event. If that event is controlling your reactor emergency rods, this could be pretty bad because poof, B missed it.
In this case you will likely need a handshake from A to B and back. We add a signal from B back to A, call it A_DONE_SEEN, to let B tell A that it has processed the event. Then A sets A_DONE, waits for A_DONE_SEEN; A clears A_DONE, waits for A_DONE_SEEN to go false, and continues its business. If A_DONE needs to be set while A_DONE is already set, or A_DONE_SEEN is set, we know we missed an event and some disaster recovery procedure can be run. B watches for A_DONE, handles the A_DONE action, sets A_DONE_SEEN, watches for A_DONE going false, and sets A_DONE_SEEN_FALSE.
I don't know about your specific PLCs, but in many systems there are atomic operations that increment counts, etc. You could use this instead of the handshake.
Yes, you need to declare a variable that has a shared scope to both cyclic programs.
You can do this by using the existing global.var file or you can create a new variable file, and limit what programs can read or write to it by placing it within a "package" (folder in your project).
To create a new var declaration file...
-right click within the logical view
-add object
-select "file" category, and choose new file
-name, and change to "save as *.var" in the drop down
By default, the new variable declaration visibility will be limited to the package it is contained within. To verify this, right click the file and go to properties. Select the details tab.
There is no way to protect from concurrent modification, but you can use the cross reference tool to see where a selected variable is being written and read within your project. First build a cross reference, and then use the tab at the bottom.
Good luck!