sampleDDM Example

This example shows how to manipulate DDM regions using packet data.


The sample DDM simulation manager, entity publisher, and simulation output:

ddmSimManager.h/cxx

ddmEntityPublisher.h/cxx

ddmSimOutput.h/cxx

ddmSimManager.h/cxx

/*******************************************************************************
** Copyright (c) 2010 MaK Technologies, Inc.
** All rights reserved.
*******************************************************************************/


#if DtHLA

#pragma once

#include <lgrHlaSimManager.h>
#include "sampleDdm.h"
#include "hlaGenericPublisher.h"

namespace MAKLogger
{

   class DT_DLL_SAMPLE_DDM DtLgrHlaDdmSimulationManager : public DtLgrHlaSimulationManager
   {
   public:

      // Constructor
      DtLgrHlaDdmSimulationManager(DtLogger& logger,
         DtLgrHlaSimDriver* simDriver);

      // Destructor
      virtual ~DtLgrHlaDdmSimulationManager();


      virtual bool connect(DtExerciseConnInitializer& initializer);

      virtual void disconnect();

   public:

      static DtLgrHlaSimulationManager* create(DtLogger& logger,
         DtLgrHlaSimDriver* simDriver);

   protected:

      // Initialize the publication lists
      virtual void initializePublicationLists();
      
      
   protected:

      // Map class names to the region set names in the publication list.
      // The base class publication list will map object names to region set names.
      std::map<DtString, DtString> myPublicationClassNameList;

   };

}
#endif // DtHLA
/*******************************************************************************
** Copyright (c) 2010 MaK Technologies, Inc.
** All rights reserved.
*******************************************************************************/


#if DtHLA

#include "ddmSimManager.h"
#include "ddmSimOutput.h"

namespace MAKLogger
{

DtLgrHlaDdmSimulationManager::DtLgrHlaDdmSimulationManager(DtLogger& logger,
   DtLgrHlaSimDriver* simDriver)
   : DtLgrHlaSimulationManager(logger, simDriver)
{
   initializePublicationLists();
}

DtLgrHlaDdmSimulationManager::~DtLgrHlaDdmSimulationManager()
{

}

DtLgrHlaSimulationManager* DtLgrHlaDdmSimulationManager::create( DtLogger& logger, DtLgrHlaSimDriver* simDriver )
{
   return new DtLgrHlaDdmSimulationManager(logger, simDriver);
}


void DtLgrHlaDdmSimulationManager::initializePublicationLists()
{
   // Add regions and region sets to object name publication list
   // Object names are added during playback when publishers are created.
   // myPublicationList
   
   // Add mappings from object class names to region set names in object class name publication list
   // The region set descriptions aren't needed in this list. They are retrieved from the object name list above.
   // myPublicationClassNameList[className] = regionSetName;
}

bool DtLgrHlaDdmSimulationManager::connect( DtExerciseConnInitializer& initializer )
{
   bool connectOK = DtLgrHlaSimulationManager::connect(initializer); 
   DtLgrHlaDdmSimOutput* ddmOutput = dynamic_cast<DtLgrHlaDdmSimOutput*>(myOutput);
   ddmOutput->initializeHandles();
   return connectOK;
}

void DtLgrHlaDdmSimulationManager::disconnect()
{
   DtLgrHlaSimulationManager::disconnect();
}

}
#endif // DtHLA

ddmEntityPublisher.h/cxx

/*******************************************************************************
** Copyright (c) 2010 MaK Technologies, Inc.
** All rights reserved.
*******************************************************************************/


#ifndef lgrHlaDdmEntityPublisher_H_
#define lgrHlaDdmEntityPublisher_H_

#if DtHLA

#include "lgrHlaEntityPublisher.h"
#include <vl/region.h>

namespace MAKLogger
{

   class DtLgrHlaSimulationManager;

   class DtLgrHlaDdmEntityPublisher : public DtLgrHlaEntityPublisher
   {
   public:

      DtLgrHlaDdmEntityPublisher(DtLgrHlaSimulationManager& simMgr, RTI::ObjectClassHandle classHandle,
         const char* objName, const DtDDMRegionSet* regionSetToUse,
         double hbtime=0.0, bool silent=false, bool stat=true);

      virtual ~DtLgrHlaDdmEntityPublisher();

      virtual bool updateRegion(const DtStateMsg& msg);

   public:

      static DtLgrHlaEntityPublisher* create(DtLgrHlaSimulationManager& simMgr,
         RTI::ObjectClassHandle classHandle, const char* objName,
         const DtDDMRegionSet* regionSetToUse, double hbtime=0.0,
         bool silent=false, bool stat=true);

   protected:

      DtLgrHlaDdmEntityPublisher(const DtLgrHlaDdmEntityPublisher &other);

      DtLgrHlaDdmEntityPublisher &operator=(const DtLgrHlaDdmEntityPublisher &other);

   protected:

      DtDDMRegionSP myLgrRegion;

   };

}

#endif   //! DtHLA

#endif   //! lgrHlaDdmEntityPublisher_H_

/*******************************************************************************
** Copyright (c) 2010 MaK Technologies, Inc.
** All rights reserved.
*******************************************************************************/


#if DtHLA

#include "ddmEntityPublisher.h"
#include "ddmSimOutput.h"

#include <lgrHlaSimManager.h>
#include <vl/entitySR.h>

namespace MAKLogger
{


DtLgrHlaDdmEntityPublisher::DtLgrHlaDdmEntityPublisher(
   DtLgrHlaSimulationManager& simMgr, RTI::ObjectClassHandle classHandle,
   const char* objName, const DtDDMRegionSet* regionSetToUse,
   double hbtime/*=0.0*/, bool silent/*=false*/, bool stat/*=true*/)
   : DtLgrHlaEntityPublisher(simMgr, classHandle, objName, regionSetToUse,
                                hbtime, silent, stat)
{
   if (regionSetToUse && regionSetToUse->size() > 0)
   {
      myLgrRegion = *regionSetToUse->begin();
   }
}

DtLgrHlaDdmEntityPublisher::~DtLgrHlaDdmEntityPublisher()
{

}


DtLgrHlaEntityPublisher* DtLgrHlaDdmEntityPublisher::create( DtLgrHlaSimulationManager& simMgr,
   RTI::ObjectClassHandle classHandle, const char* objName,
   const DtDDMRegionSet* regionSetToUse, double hbtime/*=0.0*/,
   bool silent/*=false*/, bool stat/*=true*/ )
{
   return new DtLgrHlaDdmEntityPublisher(simMgr, classHandle, objName,
      regionSetToUse, hbtime, silent, stat);
}

bool DtLgrHlaDdmEntityPublisher::updateRegion( const DtStateMsg& msg )
{
   if (!myLgrRegion)
   {
      //msg.
   }
   else if (myOrigLocation != esr()->location())
   {
      DtGeodeticCoord geodeticLocation;
      geodeticLocation.setGeocentric(esr()->location());
      DtLgrHlaDdmSimOutput::setRegionBounds(myLgrRegion, geodeticLocation);
   }

   return myLgrRegion.get() != 0;
}

}

#endif // DtHLA

ddmSimOutput.h/cxx

/*******************************************************************************
** Copyright (c) 2010 MaK Technologies, Inc.
** All rights reserved.
*******************************************************************************/


#if DtHLA

#pragma once

#include <hlaSimOutput.h>
#include <vl/geodeticRegion.h>

#include "sampleDdm.h"


namespace MAKLogger
{

   class DT_DLL_SAMPLE_DDM DtLgrHlaDdmSimOutput : public DtLgrHlaSimOutput
   {
   public:

      // Constructor
      DtLgrHlaDdmSimOutput(DtLgrHlaSimulationManager& manager);

      // Destructor
      virtual ~DtLgrHlaDdmSimOutput();

      virtual unsigned int getInteractionRegionSetFromData(const DtConstLgrHlaMessage& info,
         const DtInteraction* interaction, DtDDMRegionSet& regionSet);

      virtual bool getPublisherRegionSetFromData(const DtPacket& info,
         DtDDMRegionSet& regionSet);

      virtual void initializeHandles();

   public:

      // Creator
      static DtLgrHlaSimOutput* create(DtLgrHlaSimulationManager& manager);

      static void setRegionBounds(DtDDMRegionSP region, DtGeodeticCoord& geodeticLocation);

   protected:

      virtual DtDDMRegionSP createRegion();

      virtual void decodeLocationFromVector(const char* const netData, DtGeodeticCoord& geodeticLocation);

      virtual void decodeLocationFromSpatial(const char* const netData, DtGeodeticCoord& geodeticLocation);

      virtual bool getLocation(const DtLgrHandleValueReferenceMap* handleValueMap,
         const DtLgrHlaHandle& handleToFind, DtGeodeticCoord& geodeticLocation, bool decodeAsVector=true);

   protected:

     DtLgrHlaHandle myBaseEntityClassHandle;
     DtLgrHlaHandle myEntityLocationHandle;
     DtLgrHlaHandle myWeaponFireClassHandle;
     DtLgrHlaHandle myWeaponFireLocationHandle;
     DtLgrHlaHandle myDetonationClassHandle;
     DtLgrHlaHandle myDetonationLocationHandle;
     DtDDMRegionSP myWeaponFireRegion;
     DtDDMRegionSP myDetonationRegion;
     long myLatitude;
     long myLongitude;

   };

}

#endif // DtHLA
/*******************************************************************************
** Copyright (c) 2010 MaK Technologies, Inc.
** All rights reserved.
*******************************************************************************/


#if DtHLA

#include "ddmSimOutput.h"
#include "ddmSimManager.h"
#include "hlaPacket.h"
#include "onlineFomDesc.h"
#include "lgrFomWithRegions.h"
#include "lgrHlaSimDriver.h"
#include "baseObjDesc.h"
#include "baseIntDesc.h"

#include <vl/intClassDesc.h>
#include <vl/hInteraction.h>
#include <vl/spatialStructs.h>
#include <vl/geodeticRegion.h>
#include <vl/hFireInter.h>
#include <vl/hDetInter.h>
#include <vlutil/vlPrint.h>

namespace MAKLogger
{

DtLgrHlaDdmSimOutput::DtLgrHlaDdmSimOutput(DtLgrHlaSimulationManager& manager)
   : DtLgrHlaSimOutput(manager)
   , myBaseEntityClassHandle(0)
   , myEntityLocationHandle(0)
   , myWeaponFireClassHandle(0)
   , myWeaponFireLocationHandle(0)
   , myDetonationClassHandle(0)
   , myDetonationLocationHandle(0)
   , myLatitude(0)
   , myLongitude(0)
{
}

DtLgrHlaDdmSimOutput::~DtLgrHlaDdmSimOutput()
{

}

void DtLgrHlaDdmSimOutput::initializeHandles()
{
   if (!myHlaManager.isConnected())
   {
      return;
   }
   // Avoid ambiguity of RTI handles version of methods when using DtOnlineFomDesc
   const DtBaseFomDesc* baseFomDesc = myHlaManager.fomDescription();
   const DtBaseObjClassDesc* objClassDesc = 0;
   const DtBaseInterClassDesc* interClassDesc = 0;

   myCacheInteractionRegionsEnabled = true;
   myCacheObjectRegionsEnabled = true;

#if DtHLA_1516
   objClassDesc = baseFomDesc->objDesc(DtString("HLAobjectRoot.BaseEntity"));
#else
   objClassDesc = baseFomDesc->objDesc(DtString("ObjectRoot.BaseEntity"));
#endif

   if (objClassDesc)
   {
      const DtBaseAttrDesc* attrDesc = 0;
      myBaseEntityClassHandle = objClassDesc->handle();
      if (myHlaManager.simDriver()->fomVersion() < 2.0)
      {
         attrDesc = objClassDesc->findValueByName("WorldLocation", false);
      }
      else
      {
         attrDesc = objClassDesc->findValueByName("Spatial", false);
      }

      if (attrDesc)
      {
         myEntityLocationHandle = attrDesc->handle();
      }
   }

#if DtHLA_1516
   interClassDesc = baseFomDesc->interDesc("HLAinteractionRoot.WeaponFire");
#else
   interClassDesc = baseFomDesc->interDesc("InteractionRoot.WeaponFire");
#endif
   if (interClassDesc)
   {
      const DtBaseParamDesc* paramDesc = interClassDesc->findValueByName("FiringLocation", false);
      myWeaponFireClassHandle = interClassDesc->handle();
      if (paramDesc)
      {
         myWeaponFireLocationHandle = paramDesc->handle();
      }
   }

#if DtHLA_1516
   interClassDesc = baseFomDesc->interDesc("HLAinteractionRoot.MunitionDetonation");
#else
   interClassDesc = baseFomDesc->interDesc("InteractionRoot.MunitionDetonation");
#endif
   if (interClassDesc)
   {
      const DtBaseParamDesc* paramDesc = interClassDesc->findValueByName("DetonationLocation", false);
      myDetonationClassHandle = interClassDesc->handle();
      if (paramDesc)
      {
         myDetonationLocationHandle = paramDesc->handle();
      }
   }
}

void DtLgrHlaDdmSimOutput::decodeLocationFromVector(const char* const netData, DtGeodeticCoord& geodeticLocation)
{
   geodeticLocation.setGeocentric(*reinterpret_cast<const DtNet64Vector* const>(netData));
}

void DtLgrHlaDdmSimOutput::decodeLocationFromSpatial(const char* const netData, DtGeodeticCoord& geodeticLocation)
{
   // Get dead reckoning algorithm
   DtDeadReckonTypes drAlg =  static_cast<DtDeadReckonTypes>(static_cast<DtU8>(*reinterpret_cast<const DtNetU8*>(netData)));
   DtVector geocentricLocation(0.0,0.0,0.0);

   // based on the dead reckoning algorithm, the spatial netData contains 
   // different stuff. 
   const char* pSpatialData = netData + 8; // Skip over DR enum and 7 bytes padding
   switch( drAlg )
   {
   case DtDrStatic:
      geocentricLocation = reinterpret_cast<const DtNetSpatialStaticStruct*>(pSpatialData)->worldLocation;
      break;
   case DtDrDrmFpb:
   case DtDrDrmFpw:
      geocentricLocation = reinterpret_cast<const DtNetSpatialFPStruct*>(pSpatialData)->worldLocation;
      break;
   case DtDrDrmRpb:
   case DtDrDrmRpw:
      geocentricLocation = reinterpret_cast<const DtNetSpatialRPStruct*>(pSpatialData)->worldLocation;
      break;
   case DtDrDrmRvb:
   case DtDrDrmRvw:
      geocentricLocation = reinterpret_cast<const DtNetSpatialRVStruct*>(pSpatialData)->worldLocation;
      break;
   case DtDrDrmFvb:
   case DtDrDrmFvw:
      geocentricLocation = reinterpret_cast<const DtNetSpatialFVStruct*>(pSpatialData)->worldLocation;
      break;
   default:
      break;
   }

   geodeticLocation.setGeocentric(geocentricLocation);
}

bool DtLgrHlaDdmSimOutput::getLocation(const DtLgrHandleValueReferenceMap* handleValueMap,
   const DtLgrHlaHandle& handleToFind, DtGeodeticCoord& geodeticLocation, bool decodeAsVector/*=true*/)
{
   if (!handleValueMap)
   {
      return false;
   }
   bool gotLocation = false;
   DtLgrHandleValueReferenceMap::const_iterator findIter = handleValueMap->find(handleToFind);
   if (findIter != handleValueMap->end())
   {
      gotLocation = true;
      if (decodeAsVector)
      {
         decodeLocationFromVector(findIter->second.data, geodeticLocation);
      }
      else
      {
         decodeLocationFromSpatial(findIter->second.data, geodeticLocation);
      }
   }

   return gotLocation;
}

void DtLgrHlaDdmSimOutput::setRegionBounds(DtDDMRegionSP region, DtGeodeticCoord& geodeticLocation)
{
   if (!region)
      return;

   // The region extents will be the lat/lon box containing the location.
   long latitude = DtRad2Deg(geodeticLocation.lat())+90;
   long longitude = DtRad2Deg(geodeticLocation.lon())+180;

   //if (myLatitude != latitude || myLongitude != longitude)
   {
      //myLatitude = latitude;
      //myLongitude = longitude;
      region->setDimensionBounds("Y", latitude, latitude+1);
      region->setDimensionBounds("X", longitude, longitude+1);
      region->notifyRtiOfUpdate();
   }
}


DtDDMRegionSP DtLgrHlaDdmSimOutput::createRegion()
{
   DtDDMRegion* region = new DtDDMRegion(myHlaManager.exerciseConn());
   std::vector<DtString> dimensionNames(2);
   dimensionNames[0] = "X";
   dimensionNames[1] = "Y";

#if DtHLA_1516
   region->init(dimensionNames);
#else
   region->init("BenchmarkGeographicSpace", dimensionNames);
#endif

   return DtDDMRegionSP(region);
}

bool DtLgrHlaDdmSimOutput::getPublisherRegionSetFromData(const DtPacket& info,
   DtDDMRegionSet& regionSet)
{
   DtConstLgrHlaMessage hlaInfo(info);
   const DtBaseFomDesc& aFom = fom();
   const DtBaseObjClassDesc* classDesc = aFom.objDesc(hlaInfo.objectClassHandle());

   regionSet.clear();
   if (!classDesc)
   {
      DtDebug << "Failed to get publish region set for entity object: "
         << hlaInfo.objectName() << "(" << hlaInfo.objectHandle() << ")."
         << "Unknown object class handle: "<< hlaInfo.objectClassHandle() << std::endl;
   }
   else if (classDesc->isOfClass(myBaseEntityClassHandle))
   {
      DtGeodeticCoord geodeticLocation;

      if (getLocation(hlaInfo.referenceAttrs(), myEntityLocationHandle,
            geodeticLocation, (myHlaManager.simDriver()->fomVersion() < 2.0)))
      {
         DtDDMRegionSP region = createRegion();
         setRegionBounds(region, geodeticLocation);
         regionSet.insert(region);
      }
   }

   return regionSet.size() > 0;
}

unsigned int DtLgrHlaDdmSimOutput::getInteractionRegionSetFromData(
   const DtConstLgrHlaMessage& hlaInfo, const DtInteraction* interaction,
   DtDDMRegionSet& regionSet)
{
   const DtLgrOnlineFomDesc& fomDesc = fom();
   DtLgrHlaHandle  classHandle = hlaInfo.interactionClassHandle();
   const DtBaseInterClassDesc* classDesc = 0; //myHlaManager.fomDescription()->interDesc(classHandle);
   regionSet.clear();

   if (classDesc->isOfClass(myWeaponFireClassHandle))
   {
      const DtFireInteraction* weaponFire = reinterpret_cast<const DtFireInteraction*>(interaction);
      DtGeodeticCoord geodeticLocation;
      geodeticLocation.setGeocentric(weaponFire->location());

      if (!myWeaponFireRegion)
      {
         myWeaponFireRegion = createRegion();
      }
      setRegionBounds(myWeaponFireRegion, geodeticLocation);
      regionSet.insert(myWeaponFireRegion);
   }
   else if (classDesc->isOfClass(myDetonationClassHandle))
   {
      const DtDetonationInteraction* detonation = reinterpret_cast<const DtDetonationInteraction*>(interaction);
      DtGeodeticCoord geodeticLocation;
      geodeticLocation.setGeocentric(detonation->worldLocation());

      if (!myDetonationRegion)
      {
         myDetonationRegion = createRegion();
      }
      setRegionBounds(myDetonationRegion, geodeticLocation);
      regionSet.insert(myDetonationRegion);
   }
   return regionSet.size();
}


DtLgrHlaSimOutput* DtLgrHlaDdmSimOutput::create( DtLgrHlaSimulationManager& manager )
{
   return new DtLgrHlaDdmSimOutput( manager );
}

}

#endif // DtHLA

Document ID: Generated on Tue Oct 11 19:41:03 EDT 2011 from SVN revision 107422
Copyright © 2005-2011 VT MÄK Inc. All Rights Reserved (www.mak.com)