This example shows how to manipulate DDM regions using packet data.
/******************************************************************************* ** 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
/******************************************************************************* ** 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
/******************************************************************************* ** 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