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

Table of Contents

The f18 program simulates a simple HLA or DIS vehicle.

By default, that vehicle is an F/A-18 flying in a circle, just off the coast of California, USA, but you can control the entity type, location and route.

The f18 generates predictable HLA entity update messages (or DIS entity state PDUs), so it is a useful tool for debugging applications that receive and interpret these messages. It can also fire munitions, react to detonations, enable/disable IFF Systems, and send lethal interactions.

Major Components of the F18 Example

The F18 is composed of two major classes:

The Vehicle Sim Class

The class DtVehicleSim is responsible for simulating the Aircraft. This includes implementation of the emitter and IFF systems and the detonation and IFF interactions.

The F18 Initialization Class

The DtF18Initializer class is a subclass of VR-Link's DtVrlApplicationInitializer. This class processes the command line and reads the F18's mtl file.

VR-Link Advanced Configuration

The F18 Config Example Code config.cxx serves an an example of how to re-configure VR-Link to interpret FOM attributes and parameters differently. Specifically, after calling the configVrl function on a DtExerciseConn, a VR-Link-based application will assume that the "Position" atttribute of the "BaseEntity" object class (and its subclasses) should be encoded in outgoing messages and interpreted in incoming messages as three doubles in the order: Z, Y, X, rather than the standard X, Y, Z. The same will be true for the "FiringLocation" parameter of the "WeaponFire" interaction.

To demonstrate modifying the FOM to replace existing attributes or parameters, you can edit the .fed file to replace "Position" and "FiringLocation" with different attribute and parameter names, such as "ReversePosition" and "ReverseFiringLocation". If you do this, you will need to replace the names in this file as well (in the calls to addAttributeEncoder, addAttributeDecoder, addParameterEncoder and addParameterDecoder), so that the encoding and decoding functions will be associated with the correct parameter and attribute names.

This file is commented out and not part of the default f18. To add this functionality, compile with DtReverse defined.

How to Run the Example

  1. Launch 2 F18 examples from your VR-Link install's bin64 directory using the same protocol.
  2. To toggle enabling and disabling of Emitters, press the 'e' key in the F18 console application.
  3. To change emitter beam scan data for this aircraft, press the 'd' key.
  4. To toggle enabling and disabling of IFF, press the 'i' key.
  5. To toggle enabling and disabling of Lethal IFF Interrogation, press 'l' key.
  6. To send an interrogation of Mode 5, press the '5' key.
  7. To send a Lethal IFF Interaction, press the 's' key.
  8. To fire munitions at a nearby target, press the 'f' key.
  9. For usage information, press the 'h' key.
  10. To exit, press the 'q' key.
Note
To send any interrogation, the IFF System for the aircrafts must be enabled. Lethal Interrogation will only force a Mode 5 Reply, regardless of Mode 5 IsOn attribute status. Interrogations will only provide transponder information for Modes included in the interrogation whose isOn attribute is set to true.

Example Code

Main Application

/****************************************************************************
* Copyright (c) 2017 MAK Technologies, Inc
* All rights reserved.
****************************************************************************/
#include "multiF18Init.h"
#include <stdlib.h>
#include <iostream>
#ifndef _WIN32
#include <sys/socket.h>
#endif
// *****************************************************************
// *************************** GLOBALS *****************************
// *****************************************************************
DtTime timeOutInterval = 12.0; // seconds
DtTime timeThreshold = 5.0; // seconds
double translationThreshold = 1.0; // meters
double rotationThreshold = DtDeg2Rad( 3.0 ); // radians
// Static functions
static int keybrdTick( );
#if VXWORKS
#define main realMain
#endif
// *****************************************************************
// *************************** MAIN *******************************
// *****************************************************************
int main( int argc, char* argv[] )
{
// Used for error handling
DtINIT_MINIDUMPER( "Parallel-F18" );
try
{
// get the PID so we can run multiple F18's
int pid = DtGetPid();
DtString pidStr( pid );
// get the Application name
DtString appName = "VR-Link F18 " + pidStr;
DtF18Initializer initializer( argc, argv, appName );
#if DtDIS
// Set the default DIS version
initializer.setDisVersionToSend( 7 );
#else
// Set the default FED File, executable, and version
initializer.setFedFileName( DtDefaultRpr2Fom );
initializer.setExecName( "MAK-One-2024" );
initializer.setRprFomVersion( 2.0 );
initializer.setRprFomRevision( 1 );
#ifdef DtHLA_1516_EVOLVED
initializer.addFomModule("NETN-BASE.xml");
initializer.addFomModule("NETN-Physical.xml");
initializer.addFomModule("NETN-METOC.xml");
initializer.addFomModule("NETN-MRM.xml");
initializer.addFomModule("MAK-Physical-2_evolved.xml");
initializer.addFomModule("MAK-Aerodrome-1_evolved.xml");
initializer.addFomModule("MAK-METOC-1_evolved.xml");
initializer.addFomModule("MAK-VRFExt-9_evolved.xml");
initializer.addFomModule("MAK-DIGuy-7_evolved.xml");
initializer.addFomModule("MAK-LgrControl-2_evolved.xml");
initializer.addFomModule("MAK-VRFAggregate-6_evolved.xml");
initializer.addFomModule("MAK-DynamicTerrain-2_evolved.xml");
initializer.addFomModule("MAK-VRLExt-3_evolved.xml");
initializer.addFomModule("RPR-Enumerations_Experimental_IFF.xml");
initializer.addFomModule("RPR-MAK_Experimental_IFF-3.xml");
#endif
#endif
initializer.parseCmdLine();
initializer.setApplicationNumber( pid );
DtString defaultF18Name( initializer.f18Name() );
defaultF18Name += " " + pidStr;
initializer.setF18Name( defaultF18Name );
#ifdef DtHLA
initializer.setFederateType( "Parallel F18" );
initializer.setFederateName(defaultF18Name);
#endif
// Create an instance of our simulator
DtMultiVehicleFed simulator;
// Set up default static values
// This is the only DIS specific code in this file.
#if DtDIS
DtEntityPublisher::setDfltTimeThreshold( timeThreshold );
// MUST use async I/O in parallel mode for thread saftey
// Sync I/O in DIS not yet thread safe
initializer.setUseAsynchIO(true);
#endif
// Connect to the exercise or RTI
simulator.initializeExConn(DtTime(timeThreshold), &initializer);
DtExerciseConn* exConn = simulator.exerciseConn();
DtClock* clock = exConn->clock();
#ifdef DtHLA
// Let other VR-Link federates know that we are initializing
// Helps control request update calls when creating many entities
// Requests are delayed until all federates are initialized or executing
std::cout << "[" << clock->elapsedRealTime() << ", 0] Initializing" << std::endl;
simulator.drainInput(0.1);
#endif
DtTime frameTime = initializer.deltaTime();
// initialize the fleet
simulator.initializeFleet(0, initializer.count(), &initializer);
simulator.drainInput(frameTime);
simulator.publish();
#ifdef DtHLA
// Let other VR-Link federates know that we are initialized
simulator.drainInput(0.1);
std::cout << "[" << clock->elapsedRealTime() << ", 0] Initialized" << std::endl;
#endif
// Simulation loop
int forever = 1;
DtTime dt = frameTime;
DtTime outputTime = 0.0;
double outputInterval = initializer.outputInterval();
#ifdef DtHLA
// Let other VR-Link federates know that we are executing
std::cout << "[" << clock->elapsedRealTime() << ", 0] Executing" << std::endl;
simulator.drainInput(0.1);
#endif
// Reset elapsed time to 0 to match initial simulation time
clock->init();
unsigned long frameCount = 1;
double totalDrainDuration = 0.0;
double totalSimDuration = 0.0;
double totalPubDuration = 0.0;
double totalIdle = 0.0;
double totalFrameDuration = 0.0;
int numberFrameOverflows = 0;
double totalOverflow = 0.0;
DtTime lastTime = clock->absRealTime();
std::cout << std::fixed;
while( forever ) // to keep cfront quiet
{
DtTime idle = 0.0;
DtTime startTime = clock->absRealTime();
dt = startTime - lastTime;
simulator.setSimTime(clock->elapsedRealTime());
// process incoming data
DtTime before = clock->absRealTime();
simulator.drainInput(frameTime);
DtTime drainDuration = clock->absRealTime() - before;
totalDrainDuration += drainDuration;
if ( input.keybrdTick( ) == -1 ) break;
// Perform simulation for the current time frame
before = clock->absRealTime();
simulator.simulate();
DtTime simDuration = clock->absRealTime() - before;
totalSimDuration += simDuration;
// Publish simulation changes
before = clock->absRealTime();
simulator.publish();
DtTime pubDuration = clock->absRealTime() - before;
totalPubDuration += pubDuration;
//frameDuration = drainDuration + simDuration + pubDuration;
DtTime frameDuration = clock->absRealTime() - startTime;
totalFrameDuration += frameDuration;
if (frameDuration < frameTime)
{
idle = frameTime - frameDuration;
totalIdle += idle;
dt = frameTime;
}
else
{
dt = frameDuration;
idle = -1.0;
numberFrameOverflows++;
totalOverflow += frameDuration - frameTime;
}
if (outputInterval <= 0.0 || outputTime < startTime)
{
outputTime = clock->absRealTime() + outputInterval;
std::cout << "[" << std::setprecision(2) << simulator.simTime() << ", " << frameCount << "] #entities: " << simulator.numberRemoteEntities()
<< " total=" << std::setprecision(6) << frameDuration << "(" << totalFrameDuration / frameCount << ")"
<< " idle=" << idle << "(" << totalIdle/frameCount << ")"
<< " drain=" << drainDuration << "(" << totalDrainDuration / frameCount << ")"
<< " sim=" << simDuration << "(" << totalSimDuration / frameCount << ")"
<< " pub=" << pubDuration << "(" << totalPubDuration / frameCount << ")"
<< " #FO=" << numberFrameOverflows << "(" << (numberFrameOverflows > 0 ? totalOverflow/numberFrameOverflows : 0) << ")"
<< std::endl;
numberFrameOverflows = 0;
totalOverflow = 0.0;
}
if (idle > 0.0)
{
// wait for real time to catch up to simulated time
DtTime sleepTime = simulator.sleep(idle);
}
lastTime = startTime;
frameCount++;
}
simulator.dismantleFleet(); // Dismantle the fleet of vehicles
simulator.dismantleExConn(); // Dismantle exercise connection
}
DtCATCH_AND_WARN(std::cout);
return 0;
}

Vehicle Sim Class

Vehicle Sim Header

/*******************************************************************************
** Copyright (c) 1992-2012 MAK Technologies, Inc
** All rights reserved.
*******************************************************************************/
#pragma once
#include <vl/topoView.h>
{
public:
DtVehicleSim( double refLat, double refLon,
const DtEntityIdentifier& id, const DtEntityType& type,
const char* name, const char* markings,
const DtDeadReckonTypes alg, bool haveArtParts,
DtTime timeSpacing);
virtual ~DtVehicleSim();
virtual void init( DtConstVector initPos, double initSpeed,
double initHeading, double initTRadius,
double initPitch, bool autoRoll, double initRoll, int num );
virtual void simulate();
virtual void fireMunition( const DtGlobalObjectDesignator& tg );
virtual void fireMunition();
virtual void detonateMunition();
virtual void munitionUpdate();
virtual void reactToDetonation();
virtual int checkDetonation();
virtual void reactToDamage();
virtual bool isDestroyed();
virtual DtTime timeDestroyed();
virtual void toggleEmissions();
virtual void enableEmissions();
virtual void disableEmissions();
virtual void emissionsUpdate();
public:
// Set the current detonation for reaction.
static void setLethalDetonationRange( double range );
static void setMunitionFlightTime( DtTime time );
// set the delta time for next simTick update
static void setSimDeltaTime(DtTime theDt) { myDt = theDt; }
protected:
// delta time for next simTick update
static DtTime myDt;
// Current detonation, if any.
protected:
virtual void moveArtParts();
protected:
float mySpeed;
float myTurnRadius;
float myTurnRate;
double myBeamTime;
float myTurretAz;
float myGunElev;
protected:
static double theLethalDetonationRange;
};

Vehicle Sim Source

/*******************************************************************************
** Copyright (c) 1992-2012 MAK Technologies, Inc
** All rights reserved.
*******************************************************************************/
#include "vehicleSim.h"
#include <vlutil/vlUtil.h>
#include <vlutil/vlPrint.h>
#ifndef effZero
#define effZero 1.0E-30
#endif
// delta time for next simTick update
DtVehicleSim::DtVehicleSim( double refLat, double refLon,
const DtEntityIdentifier& id, const DtEntityType& type,
const char* name, const char* markings,
const DtDeadReckonTypes alg, bool haveArtParts,
DtObjectPublisherContainer &pubContainer, DtTime timeSpacing) :
myTimeSpacing(timeSpacing),
myPublishedObjects(pubContainer),
mySysPub( 0 )
{
myExConn = conn;
#if DtHLA
myEntityPub = new DtEntityPublisher( type, conn, name );
#elif DtDIS
myEntityPub = new DtEntityPublisher( type, conn, id );
#else
#error "Please Choose Protocol!"
#endif
// Add object to collection for later publication (in parallel)
myPublishedObjects.add(myEntityPub);
myESR = myEntityPub->entityStateRep();
myESR->setEntityType( type );
myESR->setGuise( type );
myESR->setMarkingText( markings );
myESR->setForceId( DtForceFriendly );
myESR->setAlgorithm( alg );
myESR->setEntityId( id );
myTopoView = new DtTopoView( myESR, refLat, refLon );
myRel = rel;
myFire = 0;
myDetonateTime = 0.0;
myTimeDestroyed = -1.0;
myIsDestroyed = false;
myEmissionsEnabled = false;
myHaveArtParts = haveArtParts;
}
{
}
void DtVehicleSim::init( DtConstVector initPos, double initSpeed,
double initHeading, double initTRad,
double initPitch, bool autoRoll, double initRoll, int num)
{
myPos = initPos;
mySpeed = initSpeed;
myTurnRadius = initTRad;
myTurnRate = ( ( initTRad != 0.0 ) ? ( initSpeed / initTRad ) : 0.0 );
// hack to make roll roughly proportional to turnRate for rates
// about 1/5 rad/sec
double roll = ( autoRoll ) ?
atan( 5.0 * myTurnRate ) : DtDeg2Rad( initRoll );
myEuler = DtTaitBryan( DtDeg2Rad( initHeading ),
DtDeg2Rad( initPitch ), roll );
float psi = myEuler.psi();
float cosPsi = cos( psi );
float sinPsi = sin( psi );
float phi = myEuler.phi();
float cosPhi = cos( phi );
float sinPhi = sin( phi );
myVel = DtVector32( cosPsi * mySpeed, sinPsi * mySpeed, 0.0 );
float timeOffset = (float)myTimeSpacing * (float)num;
for (int i = 0; i < 3; i++)
{
myPos[i] += myVel[i] * timeOffset;
}
// force a constant rate turn
myAccel = DtVector32( -myScalarAccel * sinPsi, myScalarAccel * cosPsi, 0.0 );
myRotRate = DtVector32( 0.0, sinPhi * myTurnRate, cosPhi * myTurnRate );
myTurretAz = 0.0;
myGunElev = 0.0;
{
DtArticulatedPart& turret = artPartList->getPart(DtPrimaryTurret1);
DtArticulatedPart& gun = artPartList->getPart(DtPrimaryGun1);
artPartList->attachPart(&gun, &turret);
}
}
{
// Update kinematic position, velocity, acceleration and orientation
double psi = DtModPerZero( ( myEuler.psi() + ( myTurnRate * myDt ) ), M_2PI );
myEuler.setPsi( psi );
for( int i=0; i<3; ++i )
{
myPos[i] += ( myVel[i] + 0.5 * myAccel[i] * myDt ) * myDt;
myVel[i] += myAccel[i] * myDt;
}
myAccel[0] = -myScalarAccel * sin( psi );
myAccel[1] = myScalarAccel * cos( psi );
myAccel[2] = 0.0;
// Simulate articulated parts, if any.
{
}
// Now that we're done simulating, tell the entity publisher
// about our current state:
// Simulate subsystems
munitionUpdate(); // Simulate munitions created by this vehicle, if any.
emissionsUpdate(); // Simulate emissions from this vehicle, if any.
}
{
DtClock* clock = myExConn->clock();
if ( clock->simTime() >= 2.0)// && clock->simTime() <= 10.0 )
{
}
else
{
}
if ( clock->simTime() >= 2.0)// && clock->simTime() <= 20.0 )
{
}
else
{
}
myGunElev = myGunElev + myGunElevRate * (float) myDt;
}
{
theDetonation = detonation;
}
{
if ( checkDetonation() )
{
}
}
{
double distance;
switch( theDetonation->result() )
{
{
{
DtInfo << "Direct hit! Going down!" << std::endl;
return 1;
}
}
// fall through
{
if ( distance < theLethalDetonationRange )
{
DtInfo << "Indirect hit only " << distance << " m away! Going down!"
<< std::endl;
return 1;
}
else
{
return 0;
}
}
default:
{ // ignore it
return 0;
}
}
}
{
myVel = DtVector32( 0.0, 0.0, 0.0 );
myAccel = DtVector32( 0.0, 0.0, 0.0 );
myRotRate = DtVector32( 0.0, 0.0, 0.0 );
myTurnRate= 0.0;
mySpeed = 0.0;
myIsDestroyed = true;
}
{
{
DtInfo << "Emissions enabled." << std::endl;
// Create emitter system
// Add it to publications
// Attach emitter system to entity
DtVector32 vec( 6.4f, 0.0, 0.0 );
// Create beam
myBeam = mySysPub->esr()->addBeam( 1 );
#if DtHLA
// HLA Only - In DIS a beam is not a separate object and
// also an emittingSystemID would be just an integer...
#endif
myBeam->setFrequency( 8999999488.000000 );
myBeam->setERP( 70 );
myBeam->setAzimuthSweep( 0.0523599f );
myBeam->setElevationCenter( 0.349066f );
myBeam->setElevationSweep( 0.523599f );
myBeamTime = 0.0;
}
}
{
{
DtInfo << "Emissions disabled." << std::endl;
// Remove it from publications
}
}
{
{
}
else
{
}
}
{
{
// Update beam
float beamAngle = (float)cos( myBeamTime );
myBeam->setAzimuthCenter( beamAngle );
}
}
// return the vehicle that is nearest to ours
static DtReflectedEntity* nearestEntity( const DtObjectId& me,
{
DtReflectedEntity* nearest = 0;
double minDistSqr = 0.0;
// Loop through the entities in the rel
for( DtReflectedEntity* entity = rel->first();
entity;
entity = entity->next() )
{
if ( entity->id() == me ) continue;
double distSqr = DtDistSqr(
entity->entityStateRep()->location(), geocPos );
if ( distSqr < minDistSqr || !nearest )
{
nearest = entity;
minDistSqr = distSqr;
}
}
return nearest;
}
{
DtReflectedEntity* nearest = nearestEntity(
if ( nearest )
{
fireMunition( nearest->globalId() );
}
}
{
if ( myFire )
{
return;
}
myFire->setRange( 1000.0 );
myFire->setRate( 0 );
#if DtHLA
#endif
DtSidewinder, 0, 0 ) );
DtInfo << "Sending fire interaction" << std::endl;
}
{
if ( !myFire )
{
return;
}
// Sidewinder Missile
DtEntityType sidewinder(2,1,255,1,1,3,0);
det.setMunitionType(sidewinder);
det.setTargetId(myFire->targetId());
det.setVelocity( DtVector32( 0.0, 0, 0 ) );
det.setEntityLocation( DtVector32( 0.0, 0.0, 0.0 ) );
if ( ent )
{
// Get vector from fire location to detonation location
DtVector difference = myFire->location() - ent->esr()->location();
// Velocity = Distance / Time
DtVector32 velocity;
velocity.setX(difference.x() / theMunitionFlightTime);
velocity.setY(difference.y() / theMunitionFlightTime);
velocity.setZ(difference.z() / theMunitionFlightTime);
det.setVelocity(velocity);
det.setWorldLocation( ent->entityStateRep()->location() );
det.setResult( DtDetResEntityImpact );
}
else
{
// just detonate 1000 meters under us.
det.setVelocity(DtVector32(0.0, 0.0, 1000.0f / theMunitionFlightTime));
det.setWorldLocation( DtVector( myPos[0], myPos[1], myPos[2] + 1000.0 ) );
det.setResult( DtDetResDetonation );
}
DtInfo << "Sending detonation interaction" << std::endl;
}
{
{
}
}
{
return myIsDestroyed;
}
{
}
{
}
{
}

F18 Initializer Class

F18 Initializer Header

/*******************************************************************************
** Copyright (c) 1992-2010 MAK Technologies, Inc
** All rights reserved.
*******************************************************************************/
#pragma once
{
public:
DtF18Initializer(int argc, char* argv[], DtString AppName);
virtual ~DtF18Initializer();
private:
public:
virtual void parseCmdLine();
virtual void initializeMtlParams();
virtual void setInitialPosition(const DtVector& loc);
virtual DtVector initialPosition() const;
virtual void setLispFileName(const DtString& name);
virtual DtString lispFileName() const;
virtual void setDeadReckonAlgorithm(unsigned long alg);
virtual unsigned long deadReckonAlgorithm() const;
virtual void setInitialTurnRadius(double radius);
virtual double initialTurnRadius() const;
virtual void setInitialSpeed(double speed);
virtual double initialSpeed() const;
virtual void setEntityTypeStr(const DtString& type);
virtual DtString entityTypeStr() const;
virtual void setF18Markings(const DtString& markings);
virtual DtString f18Markings() const;
virtual void setF18Name(const DtString& name);
virtual DtString f18Name() const;
virtual void setDestroyedToFinalDelay(double delay);
virtual double destroyedToFinalDelay() const;
virtual void setInitialHeading(double heading);
virtual double initialHeading() const;
virtual void setLethalDetonationRange(double range);
virtual double lethalDetonationRange() const;
virtual void setMunitionFlightTime(double time);
virtual double munitionFlightTime() const;
virtual void setInitialPitch(double pitch);
virtual double initialPitch() const;
virtual void setInitialRoll(double roll);
virtual double initialRoll() const;
virtual void setAutoRoll(bool onOff);
virtual bool autoRoll() const;
virtual void setEntityNumber(int number);
virtual int entityNumber() const;
virtual void setHaveArtParts(bool onOff);
virtual bool haveArtParts() const;
virtual void setDeltaTime(DtTime time);
virtual DtTime deltaTime() const;
#ifdef DtHLA_1516_EVOLVED
virtual void setSuppressDefaultModules(bool onOff);
virtual bool suppressDefaultModules();
#endif
virtual void setRefLatitude(double lat);
virtual double refLatitude() const;
virtual void setRefLongitude(double lon);
virtual double refLongitude() const;
#if DtHLA
virtual void setApplicationNumber(int num);
virtual int applicationNumber() const;
virtual void setSiteId(int id);
virtual int siteId() const;
#endif
protected:
virtual void loadMtlFile(const DtString& fileName);
protected:
#ifdef DtHLA_1516_EVOLVED
#endif
#if DtHLA
#endif
};

F18 Initializer Source

/****************************************************************************
* Copyright (c) 2015 MAK Technologies, Inc
* All rights reserved.
****************************************************************************/
#include "f18Init.h"
#include <vlpi/disEnums.h>
#include <stdio.h>
// Constructor -- Initialize the base class (will initialize protocol-specific
// parameters), command line arguments and mtl parameters
DtF18Initializer::DtF18Initializer( int argc, char* argv[], DtString appName )
: DtVrlApplicationInitializer( argc, argv, appName )
, myInitialPosition( mySettings, "initialPosition", DtVector(0.0,0.0,-1230.0),
"Initial Location", DtBaseConfigVariable::DtScopeBoth, false, "L" )
, myLispFileName( mySettings, "&lispFile", "f18.xml", "LISP File Name" )
, myDeadReckonAlgorithm( mySettings, "deadReckonAlgorithm", DtDrDrmRvw, "Dead Reckon Algorithm",
DtBaseConfigVariable::DtScopeBoth, false, "D" )
, myInitialTurnRadius( mySettings, "initialTRadius", -250.0, "Initial Turn Radius",
DtBaseConfigVariable::DtScopeBoth, false, "r" )
, myInitialSpeed( mySettings, "initialSpeed", 40.0, "Initial Speed" )
, myEntityTypeString( mySettings, "entity&TypeStr", "1:2:225:1:9:0:0", "Entity Type String" )
, myMarkings( mySettings, "f18&Markings", "MAK-VRLink-F18", "F18 Markings" )
, myName( mySettings, "f18Name", "MAK-F18", "F18 Object Name" )
, myDestroyedToFinalDelay( mySettings, "&destroyedToFinalDelay", 20.0,
"Destroyed To Final Delay" )
, myInitialHeading( mySettings, "initial&Heading", 180.0, "Initial Heading" )
, myTopoOrigin( mySettings, "topo&Origin", "35.699760,-121.326577",
"Topographic Coordinate System Origin" )
, myWorldPosition( mySettings, "worldPos", DtVector(0.0,0.0,0.0),
"Initial Position in Geocentric Coordinates", DtBaseConfigVariable::DtScopeBoth, false, "W" )
, myLethalDetonationRange( mySettings, "lethalDetonationRange", 20.0, "Lethal Detonation Range",
DtBaseConfigVariable::DtScopeConfigFile )
, myMunitionFlightTime( mySettings, "munitionFlightTime", 3.0, "Munition Flight Time",
DtBaseConfigVariable::DtScopeConfigFile )
, myInitialPitch( mySettings, "initialPitch", 0.0, "Initial Pitch",
DtBaseConfigVariable::DtScopeConfigFile )
, myInitialRoll( mySettings, "initialRoll", 0.0, "Initial Roll",
DtBaseConfigVariable::DtScopeConfigFile )
, myAutoRoll( mySettings, "autoRoll", true, "Auto Roll",
DtBaseConfigVariable::DtScopeConfigFile )
, myEntityNumber( mySettings, "entNum", 1, "Entity Number",
DtBaseConfigVariable::DtScopeConfigFile )
, myHaveArtParts( mySettings, "haveArtParts", false, "Have Articulated Parts",
DtBaseConfigVariable::DtScopeConfigFile )
, myRefLatitude( mySettings, "refLatitude", 35.699760, "Reference Latitude",
DtBaseConfigVariable::DtScopeConfigFile )
, myRefLongitude( mySettings, "refLongitude", -121.326577, "Reference Longitude",
DtBaseConfigVariable::DtScopeConfigFile )
, myDeltaTime( mySettings, "deltaTime", 0.05, "Delta Time",
DtBaseConfigVariable::DtScopeConfigFile )
#ifdef DtHLA_1516_EVOLVED
, mySuppressDefaultModules( mySettings, "suppressDefaultModules", false, "Suppress Default Modules (HLA1516-2010 only)",
DtBaseConfigVariable::DtScopeBoth )
#endif
, myMtlAutoRoll( 1 )
#if DtHLA
, myConfigVarApplicationNumber(mySettings, "&appNumber", 2, "Application Number")
, mySiteId(mySettings, "&siteId", 1, "Site ID")
#endif
, myMtlHaveArtParts( 0 )
, myMtlInitialPosition( 0.0, 0.0, -1230.0 )
{
mySettings.setChangeOnce(true);
}
{
}
{
//myMtlEnv->registerConfigVar( mySuppressDefaultModules );
myMtlEnv->registerVar( "haveArtParts", &myMtlHaveArtParts );
myMtlEnv->registerVar( "initialPos[0]", &myMtlInitialPosition[0] );
myMtlEnv->registerVar( "initialPos[1]", &myMtlInitialPosition[1] );
myMtlEnv->registerVar( "initialPos[2]", &myMtlInitialPosition[2] );
#if DtHLA
#endif
}
// Parses the command line
{
// Note that we're manually parsing the command line here in order to
// see whether a file has been specified. This is due to the support of
// MTL files. If the command line is parsed, and then an MTL file is loaded,
// the command line values will be overridden. This is not the case with XML.
// As long as "changeOnce" is set to true on the application settings object,
// values can only be changed once. In other words, if the command line is parsed,
// and values are set, and a file is then loaded, the values set by the command
// line will not be overridden. This is not the case with MTL yet.
for ( int index = 1; index < myArgc; ++index )
{
if ( ! strcmp(myArgv[index],"-l") || ! strcmp(myArgv[index],"--lispFile") )
{
if ( index + 1 < myArgc )
{
break;
}
}
}
if ( myInitialPosition.isSet() )
{
// NOTE: only -L specifies X, Y, and -Z (north, east, and up)
// All local positions are north, east, down [not up]
DtVector posVec = myInitialPosition.value();
posVec[2] = -posVec[2];
myInitialPosition.setValue( posVec );
}
{
double refLat = myRefLatitude.defaultValue();
double refLon = myRefLongitude.defaultValue();
int numReads = sscanf( myTopoOrigin.value().c_str(), "%lf,%lf", &refLat, &refLon );
if ( numReads > 0 )
{
if ( numReads > 1 )
{
}
}
}
if ( myWorldPosition.isSet() )
{
DtGeodeticCoord initPos;
initPos.setGeocentric( myWorldPosition.value() );
}
}
//--------------------------------------------------------------
// ACCESSORS/MODIFIERS
// Provide a way to inspect/modify the data
//--------------------------------------------------------------
{
myInitialPosition.setValue( loc );
}
{
return myInitialPosition.value();
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
myMarkings.setValue( markings );
}
{
return myMarkings.value();
}
{
myName.setValue( name );
}
{
return myName.value();
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
return myInitialRoll.value();
}
{
myAutoRoll.setValue( onOff );
}
{
return myAutoRoll.value();
}
{
}
{
}
{
}
{
return myRefLatitude.value();
}
{
}
{
}
{
}
{
}
{
}
{
return myDeltaTime.value();
}
#ifdef DtHLA_1516_EVOLVED
{
}
{
}
#endif
void DtF18Initializer::loadMtlFile( const DtString& fileName )
{
}
#if DtHLA
{
}
{
}
{
}
{
return mySiteId.value();
}
#endif

F18 Config Example Code

/*******************************************************************************
** Copyright (c) 1992-2010 MAK Technologies, Inc
** All rights reserved.
*******************************************************************************/
#if DtHLA
#if DtReverse
#include <vl/fomMapper.h>
// Encoder function to be used for the "Position" attribute.
void DtPosEncoder( const DtEntityStateRepository& stateRep,
RTI::AttributeHandleValuePairSet* avList,
RTI::AttributeHandle handle )
{
DtVector loc = stateRep.location();
DtNet64Vector netVal( loc[2], loc[1], loc[0] );
avList->add( handle, (char*)&netVal, sizeof( DtNet64Vector ) );
}
// Decoder function to be used for the "Position" attribute.
void DtPosDecoder( DtEntityStateRepository* stateRep,
const RTI::AttributeHandleValuePairSet& avlist,
int pairSetIndex )
{
DtNet64Vector netVal;
RTI::ULong length = 0;
avlist.getValue( pairSetIndex, (char*)&netVal, length );
stateRep->setLocation( DtVector( netVal[2], netVal[1], netVal[0] ) );
}
// Encoder function to be used for the "FiringLocation" parameter.
void DtFirePosEncoder( const DtFireInteraction& fire,
RTI::ParameterHandleValuePairSet* pvList,
RTI::ParameterHandle handle )
{
DtVector loc = fire.location();
DtNet64Vector netVal( loc[2], loc[1], loc[0]);
pvList->add( handle, (char*)&netVal, sizeof( DtNet64Vector ) );
}
// Decoder function to be used for the "FiringLocation" parameter.
void DtFirePosDecoder( DtFireInteraction* fire,
const RTI::ParameterHandleValuePairSet& pvlist,
int pairSetIndex )
{
DtNet64Vector netVal;
RTI::ULong length = 0;
pvlist.getValue( pairSetIndex, (char*)&netVal, length );
fire->setLocation( DtVector( netVal[2], netVal[1], netVal[0] ) );
}
// configVrl tells the DtExerciseConn's DtFomMapper that the functions
// defined above should be used in place of the default encoding
// and decoding functions for the specified attributes and parameters.
void configVrl( DtExerciseConn* exConn )
{
addAttributeEncoder( "BaseEntity", "Position",
addAttributeDecoder( "BaseEntity", "Position",
addParameterEncoder( "WeaponFire", "FiringLocation",
addParameterDecoder( "WeaponFire", "FiringLocation",
}
#endif // DtReverse
#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)