VR-Link API Documentation for HLA 1.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Vehicle Sim

The class DtVehicleSim is responsible for simulating the Aircraft.


Header file:

/*******************************************************************************
** Copyright (c) 1992-2012 VT MAK
** All rights reserved.
*******************************************************************************/
#pragma once
#include <vl/topoView.h>
{
public:
DtVehicleSim( double refLat, double refLon,
const DtEntityIdentifier& id, const DtEntityType& type,
const char* name, const char* markings,
const DtDeadReckonTypes alg, bool haveArtParts,
DtTime timeSpacing);
virtual ~DtVehicleSim();
virtual void init( DtConstVector initPos, double initSpeed,
double initHeading, double initTRadius,
double initPitch, bool autoRoll, double initRoll, int num );
virtual void simulate();
virtual void fireMunition( const DtGlobalObjectDesignator& tg );
virtual void fireMunition();
virtual void detonateMunition();
virtual void munitionUpdate();
virtual void reactToDetonation();
virtual int checkDetonation();
virtual void reactToDamage();
virtual bool isDestroyed();
virtual DtTime timeDestroyed();
virtual void toggleEmissions();
virtual void enableEmissions();
virtual void disableEmissions();
virtual void emissionsUpdate();
public:
// Set the current detonation for reaction.
static void setLethalDetonationRange( double range );
static void setMunitionFlightTime( DtTime time );
// set the delta time for next simTick update
static void setSimDeltaTime(DtTime theDt) { myDt = theDt; }
protected:
// delta time for next simTick update
static DtTime myDt;
// Current detonation, if any.
protected:
virtual void moveArtParts();
protected:
float mySpeed;
float myTurnRadius;
float myTurnRate;
double myBeamTime;
float myTurretAz;
float myGunElev;
protected:
static double theLethalDetonationRange;
};

Implementation:

/*******************************************************************************
** Copyright (c) 1992-2012 VT MAK
** All rights reserved.
*******************************************************************************/
#include "vehicleSim.h"
#include <vlutil/vlUtil.h>
#include <vlutil/vlPrint.h>
#ifndef effZero
#define effZero 1.0E-30
#endif
// delta time for next simTick update
DtVehicleSim::DtVehicleSim( double refLat, double refLon,
const DtEntityIdentifier& id, const DtEntityType& type,
const char* name, const char* markings,
const DtDeadReckonTypes alg, bool haveArtParts,
DtObjectPublisherContainer &pubContainer, DtTime timeSpacing) :
myTimeSpacing(timeSpacing),
myPublishedObjects(pubContainer),
mySysPub( 0 )
{
myExConn = conn;
#if DtHLA
myEntityPub = new DtEntityPublisher( type, conn, name );
#elif DtDIS
myEntityPub = new DtEntityPublisher( type, conn, id );
#else
#error "Please Choose Protocol!"
#endif
// Add object to collection for later publication (in parallel)
myPublishedObjects.add(myEntityPub);
myESR = myEntityPub->entityStateRep();
myESR->setEntityType( type );
myESR->setGuise( type );
myESR->setMarkingText( markings );
myESR->setForceId( DtForceFriendly );
myESR->setAlgorithm( alg );
myESR->setEntityId( id );
myTopoView = new DtTopoView( myESR, refLat, refLon );
myRel = rel;
myFire = 0;
myDetonateTime = 0.0;
myTimeDestroyed = -1.0;
myIsDestroyed = false;
myEmissionsEnabled = false;
myHaveArtParts = haveArtParts;
}
{
}
void DtVehicleSim::init( DtConstVector initPos, double initSpeed,
double initHeading, double initTRad,
double initPitch, bool autoRoll, double initRoll, int num)
{
myPos = initPos;
mySpeed = initSpeed;
myTurnRadius = initTRad;
myTurnRate = ( ( initTRad != 0.0 ) ? ( initSpeed / initTRad ) : 0.0 );
// hack to make roll roughly proportional to turnRate for rates
// about 1/5 rad/sec
double roll = ( autoRoll ) ?
atan( 5.0 * myTurnRate ) : DtDeg2Rad( initRoll );
myEuler = DtTaitBryan( DtDeg2Rad( initHeading ),
DtDeg2Rad( initPitch ), roll );
float psi = myEuler.psi();
float cosPsi = cos( psi );
float sinPsi = sin( psi );
float phi = myEuler.phi();
float cosPhi = cos( phi );
float sinPhi = sin( phi );
myVel = DtVector32( cosPsi * mySpeed, sinPsi * mySpeed, 0.0 );
float timeOffset = (float)myTimeSpacing * (float)num;
for (int i = 0; i < 3; i++)
{
myPos[i] += myVel[i] * timeOffset;
}
// force a constant rate turn
myAccel = DtVector32( -myScalarAccel * sinPsi, myScalarAccel * cosPsi, 0.0 );
myRotRate = DtVector32( 0.0, sinPhi * myTurnRate, cosPhi * myTurnRate );
myTurretAz = 0.0;
myGunElev = 0.0;
{
DtArticulatedPart& turret = artPartList->getPart(DtPrimaryTurret1);
DtArticulatedPart& gun = artPartList->getPart(DtPrimaryGun1);
artPartList->attachPart(&gun, &turret);
}
}
{
// Update kinematic position, velocity, acceleration and orientation
double psi = DtModPerZero( ( myEuler.psi() + ( myTurnRate * myDt ) ), M_2PI );
myEuler.setPsi( psi );
for( int i=0; i<3; ++i )
{
myPos[i] += ( myVel[i] + 0.5 * myAccel[i] * myDt ) * myDt;
myVel[i] += myAccel[i] * myDt;
}
myAccel[0] = -myScalarAccel * sin( psi );
myAccel[1] = myScalarAccel * cos( psi );
myAccel[2] = 0.0;
// Simulate articulated parts, if any.
{
}
// Now that we're done simulating, tell the entity publisher
// about our current state:
// Simulate subsystems
munitionUpdate(); // Simulate munitions created by this vehicle, if any.
emissionsUpdate(); // Simulate emissions from this vehicle, if any.
}
{
DtClock* clock = myExConn->clock();
if ( clock->simTime() >= 2.0)// && clock->simTime() <= 10.0 )
{
}
else
{
}
if ( clock->simTime() >= 2.0)// && clock->simTime() <= 20.0 )
{
}
else
{
}
myGunElev = myGunElev + myGunElevRate * (float) myDt;
}
{
theDetonation = detonation;
}
{
if ( checkDetonation() )
{
}
}
{
double distance;
switch( theDetonation->result() )
{
{
{
DtInfo << "Direct hit! Going down!" << std::endl;
return 1;
}
}
// fall through
{
if ( distance < theLethalDetonationRange )
{
DtInfo << "Indirect hit only " << distance << " m away! Going down!"
<< std::endl;
return 1;
}
else
{
return 0;
}
}
default:
{ // ignore it
return 0;
}
}
}
{
myVel = DtVector32( 0.0, 0.0, 0.0 );
myAccel = DtVector32( 0.0, 0.0, 0.0 );
myRotRate = DtVector32( 0.0, 0.0, 0.0 );
myTurnRate= 0.0;
mySpeed = 0.0;
myIsDestroyed = true;
}
{
{
DtInfo << "Emissions enabled." << std::endl;
// Create emitter system
// Add it to publications
// Attach emitter system to entity
DtVector32 vec( 6.4f, 0.0, 0.0 );
// Create beam
myBeam = mySysPub->esr()->addBeam( 1 );
#if DtHLA
// HLA Only - In DIS a beam is not a separate object and
// also an emittingSystemID would be just an integer...
#endif
myBeam->setFrequency( 8999999488.000000 );
myBeam->setERP( 70 );
myBeam->setAzimuthSweep( 0.0523599f );
myBeam->setElevationCenter( 0.349066f );
myBeam->setElevationSweep( 0.523599f );
myBeamTime = 0.0;
}
}
{
{
DtInfo << "Emissions disabled." << std::endl;
// Remove it from publications
}
}
{
{
}
else
{
}
}
{
{
// Update beam
float beamAngle = (float)cos( myBeamTime );
myBeam->setAzimuthCenter( beamAngle );
}
}
// return the vehicle that is nearest to ours
static DtReflectedEntity* nearestEntity( const DtObjectId& me,
{
DtReflectedEntity* nearest = 0;
double minDistSqr = 0.0;
// Loop through the entities in the rel
for( DtReflectedEntity* entity = rel->first();
entity;
entity = entity->next() )
{
if ( entity->id() == me ) continue;
double distSqr = DtDistSqr(
entity->entityStateRep()->location(), geocPos );
if ( distSqr < minDistSqr || !nearest )
{
nearest = entity;
minDistSqr = distSqr;
}
}
return nearest;
}
{
DtReflectedEntity* nearest = nearestEntity(
if ( nearest )
{
fireMunition( nearest->globalId() );
}
}
{
if ( myFire )
{
return;
}
myFire->setRange( 1000.0 );
myFire->setRate( 0 );
#if DtHLA
#endif
DtSidewinder, 0, 0 ) );
DtInfo << "Sending fire interaction" << std::endl;
}
{
if ( !myFire )
{
return;
}
// Sidewinder Missile
DtEntityType sidewinder(2,1,255,1,1,3,0);
det.setMunitionType(sidewinder);
det.setTargetId(myFire->targetId());
det.setVelocity( DtVector32( 0.0, 0, 0 ) );
det.setEntityLocation( DtVector32( 0.0, 0.0, 0.0 ) );
if ( ent )
{
// Get vector from fire location to detonation location
DtVector difference = myFire->location() - ent->esr()->location();
// Velocity = Distance / Time
DtVector32 velocity;
velocity.setX(difference.x() / theMunitionFlightTime);
velocity.setY(difference.y() / theMunitionFlightTime);
velocity.setZ(difference.z() / theMunitionFlightTime);
det.setVelocity(velocity);
det.setWorldLocation( ent->entityStateRep()->location() );
det.setResult( DtDetResEntityImpact );
}
else
{
// just detonate 1000 meters under us.
det.setVelocity(DtVector32(0.0, 0.0, 1000.0f / theMunitionFlightTime));
det.setWorldLocation( DtVector( myPos[0], myPos[1], myPos[2] + 1000.0 ) );
det.setResult( DtDetResDetonation );
}
DtInfo << "Sending detonation interaction" << std::endl;
}
{
{
}
}
{
return myIsDestroyed;
}
{
}
{
}
{
}

Document ID: Generated on Mon Jun 22 21:18:40 EDT 2020 from SVN revision 213785
Copyright © 2005-2018 MAK Technologies. All Rights Reserved (www.mak.com)