Ejemplo n.º 1
0
//------------------------------------------------------------------------------
// irRequestSignature() -- Send an IR query packet at all active players to request an IR signature
//------------------------------------------------------------------------------
void IrSeeker::irRequestSignature(IrQueryMsg* const irQuery)
{
   // Need something to store the required data for the IR signatures and someone to send to

   Tdb* tdb0 = getCurrentTDB();
   Player* ownship = getOwnship();
   if (irQuery == 0 || tdb0 == 0 || ownship == 0) {
      // Clean up and leave
      if (tdb0 != 0) tdb0->unref();
      return;
   }

   // ---
   // Compute gimbal boresight data for our targets
   // ---

   // FAB - cannot use ownHdgOnly
   unsigned int ntgts = tdb0->computeBoresightData();
   if (ntgts > MAX_PLAYERS) ntgts = MAX_PLAYERS;

   // ---
   // If we have targets
   // ---
   const osg::Vec3d* losG = tdb0->getGimbalLosVectors();
   if (ntgts > 0 && losG != 0) {

      // Fetch the required data arrays from the TargetDataBlock
      const double* ranges = tdb0->getTargetRanges();
      const double* rngRates = tdb0->getTargetRangeRates();
      const double* anglesOffBoresight = tdb0->getBoresightErrorAngles();
      const osg::Vec3d* losO2T = tdb0->getLosVectors();
      const osg::Vec3d* losT2O = tdb0->getTargetLosVectors();
      Player** targets = tdb0->getTargets();
      LCreal maximumRange = irQuery->getMaxRangeNM()*Basic::Distance::NM2M;

      // ---
      // Send query packets to the targets
      // ---
      for (unsigned int i = 0; i < ntgts; i++) {

         // filter on sensor max range 
         // can't filter on sensor range in processPlayers - different sensors can have different max range
         if (maximumRange > 0.0 && ranges[i] > maximumRange)
            continue;

         // Get a free query packet
         lcLock(freeQueryLock);
         IrQueryMsg* query = freeQueryStack.pop();
         lcUnlock(freeQueryLock);

         if (query == 0) { 
            query = new IrQueryMsg();
            //if (ownship->getID() != 1) {
            //    static tcnt = 0;
            //    tcnt++;

            //if (isMessageEnabled(MSG_INFO)) {
            //    std::cout << "new IrQueryMsg(" << this << "): " << tcnt << ", inused: " << inUseEmQueue.entries() << ", em = " << em << std::endl;
            //}

            //}
         }

         // Send the IR query message to the other player
         if (query != 0) {

            // a) Copy the template query msg
            *query = *irQuery;

            // b) Set target unique data
            query->setGimbal(this);
            query->setOwnship(ownship);

            query->setRange( LCreal(ranges[i]) );
            query->setLosVec( losO2T[i] );
            query->setTgtLosVec( losT2O[i] );
            query->setRangeRate( LCreal(rngRates[i]) );
            query->setTarget(targets[i]);
            query->setAngleOffBoresight( LCreal(anglesOffBoresight[i]) );

            query->setGimbalAzimuth( LCreal(getAzimuth()) );
            query->setGimbalElevation( LCreal(getElevation()) );

            // c) Send the query to the target
            targets[i]->event(IR_QUERY, query);

            // d) Dispose of the query
            if (query->getRefCount() <= 1) {
               // Recycle the query packet
               query->clear();
               lcLock(freeQueryLock);
               if (freeQueryStack.isNotFull()) {
                  freeQueryStack.push(query);
               }
               else {
                  query->unref();
               }
               lcUnlock(freeQueryLock);
            }
            else {
               // Store for future reference
               lcLock(inUseQueryLock);
               if (inUseQueryQueue.isNotFull()) {
                  inUseQueryQueue.put(query);
               }
               else {
                  // Just forget it
                  query->unref();
               }
               lcUnlock(inUseQueryLock);
            }
         }
         else {
            // When we couldn't get a free query packet
            if (isMessageEnabled(MSG_WARNING)) {
               std::cerr << "Iw Seeker: OUT OF Query messages!" << std::endl;
            }
         }
      }
   }

   // Unref() the TDB
   tdb0->unref();
}