VR-Link API Documentation for HLA 1.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
HLA Constrained Listen Example

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


/****************************************************************************
* 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
int keybrdTick( void );
#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 GlobalFedTime;
const HLAfloat64Time FedTimeAdvance( 0.25 );
#else
LogicalTimeImpl GlobalFedTime;
const LogicalTimeImpl FedTimeAdvance( 0.25 );
#endif
#else
const RTIfedTime FedTimeAdvance( 0.25 );
RTIfedTime GlobalFedTime;
#endif
bool GlobalTimeConstraintOn = false;
bool GlobalTimeMoved = 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-RPR-2.0" );
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 ( !GlobalTimeConstraintOn )
{
// 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 ( keybrdTick() == -1 )
break;
// Only preform work if time has advanced, it is possible we
// might be waiting for some time.
if ( GlobalTimeMoved )
{
// 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( GlobalFedTime.getTime() );
GlobalTimeMoved = false;
#if DtHLA_1516
#if DtHLA_1516_EVOLVED
HLAfloat64Time reqTime;
#else
LogicalTimeImpl reqTime;
#endif
reqTime = GlobalFedTime.getTime() + FedTimeAdvance.getTime();
exConn.rtiAmb()->timeAdvanceRequest( reqTime );
#else
exConn.rtiAmb()->timeAdvanceRequest( GlobalFedTime +
FedTimeAdvance );
#endif
DtInfo << "requesting time: "
<< ( GlobalFedTime.getTime() + FedTimeAdvance.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: "
<< GlobalFedTime.getTime()
<< " Position: " << topoView.location().string() << std::endl;
}
}
// wait till next iteration.
exConn.drainInput();
DtSleep( 0.5 );
}
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 )
{
GlobalFedTime = aTime;
GlobalTimeMoved = true;
DtInfo << "Time Advance Grant to: "
<< GlobalFedTime.getTime() << std::endl;
}
void timeConstrainedEnabledCb(
#if DtHLA_1516
const RTI::LogicalTime &aTime,
#else
const RTI::FedTime &aTime,
#endif
void *userData )
{
GlobalFedTime = aTime;
GlobalTimeConstraintOn = true;
GlobalTimeMoved = true;
DtInfo << "Time Constrained Enabled at time: "
<< GlobalFedTime.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 Mon Apr 25 03:39:01 EDT 2022 from SVN revision 242502
Copyright © 2005-2021 MAK Technologies. All Rights Reserved (www.mak.com)