GMLC-TDC / HELICS

Hierarchical Engine for Large-scale Infrastructure Co-Simulation (HELICS)
https://docs.helics.org/en/latest/
BSD 3-Clause "New" or "Revised" License
126 stars 40 forks source link

HELICS python example issue #998

Open ArtRie opened 4 years ago

ArtRie commented 4 years ago

Bug Description HELICS python example includes "pi sender" and "pireceiver" examples https://github.com/GMLC-TDC/HELICS-Examples/blob/master/python/pi-exchange/pisender.py https://github.com/GMLC-TDC/HELICS-Examples/blob/master/python/pi-exchange/pireceiver.py When running the example, it looks that two extra messages are received but never sent. One message arrives after time window that is allowed (picture attached).

Expected behavior Receive exactly as many messages as are sent within the time limit allowed.

To Reproduce Follow the instructions https://helics.readthedocs.io/en/latest/introduction/python.html

Environment (please complete the following information):

nightlark commented 4 years ago

Can you test pireceiver.py with lines 57-62 inside of an if statement that checks helicsInputIsUpdated and see if it still prints the two extra lines? It looks like the receiver is just printing the values it previously got from the sender at the earlier timestep.

I think it would look something like this:

    if h.helicsInputIsUpdated(sub):
        value = h.helicsInputGetString(sub)
        print(
            "PI RECEIVER: Received value = {} at time {} from PI SENDER".format(
                value, currenttime
            )
        )

Since this example is using the value federate [publication/subscription] interface, the names sender/receiver might be a bit of a misnomer. With the message federate interface there's a strong tie between the message sent and the time, whereas with the value interface the value published stays the same until a new value is published. Maybe more accurate names would be pigenerator/publisher/producer and pisubscriber/consumer?

kdheepak commented 4 years ago

@ArtRie This was intentional on my part when I wrote the example but I didn't explain why. I wanted to show what happens when you make a request time in some edge cases, i.e. when the other federate has disconnected and when you request time that is past.

Federate 2 (PIRECEIVER) requests for time 100 always, and is granted time 5.0, 6.0, 7.0, 8.0 and finally 9.0. These are the times Federate 1 (PISENDER) requests and sends data on a publication. After it sends data at time 9.0, Federate 1 calls finalize. Federate 2 continues to make a request time for 100, and this time is granted 100 since no event that Federate 2 is subscribed to has occurred between the previous time and the requested time.

Then, since the while condition is while current <= 100: and the value of current is 100.0, it makes a request time for 100 again but this time it is granted 100.01, i.e. 100.0 + $(deltat). That exits the while loop and Federate 2 then calls finalize.

Subscriptions always get the last value that was published on that topic, and that is why it appears that "two extra messages are received but never sent".

@nightlark I agree that the naming here can be improved.