This chapter introduces the RTIambassador service and FederateAmbassador callback methods that support time management functionality. The RTI provides a variety of optional time management services. Though optional, it is important to understand the time management models available in the RTI and the implication of exchanging events between federates with different time management policies. Chapter 3, The Role of Time, provides a philosophical introduction to time management. The focus here is on the mechanics required to implement time management policies and negotiate time advances.
Chapter 3, The Role of Time, presented the definitions for "regulating" and "constrained." Figure 6-1 identifies the RTIambassador and FederateAmbassador member functions associated with establishing whether a federate is regulating or not, and whether a federate is constrained or not. Key methods are presented briefly below and discussed in detail in the appendices.
Figure 6-1. Toggling "regulating" and "constrained" Status
Regulation Policy
Federates have regulation disabled by default. A federate utilizes the RTIambassador member function enableTimeRegulation() to request that the federate be acknowledged as a regulating federate. The Local RTI Component (LRC) calls the FederateAmbassador callback timeRegulationEnabled() to inform a federate that the enableTimeRegulation() request has been granted and informs the federate of its (possibly new) logical time. In Section 3.4, Advancing Time, the effect of a late arriving federate wishing to be time regulating was discussed. In synopsis, such a federate is obligated to advance to a time such that the current LBTS of existing federates is guaranteed to be honored.
It is possible to change the regulation policy dynamically. The RTIambassador method disableTimeRegulation() is the counterpart to enableTimeRegulation(). Unlike enableTimeRegulation(), disableTimeRegulation() takes effect immediately.
Federates have constrained disabled by default. A federate utilizes the RTIambassador member function enableTimeConstrained() to request that the federate be acknowledged as a constrained federate. The timeConstrainedEnabled() callback informs a federate that the enableTimeConstrained() request has been granted. It is possible to change the constrained policy dynamically. The RTIambassador method disableTimeConstrained() is the counterpart to enableTimeConstrained().
Three variants of the time advancement service exist to provide the requisite functionality for time-step, event-based, and optimistic federates. Typically, a federate will employ only one of the time advancement services; however, some federates may find it useful to use more than one of the services throughout the federate’s execution.
Time-Stepped FederatesTime-stepped federates will calculate values based on a point in time and then process all events that occur up to the next point in time (current time + time step). Figure 6-2 illustrates the functions used to advance a federate's logical time for a time-stepped simulation.
When a timeAdvanceRequest() or timeAdvanceRequestAvailable() service is used, the federate’s LRC will be eligible to release any receive order messages from the FIFO Queue and all time-stamp ordered messages that have a time stamp less than or equal to the time requested from the TSO queue. After all TSO messages in a federation execution with time less than or equal to the requested time have been received, the federate will receive a timeAdvanceGrant() callback via the FederateAmbassador. See the man pages for a more detailed discussion of the released events and the granted time for the timeAdvanceRequest() and timeAdvanceRequestAvailable() services.
Figure 6-2. Logical Time Advancement for a Time-Step Federate
Event-based federates will calculate values based on each event received from the federation execution. After an event is processed, the federate may need to send new events to the federation execution. This implies that the events may not happen on set time intervals but the times of events will be based on the time of the received events. Figure 6-3 illustrates the functions used to advance a federate's logical time for an event-based simulation.
When a nextEventRequest() or nextEventRequestAvailable() service is used, the federate’s LRC will be eligible to release any receive order messages from the FIFO Queue and all time-stamp ordered messages that have a time stamp equal to the minimum next event time from the TSO queue.
After all TSO messages with time equal to the minimum next event time have been received, the federate will receive a timeAdvanceGrant() callback via the FederateAmbassador. See the man pages for a more detailed discussion of the released events and the granted time for the nextEventRequest() and nextEventRequestAvailable() services.
Figure 6-3. Logical Time Advancement for an Event-Based Federate
Optimistic federates do not want to be constrained by the time advancement of regulating federates but instead will proceed ahead of LBTS to calculate and send events in the future. These federates will want to receive all of the events that have been sent in the federation execution regardless of the time-stamp ordering. A federate that uses the flushQueueRequest() service is likely to generate events that are in the future of messages that it has yet to receive. The messages that are received with a time-stamp less than messages already sent may invalidate the previous messages. In this case, the optimistic federate will need to retract the messages that have been invalidated and all federates that have received the invalid messages will receive a requestRetraction() callback on their FederateAmbassador. See the man pages for a detailed discussion of the retract() and requestRetraction() services.
When the flushQueueRequest() service is used, the federate’s LRC will be eligible to release all receive order messages from the FIFO Queue and all time-stamp ordered messages from the TSO queue. After all TSO messages that were in the queue at the time of the flushQueueRequest() invocation have been released, the federate will receive a timeAdvanceGrant() callback via the FederateAmbassador. See the man pages for a more detailed discussion of the released events and the granted time for the flushQueueRequest() service. Figure 6-4 illustrates the functions used to advance a federate's logical time for an optimistic simulation.
Figure 6-4. Logical Time Advancement for an Optimistic Federate
Time advance requests are made through an RTIambassador instance. Time advance grants are received through a FederateAmbassador instance. User code must unite the request and grant. This pattern is repeated throughout the RTI. One approach to uniting code is to communicate through global variables (globals). In the following examples, globals are used to tie the following service request, callback pairs:
RTIambassador::enableTimeRegulation()® FederateAmbassador::timeRegulationEnabled()
RTIambassador::enableTimeConstrained()® FederateAmbassador::timeConstrainedEnabled()
RTIambassador::timeAdvanceRequest()® FederateAmbassador::timeAdvanceGrant()
Whenever user-defined global variables or global functions are used in coding examples, they're preceded by the global scope resolution operator "::". While it is a bad practice to use globals, it is a good practice to identify any globals with this operator.
The two-argument form of tick is called in the preceding example. In the example, the goal is to slow the simulation so students can observe simulation progress. As an alternative to line 87, the one-argument version of tick() might be used. Between calls to tick() and prior to receiving a time advance grant, the federate may choose to interleave some preparatory work.
Several additional time management functions are available to query or fine tune time policy. Figure 6-4, Time Queries, shows additional functions. Consult the man pages for these functions for detailed descriptions.
Figure 6-4. Time Queries