eclipse-4diac / 4diac-forte

Eclipse Public License 2.0
25 stars 29 forks source link

E_IMPULSE works different than expected - FB or event scheduling? #42

Closed kaartee closed 5 months ago

kaartee commented 6 months ago

image

Deploying the depicted FB network to a FORTE_PC instance, it can be observed that E_SR's Q output value doesn't toggle in the 4diac debugger's watch, nor does E_PERMIT indicate that a detectable number of events EI are processed for PERMIT = FALSE.

Does the FORTE event scheduler treat output events and their associated output variable values atomically for each separate event? That is, upon reception in a subsequent FB, does each of these events get processed with the variable values of each distinct event, or could two subsequent events, when received, operate on the output variables values of the later of the two events only?

Is this behavior of E_IMPULSE consistent with whatever the expectation is of an E_IMPULSE? I lack access to any documentation.

At present, I don't think E_IMPULSE provides any deterministic behavior. Different combinations of DT of E_CYCLE and DT of E_DELAY yield, modestly speaking, other interesting, but IMHO hardly useful, results. Which means, I thought that E_IMPULSE emits one or zero CNF with QO = TRUE in TM time units.

diplfranzhoepfinger commented 6 months ago

Hi, i will have a look, OK ?

diplfranzhoepfinger commented 6 months ago

Btw: we renamed E_IMPULSE to E_PULSE and placed it in the Timers Folder together with E_TP.

E_PULSE and E_TP should have same behavior as defined in IEC 61131-3 for TP with the difference that E_PULSE is Event triggered and E_TP is Event and raising Edge Triggered.

azoitl commented 6 months ago

Currently in 4diac FORTE events and data are separate. The scheduler only stores input events in a FIFO queue. FBs operate always on the last data made available to them. For that 4diac FORTE has a buffer on data connections. On output events data is sampled onto the connections on input events it is sampled from the connection.

May I ask what you want to achieve because with the given setup you application is not only getting wrong results from our event handling but as you can see on the outputs it is very sensitive to any jitter our timer may have and on the event order arriving at the E_SR block.

kaartee commented 6 months ago

By now, I am a little desperate that I look at an FB and it's network and cannot figure out what the intended purpose is, respectively, I suspect that it might be broken. Thus, it would be great if someone could explain what E_PULSE is supposed to do and why it works correctly. Notwithstanding, your question is quite justified and helpful, and if you could point me toward a solution to what I was trying to achieve, all the better:

I sample data from ADC, in async mode, so I have to deal with (cyclical) request events based on one central event source, i.e. E_CYCLE. But I also have concurrent IND events generated by modular IO upon ADC sampling completion. To keep the processing rate for subsequent computationally expensive FBs under control, I thought I wanted to filter out extraneous events that move through the FB network graph and fix the event rate at the E_PULSE node to less than or equal one per TM time units. E_PULSE doesn't give me that.

azoitl commented 6 months ago

By now, I am a little desperate that I look at an FB and it's network and cannot figure out what the intended purpose is, respectively, I suspect that it might be broken. Thus, it would be great if someone could explain what E_PULSE is supposed to do and why it works correctly.

E_PULSE should generate an pulse of length DT at its output. However I think E_PULSE as AFAIK most pulse generators has problems if the triggering of the pulse generation is faster then the length of the pulse.

Notwithstanding, your question is quite justified and helpful, and if you could point me toward a solution to what I was trying to achieve, all the better:

I sample data from ADC, in async mode, so I have to deal with (cyclical) request events based on one central event source, i.e. E_CYCLE. But I also have concurrent IND events generated by modular IO upon ADC sampling completion. To keep the processing rate for subsequent computationally expensive FBs under control, I thought I wanted to filter out extraneous events that move through the FB network graph and fix the event rate at the E_PULSE node to less than or equal one per TM time units. E_PULSE doesn't give me that.

Yes I don't think that E_PULSE is the right thing here. Just to be sure that I understand you have one or more IND events from the IO infra which trigger your application appon completion of an ADC conversion.

  1. Do you have one computational heavy block that should be triggered once all IND events have arrived?
  2. Do you you just want to trigger your computational heavy block with your E_CYCLE and take the latest data that is there?

ad 1) here I would recommend a synchronization block that take all IND events and when all have arrived once send an output event. To avoid deadlock maybe a watchdog would make sense to trigger the output at least every x ms.

ad 2) just connect your E_CYCLE to your computational heavy FB and ignore the IND events. The computational heavy FB will automatically and correctly sample the latest values from your IO Blocks.

kaartee commented 6 months ago

Thus, an E_TP with a feedback of the value of Q, boolean inverted, to IN, provides a hardened E_PULSE substitute for REQs occurring while a pulse is "in progress"?

kaartee commented 6 months ago

Please allow me to mention it here: the modular IO infrastructure code [edit: when used with ADC input] generates a lot of IND events from the ID FB, by how the Zephyr port uses the API. In practice, for each REQ to ID I have been able to trigger one CNF event, but at the same time threefold as many IND events. I don't know about the other modular IO-based boards, or the predecessor API.

diplfranzhoepfinger commented 6 months ago

Please allow me to mention it here: the modular IO infrastructure code generates a lot of IND events from the ID FB, by how the Zephyr port uses the API. In practice, for each REQ to ID I have been able to trigger one CNF event, but at the same time threefold as many IND events. I don't know about the other modular IO-based boards, or the predecessor API.

maybe have a look at my ESP32 "modular IO" with "button" in the back. we do not use REQ at all, only use IND.

and it generates exactly 2 Events on a IX Block, one at Press, one at Release. and exactly 1 Event on a IE Block, e.g. at a double-Click. all the Debouncing is done in Hardware Timers. no REQ needed at all.

therefore i do not understand your concept of REQ and so on. Please explain more.

diplfranzhoepfinger commented 6 months ago

https://github.com/Meisterschulen-am-Ostbahnhof-Munchen/4diac_training1

kaartee commented 6 months ago

@diplfranzhoepfinger I failed to mention that was referring to ADC. In your case you don't have to ever REQ button reads, but an ADC measurement needs to be triggered. Is this little clarification sufficient? I'm sorry for omitting that.

diplfranzhoepfinger commented 6 months ago

this is my Sample Repo, feel free to have a look. 

also you could write me franz.hoepfinger.4diac@logibus.tech and we share some documentation.

diplfranzhoepfinger commented 6 months ago

@diplfranzhoepfinger I failed to mention that was referring to ADC. In your case you don't have to ever REQ button reads, but an ADC measurement needs to be triggered. Is this little clarification sufficient? I'm sorry for omitting that.

even ADC Reads i do not neccessarily trigger. 

i give it a Hysteresis on the Mapping, and it IND from the ID Block, only if i want to have the Value "Above of time" i do trigger it. 

but yes, then i trigger it. 

but E_PULSE does not work then, at it works only for BOOL Output. 

not for Analog Values.

azoitl commented 6 months ago

Please allow me to mention it here: the modular IO infrastructure code [edit: when used with ADC input] generates a lot of IND events from the ID FB, by how the Zephyr port uses the API. In practice, for each REQ to ID I have been able to trigger one CNF event, but at the same time threefold as many IND events. I don't know about the other modular IO-based boards, or the predecessor API.

The idea of the modular IO was that you have a configuration that defines scan cycles of IOs with the IO configuration FBs and that the IO infrastructure notifies registered FBs. For analog values this could be in sync with the scan cycle, it could be in sync with the ADC interrupt, with hysteresis, or no notification at all. In the latter case REQ would fetch the latest value from the IO image and notifies with CNF that the latest value is at its output.

But it is against the idea of the IO infra that an event at the IO block is triggering some execution in the IO Infra.

kaartee commented 6 months ago

even ADC Reads i do not neccessarily trigger.

Meaning you rely on the UpdateInterval that is set in the device configuration resource, instead of ever triggering through the ID FB of the application resource? In this way, programming in the application FB network any complex interactions like crosstalk or event-based ADC are replaced C++ implementations of hysteresis and cyclical readout? I don't feel comfortable with that approach. Otherwise though, I remember now that it is that UpdateInterval that is responsible for all the additional INDs. If I raise it high enough or turn the updates off altogether, I only get an unaccounted-for additional 10 INDs from the ADC's ID FB.

kaartee commented 6 months ago

But it is against the idea of the IO infra that an event at the IO block is triggering some execution in the IO Infra.

Uh oh. Is that an categorical statement? I would like to think that an application may very well have to decide which channels to sample at which time, and not leave that to cyclical scanning on the device configuration end. If I did that, I would place an important part of our application in the device configuration resource.

diplfranzhoepfinger commented 6 months ago

even ADC Reads i do not neccessarily trigger.

Meaning you rely on the UpdateInterval that is set in the device configuration resource, instead of ever triggering through the ID FB of the application resource?

means i read ADC e.g. at 1MHz Speed. make some Averaging, and then get the averaged ADC Value to 4diac FORTE.

kaartee commented 6 months ago

@diplfranzhoepfinger Our algorithm is proprietary and I am not in a position to discuss it further.

diplfranzhoepfinger commented 6 months ago

OK, so take it:

E_PULSE generates a Impulse on a DIGITAL Output on say 3s length on the Press of a Button. it is not suited for anything else.

it is well tested in Many industrial grade Applications.

azoitl commented 6 months ago

even ADC Reads i do not neccessarily trigger.

Meaning you rely on the UpdateInterval that is set in the device configuration resource, instead of ever triggering through the ID FB of the application resource? In this way, programming in the application FB network any complex interactions like crosstalk or event-based ADC are replaced C++ implementations of hysteresis and cyclical readout? I don't feel comfortable with that approach. Otherwise though, I remember now that it is that UpdateInterval that is responsible for all the additional INDs. If I raise it high enough or turn the updates off altogether, I only get an unaccounted-for additional 10 INDs from the ADC's ID FB.

I mostly wanted to say that the core design idea of the current IO layer had in mind that we have some scan cycle for a backplane, fieldbus or some other ios and that the thread there is in charge of updating the values and sending output events. However the setup is rather flexible and you not necessarily need to do a pure update cycle. Your IOHandler implementation is responsible for producing the IND events. If you want to do it special for you you should be able to do it. But if you send INDs that you don't want to have or that disturb your application it feels that something in the design of your IO system is wrong.

azoitl commented 6 months ago

@diplfranzhoepfinger Our algorithm is proprietary and I am not in a position to discuss it further.

I want to explicitly point out that we know that Eclipse 4diac is used in different settings and some are sensitive and not all information about Eclipse 4diac usage can be disclosed. No one here should feel pressed to give details about stuff that is not possible. If anyone has the feeling that this is the case please let me know.

kaartee commented 5 months ago

Every new and pristine installation of nightly build of 4diac indicates that E_IMPULSE is broken:

Description Resource    Path    Location    Type
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /ControlValve/Type Library/events   CNF.YPOSITION   4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /ControlValve/Type Library/events   CNF.YPOSITION   4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /ControlValve/Type Library/events   QO.YPOSITION    4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /ControlValve/Type Library/events   QO.YPOSITION    4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /ControlValve/Type Library/events   REQ.YPOSITION   4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /ControlValve/Type Library/events   REQ.YPOSITION   4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /ControlValve/Type Library/events   TM.YPOSITION    4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /ControlValve/Type Library/events   TM.YPOSITION    4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /ESP32/Type Library/events  CNF.YPOSITION   4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /ESP32/Type Library/events  QO.YPOSITION    4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /ESP32/Type Library/events  REQ.YPOSITION   4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /ESP32/Type Library/events  TM.YPOSITION    4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /E_IMPULSE_Test/Type Library/events CNF.YPOSITION   4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /E_IMPULSE_Test/Type Library/events QO.YPOSITION    4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /E_IMPULSE_Test/Type Library/events REQ.YPOSITION   4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /E_IMPULSE_Test/Type Library/events TM.YPOSITION    4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /HWIO/Type Library/events   CNF.YPOSITION   4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /HWIO/Type Library/events   CNF.YPOSITION   4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /HWIO/Type Library/events   CNF.YPOSITION   4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /HWIO/Type Library/events   QO.YPOSITION    4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /HWIO/Type Library/events   QO.YPOSITION    4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /HWIO/Type Library/events   QO.YPOSITION    4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /HWIO/Type Library/events   REQ.YPOSITION   4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /HWIO/Type Library/events   REQ.YPOSITION   4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /HWIO/Type Library/events   REQ.YPOSITION   4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /HWIO/Type Library/events   TM.YPOSITION    4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /HWIO/Type Library/events   TM.YPOSITION    4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /HWIO/Type Library/events   TM.YPOSITION    4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /NewControllerFBs/Type Library/events   CNF.YPOSITION   4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /NewControllerFBs/Type Library/events   QO.YPOSITION    4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /NewControllerFBs/Type Library/events   REQ.YPOSITION   4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /NewControllerFBs/Type Library/events   TM.YPOSITION    4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /RevisionControl/Type Library/events    CNF.YPOSITION   4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /RevisionControl/Type Library/events    QO.YPOSITION    4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /RevisionControl/Type Library/events    REQ.YPOSITION   4diac IDE Initial Value Problem
Cannot convert from SINT to STRING  E_IMPULSE.fbt   /RevisionControl/Type Library/events    TM.YPOSITION    4diac IDE Initial Value Problem

There are a few more messages from other types, too - but those somehow don't get flagged in the System Explorer tree.

Either way, deploying shows a pop-up that there are errors, too.

Telling you just in case I'm the first one noticing that.

azoitl commented 5 months ago

Thx for pointing this out. Yes we noticed that. The problem here is that the our automatic layout algorithm added attributes in a format that we are not supporting anymore. Or better said where we have more correct checks.

In the meantime the E_IMPULSE is deleted from Eclipse 4diacs Tool Library and in the replacing E_PULSE this problem is fixed.

You can simply replace the E_IMPLUSE with the E_PULSE in your projects.

We have in the nightly build a first prototype where the tool library is not copied into the projects anymore but only linked. With that such issue will be resolved easier.

MartinMelikMerkumians commented 5 months ago

@azoitl from your answer I assume we can close this issue?

azoitl commented 5 months ago

@MartinMelikMerkumians yes I think so. Thanks for pointing it out.