Codesys LD: how to jump from a process to other process - codesys

I am new to Codesys Ladder programming.  We are converting our Ladder application to Codesys LD. Our application has several processes. Each process handles different subjects. Each process is activated by a Jump To Subprocess element from another process.
For example:
MainProcess:
Rung1: if Relay is Open->Jump to Process1; If Relay is closed - Jump to Process2
Process1{}
Process2{}
I'm looking for a way to implement the same thing (jump from a process to a different process ) with Syscode LD. 
Thanks

I would suggest creating methods for process1 and process2.
Then, you can simply have your relay NC rung call process1 method and your relay NO rung call process2 method.
MainProcess has sub objects:
Method Process1
Method Process2
Then you can do the following without any “jumping”
Relay
|—-|/|—-Process1—-|
Relay
|—-| |—-Process2—-|
You can also replace calls to sub process objects with calls to separate programs or methods of other programs:
Relay
|—-|/|—-DifferentProg.Process—-|
Relay
|—-| |—-AnotherProg.Process—-|
However, you can use the JUMP to label command to achieve what you ask (if your jump to is in the same program). The key is to add a label to the rung by clicking in the area in the upper left of the rung (there is a line for comment and a line for label). Check your LD options to make sure your editor shows those areas.
Just be sure to put a jump to end and make an end for this style otherwise process 1 will go right into process 2!

Related

How to get around using Enter and Exit blocks in "Prepare" flowchart (Execution error "0 isn't supported for building resource behavior flowcharts")

I have an airlock (small room called AL_2216) between 2 areas. The airlock has many different agent types passing through it (cart, product, operator, etc). There are queuing areas on either side of the airlock.
Because the space is small, I built a short flowchart that has a queue and restricted area blocks that all agents must pass through when going through this space. If the restricted area's capacity is full, the agents wait in either the InsideQueueArea or OutsideQueueArea depending on the direction they're going.
I send agents via Exit and Enter blocks to this flowchart and it works great on the top portion of the flowchart.
BUT if I try to use an Enter or Exit block in the prepare flowchart, I get this error:
I tried using a custom block instead of Enter and Exit blocks, but that creates a new instance of the code each time and the restrictions don't work together across the multiple custom blocks.
This airlock is just one of many in my model. Without referring to the same code, I'll have multiple copies that need to refer to each other's restricted areas and the flowcharts become huge and complicated. Is there a way to get around this?
EDIT:
I'm not sure what to do with these ports. They have no properties that do anything:
EDIT2:
Here's a file to see the behavior - Model2.zip
The Prepared flowchart portion is set to "ignore" so the code will run. You can see the operators and the carts passing through AL_2216 with only 2 being allowed at a time. If you uncheck "ignore" for the prepare flowchart, the error will trigger.
AnyLogic sent the right answer!!
So I was asking Anylogic a different question and they recognized my name from this post! They sent a fix to me and it works exactly the way it should! The exception error message I was getting "out: 0 isn't supported for..." made me think the exit/enter blocks were not supported in perparation flowcharts.
But actually, the seizeCart block didn't know where to start the prep flowchart because it wasn't directly connected to the resource task start block. A quick setting change under the Advanced section of the seizeCart block defining which resource task start block to start at did the trick! Here's the email from AnyLogic:
-The error text and documentation are not sufficient for understanding this (the error text is confusing), I suppose it is obsolete error text. We will rectify the description;
-Under the question there is a more generic discussion which seems to be unrelated to the initial problem. Please let me know if I miss something or if your model does not work as you expect even after adjustment of seizeCart block property.
I think you should replace the Enter and Exit blocks that lead to the bottom input of your seizeCart Seize block with simple Port objects (from the Agent palette).
As per the help for Seize:
So it wants a direct link to a ResourceTaskStart flow and your Enter/Exit combinations might be ... not "direct" enough... Try it.
So here's what I ended up doing. It's the best I could come up with that could be easily replicated for lots of airlocks.
I've added a wait block (dummyThruAL_2216) to my Product flowchart prior to seizing the cart. This wait block injects a new Agent into sourceDummy at the cartHome node. The dummy then seizes a cart and moves through the airlock and it's restriction. Upon exiting the restriction, I check what type of agent and direct the agent to the correct exit block. The dummy agent and cart move to the Product where the dummy agent releases the cart and sinks. The sink frees the wait block and the Product seizes the cart that is right next to it and continues on it's journey.
It's an easy copy/paste to add more airlocks. Not as nice as my original, but what are you going to do... Thanks for everyone's help and suggestions.
As others have said, there are (not really documented) restrictions on what blocks you can use in preparation and wrap-up flowcharts, which mean what you're attempting won't work.
As you say, it's important to keep a single 'instance' of the airlock flow so that the restrictions (queue and restricted area) are 'global' when this represents the same physical airlock. (Otherwise a repeated custom block is precisely what you should use for each different physical airlock.)
Your best option (and assuming you needed to attach the Cart resource to the Product) is probably to
Add dummy agents (via Source block inject calls) to a separate mini-process that represents your resource preparation requirement (but now not attached to the Seize block).
Replace the Seize in your main process with a Seize-Wait-Release-Seize combination:
The Seize block seizes the cart as normal (without moving or attaching it; no 'Send seized resources' or 'Attach seized resources' options) and then injects an agent into your mini-process (which can use Exit and Enter blocks to use the airlock sub-process). This agent represents the seized resource agent (Cart) and thus should start where it starts and be animated so it looks like it. (You can make the actual Cart temporarily non-visible during this mini-process.)
When the agent reaches the end of the mini-process (at a Sink block), instantly move the related Cart to your node (use jumpTo), make it visible again and free the Product agent from the Wait block
Release the seized Cart and then immediately re-Seize it, but now attaching it (so the animation looks correct). If you use the Resource selection 'Nearest to the agent' option you should be guaranteed to seize the correct cart. (You can also use the 'Customise resource choice' option with some code to ensure that you absolutely always choose the same Cart.)
(It is simpler than the above if you don't care about having a correct animation, and you can use custom blocks to make this block combination reusable and thus not too clunky.)
Edit: A very similar alternative which also works (and is the basis for your own answer) is to have a dummy agent representing your Product in the sub-flow which seizes (and attaches) the actual Cart agent, leaving it at the Product's location to be immediately seized as above. This is slightly better since you don't have to worry about the visibility and 'jumping' of the real resource agent, plus you can move a Seize and a Release from the main flow (which now just has Wait-Seize) to the sub-flow (thus 'hiding them away').

Can you connect 2 separate flowcharts with one restricted area?

Our model has a ProductionOrder seize some Operators. The seize block has a Prepare flowchart for the Operators to move through an airlock (PAL) into a room. After the ProductionOrder operation (a delay block), the Operators are released and have a Wrap-Up flowchart that sends them out of the room through the same airlock. Because this airlock can only have 2 people, we need to restrict the combined Operators in the Prepare and Wrap-up flowcharts to 2 people in the airlock regardless of them coming in or going out (i.e. max 2 at any time).
If we do this by connecting the blocks with connectors, an error comes up basically saying you can't connect a Prepare flowchart to a Wrap-up flowchart.
Is there a way to link the circled queues and restricted area start blocks?
Instead of using a queue (PALqueue) use a wait block there (in both flows)
And you can do in the on enter of each wait block PALqueue:
if(PALCapacityLimit.entitiesInside()+PALCapacityLimit1.entitiesInside()<2){
self.free(agent);
}
And in the on onter of the PalInLimit (both)
if(PALqueue.size()>0)
PALqueue.free(PALqueue.get(0)); //remember now PALqueue is a wait block
else if(PALqueue1.size()>0)
PALqueue1.free(PALqueue1.get(0));
And there you go :)

How to cancel a process waiting to return with ptrace()

I am trying to cancel when a process calls wait(), read(), recvfrom() or similar, because if I use ptrace on it, after the PTRACE_ATTACH and later PTRACE_CONT, my tracer becomes blocked until the function in the tracee returns. Also I think it happens the same with sleep().
Would be possible to cancel the call, or reproduce a fake return?
Thanks.
Yes, you should send a PTRACE_INTERRUPT. This will trigger the syscall to exit.
To do this, you need not to waitpid on your tracee, because that would block you (the tracer) too.
You can either have multiple threads: one that will block on the tracee, one that will "decide" to cancel the blocking syscall - e.g. a GUI thread that the user will press "cancel" (like a normal debugger, e.g. GDB).
Or you can use PTRACE_SYSCALL to manually diagnose every syscall the program is doing and then decide preemptively if you wish to execute that syscall. This way you can decide to not run wait at all, or perhaps mock them by having your return value instead.

Handle signals of child processes

Is it possible to catch signals received (specifically SIGSEGV, SIGABRT) by child processes of a program without actually modifying it (or with minimal modification)?
The program I'm talking about is a pretty complex tool of which I don't have low-level (implementation details) knowledge of. I do have access to its source code. I can start it using a command like:
$ ./tool_name start # tool_name is an executable created after compiling and building its source code
It forks many child processes and I want to see if those child processes are being killed by a signal or not.
What I have thought about is to create a simple C program and call above command through that (using system()). Write a signal handler for above signals I'm looking for, and do other stuffs. Is it a right way to keep track of signals received by child processes? Is there a better way to do the same?

Managing Signal Handling for daemons that fork()

I want to write a robust daemon in perl that will run on Linux and am following the template described in this excellent answer. However there are a few differences in my situation: First I am using Parallel::ForkManager start() and next; to fork on an event immediately followed by exec('handle_event.pl')
In such a situation, I have the following questions:
Where should I define my signal handlers. Should I define them in the parent (the daemon) and assume that they will be inherited in the children?
If I run exec('handle_event.pl') will the handlers get inherited across the exec (I know that they are inherited across the fork)?
If I re-define a new signal handler in handle_event.pl will this definition override the one defined in the parent?
What are best practices in a situation like this?
Thank you
When you fork, the child process has the same signal handlers as the parent. When you exec, any ignored signals remain ignored; any handled signals are reset back to the default handler.
The exec replaces the whole process code with the code that will be executed. As signal handlers are code in the process image, they cannot be inherited across an exec, so exec will reset the signal handling dispositions of handled signals to their default states (ignored signals will remain ignored). You will therefore need to install any signal handling in the execed process when it starts up.