VR-Forces 4.3.1 Class Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Extended Fixed Wing Pilot Controller

This subclass of DtFixedWingPilotController will fly away from a radar installation if signalled to do do by the DtSimpleRadarWarningReceiver.


The new controller component, DtSimpleRadarWarningResponse (simpleRdrWrnResp.h), provides a simple response when it receives a warning from the radar warning receiver. It attempts to move toward a waypoint named Safe Haven, if an object by that name exists in the simulation.
The controller for handling the reaction to a threat detected by the radar warning receiver is intended for a fixed-wing entity. All of the movement-related controllers for fixed-wing aircraft are derived from DtFixedWingPilotController, so we derive from that class for our new controller. Among other things, we inherit the ports required to control a DtFixedWingActuatorComponent, the actuator used by the F-16 entity. Like the sensor components created in “Creating the New Sensor Components,”, the following member functions must be implemented for the component to function correctly within the component architecture:

if(!safeControlPoint)
{
   DtWarn("DtSimpleRadarWarningResponse::tick() :
       Invalid safe control " "point %s",
       mySafeControlPointName.string());
   return;
}
DtVector safeLocation = safeControlPoint->vrfState()->vrfKinematicState()->localPosition();
if (myFixedWingControlPortGroup->attemptToActivate())
{
   if (inVicinity(safeLocation))
   {
      DtInfo("DtSimpleRadarWarningResponse::tick(): we're done! "
             "Resume normal activity”);
      myReactingToWarning = false;
      myFixedWingControlPortGroup->deactivate();
   }
   else
   {
      flyTo(safeLocation, myFixedWingEntityState->orderedSpeed());
   }
}
const DtList* emitterList = myEmitterListPort->value();
if (!(emitterList->first() && emitterList->first()->data()))
{
   myEmitterListPort->dataReceived();
   return;
}
DtEntityIdentifier * id = (DtEntityIdentifier *)emitterList->first()->data();
DtVrfObject* emitterSystemHost = mySimManager->vrfObjectManager()->lookupVrfObject(*id);
if (!emitterSystemHost)
{
   myEmitterListPort->dataReceived();
   return;
}
myReactingToWarning = true;
DtInfo("Simple radar warning rx detected emitter %s”, id->string());
DtInfo("Move away from the source!”);
if (myFixedWingControlPortGroup->attemptToActivate())
{
   flyTo(safeLocation, myFixedWingEntityState->orderedSpeed());
}
myEmitterListPort->dataReceived();

To get your new sensor and controller components into VR-Forces you must register the creators with the component factory. See “Adding the Actuator Component to the Component Factory,” in VR-Forces Developer’s Guide for details. You do this in plugin.cxx:

app->cgf()->factoryManager()->componentFactory()->addCreatorFcn("simple-radar-warning-receiver",
          DtSimpleRadarWarningReceiver::creator);
app->cgf()->factoryManager()->componentFactory()->addCreatorFcn("simple-radar-warning-response",
     DtSimpleRadarWarningResponse::creator);
app->cgf()->factoryManager()->componentFactory()->addCreatorFcn("scanning-radar", DtScanningRadar::creator);

Configuring Entities to Use the New Components
Now that we have incorporated the new components into the application, we need to configure specific entities to use the new components. In our new sensor and controller classes we did not add any new parameters, so we use the existing parameter and component descriptor classes associated with each component. (For an example of adding new parameters see “Creating a New Controller,” in the VR-Forces Developer’s Guide.)
In this example, we extended the CIS generic attack/strike fixed-wing entity entity with the new radar warning receiver and corresponding response controller.

;;
;; Entry for CIS generic attack/strike fixed wing platform
;;
(CIS-attack-strike-fixed-wing-platform
   (parameter-type "fixed-wing-entity-param")
   (object-type 1 (1 2 222 2 -1 -1 -1))
   (sensors
      . . .
      (simple-radar-warning-rx
         ;; We don't have any special parameters - the base class component
         ;; descriptor will suffice
         (component-descriptor-type "component-descriptor")
         ;; This identifies the class type to create for this sensor. It
         ;; should match the string returned by
         ;; DtRadarWarningReceiver::type().
         (component-type "simple-radar-warning-receiver")
      )
   )
   (controllers
      . . .
      ;;
      ;; Add our new controller component
      ;;
      (simple-radar-warning-reaction-controller
         (component-descriptor-type "fixed-wing-pilot-controller-descriptor")
         (component-type "simple-radar-warning-response")
         ;; These are additional parameters for the descriptor class we're
         ;; using (DtFixedWingPilotControllerDescriptor).
         (max-turning-Gs 9.)
         (max-turnrate-cutoff-angle 0.5236) ;; 30. degrees
      )
   )
   (actuators
      . . .
   ) ;; end actuators
   (connections
      . . .
      ;;
      ;; Connect the sensor to the new controller
      ;;
      (connect simple-radar-warning-rx:emitter-list simple-radar-warning-reaction-controller:emitter-list)
      ;;
      ;; Connect the new controller to the fixed wing actuator
      ;;
      . . .
   ) ;; end connections
) ;; end US-attack-strike-fixed-wing-entity

A modified object parameters database (configured with the new components) is in ./examples/radarWarnRx/scenario/RadarWarnRx.opd.


Header file:

/*******************************************************************************
** Copyright (c) 2003 MAK Technologies, Inc.
** All rights reserved.
*******************************************************************************/
/*******************************************************************************
** $RCSfile: simpleRdrWrnResp.h,v $ $Revision: 1.7 $ $State: Exp $
*******************************************************************************/

#ifndef DtSimpleRadarWarningResponse_H_
#define DtSimpleRadarWarningResponse_H_

#include "vrfmodel/fixedWingPilotController.h"

//class DtSimpleRadarWarningResponse:
//
//Instances of DtSimpleRadarWarningResponse are an example of a controller
//that implements a reactive behavior when a it receives sensor input that
//a radar has been detected.  It receives a list of emitter systems (hostile
//radar systems).  It takes the first emitter in the list and flys away to
//a location in the opposite direction.

class DtVrfObject;
class DtEntityListInputPort;   

class DtSimpleRadarWarningResponse : public DtFixedWingPilotController
{
public:
   
   //constructor
   DtSimpleRadarWarningResponse(const DtString& name, DtVrfObject* owner,
      DtSimManager* simManager, DtComponentDescriptor* desc = NULL,
      DtReaderWriterRegistry* const parentRegistry = 0);


   //destructor
   virtual ~DtSimpleRadarWarningResponse();

   //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-response".
   virtual DtString type() const;

   //Calculate new control values.
   virtual void tick();

   //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.
   static DtSimComponent* creator(const DtString& name, DtVrfObject* owner,
      DtSimManager* simManager, DtComponentDescriptor* desc,
      DtReaderWriterRegistry* parentRegistry);

protected:

   //Called by DtSimComponent::init to create myEntityListPort used to manage
   //multiple sensors that might provide targets to this controller.
   virtual bool createPorts();

   //Looks up safe control point by name.  If the object exists and it has
   //a valid state repository, returns the object.  Otherwise returns NULL.
   virtual DtVrfObject* getControlPoint(const DtString& name);

   //Returns true if we are in the vicinity of the given position.  To be
   //in the vicinity of the position means that we are within 5 seconds of
   //the given location, given our ordered speed.
   virtual bool inVicinity(const DtVector& localPosition);

protected:

   //default constructor
   DtSimpleRadarWarningResponse();

   //copy constructor, not implemented
   DtSimpleRadarWarningResponse(const DtSimpleRadarWarningResponse& orig);

   //assignment operator, not implemented
   DtSimpleRadarWarningResponse& operator=(const DtSimpleRadarWarningResponse& orig);

protected:

   //Port though which the list of hostile emitter systems will be received.
   DtEntityListInputPort* myEmitterListPort; 
   
   //true while in state of reacting to the detection of an emitter.
   bool myReactingToWarning;

   //Name of the safe location (a control point) we can retreat to.
   DtString mySafeControlPointName;

   DtVector myLocalGoal;
};

#endif


Implementation:

/*******************************************************************************
** Copyright (c) 2003 MAK Technologies, Inc.
** All rights reserved.
*******************************************************************************/
/*******************************************************************************
** $RCSfile: simpleRdrWrnResp.cxx,v $ $Revision: 1.18 $ $State: Exp $
*******************************************************************************/

#include "simpleRdrWrnResp.h"
#include <vlutil/vlPrint.h>
#include "vrfcore/simManager.h"
#include "vrfcore/exerciseClock.h"
#include "vrfobjcore/fixedWingEntityStateRepository.h"
#include "vrfobjcore/entListIOPort.h"
#include "vrfobjcore/vrfObjectManager.h"
#include "vrfobjcore/vrfObject.h"
#include "vrfobjcore/vrfKinematicState.h"
#include "vrfobjcore/vrfObjectGeometry.h"
#include "vrfobjcore/fixedWingFlightPSR.h"
#include "vrfobjcore/outputPortGroup.h"

DtSimpleRadarWarningResponse::DtSimpleRadarWarningResponse(
   const DtString & name, DtVrfObject* owner, DtSimManager * simManager, 
   DtComponentDescriptor* desc, DtReaderWriterRegistry * const parentRegistry) :
   DtFixedWingPilotController(name, owner, simManager, desc, parentRegistry),
   myEmitterListPort(NULL),
   myReactingToWarning(false),
   mySafeControlPointName("Safe Haven")
{
}

DtSimpleRadarWarningResponse::~DtSimpleRadarWarningResponse()
{
   if (myEmitterListPort)
   {
      delete myEmitterListPort;
      myEmitterListPort = NULL;
   }
}

DtString DtSimpleRadarWarningResponse::type() const
{
   return DtString("simple-radar-warning-response");
}

bool DtSimpleRadarWarningResponse::createPorts()
{
   if (!(myEmitterListPort = new DtEntityListInputPort("emitter-list")))
   {
      return false;
   }

   addInputPort(myEmitterListPort);

   return DtFixedWingPilotController::createPorts();
}

void DtSimpleRadarWarningResponse::tick()
{
   DtFixedWingPilotController::tick();

   //If dT is > 0 (we're not paused), then do the work
   if (dT() > 0.) 
   {
      //Called each frame by the deriving controllers to set up need variables,
      //such as myNormalBodyVelocity and myLocalAngularVelocity.
      initializeControllerForTick();

      DtVrfObject* safeControlPoint = getControlPoint(mySafeControlPointName);
      
      if (!safeControlPoint)
      {
         DtWarn("DtSimpleRadarWarningResponse::tick() : Invalid safe control "
            "point %s\n", mySafeControlPointName.string());

         return;
      }

      DtVector safeLocation = safeControlPoint->vrfState()->
         vrfKinematicState()->localPosition();

      //If I'm already reacting to a previous radar warning
      if (myReactingToWarning)
      {

         //Take control of the port group - this gives us exclusive control
         //over the fixed-wing actuator until we give that control up or a 
         //higher priority controller overrides us
         if (myFixedWingControlPortGroup->attemptToActivate())
         {
            if (inVicinity(safeLocation))
            {
               //We're done

               objectConsoleWarn() << "radarWarnRx Example - " << 
                  "We have reached the safe location!  " << std::endl;
               objectConsoleWarn() << "radarWarnRx Example - " << 
                  "Resume normal activity." << std::endl;

               myReactingToWarning = false;

               //Give up control of actuator's port group so other 
               //components may control it. 
               myFixedWingControlPortGroup->deactivate();
            }
            else
            {
               //Move toward the safe location
               flyTo(safeLocation, myFixedWingEntityState->orderedSpeed());
            }
         }
      }
      else
      {
         if (! myEmitterListPort || ! myEmitterListPort->activeConnection() ||
            !myEmitterListPort->value())
         {
            objectConsoleVerbose() << "radarWarnRx Example - " << 
            "No emitter list for radar warning reaction controller" <<
            std::endl;

            return;
         }

         //Get 1st emitter system on list of emitters on the port 
         const DtEntityTargetList* emitterList = myEmitterListPort->value();
      
         //If there aren't any emitters out there, there's nothing to react to
         if (!(emitterList->first() && emitterList->first()->data()))
         {
            //Mark the data as "old"
            myEmitterListPort->dataReceived();

            return;
         }

         //We have an emitter out there
         DtEntityTargetInformation * info = 
            (DtEntityTargetInformation *)emitterList->first()->data();

         //Look up the entity with the radar
         DtVrfObject* emitterSystemHost = 
            mySimManager->vrfObjectManager()->lookupVrfObject(info->id());

         if (!emitterSystemHost)
         {
            //Mark the data as "old"
            myEmitterListPort->dataReceived();

            return;
         }

         //We're now reacting to an emitter
         myReactingToWarning = true;

         objectConsoleWarn() << "radarWarnRx Example - " << 
         "Simple radar warning rx detected emitter " << info->id().string() <<
         "." << std::endl;
         objectConsoleWarn() << "radarWarnRx Example - " << 
         "Move away from the source!" << std::endl;

         //Take control of port group - this gives us exclusive control
         //over the fixed-wing actuator for the duration of the frame (no other
         //controllers that come after this one will be able to control it).
         if (myFixedWingControlPortGroup->attemptToActivate())
         {
            //Move toward the safe location
            flyTo(safeLocation, myFixedWingEntityState->orderedSpeed());
         }
      
         //Mark the data as "old"
         myEmitterListPort->dataReceived();
      }
   }
}

DtSimComponent * DtSimpleRadarWarningResponse::creator(const DtString & name, 
   DtVrfObject* owner, DtSimManager * simManager, DtComponentDescriptor* desc,
   DtReaderWriterRegistry * parentRegistry)
{
   return new DtSimpleRadarWarningResponse(name, owner, simManager, desc, 
      parentRegistry);
}

DtVrfObject* DtSimpleRadarWarningResponse::getControlPoint(const DtString& name)
{
   DtVrfObject* controlPoint = mySimManager->vrfObjectManager()->
      lookupVrfObjectByName(mySafeControlPointName);
   
   if (!controlPoint)
   {
      objectConsoleWarn() << "radarWarnRx Example - " << 
      "DtSimpleRadarWarningResponse::getControlPoint() : Can't find control point " <<
      name << std::endl;
      return NULL;
   }
   
   if (!controlPoint->vrfState())
   {
      objectConsoleWarn() << "radarWarnRx Example - " << 
         "Control point " << name << " does not have state repository!" << std::endl;
      return NULL;
   }

   return controlPoint;
}

bool DtSimpleRadarWarningResponse::inVicinity(
   const DtVector& localPosition)
{
   DtLocalVector location = myFixedWingEntityState->localPosition();

   myProcessState->setDistanceSquared(location.distSquaredTo2D(localPosition));
   
   if (myProcessState->lastDistanceSquared() == 0.0)
   {
	   myProcessState->setLastDistanceSquared(myProcessState->distanceSquared());
   }

   if (myProcessState->distanceSquared() < (myFixedWingEntityState->orderedSpeed() * 
      myFixedWingEntityState->orderedSpeed() * 25.0)) //5 seconds away...
   {
      return true;
   }

   return false;
}

Document ID: Generated on Wed Jul 29 00:55:00 EDT 2015 from SVN revision 155257
Copyright © 2005-2015 VT MÄK. All Rights Reserved (www.mak.com)