![]() |
VR-Forces 4.8 Class Documentation
|
This subclass of DtSimComponent will check to see if there are any emitter systems in the area that could sense a fixed wing.
VR-Forces provides a component class, DtSimComponent (simCmpnt.h), so we can derive our radar sensor from this component. Anytime you create a new component, you have to provide the following member items in your new class:
DtSimComponent(const DtString & name, DtVrfObject* owner, DtSimManager* simManager, DtComponentDescriptor* desc = 0, DtReaderWriterRegistry* parentRegistry = 0);
The string returned by the type() function is the key into the component factory that VR-Forces uses to instantiate new components. See compTypes.h for the set of string types for VR-Forces component classes.
Implementing the Radar Warning Receiver Class
The radar warning receiver class, DtSimpleRadarWarningReceiver (simpleRadarWarnRx.h), needs to detect the emissions and notify any interested controllers that it has detected one or more radars. In this example it merely checks for anything sending out emissions within a 5 Km radius. The class has a VR-Link DtReflectedEmitterSystem- List data member, myReflectedEmitterList, which it uses to gain knowledge of all entities generating emission PDUs over the network.
If it finds any, it extracts the host ID of the emitter and places that host ID on an emitter list port. The radar warning receiver uses the existing DtEntityListOutputPort class to communicate the identity of the set of radars it has detected in the current tick. It will ultimately be connected to the radar warning response controller that will receive the data on the emitter list port (a list of detected radars) and use that information to drive its behavior.
Adding a Sensor Component
As a provider of data (the list of detected emitters), the DtSimpleRadarWarningReceiver has a DtEntityListPort data member, myEmitterListPort. It is responsible for creating and setting values on the port. Each tick, it does the following:
void DtSimpleRadarWarningReceiver::tick() { if(!entity()) { return; } if(!myEmitterListPort) { return; } if (myEmitterListPort->attemptToActivate()) { myEmitterListPort->emptyList(); DtReflectedEmitterSystem* emitterSystem; for(emitterSystem = myReflectedEmitterList->first(); emitterSystem; emitterSystem = emitterSystem->next()) { DtGlobalObjectDesignator emitterSystemHostId = emitterSystem->emitterSysRep()->hostId(); if(emitterSystemHostId == myGlobalId) { continue; } DtVrfObject* emitterEntity = mySimManager->vrfObjectManager()-> lookupVrfObjectByGlobalId(emitterSystemHostId); if(!emitterEntity) { continue; } DtListItem beamItem = emitterSystem->emitterSysRep()-> beamList()->first(); DtEmitterBeamRepository *beamSR = NULL; bool found = false; while (beamItem && !found) { beamSR = (DtEmitterBeamRepository) beamItem->data(); if (beamSR->ERP() > 0) { double rangeSquaredToEmitter = DtDistSqr( entity()->vrfState()->localPosition(), emitterEntity->vrfState()->localPosition()); if(rangeSquaredToEmitter < 25000000.0) { myEmitterListPort->addEntity(emitterEntity->objectIdentifier()); found = true; } } beamItem = beamItem->next(); } } } }
Header file:
/********************************************************************************* Copyright (c) 2017 MAK Technologies, Inc.** All rights reserved.*******************************************************************************/#pragma once#include "vrfobjcore/simComponent.h"#include <vl/globalObjectDesignator.h>//class DtSimpleRadarWarningReceiver:////Instances of DtSimpleRadarWarningReceiver are an example of a simple radar//warning reciever. For the purposes of example this receiver determines//that it has detected a remote radar if a given remote emitter system//is located within a given distance from the entity configured with the//reciever. The list of radar emitters sensed this tick is generated as//output.class DtEntityListOutputPort;{public://constructorDtSimManager * simManager, DtComponentDescriptor* desc = NULL,DtReaderWriterRegistry * parentRegistry = 0);//destructorvirtual ~DtSimpleRadarWarningReceiver();//Calls createRelfectedEmitterList() and createEmitterListPort().//Called by init(). Creates the VR-Link list of all reflected emitter//objects in the simulation.//This returns a string that uniquely identifies this type of component.//(must be unique with respect to the component types defined in compTypes.h//as well as any additional user-defined components). Returns the string//"simple-radar-warning-receiver".//This is the entity we're detecting for. We override because we//want to grab and cache the global object designator.//Detects emitters and places them on our port.//Returns the list of emitters we've detected.//Returns a newly created instance of this class. We need to provide//this function so that we can register this class with the component//factory.DtSimManager * simManager, DtComponentDescriptor* desc,DtReaderWriterRegistry * parentRegistry);protected://Overridden to create myEmitterListPortprotected://Default constructor; should not be called. Here because the compiler//will generate an unprotected one otherwise.//copy constructor, not implemented//assignment operator, not implementedconst DtSimpleRadarWarningReceiver& orig);protected://Port used to communicate the list of detected emitter systems to//other components.//The id of the entity this receiver is mounted on.//Pointer to the descriptor that holds the initialization parameters for this component.//This pointer is const because all instances of this component share a single//descriptor instance, so they should not be writing data back to it.};
Implementation:
/********************************************************************************* Copyright (c) 2003 MAK Technologies, Inc.** All rights reserved.*******************************************************************************//********************************************************************************* $RCSfile: simpleRadarWarnRx.cxx,v $ $Revision: 1.11 $ $State: Exp $*******************************************************************************/#include "simpleRadarWarnRx.h"#include <vlutil/vlPrint.h>#include <vl/reflectedEmitterSystemList.h>#include "vrfobjcore/entListIOPort.h"#include "vrfcore/simManager.h"#include "vrfobjcore/vrfObject.h"#include "vrfobjcore/vrfObjectManager.h"#include "radarWarningReceiverDesc.h"// Global reflected emitter list such that multiple instances of this receiver do// not have to create their own list. The reference count is to delete the list when the last// controller is removedstatic int theReflectedListInstanceCount = 0;//List of all remote emitter systems.static DtReflectedEmitterSystemList* theReflectedEmitterList = 0;DtReaderWriterRegistry * parentRegistry) :DtSimComponent(name, owner, simManager, desc, parentRegistry),myEmitterListPort(NULL),#if DtHLAmyGlobalId(DtString::nullString())#elsemyGlobalId(DtEntityIdentifier::nullId())#endif, myDescriptor(0){//Initialize myDescriptor from the descriptor passed into the constructor.//Warn the user if the OPE or sysdef file was configured with the incorrect//descriptor for this component.if (!myDescriptor){objectConsoleError() << "DtSimpleRadarWarningReceiver requires descriptor of type " <<}++theReflectedListInstanceCount;}{--theReflectedListInstanceCount;if (theReflectedListInstanceCount <= 0){theReflectedListInstanceCount = 0;delete theReflectedEmitterList;theReflectedEmitterList = NULL;}if (myEmitterListPort){delete myEmitterListPort;myEmitterListPort = NULL;}}{if (!DtSimComponent::init()){return false;}if (!createReflectedEmitterList()){return false;}return true;}{if (myEmitterListPort){delete myEmitterListPort;myEmitterListPort = NULL;}//Create the sensor's output port.return DtSimComponent::createPorts();}{if (!theReflectedEmitterList){//Safety check - this should never happenif (!mySimManager){DtWarn("Can't create reflected emitter list - no sim manager!\n");return false;}DtExerciseConn* exerciseConn = mySimManager->exerciseConn();//Safety check - this should never happenif (!exerciseConn){DtWarn("Can't create reflected emitter list - no exercise connection!\n");return false;}theReflectedEmitterList = new DtReflectedEmitterSystemList(exerciseConn);}return true;}namespace{const char* SimpleRadarWarningReceiver = "simple-radar-warning-receiver";}//This returns a string that uniquely identifies this type of component.//(must be unique with respect to the component types defined in compTypes.h//as well as any additional user-defined components).{return SimpleRadarWarningReceiver;}//This is the entity we're detecting for. We override because we//want to grab and cache the global object designator.{DtSimComponent::setEntity(entity);if (entity){myGlobalId = entity->globalId();}}//Detects emitters and places them on our port.{//Check to see if the simulation is pausedif (dT() == 0.){return;}if (!entity()){return;}//Safety check - this should have been created in init()if (!myEmitterListPort){return;}//Attempt to take control of the emitter list output port{//Clean out list of emitter systems on port//Iterate through list of current emitter systemsDtReflectedEmitterSystem* emitterSystem;for(emitterSystem = theReflectedEmitterList->first(); emitterSystem;emitterSystem = emitterSystem->next()){DtGlobalObjectDesignator emitterSystemHostId =emitterSystem->emitterSysRep()->hostId();//Make sure its doesn't belong to usif(emitterSystemHostId == myGlobalId){continue;}//Look up the entity with the emitterlookupVrfObjectByGlobalId(emitterSystemHostId);//If for some reason we can't find it, move on to the next oneif(!emitterEntity){continue;}//Use the emitter detection range that was configured in the descriptor.//If the descriptor was misconfigured and doesn't exist, use a default//value instead.//Store the square of it here to use inside the loop below for efficiency.double emitterDetectionRangeSquared = 25000000.0;if (myDescriptor){emitterDetectionRangeSquared = myDescriptor->emitterDetectionRange() *}//Check for at least one beam with >0 ERP.DtListItem *beamItem = emitterSystem->emitterSysRep()->beamList()->first();DtEmitterBeamRepository *beamSR = NULL;bool found = false;while (beamItem && !found){beamSR = (DtEmitterBeamRepository*) beamItem->data();if (beamSR->ERP() > 0){//Check the distance to the emitter - if it falls 5 km range,//add it to our list of detected emittersdouble rangeSquaredToEmitter = DtDistSqr(entity()->vrfState()->localPosition(),emitterEntity->vrfState()->localPosition());if(rangeSquaredToEmitter < emitterDetectionRangeSquared){//Consider the emitter system to be detected. Put it on//our port.emitterEntity->objectIdentifier());found = true; //found 1, so don't check for others.}}beamItem = beamItem->next();}}}}{return myEmitterListPort;}//Returns a newly created instance of this class. We need to provide//this function so that we can register this class with the component//factory.DtReaderWriterRegistry * parentRegistry){parentRegistry);}