VR-Link API Documentation for HLA Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
HLA Time Managed Talk-Listen Example

Table of Contents

This is a time constrained version of the VR-Link Talk-Listen example.

HLA Time Regulating Talk Example

Time Regulation

This program is a time regulating version of TalkRPR. It gets an initial time when time regulation is enabled and then advances for about 10 time units. Movement of the entity is not even. It sends one interaction. Time regulation is turned off when the federate is ready to leave; this will allow time constrained federates to advance at that point. It is possible, and usually desirable, to move time forward as the simulation progresses. However, we choose not to here.

HLA Time Constrained Listen Example

Time Constraint

This program is a slightly modified version of Listen example with HLA time management enabled.

In time managed mode, do not use the RPR time stamp in User tag. If this option is True (the default), the FedTime supplied in a reflect attribute callback is overwritten in the DtStateMsg by the timestamp in the RPR User Tag field. This means that the updated attributes are applied to the state repo with the current simTime, or with the RPR User tag time, depending on relative time mode or absolute. This will in turn cause bad dead reckoning values when querying the state repo for location, for example.

In time managed mode, set the exercise connection timestamp type to Absolute. This will tell the decoders to use the time stamp value contained in the reflect attribute update message. If this is not enabled, the timestamp will be ignored and the sim time at time of receipt will be used instead.

After we have initialized the exercise connection, we need to register for two callbacks to:

Time Managed Example Code

HLA Time Regulating Talk Example Code

/****************************************************************************
* Copyright (c) 2020 MAK Technologies
* All rights reserved.
****************************************************************************/
#ifdef DtHLA
#include <vl/topoView.h>
#if DtHLA_1516
#if DtHLA_1516_EVOLVED
#include <RTI/time/HLAfloat64Time.h>
#include <RTI/time/HLAfloat64Interval.h>
#else
#include <RTI/logicalTimeImpl.h>
#include <RTI/logicalTimeIntervalImpl.h>
#endif
#else
#include <fedtime.hh>
#endif
int keybrdTick();
#if DtHLA_1516
void timeAdvanceRequestCb(const RTI::LogicalTime &, void *);
void timeRegulationEnabledCb(const RTI::LogicalTime &, void *);
#else
void timeAdvanceRequestCb(const RTI::FedTime &, void *);
void timeRegulationEnabledCb(const RTI::FedTime &, void *);
#endif
// Globals
bool theTimeRegOn(false);
bool theTimeMoved(false);
#if DtHLA_1516
#if DtHLA_1516_EVOLVED
HLAfloat64Time theGlobalFedTime;
const HLAfloat64Interval theLookAhead(2.0);
const HLAfloat64Interval theFedTimeAdvance(0.5);
#else
LogicalTimeImpl theGlobalFedTime;
const LogicalTimeIntervalImpl theLookAhead(2.0);
const LogicalTimeIntervalImpl theFedTimeAdvance(0.5);
#endif
#else
RTIfedTime theGlobalFedTime;
const RTIfedTime theLookAhead(2.0);
const RTIfedTime theFedTimeAdvance(0.5);
#endif
int main( int argc, char* argv[] )
{
// Used for error handling
DtINIT_MINIDUMPER( "TimeRegulator" );
DtVrlApplicationInitializer appInit( argc, argv, "VR-Link timeRegulator" );
// Set the default FED File, executable, and version
appInit.setFedFileName( DtDefaultRpr2Fom );
appInit.setExecName( "MAK-One-2024" );
appInit.setRprFomVersion( 2.0 );
appInit.setRprFomRevision( 1 );
#ifdef DtHLA_1516_EVOLVED
std::vector<DtString> fomModules;
std::vector<DtString> fomModuleFromCommandLine;
appInit.fomModules(fomModuleFromCommandLine);
fomModules.push_back("NETN-Physical.xml");
fomModules.insert(fomModules.end(), fomModuleFromCommandLine.begin(), fomModuleFromCommandLine.end());
appInit.setFomModules(fomModules);
#endif
appInit.parseCmdLine();
DtExerciseConn exConn( appInit );
DtInfo << "Time Management examples require attributes in FOM to be set to TimeStamp order." << std::endl;
// Register for
// 1) time advance grants, to let us move time forward.
exConn.fedAmb()->addTimeAdvanceGrantCb( timeAdvanceRequestCb, 0 );
// 2) time regulation turning on, because we cant start simulating until
// it goes on.
exConn.fedAmb()->addTimeRegulationEnabledCb( timeRegulationEnabledCb, 0 );
#if DtHLA_1516
exConn.rtiAmb()->enableTimeRegulation(theLookAhead);
#else
exConn.rtiAmb()->enableTimeRegulation(theGlobalFedTime, theLookAhead);
#endif
// Tell the Exercise Connection that all our messages should be
// sent TSO. If we want to send a message non TSO, this can be turned on
// and off throughout the life of the application.
exConn.setSendFedTime(true);
// We have requested Time regulation, as we don't know what time
// will begin as, we need to wait before moving forward.
while(!theTimeRegOn)
{
// Wait and query the RTI
exConn.drainInput();
DtSleep(0.05);
}
DtVector position(0.0, 0.0, 0.0);
DtVector32 velocity(10.0, 0.0, 0.0);
// Create an entity publisher for the entity we are simulating.
DtEntityPublisher *entityPub = new DtEntityPublisher(*f18Type, &exConn,
// Hold on to its state repository, where we can set data.
// Create a topographic view on the state repository, so we
// can set position information in topographic coordinates.
double refLatitude = DtDeg2Rad( 35.699760);
double refLongitude = DtDeg2Rad(-121.326577);
DtTopoView topoView(esr, refLatitude, refLongitude);
topoView.setLocation(position);
topoView.setVelocity(velocity);
// We can use the ESR to set state.
esr->setMarkingText("VR-Link");
#if DtHLA_1516
DtTime timeAdvanceInterval = theFedTimeAdvance.getInterval();
#else
DtTime timeAdvanceInterval = theFedTimeAdvance.getTime();
#endif
// messages we send out will be tagged with the Sim Time.
// with TSO messages as a time regulator we make a contract
// to send no messages earlier than globalFedTime + Lookahead.
// Lookahead may by 0 however, this imposes stress on the RTI and
// should be avoided.
#if DtHLA_1516
DtTime lookahed = theLookAhead.getInterval();
DtTime simTime = theGlobalFedTime.getTime() + lookahed;
#else
DtTime lookahed = theLookAhead.getTime();
DtTime simTime = theGlobalFedTime.getTime() + lookahed;
#endif
// Initialize VR-Link time.
exConn.clock()->setSimTime(simTime);
// Send a Fire Interaction.
DtInfo << "\nSending Interaction at Time: " << simTime << "\n\n";
fire.setAttackerId(entityPub->globalId());
exConn.sendStamped(fire);
int updateCount = 0;
DtTime endTime = simTime + 10.0;
DtTime lastTime = simTime;
while (simTime <= endTime)
{
if (keybrdTick() == -1)
break;
if (theTimeMoved)
{
theTimeMoved = false;
DtTime dt = simTime - lastTime;
// Tell VR-Link the current value of simulation time.
exConn.clock()->setSimTime(simTime);
position[0] += velocity[0] * dt;
position[1] = simTime;
position[2] = updateCount++;
topoView.setLocation(position);
topoView.setVelocity(velocity);
entityPub->tick();
// Print the fed time and position.
// Since it returns a DtString, we need to force it to const char* with a cast.
DtInfo << "Fed Time: " << theGlobalFedTime.getTime()
<< " Sim Time: " << simTime
<< " Pos: " << topoView.location().string() << '\n'
<< "--------" << std::endl;
lastTime = simTime;
simTime += timeAdvanceInterval;
#if DtHLA_1516
#if DtHLA_1516_EVOLVED
HLAfloat64Time reqTime(theGlobalFedTime);
#else
LogicalTimeImpl reqTime(theGlobalFedTime);
#endif
reqTime = theGlobalFedTime;
reqTime += theFedTimeAdvance;
exConn.rtiAmb()->timeAdvanceRequest(reqTime);
DtInfo << "requesting time: " << (theGlobalFedTime.getTime() + theFedTimeAdvance.getInterval()) << std::endl;
#else
exConn.rtiAmb()->timeAdvanceRequest(theGlobalFedTime + theFedTimeAdvance);
DtInfo << "requesting time: " << (theGlobalFedTime.getTime() + theFedTimeAdvance.getTime()) << std::endl;
#endif
}
// Suspend for longer and longer periods of time
// but if we join late lets not make it obnoxious
exConn.drainInput();
DtSleep(((int)simTime%10) + 1);
}
// Delete these items before you turn off time regulation. If
// time reg goes off (remember, it takes affect right away) then
// the deleteObject message will not have a time stamp and may be
// delivered BEFORE the discoverObject is issued.
delete f18Type;
delete entityPub;
// Disable time regulation. The RTI should be able to figure this out
// but its nice to be polite.
// Drain Input to work around a potential bug in the RTI where
// resigning from the Exercise will delete all objects with TSO
exConn.drainInput();
return 0;
}
int keybrdTick()
{
char *keyPtr = DtPollInputLine();
if (keyPtr && (*keyPtr == 'q' || *keyPtr == 'Q'))
return -1;
else
return 0;
}
void timeAdvanceRequestCb(
#if DtHLA_1516
const RTI::LogicalTime &aTime,
#else
const RTI::FedTime &aTime,
#endif
void *userData)
{
theGlobalFedTime = aTime;
theTimeMoved = true;
DtInfo << "Time Advance Grant to: " << theGlobalFedTime.getTime() << std::endl;
DtInfo.flush();
}
void timeRegulationEnabledCb(
#if DtHLA_1516
const RTI::LogicalTime &aTime,
#else
const RTI::FedTime &aTime,
#endif
void *userData)
{
theGlobalFedTime = aTime;
theTimeRegOn = true;
theTimeMoved = true;
DtInfo << "\nTime Regulation Enabled at time: " << theGlobalFedTime.getTime() << "\n\n";
DtInfo.flush();
}
#else // !DtHLA
#include <iostream>
int main()
{
std::cout << "Time Management Is only available in HLA" << std::endl;;
return 0;
}
#endif // !DtHLA

HLA Time Constrained Listen Example Code

/****************************************************************************
* Copyright (c) 2020 MAK Technologies
* All rights reserved.
****************************************************************************/
#ifdef DtHLA
#include <vl/topoView.h>
#include <vl/stateMsg.h>
#if DtHLA_1516
#if DtHLA_1516_EVOLVED
#include <RTI/time/HLAfloat64Time.h>
#else
#include <RTI/logicalTimeImpl.h>
#endif
#else
#include <fedtime.hh>
#endif
#include <iostream>
//
// This Program is a Time Constrained Federate. It is a slightly modified
// version of listenHLA with time management enabled.
//
// Forwards
#if DtHLA_1516
void timeAdvanceRequestCb( const RTI::LogicalTime &, void * );
void timeConstrainedEnabledCb( const RTI::LogicalTime &, void * );
#else
void timeAdvanceRequestCb( const RTI::FedTime &, void * );
void timeConstrainedEnabledCb( const RTI::FedTime &, void * );
#endif
void fireCb( DtFireInteraction*, void* );
// Globals
#ifdef DtHLA_1516
#ifdef DtHLA_1516_EVOLVED
HLAfloat64Time theFedTime;
const HLAfloat64Time theFedTimeAdvance( 0.25 );
#else
LogicalTimeImpl theFedTime;
const LogicalTimeImpl theFedTimeAdvance( 0.25 );
#endif
#else
const RTIfedTime theFedTimeAdvance( 0.25 );
RTIfedTime theFedTime;
#endif
bool theTimeConstraintOn = false;
bool theTimeMoved = false;
int main( int argc, char* argv[] )
{
// Used for error handling
DtINIT_MINIDUMPER( "TimeConstrained" );
DtVrlApplicationInitializer appInit( argc, argv, "VR-Link timeConstrained" );
// Set the default FED File, executable, and version
appInit.setFedFileName( DtDefaultRpr2Fom );
appInit.setExecName( "MAK-One-2024" );
appInit.setRprFomVersion( 2.0 );
appInit.setRprFomRevision( 1 );
appInit.parseCmdLine();
DtInfo << "Time Management examples require attributes in FOM to be set to TimeStamp order." << std::endl;
//In time managed mode, do not use the RPR time stamp in User tag.
//If this option is True (the default), the FedTime supplied in a reflect attribute callback is overwritten
//in the DtStateMsg by the timestamp in the RPR User Tag field. This means that the updated attributes are applied
//to the state repo with the current simTime, or with the RPR User tag time. (Depending on relative time mode or absolute)
//This will in turn cause bad dead reckoning values when querying the state repo for location (for example).
DtExerciseConn exConn( appInit );
//In time managed mode, set the exercise connection timestamp type to Absolute.
//This will tell the decoders to use the time stamp value contained in the reflect attribute update message.
//If this is not enabled, the timestamp will be ignored and the sim time at time of receipt will be used instead.
// Register a callback to handle fire interactions.
DtFireInteraction::addCallback( &exConn, fireCb, 0 );
exConn.drainInput();
// Register for the two callbacks we need
// 1) to let us know when time moves forward as we will be lock step.
// 2) to let us know that we have become time constrained.
exConn.fedAmb()->addTimeAdvanceGrantCb( timeAdvanceRequestCb, 0 );
exConn.fedAmb()->addTimeConstrainedEnabledCb( timeConstrainedEnabledCb, 0 );
// Let the RTI know we wish to be time constrained.
// We need to wait until we are time constrained before we move forward.
DtInfo << "Waiting for Time Constraint Grant." << std::endl;
while ( !theTimeConstraintOn )
{
// Wait and query the RTI
exConn.drainInput();
DtSleep( 0.25 );
}
// Create an object to manage entities that we hear about
// on the network.
DtReflectedEntityList rel( &exConn );
// Initialize VR-Link time.
DtClock* clock = exConn.clock();
#if DtHLA_1516
#if DtHLA_1516_EVOLVED
HLAfloat64Time lastTime( -10 );
#else
LogicalTimeImpl lastTime( -10 );
#endif
#else
RTIfedTime lastTime( -10 );
#endif
int forever = 1;
while ( forever )
{
// Check if user hit 'q' to quit.
if ( input.keybrdTick() == -1 )
break;
// Only preform work if time has advanced, it is possible we
// might be waiting for some time.
if ( theTimeMoved )
{
// Sim time will be kept in sync with GlobalFedTime
// as we are just reading from the network. If this federate
// were regulating as well as constrained, we would want to keep
// sim time at GlobalFedTime + lookahead()
clock->setSimTime( theFedTime.getTime() );
theTimeMoved = false;
#if DtHLA_1516
#if DtHLA_1516_EVOLVED
HLAfloat64Time reqTime;
#else
LogicalTimeImpl reqTime;
#endif
reqTime = theFedTime.getTime() + theFedTimeAdvance.getTime();
exConn.rtiAmb()->timeAdvanceRequest( reqTime );
#else
exConn.rtiAmb()->timeAdvanceRequest( theFedTime +
theFedTimeAdvance );
#endif
DtInfo << "requesting time: "
<< ( theFedTime.getTime() + theFedTimeAdvance.getTime() )
<< std::endl;
// Find the first entity in the reflected entity list.
DtReflectedEntity *first = rel.first();
if ( first )
{
// Grab its state repository, where we can inspect its data.
DtEntityStateRepository *esr = first->entityStateRep();
// Create a topographic view on the state repository, so we
// can look at position information in topographic coordinates.
double refLatitude = DtDeg2Rad( 35.699760 );
double refLongitude = DtDeg2Rad( -121.326577 );
DtTopoView topoView( esr, refLatitude, refLongitude );
DtInfo << "time: "
<< theFedTime.getTime()
<< " Position: " << topoView.location().string() << std::endl;
}
}
// wait till next iteration.
exConn.drainInput();
DtSleep( 0.5 );
}
return 0;
}
void timeAdvanceRequestCb(
#if DtHLA_1516
const RTI::LogicalTime &aTime,
#else
const RTI::FedTime &aTime,
#endif
void *userData )
{
theFedTime = aTime;
theTimeMoved = true;
DtInfo << "Time Advance Grant to: "
<< theFedTime.getTime() << std::endl;
}
void timeConstrainedEnabledCb(
#if DtHLA_1516
const RTI::LogicalTime &aTime,
#else
const RTI::FedTime &aTime,
#endif
void *userData )
{
theFedTime = aTime;
theTimeConstraintOn = true;
theTimeMoved = true;
DtInfo << "Time Constrained Enabled at time: "
<< theFedTime.getTime() << std::endl;
}
void fireCb( DtFireInteraction* fire, void* /*usr*/ )
{
DtInfo << "------------------------------------\n "
<< "Fire Interaction from" << fire->attackerId().string() << '\n';
fire->print();
DtInfo << "------------------------------------\n" << std::endl;
}
#else // !DtHLA
#include <stdio.h>
int main()
{
DtInfo << "Time Management is only available in HLA" << std::endl;
return 0;
}
#endif // !DtHLA

Document ID: Generated on Thu Sep 19 02:12:35 EDT 2024 from SVN revision 269601
Copyright © 2005-2024 MAK Technologies. All Rights Reserved (www.mak.com)