![]() |
VR-Forces 4.0.4 Class Documentation
|
The DtRetreatController is a new class that implements the DtRetreatTask to cause an entity to retreat under user defined circumstances
/******************************************************************************* ** Copyright (c) 2000 MAK Technologies, Inc. ** All rights reserved. *******************************************************************************/ /******************************************************************************* ** $RCSfile: retreatCtrl.h,v $ $Revision: 1.2 $ $State: Exp $ *******************************************************************************/ // //class DtRetreatController // //The retreating behavior of this controller was not intended to be //intelligent; it is meant to be an example of a controller invoked by a //DtUserTask. Because the currentTarget is used to determine which way to //flee, the behavior is best demonstrated tank vs. tank. Vehicles which do not //target other vehicles, such as utility vehicles, will simply flee towards //their current heading. Tanks will not flee from entities which they do //not target, such as helicopters. // //The retreat DtUserTask takes one argument from the "Argument 1" box //of the DtUserTask dialog. If it is set to "hold ground", entities set to //retreat will not start moving untill their underFire flag is set. // //To enable an entity to retreat, there must be an entry for //"retreat-controller" in its controller list in the object parameters //database. The following sample can be used: // // (controllers // ... // (retreat // (component-descriptor-type "component-descriptor") // (component-type "retreat-controller") // ) // ... // ) // // (connections // .... // (connect retreat:automotive-control powertrain:automotive-control) // ... // ) // #include "vrfobjcore/singleTaskControllerComponent.h" #include "vrfmodel/gndAutoCntlr.h" //String which uniquely identifies this controller const char TestRetreatControllerType[] = "retreat-controller"; class DtRetreatController : public DtGroundAutoControllerComponent { public: //constructor DtRetreatController(const DtString & name, DtVrfObject* owner, DtSimManager * simManager, DtComponentDescriptor* desc = NULL, DtReaderWriterRegistry * parentRegistry = 0); //destructor virtual ~DtRetreatController(); //copy constructor DtRetreatController(const DtRetreatController& orig); //assignment operator DtRetreatController& operator=(const DtRetreatController& orig); //This returns the string TestRetreatControllerType (defined above), //used to uniquely identify the type of component. virtual DtString type() const; //Register a callback for notification of DtUserTask tasks. virtual void registerTaskMsgCallbacks(); //Callback function (registered in registerTaskMsgCallbacks()) for //DtRetreat task messages. Calls processRetreatTask() to actually handle //the task. static void retreatTaskCallback(DtSimMessage * msg, void * usr); //Callback function (registered in registerTaskMsgCallbacks()) for //DtUserTask messages. Calls processUserTask() to actually handle //the task. static void userTaskCallback(DtSimMessage * msg, void * usr); //Called by retreatTaskCallback() when a new DtRetreatTask message is //received. virtual void processRetreatTask(DtSimMessage * msg); //Called by userTaskCallback() when a new DtRetreatTask message is //received. virtual void processUserTask(DtSimMessage * msg); //Update control values virtual void tick(); //This is called by the factory static DtSimComponent* creator(const DtString & name, DtVrfObject* owner, DtSimManager * simManager, DtComponentDescriptor* desc, DtReaderWriterRegistry * parentRegistry); //Determine which way to flee based on the current target virtual double getHeading(); //Returns the amount of fuel left. If no fuel left, can no longer retreat virtual double fuelLeft() const; protected: DtReal myCurrentHeading; //determined by DtUserTask arg1, see above bool myHoldGround; };
/******************************************************************************* ** Copyright (c) 2003 MAK Technologies, Inc. ** All rights reserved. *******************************************************************************/ /******************************************************************************* ** $RCSfile: retreatCtrl.cxx,v $ $Revision: 1.3 $ $State: Exp $ *******************************************************************************/ // //class DtRetreatController // #include "retreatCtrl.h" #include "vrfobjcore/compTypes.h" #include "vrfobjcore/conAnalogIOPort.h" #include "vrfobjcore/conIntegerIOPort.h" #include "vrfcore/exClock.h" #include "vrfcore/simMgr.h" #include "vrfobjcore/simRadio.h" #include "vrftasks/taskTypes.h" #include "vrfmsgs/taskMsg.h" #include "vrftasks/userTask.h" #include "retreatTask.h" #include "vrfobjcore/outputPortGroup.h" #include "vrfobjcore/vrfObject.h" #include "vrfobjcore/vrfObjSR.h" #include "vrfobjcore/vrfObjMgr.h" #include "vrfobjcore/weaponPSR.h" #include "vrfutil/rsrcTypes.h" #include "vrfutil/intRsrc.h" #include "vrfutil/realRsrc.h" #include "vrfobjcore/gndVehSR.h" //constructor DtRetreatController::DtRetreatController(const DtString & name, DtVrfObject* owner, DtSimManager * simManager, DtComponentDescriptor* desc, DtReaderWriterRegistry * parentRegistry) : DtGroundAutoControllerComponent(name, owner, simManager, desc, parentRegistry) { myHoldGround = false; } //destructor DtRetreatController::~DtRetreatController() { } //[The type function] DtString DtRetreatController::type() const { //Defined in retreatCtlr.h return TestRetreatControllerType; } //[The type function] //[Registering a callback] void DtRetreatController::registerTaskMsgCallbacks() { //Register for any task messsages required by the base class DtSingleTaskControllerComponent::registerTaskMsgCallbacks(); //Specify the task type, the callback function, and user data. addTaskProcessorCallback(DtUserTaskType, userTaskCallback, (void *) this); //Specify the task type, the callback function, and user data. addTaskProcessorCallback(DtRetreatTaskType, retreatTaskCallback, (void *) this); } void DtRetreatController::retreatTaskCallback(DtSimMessage * msg, void * usrData) { DtRetreatController * controller = (DtRetreatController *) usrData; if (controller) { //Call processRetreatTask to handle the incoming retreat task message. controller->processRetreatTask(msg); } } void DtRetreatController::userTaskCallback(DtSimMessage * msg, void * usrData) { DtRetreatController * controller = (DtRetreatController *) usrData; if (controller) { //Call processUserTask to handle the incoming user task message. controller->processUserTask(msg); } } //[Registering a callback] //[Checking the task name] void DtRetreatController::processRetreatTask(DtSimMessage * msg) { if (msg) { //Retrieve the task from the task message. DtTaskMessage * tm = (DtTaskMessage *) msg; DtRetreatTask * retreatTask = (DtRetreatTask *) tm->task(); //Check to see if the task is a user-defined retreat task. This //is the string that is matched against the User Task dialog. if(retreatTask->retreatKind() == "hold-ground") { myHoldGround = true; }; } } void DtRetreatController::processUserTask(DtSimMessage * msg) { if (msg) { //Retrieve the task from the task message. DtTaskMessage * tm = (DtTaskMessage *) msg; DtUserTask * userTask = (DtUserTask *) tm->task(); //Check to see if the task is a user-defined retreat task. This //is the string that is matched against the User Task dialog. if(userTask->userTaskName() != "retreat") { taskComplete(false); return; } //Extract parameters from arguments if (userTask->arg1Text() == "hold ground") { myHoldGround = true; }; } } //[Checking the task name] double DtRetreatController::fuelLeft() const { const DtSimResource *resource = resourceManager().lookupResource("fuel"); if (resource) { DtString resourceType = resource->type(); if (resourceType == DtRealResourceType) { const DtRealResource * realResource = (const DtRealResource *)resource; return realResource->amount(); } else if (resourceType == DtIntegerResourceType) { const DtIntegerResource * intResource = (const DtIntegerResource *)resource; return (double) intResource->amount(); } } //have plenty... return 1.0E8; } //calculate new control values void DtRetreatController::tick() { double dT = mySimManager->exerciseClock()->dT(); if (tasked() && (dT > 0.0) && myAutomotiveControlPortGroup->attemptToActivate()) { double targetHeading = getHeading(); double localHeading = entity()->vrfState()->localOrientation().psi(); mySteeringPort->setValue(calculateSteering(localHeading, targetHeading)); //if tasked to hold ground, don't start running until under fire if ((!myHoldGround || entity()->vrfState()->underFire()) && fuelLeft()) { myThrottlePort->setValue(1.0); myBrakePort->setValue(0.0); } else { myThrottlePort->setValue(0.0); myBrakePort->setValue(1.0); } } } DtSimComponent* DtRetreatController::creator(const DtString& name, DtVrfObject* owner, DtSimManager* simManager, DtComponentDescriptor* desc, DtReaderWriterRegistry* parentRegistry) { return new DtRetreatController(name, owner, simManager, desc, parentRegistry); } double DtRetreatController::getHeading() { DtVector myPos; DtVector targetPos; DtVector vectorFromEntityToTarget; DtEntityIdentifier targetId = myLocalStateRepository->firstWeaponPSR()-> currentTarget(); DtVrfObject* target = mySimManager->vrfObjectManager()->lookupVrfObject(targetId); if (target == NULL) { return myLocalStateRepository->currentHeading(); } myPos = myLocalStateRepository->localPosition(); targetPos = target->vrfState()->localPosition(); DtVecSub(targetPos, myPos, vectorFromEntityToTarget); myCurrentHeading = atan2(vectorFromEntityToTarget[0], vectorFromEntityToTarget[1]) + 3.14; return myCurrentHeading; }