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

Listen is a simple listen-only VR-Link application which has been extended to take advantage of HLA Evolved Specific functionality.

With each iteration of the loop, the program prints an entity's updated, dead-reckoned position in topographic coordinates. If a fire PDU or interaction is detected on the network, the program prints a message showing the entity ID of the attacker.

To exit, press the 'q' key. This example works with the Talk example.

Connecting to An Exercise

The program creates an exercise connection (DtExerciseConn.) This connection serves as the program's interface to an exercise. After it's regular connection features, it then loads an HLA Evolved FOM Module that defines the update rate reduction parameters of the aircraft.

Update Rate Reduction

HLA Evolved allows us to subscribe to an object but only receive a limited subset of updates based on time. In order to do this, one must pass the name of the string defineding update rate reduction in the FOM (in this case "everyFiveSeconds") to the DtReflectedEntityList. VR-Link takes care of the rest.

Tracking Federates

In addition to tracking updates and interactions, HLA Evolved provides a way to access the name of the producing federate. One can access this federate by calling the producingFederate() function available in all objects and interactions in an HLA Evolved exercise. You must enable the conveyProducingFederate FOM switch for this to work.


/****************************************************************************
* Copyright (c) 2016 VT MAK
* All rights reserved.
****************************************************************************/
#include <vl/topoView.h>
#include <iostream>
int keybrdTick(void);
void reflectCb( const DtStateMsg& msg, DtHlaObject* obj, void* usr );
void removeObjectCb( DtHlaObject* obj, void* usr );
void discoverObjectCb( DtHlaObject* obj, void* usr );
unsigned int numUpdates = 0;
DtTime initialTime;
bool hasDiscovered = false;
DtString lastProducingFederate;
double updatesPerSecond = 0.0;
// Define a callback to process fire interactions.
void fireCb(DtFireInteraction* fire, void* /*usr*/)
{
std::cout << "Fire Interaction from "
<< fire->attackerId().string() ;
// HLA Evolved provides a way of returning the name of the federate
// that created the object or interaction. Here we print this
// producing federate if it has been provided.
// You must enable the conveyProducingFederate switch for this to work.
DtString producingFederate = fire->producingFederateName();
if ( producingFederate.size() )
{
std::cout << " Federate Name " << producingFederate;
}
std::cout << std::endl;
}
int main(int argc, char** argv)
{
try
{
// Create an exercise conn initializer. This will parse the command
// line, as well as parse an mtl file with the same name as this application.
DtVrlApplicationInitializer appInit(argc, argv, "VR-Link Listen");
// HLA Evolved has both a federate name, which must be unique, and a
// federate type, which does not have to be.
appInit.setFederateType( "Listen Evolved Example" );
// Set the default FED File, executable, and version
appInit.setFedFileName( DtDefaultRpr2Fom );
appInit.setExecName( "MAK-RPR-2.0" );
appInit.setRprFomVersion( 2.0 );
appInit.setRprFomRevision( 1 );
// Process the command line. This will actually set values in the
// DtVrlApplicationInitializer class and should be called before
// creating the DtExerciseConn instance.
appInit.parseCmdLine();
appInit.addFomModule("updateRate.xml");
// The DtExerciseConn instance is perhaps the most important class
// in any VR-Link exercise. Think of it as the hub which holds
// everything else together. Technically this instance is what's
// responsible for connecting this federate to another federate via
// a network, or an RTI. After exConn is created, and if no error
// has occurred this simulator will be a live federate.
DtExerciseConn exConn(appInit);
// Register a callback to handle fire interactions.
DtFireInteraction::addCallback(&exConn, fireCb, NULL);
// Create an object to manage entities that we hear about
// on the network. This object will use the HLA Evolved feature
// of update rate reduction to only update every five seconds.
try
{
rel = new DtReflectedEntityList(&exConn, DtString("everyFiveSeconds"));
}
catch(...)
{
DtFatal << "Update Rate Reduction failed.\n"
"This may be due to using a lightweight connection,\nor a non-standard compliant RTI.\n";
return -1;
}
// Initialize VR-Link time.
DtClock* clock = exConn.clock();
exConn.addDiscoverObjectCallback( RTI::ObjectClassHandle(), discoverObjectCb, 0 );
int forever = 1;
while (forever)
{
// Check if user hit 'q' to quit.
if (keybrdTick() == -1)
break;
// Tell VR-Link the current value of simulation time.
clock->setSimTime(clock->elapsedRealTime());
// Process any incoming messages.
exConn.drainInput();
// 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.
// 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);
DtTime effectiveCurrTime = clock->elapsedRealTime() - initialTime;
updatesPerSecond = ((double)(numUpdates)) / ((double)(effectiveCurrTime));
std::cout << " num updates / second = " << updatesPerSecond ;
// HLA Evolved provides a way of returning the name of the federate
// that created the object or interaction. Here we print this
// producing federate if it has been provided.
// You must enable the conveyProducingFederate switch for this to work.
lastProducingFederate = first->lastProducingFederate();
if ( lastProducingFederate.size() )
{
std::cout << ". Last Update from " << lastProducingFederate ;
}
std::cout << std::endl;
}
// Sleep till next iteration.
DtSleep(1);
}
}
DtCATCH_AND_WARN(std::cout);
return 0;
}
int keybrdTick()
{
char *keyPtr = DtPollBlockingInputLine();
if (keyPtr && (*keyPtr == 'q' || *keyPtr == 'Q'))
return -1;
else
return 0;
}
#if DtHLA
void reflectCb( const DtStateMsg& msg, DtHlaObject* obj, void* usr )
{
DtExerciseConn* exConn = obj->exerciseConn();
DtClock* clock = obj->exerciseConn()->clock();
DtTime curr = clock->elapsedRealTime();
++numUpdates;
if ( 0 == numUpdates )
{
initialTime = curr;
}
}
void removeObjectCb( DtHlaObject* obj, void* usr )
{
obj->removeRemoveObjectCb( removeObjectCb, 0 );
obj->removePostReflectCb( reflectCb, 0 );
hasDiscovered = false;
}
void discoverObjectCb( DtHlaObject* obj, void* usr )
{
if ( !hasDiscovered )
{
obj->addPostReflectCb( reflectCb, 0 );
obj->addRemoveObjectCb( removeObjectCb, 0 );
}
hasDiscovered = true;
}
#endif

Document ID: Generated on Mon Feb 6 18:36:34 EST 2017 from SVN revision 173107
Copyright © 2005-2016 VT MÄK. All Rights Reserved (www.mak.com)