VR-Link API Documentation for DIS
F18 Example

The f18 program simulates a simple HLA or DIS vehicle.

By default, that vehicle is n F/A18 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 and react to detonations.


The F18 is composed of two major classes:

The F18 example is contained in several major files:

The main application:

/*******************************************************************************
 ** Copyright (c) 1992-2010 VT MAK
 ** All rights reserved.
 *******************************************************************************/

#include <vl/exerciseConn.h>
#include <vl/reflEntList.h>
#include "vehicleSim.h"
#include "f18Init.h"
#include <vlutil/vlProcessControl.h>
#include <matrix/geodCoord.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( DtVehicleSim* );

#if VXWORKS
#define main realMain
DT_VXWORKS_APP(f18)
#endif

// *****************************************************************
// ***************************  MAIN *******************************
// *****************************************************************
int main( int argc, char** argv )
{
   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 );

      initializer.setApplicationNumber( pid );
      DtString defaultF18Name( initializer.f18Name() );
      defaultF18Name += " " + pidStr;
      initializer.setF18Name( defaultF18Name );
#ifdef DtHLA
      initializer.setFederateType( defaultF18Name );
#endif

      initializer.parseCmdLine();

#ifndef DtTENA // non-TENA case

      DtExerciseConn::InitializationStatus status = DtExerciseConn::DtINIT_SUCCESS;

      DtExerciseConn* exConn = new DtExerciseConn(initializer, &status);
      if (status != 0)
      {
         std::cout << "Error creating exercise connection." << std::endl;
         return -1;
      }
#else
      DtExerciseConn* exConn = NULL;
      try
      {
         exConn = new DtExerciseConn(initializer);
      }
      catch (...)
      {
         std::cout << "Error creating exercise connection." << std::endl;
         return -1;
      }
#endif
      DtReflectedEntityList* rel = new DtReflectedEntityList( exConn );
      rel->setTimeoutInterval( timeOutInterval );

      DtEntityPublisher::setDfltRotationThreshold( rotationThreshold );
      DtEntityPublisher::setDfltTranslationThreshold( translationThreshold );

      // This is the only DIS specific code in this file. 
#if DtDIS
      DtEntityPublisher::setDfltTimeThreshold( timeThreshold );
#endif

      // DIS-style site-host-entity triple
      DtEntityIdentifier entityId = DtEntityIdentifier( initializer.siteId(), 
         initializer.applicationNumber(), initializer.entityNumber() );

      DtEntityType type( initializer.entityTypeStr() );

      // Create the vehicle class. 
      DtVehicleSim* myVehicle = new DtVehicleSim(
         DtDeg2Rad( initializer.refLatitude() ), DtDeg2Rad( initializer.refLongitude() ),
         exConn, rel, entityId, type, initializer.f18Name(), initializer.f18Markings(),
         DtDeadReckonTypes( initializer.deadReckonAlgorithm() ), initializer.haveArtParts() );

      myVehicle->init( initializer.initialPosition(), initializer.initialSpeed(),
                       initializer.initialHeading(), initializer.initialTurnRadius(),
                       initializer.initialPitch(), initializer.autoRoll(), initializer.initialRoll() );

      DtVehicleSim::setLethalDetonationRange( initializer.lethalDetonationRange() );
      DtVehicleSim::setMunitionFlightTime( initializer.munitionFlightTime() );

      // Start the simulation
      DtTime simTime = 0.0; 
      DtClock* clock = exConn->clock();

      int forever = 1;
      while( forever ) // to keep cfront quiet
      {
         clock->setSimTime( simTime );

         // a simple keyboard reader
         if ( keybrdTick( myVehicle ) == 0 )  break;

         // process incoming data
         exConn->drainInput();

         myVehicle->simTick( initializer.deltaTime() );

         if ( myVehicle->isDestroyed() && clock->simTime() >
              ( myVehicle->timeDestroyed() + initializer.destroyedToFinalDelay() ) )  break;

         DtTime sleeptime = ( simTime += initializer.deltaTime() ) - clock->elapsedRealTime();
         DtSleep( sleeptime ); // returns immediately if negative
      }


      delete myVehicle;
      delete rel;
      delete exConn;
   }
   DtCATCH_AND_WARN(std::cout);


   return 0;
}


int keybrdTick( DtVehicleSim* vehicle )
{
   char* keyPtr = DtPollBlockingInputLine();
   if ( !keyPtr )  return 1;  // no input

   switch( *keyPtr )
   {
      case 'q':
      case 'Q':
         return 0;
      case 'b': // bang, bang
      case '\n':
      case '\r':
         vehicle->fireMunition();
         break;
      case 'e':
         vehicle->toggleEmissions();
         break;
      default:
         std::cout <<  "Unrecognized command key " <<  *keyPtr  << std::endl;
         break;
   }
   return 1;
}  


Document ID: Generated on Mon May 14 08:06:18 EDT 2012 from SVN revision 114750
Copyright © 2005-2012 VT MÄK Inc. All Rights Reserved (www.mak.com)