Ejemplo n.º 1
0
//------------------------------------------------------------------------------
// updateData() -
//------------------------------------------------------------------------------
void Adi::updateData(const LCreal dt)
{
    // update our base class first
    BaseClass::updateData(dt);

    // drive our adi toward the actual pitch, from our current pitch, no faster
    // than our MAX_RATE (this allows for greater fidelity, simulates an analog adi)
    LCreal delta = 0;
    delta = alim (lcAepcDeg(pitch - curTheta), maxRate * dt);
    curTheta = lcAepcDeg(curTheta + delta);

    // now do the same thing for roll
    delta = alim (lcAepcRad(roll - curPhi), maxRate * dt);
    curPhi = lcAepcRad(curPhi + delta);

    // get our table, and do the linear interpolation ourself
    setInstVal(curTheta);
    scaledPitch = getInstValue();
}
Ejemplo n.º 2
0
//------------------------------------------------------------------------------
// updateData() - updates our non time-critical threads here
//------------------------------------------------------------------------------
void BearingPointer::updateData(const LCreal dt)
{
    // update our base class first
    BaseClass::updateData(dt);
    
    // get our heading and bearing (hopefully they are in radians, if not, the
    // calculation will be skewed
    LCreal hdg = getRotationRad();
    
    // stay between +- 3.14 radians
    bearing = lcAepcRad(bearing - hdg);
    LCreal dbrg = lcAepcRad(myRotation - bearing);
    
    // if we are over the max, rotate the other way
    LCreal dd0 = dbrg * dt;
    LCreal maxdd0 = (90.0f * (LCreal) Basic::Angle::D2RCC) * dt;      // Limit to 90 degs/sec
    if (dd0 < -maxdd0) dd0 = -maxdd0;
    if (dd0 > maxdd0) dd0 = maxdd0;
    bearing += dd0;
    
    myRotation = bearing;
}
Ejemplo n.º 3
0
//------------------------------------------------------------------------------
// Process players-of-interest --- Scan the provided player list and compute range,
// range rate, normalized Line-Of-Sight (LOS) vectors for each target player.
// (Background task)
//------------------------------------------------------------------------------
unsigned int TdbIr::processPlayers(Basic::PairStream* const players)
{
   // Clear the old data
   clearArrays();

   // ---
   // Early out checks (no ownship, no players of interest, no target data arrays)
   // ---
   if (gimbal == 0 || ownship == 0 || players == 0 || maxTargets == 0) return 0;
    
   //const Basic::Pair* p = ((Player*)ownship)->getIrSystemByType( typeid(IrSensor) );
   //if (p == 0) return 0;

   // FAB - refactored
   //const IrSensor* irSensor = (const IrSensor*)( p->object() );
   //if (irSensor == 0) 
      //return 0;

   // FAB - limit is +/- (1/2 FORtheta + 1/2 IFOVtheta) (but both get..Theta() actually return 1/2 Theta)		   
   //LCreal fieldOfRegardTheta = irSensor->getFieldOfRegardTheta() + irSensor->getIFOVTheta();
   //LCreal maxRange = irSensor->getMaximumRange();

   // FAB - basically the same as TDB/gimbal version:
   const double maxRange = gimbal->getMaxRange2PlayersOfInterest();
   const double maxAngle = gimbal->getMaxAngle2PlayersOfInterest();

   // ---
   // Get our position and velocity vectors
   // ## using ownship position for now; should include the location of the gimbal ##
   // ---
   osg::Vec3 p0 = ownship->getPosition();  // Position Vector
   osg::Vec3 v0 = ownship->getVelocity();  // Ownship Velocity Vector

   // ---
   // 1) Scan the player list --- compute the normalized Line-Of-Sight (LOS) vectors,
   // range, and range rate for each target.
   // ---
   for (Basic::List::Item* item = players->getFirstItem(); item != 0 && numTgts < maxTargets; item = item->getNext()) {

      
      // Get the pointer to the target player
      Basic::Pair* pair = (Basic::Pair*)(item->getValue());
      Player* target = (Player*)(pair->object());

     // FAB - testing - exclude our launch vehicle in tdb
     //if (ownship->isMajorType(Player::WEAPON) && ((Weapon*)ownship)->getLaunchVehicle() == target)
     //continue;

      if (target != ownship && target->isActive()) {
         bool aboveHorizon = true; 
         aboveHorizon = horizonCheck (ownship->getPosition(), target->getPosition());

         // FAB - refactored - don't continue if we know we're excluding this target
         if (!aboveHorizon) continue;

         // Determine if target is within azimuth and elevation checks. If it is, keep it.
         // Otherwise, reject.

         osg::Vec3 targetPosition = target->getPosition();
         osg::Vec3 losVector = targetPosition - p0;
         //osg::Vec3 xlos = -losVector;
       LCreal aazr;
       LCreal aelr;
       LCreal ra;

      if (irSensor->getSeeker()->getOwnHeadingOnly()) {
         // FAB - this calc for gimbal ownHeadingOnly true
         // compute ranges
         LCreal gndRng2 = losVector.x()*losVector.x() + losVector.y()*losVector.y();
         ra = lcSqrt(gndRng2);
         
         // compute angles
         LCreal los_az = lcAtan2(losVector.y(),losVector.x());
         double hdng = ownship->getHeadingR();
         aazr = lcAepcRad(los_az - (float)hdng);
         aelr = lcAtan2(-losVector.z(), ra);
      }
      else {
         // FAB - this calc for gimbal ownHeadingOnly false
         //osg::Vec4 los0( losVector.x(), losVector.y(), losVector.z(), 0.0 );
         //osg::Vec4 aoi = ownship->getRotMat() * los0;
         osg::Vec3 aoi = ownship->getRotMat() * losVector;
         // 3) Compute the azimuth and elevation angles of incidence (AOI)

         // 3-a) Get the aoi vector values & compute range squared
         LCreal xa = aoi.x();
         LCreal ya = aoi.y();
         LCreal za = -aoi.z();

         ra = lcSqrt(xa*xa + ya*ya);
         // 3-b) Compute azimuth: az = atan2(ya, xa)
         aazr = lcAtan2(ya, xa);
         // 3-c) Compute elevation: el = atan2(za, ra), where 'ra' is sqrt of xa*xa & ya*ya
         aelr = lcAtan2(za,ra);
      }

         LCreal absoluteAzimuth = aazr; 

         if (aazr < 0) absoluteAzimuth = -aazr; 

         LCreal absoluteElevation = aelr;
         if (aelr < 0) absoluteElevation = -aelr;

         bool withinView = true; 

      //   LCreal fieldOfRegardTheta = 0;
      //   LCreal sensorMaxRange = 0;
      //   {
      //      //const Basic::Pair* p = ((Player*)ownship)->getIrSystemByType( typeid(IrSensor) );
      //      //if (p != 0) {
      //         //const IrSensor* irSensor = (const IrSensor*)( p->object() );
      //         // fieldOfRegardTheta = irSensor->getFieldOfRegardTheta();
          //// FAB - limit is +/- (1/2 FORtheta + 1/2 IFOVtheta) (but both get..Theta() actually return 1/2 Theta)
          //fieldOfRegardTheta = irSensor->getFieldOfRegardTheta() + irSensor->getIFOVTheta();
      //         sensorMaxRange = irSensor->getMaximumRange();
      //      //}
      //   }

         if ((absoluteAzimuth > maxAngle) ||  // outside field of view
            (absoluteElevation > maxAngle) ||
            (ra > maxRange) ||    // beyond max range of sensor
            !aboveHorizon)
            withinView = false; 
 
         if (withinView) {

            // Ref() and save the target pointer
            // (## It must be unref()'d by the owner/manager of the Tdb array ##)
            target->ref();
            targets[numTgts] = target;

          // FAB - these seem to be unnecessary - recalc'd by Tdb::computeBoresightData anyway
            // Line-Of-Sight (LOS) vector (world)
            //losO2T[numTgts] = target->getPosition() - p0;

            // Normalized and compute length [unit vector and range(meters)]
            //ranges[numTgts] = losO2T[numTgts].normalize();

            // Computer range rate (meters/sec)
            //rngRates[numTgts] = (LCreal) ((target->getVelocity() - v0) * losO2T[numTgts]);

            // Save the target pointer (for quick access)
            numTgts++;
         }
      } //(target != ownship && target->isActive())
   }

   return numTgts;
}
Ejemplo n.º 4
0
void LifeForm::look(const LCreal up, const LCreal sdws)
{
    if (getDamage() < 1) {
        if (lockMode != LOCKED) {
            lockMode = SEARCHING;
            // our up and sideways come in as -5 to 5, which is a rate to adjust heading
            const osg::Vec3 old = getEulerAngles();
            LCreal hdg = old.z();
            LCreal ptc = lookAngle;
            LCreal tempSdws = sdws;
            LCreal tempUp = up;
            if (lcAbs(tempSdws) < 0.00005) tempSdws = 0;
            if (lcAbs(tempUp) < 0.05) tempUp = 0;
            hdg += tempSdws;
            hdg = lcAepcRad(hdg);
            // we don't change our pitch when we look up and down, we only change our look angle, so we have to keep
            // that separate.  WE do, however, change our heading based on where we are looking, so that is correct
            ptc += tempUp;
            if (ptc > 90) ptc = 90;
            else if (ptc < -90) ptc = -90;
            //std::cout << "HEADING = " << hdg << std::endl;
            setLookAngle(ptc);
            osg::Vec3 eul(0, 0, hdg);
            setEulerAngles(eul);
            // now based on this we need to know if we have a target in our crosshairs...
            tgtAquired = false;
            if (tgtPlayer != nullptr) tgtPlayer->unref();
            tgtPlayer = nullptr;
            const osg::Vec3 myPos = getPosition();
            osg::Vec3 tgtPos;
            osg::Vec3 vecPos;
            LCreal az = 0.0, el = 0.0, range = 0.0, diffAz = 0.0, diffEl = 0.0;
            const LCreal maxAz = (0.7f * static_cast<LCreal>(Basic::Angle::D2RCC));
            const LCreal maxEl = (0.7f * static_cast<LCreal>(Basic::Angle::D2RCC));
            //LCreal maxRange = 1500.0f; // long range right now
            const LCreal la = lookAngle * static_cast<LCreal>(Basic::Angle::D2RCC);
            Simulation* sim = getSimulation();
            if (sim != nullptr) {
                Basic::PairStream* players = sim->getPlayers();
                if (players != nullptr) {
                    Basic::List::Item* item = players->getFirstItem();
                    while (item != nullptr && !tgtAquired) {
                        Basic::Pair* pair = static_cast<Basic::Pair*>(item->getValue());
                        if (pair != nullptr) {
                            Player* player = dynamic_cast<Player*>(pair->object());
                            if (player != nullptr && player != this && !player->isMajorType(WEAPON) && !player->isDestroyed()) {
                                // ok, calculate our position from this guy
                                tgtPos = player->getPosition();
                                vecPos = tgtPos - myPos;
                                az = lcAtan2(vecPos.y(), vecPos.x());
                                range = (vecPos.x() * vecPos.x() + vecPos.y() * vecPos.y());
                                range = std::sqrt(range);
                                // now get our elevation
                                el = lcAtan2(-vecPos.z(), range);
                                diffAz = lcAbs(lcAepcRad(az - static_cast<LCreal>(getHeadingR())));
                                diffEl = lcAbs(lcAepcRad(la - el));
                                if ((diffAz <= maxAz) && (diffEl <= maxEl)) {
                                    lockMode = TGT_IN_SIGHT;
                                    tgtAquired = true;
                                    if (tgtPlayer != player) {
                                        if (tgtPlayer != nullptr) tgtPlayer->unref();
                                        tgtPlayer = player;
                                        tgtPlayer->ref();
                                    }
                                }
                            }
                        }
                        item = item->getNext();
                    }
                    players->unref();
                    players = nullptr;
                }
            }
        }
        // else we are locking on target, and need to follow our target player
        else {
            if (tgtPlayer == nullptr) lockMode = SEARCHING;
            else {
                const osg::Vec3 vecPos = tgtPlayer->getPosition() - getPosition();
                const LCreal az = lcAtan2(vecPos.y(), vecPos.x());
                LCreal range = (vecPos.x() * vecPos.x() + vecPos.y() * vecPos.y());
                range = std::sqrt(range);
                // now get our elevation
                const LCreal el = lcAtan2(-vecPos.z(), range);
                // now force that on us
                setLookAngle(el * static_cast<LCreal>(Basic::Angle::R2DCC));
                setEulerAngles(0, 0, az);
            }
        }
    }
}
Ejemplo n.º 5
0
//------------------------------------------------------------------------------
// weaponDynamics -- default missile dynamics; using Robot Aircraft (RAC) dynamics
//------------------------------------------------------------------------------
void Missile::weaponDynamics(const LCreal dt)
{
   static const LCreal g = ETHG;              // Acceleration of Gravity

   // ---
   // Max turning G (Missiles: Use Gmax)
   // ---
   LCreal gmax = maxG;

   // ---
   // Computer max turn rate, max/min pitch rates
   // ---

   // Turn rate base on vp and g,s
   LCreal ra_max = gmax * g / getTotalVelocity();

   // Set max (pull up) pitch rate same as turn rate
   LCreal qa_max = ra_max;

   // Set min (push down) pitch rate
   LCreal qa_min = -qa_max;

   // ---
   // Get old angular values 
   // ---
   const osg::Vec3 oldRates = getAngularVelocities();
   //LCreal pa1 = oldRates[IROLL];
   LCreal qa1 = oldRates[IPITCH];
   LCreal ra1 = oldRates[IYAW];

   // ---
   // Find pitch rate and update pitch
   // ---
   LCreal qa = lcAepcRad(cmdPitch - (LCreal) getPitchR());
   if(qa > qa_max) qa = qa_max;
   if(qa < qa_min) qa = qa_min;

   // Using Pitch rate, integrate pitch
   LCreal newTheta = (LCreal) (getPitch() + (qa + qa1) * dt / 2.0);

   // Find turn rate
   LCreal ra = lcAepcRad(cmdHeading - (LCreal) getHeadingR());
   if(ra > ra_max) ra = ra_max;
   if(ra < -ra_max) ra = -ra_max;

   // Use turn rate integrate heading
   LCreal newPsi = (LCreal) (getHeading() + (ra + ra1) * dt / 2.0);
   if(newPsi > 2.0f*PI) newPsi -= (LCreal)(2.0*PI);
   if(newPsi < 0.0f) newPsi += (LCreal)(2.0*PI);

   // Roll angle proportional to max turn rate - filtered
   LCreal pa = 0.0;
   LCreal newPhi = (LCreal) ( 0.98 * getRollR() + 0.02 * ((ra / ra_max) * (Basic::Angle::D2RCC * 60.0)) );

   // Sent angular values
   setEulerAngles(newPhi, newTheta, newPsi);
   setAngularVelocities(pa, qa, ra);

   // Find Acceleration
   LCreal vpdot = (cmdVelocity - getTotalVelocity());
   if(vpdot > maxAccel)  vpdot = maxAccel;
   if(vpdot < -maxAccel) vpdot = -maxAccel;

   // Set acceleration vector
   osg::Vec3 aa(vpdot, 0.0, 0.0);
   osg::Vec3 ae = aa * getRotMat();
   setAcceleration(ae);

   // Comute new velocity
   LCreal newVP = getTotalVelocity() + vpdot * dt;

   // Set acceleration vector
   osg::Vec3 ve0 = getVelocity();
   osg::Vec3 va(newVP, 0.0, 0.0);
   osg::Vec3 ve1 = va * getRotMat();
   setVelocity(ve1);
   setVelocityBody(newVP, 0.0, 0.0);
}