openlvc / portico

Portico is an open source, cross-platform, fully supported HLA RTI implementation. Designed with modularity and flexibility in mind, Portico is a production-grade RTI for the Simulation and Training Community, so come say hi!
http://www.porticoproject.org
151 stars 81 forks source link

Filtering of received interactions removes all parameters #269

Open tpr1 opened 6 years ago

tpr1 commented 6 years ago

I have two interactions: InteractionRoot.Parent handle=793 with parameters [794, 795, 796, 797, 798] and InteractionRoot.Parent.Child handle=799 that inherits the 5 parameters of its parent with 2 more.

I have a federate that publishes InteractionRoot.Parent.Child and another federate that subscribes to InteractionRoot.Parent. I expect the received interaction to be filtered to the set of 5 shared parameters in the parent interaction class.

Here's the actual output:

17:59:11,143 DEBUG [Thread-1] portico.lrc: @REMOTE Received INTERACTION [799] with parameters [800, 801, 802, 803, 804, 805, 806] @1.2
17:59:11,158 DEBUG [Thread-1] portico.lrc: FILTER  incoming interaction type=799, subscribed type=793
17:59:11,158 TRACE [Thread-1] portico.lrc: CALLBACK receiveInteraction(class=793,parameters=[],time:1.2) (TSO)

The received interaction is filtered to the correct class (from 799 to 793), but it's received with an empty parameter set despite having inherited 800 thru 804 from its parent.

Here is the filter method:

https://github.com/openlvc/portico/blob/7559c505bd4c5b62935a6677750458c6ec09f082/codebase/src/java/portico/org/portico/lrc/services/object/handlers/incoming/ReceiveInteractionHandler.java#L130-L141

Which ends up calling:

https://github.com/openlvc/portico/blob/7559c505bd4c5b62935a6677750458c6ec09f082/codebase/src/java/portico/org/portico/lrc/model/ICMetadata.java#L207-L227

The filter method is called with ICMetadata {interactionHandle=793 parameters=[794, 795, 796, 797, 798] } and with raw parameters [800, 801, 802, 803, 804, 805, 806]. It visits each parent interaction to see if any of them recognize the passed parameters. However, because of how handles are initialized (using handle++), when this method recurses the next ICMetadata will always end up with lower parameter handles - so the 800+ values will never be recognized as valid parameters.

It seems like the filter method would never return anything but an empty set (for upcasts) or the entire set (for downcasts). Am I misunderstanding how it should work?

tpr1 commented 6 years ago

This happens when you re-define parameters in the fed file; not sure what happens with 1516e fom files.

Excerpt from a fed file that causes the problem:

(class InteractionBase reliable timestamp 
    (parameter actualLogicalGenerationTime)
    (parameter federateFilter)
    (parameter id)
    (parameter originFed)
    (parameter sourceFed)
    (class InteractionChallenge reliable timestamp 
        (parameter actualLogicalGenerationTime)
        (parameter beginIndex)
        (parameter federateFilter)
        (parameter id)
        (parameter originFed)
        (parameter sourceFed)
        (parameter stringValue)
    )
    (class Response reliable timestamp 
        (parameter actualLogicalGenerationTime)
        (parameter federateFilter)
        (parameter id)
        (parameter originFed)
        (parameter sourceFed)
        (parameter substring)
    )
)

Each instance of parameter id gets assigned a separate handle, although it is the same parameter in all three interaction classes. So the id for BaseInteraction with handle=794 is not the same as the id for InteractionChallenge with handle=800, and gets removed during the filter. Is there a reason this doesn't cause an error / reuse the same handle?