コード例 #1
0
ファイル: IrSeeker.cpp プロジェクト: azcbuell/OpenEaagles
//------------------------------------------------------------------------------
// process() -- Process phase
//------------------------------------------------------------------------------
void IrSeeker::process(const LCreal dt)
{
   BaseClass::process(dt);

   // ---
   // Update IR query queues: from 'in-use' to 'free' 
   // ---
   lcLock(inUseQueryLock);
   int n = inUseQueryQueue.entries();
   for (int i = 0; i < n; i++) {
      IrQueryMsg* query = inUseQueryQueue.get();
      if (query != 0) {
         if (query->getRefCount() <= 1) {
            // No one else is referencing the query, push on free stack
            query->clear();
            lcLock(freeQueryLock);
            if (freeQueryStack.isNotFull()) {
               freeQueryStack.push(query);
            }
            else {
               query->unref();
            }
            lcUnlock(freeQueryLock);
         }
         else {
            // Others are still referencing the query, put back on in-use queue
            inUseQueryQueue.put(query);
         }
      }
   }
   lcUnlock(inUseQueryLock);
}
コード例 #2
0
ファイル: Radio.cpp プロジェクト: jmc734/OpenEaagles
//------------------------------------------------------------------------------
// receive() -- process received emissions
//------------------------------------------------------------------------------
void Radio::receive(const LCreal dt)
{
   BaseClass::receive(dt);

   // Receiver losses
   LCreal noise = getRfRecvNoise();

   // ---
   // Process Emissions
   // ---

   Emission* em = nullptr;
   LCreal signal = 0;

   // Get an emission from the queue
   lcLock(packetLock);
   if (np > 0) {
      np--; // Decrement 'np', now the array index
      em = packets[np];
      signal = signals[np];
   }
   lcUnlock(packetLock);

   while (em != nullptr) {


      // Signal/Noise  (Equation 2-9)
      LCreal sn = signal / noise;
      LCreal snDbl = 10.0 * lcLog10(sn);

      // Is S/N above receiver threshold?
      if ( snDbl >= getRfThreshold() ) {
         // Report this valid emission to the radio model ...
         receivedEmissionReport(em);
      }

      em->unref();
      em = nullptr;

      // Get another emission from the queue
      lcLock(packetLock);
      if (np > 0) {
         np--;
         em = packets[np];
         signal = signals[np];
      }
      lcUnlock(packetLock);
   }
}
コード例 #3
0
ファイル: IrSeeker.cpp プロジェクト: azcbuell/OpenEaagles
//------------------------------------------------------------------------------
// clearQueues() -- clear out all queues
//------------------------------------------------------------------------------
void IrSeeker::clearQueues()
{
   lcLock(freeQueryLock);
   IrQueryMsg* query = freeQueryStack.pop();
   while (query != 0) {
      query->unref();
      query = freeQueryStack.pop();
   }
   lcUnlock(freeQueryLock);

   lcLock(inUseQueryLock);
   query = inUseQueryQueue.get();
   while (query != 0) {
      query->unref();
      query = inUseQueryQueue.get();
   }
   lcUnlock(inUseQueryLock);
}
コード例 #4
0
ファイル: Antenna.cpp プロジェクト: azcbuell/OpenEaagles
//------------------------------------------------------------------------------
// clearQueues() -- clear out all queues
//------------------------------------------------------------------------------
void Antenna::clearQueues()
{
   lcLock(freeEmLock);
    Emission* em = freeEmStack.pop();
    while (em != 0) {
        em->unref();
        em = freeEmStack.pop();
    }
   lcUnlock(freeEmLock);

   lcLock(inUseEmLock);
    em = inUseEmQueue.get();
    while (em != 0) {
        em->unref();
        em = inUseEmQueue.get();
    }
   lcUnlock(inUseEmLock);
}       
コード例 #5
0
ファイル: Timers.cpp プロジェクト: AFIT-Hodson/OpenEaagles
// -----------------------------------------------------------------
// Update all timers in the list
// -----------------------------------------------------------------
void Timer::updateTimers(const double dt)
{
    if (!frz) {
      lcLock( semaphore );
      for (unsigned int i = 0; i < nTimers; i++) {
         timers[i]->update(dt);
      }
      lcUnlock( semaphore );
   }
        }
コード例 #6
0
ファイル: Radar.cpp プロジェクト: jmc734/OpenEaagles
//------------------------------------------------------------------------------
// clearTracksAndQueues() -- clear out tracks and queues
//------------------------------------------------------------------------------
void Radar::clearTracksAndQueues()
{
   // Clear reports
   lcLock(myLock);
   for (unsigned int i = 0; i < numReports && i < MAX_REPORTS; i++) {
      if (reports[i] != nullptr) {
         reports[i]->unref();
         reports[i] = nullptr;
      }
   }
   numReports = 0;
   lcUnlock(myLock);

   // ---
   // Clear out the queues
   // ---
   lcLock(myLock);
   for (Emission* em = rptQueue.get(); em != nullptr; em = rptQueue.get()) { em->unref(); }
   while (rptSnQueue.isNotEmpty()) { rptSnQueue.get(); }
   lcUnlock(myLock);
}
コード例 #7
0
ファイル: Timers.cpp プロジェクト: AFIT-Hodson/OpenEaagles
// -----------------------------------------------------------------
// Add a new timer to the list
// -----------------------------------------------------------------
void Timer::addToTimerList(Timer* timer)
{
   bool ok = false;
   lcLock( semaphore );
   if (nTimers < MAX_TIMERS) {
      timers[nTimers++] = timer;
      ok = true;
   }
   lcUnlock( semaphore );

   if (!ok) {
      std::cerr << "Timer::addToTimerList() ERROR failed to add a new timer to static timer list" << std::endl;
   }
}
コード例 #8
0
//------------------------------------------------------------------------------
// rfReceivedEmission() -- process returned RF Emission
//------------------------------------------------------------------------------
void RfSystem::rfReceivedEmission(Emission* const em, Antenna* const, LCreal raGain)
{
   // Queue up emissions for receive() to process
   if (em != 0 && isReceiverEnabled()) {

      // Test to make sure the received emission is in-band before proceeding
      if (affectsRfSystem(em)) {

         // Pulses this radar frame (from emission)
         //LCreal pulses = LCreal( em->getPulses() );
         //if (pulses <= 0) pulses = 1.0f;

         // Compute signal losses
         //    Basically, we're simulation Hannen's S/I equation from page 356 of his notes.
         //    Where I is N + J. J is noise from jamming.
         //    Receiver Loss affects the total I, so we have to wait until J is added to N in Radar.
         LCreal losses = getRfSignalProcessLoss() * em->getAtmosphericAttenuationLoss() * em->getTransmitLoss();
         if (losses < 1.0f) losses = 1.0f;

         // Range loss
         LCreal rl = em->getRangeLoss();

         // Signal Equation (one way signal)
         // Signal Equation (Part of equation 2-7)
         // Signal (equation 3-3)
         LCreal signal = em->getPower() * rl * raGain / losses;

         // Noise Jammer -- add this signal to the total interferance signal (noise)
         if (em->isECM()) {
            // CGB part of the noise jamming equation says we're only affected by the ratio of the
            // transmitter and receiver bandwidths.
            // It's possible that we'll want to account for this in the signal calculation above.
            // But, for now, it is sufficient right here.
            jamSignal += (signal * getBandwidth() / em->getBandwidth());
         }

         // Save packet and signal for receive()
         lcLock(packetLock);
         if (np < MAX_EMISSIONS) {
            em->ref();
            packets[np] = em;
            signals[np] = signal;
            np++;
         }
         lcUnlock(packetLock);

      }
   }
}
コード例 #9
0
ファイル: Antenna.cpp プロジェクト: azcbuell/OpenEaagles
//------------------------------------------------------------------------------
// process() -- Process phase
//------------------------------------------------------------------------------
void Antenna::process(const LCreal dt)
{
   BaseClass::process(dt);

   // ---
   // Recycle emissions ...
   // Update emission queues: from 'in-use' to 'free' 
   // ---
   if (recycle) {
      unsigned int n = inUseEmQueue.entries();

      for (unsigned int i = 0; i < n; i++) {

         lcLock(inUseEmLock);
         Emission* em = inUseEmQueue.get();
         lcUnlock(inUseEmLock);

         if (em != 0 && em->getRefCount() > 1) {
            // Others are still referencing the emission, put back on in-use queue
            lcLock(inUseEmLock);
            inUseEmQueue.put(em);
            lcUnlock(inUseEmLock);
         }

         else if (em != 0 && em->getRefCount() <= 1) {
            // No one else is referencing the emission, push to the free stack
            em->clear();
            lcLock(freeEmLock);
            if (freeEmStack.isNotFull()) freeEmStack.push(em);
            else em->unref();
            lcUnlock(freeEmLock);
         }
      }
   }

}
コード例 #10
0
ファイル: Radar.cpp プロジェクト: jmc734/OpenEaagles
//------------------------------------------------------------------------------
// getReports() -- returns a list of prereferenced pointers to emission reports
//------------------------------------------------------------------------------
unsigned int Radar::getReports(const Emission** list, const unsigned int max) const
{
   unsigned int num = 0;
   if (list != nullptr && max > 0 && numReports > 0) {
      lcLock(myLock);
      num = numReports;
      if (num > max) num = max;
      for (unsigned int i = 0; i < num; i++) {
         reports[i]->ref();
         list[i] = reports[i];
      }
      lcUnlock(myLock);
   }
   return num;
}
コード例 #11
0
ファイル: Timers.cpp プロジェクト: AFIT-Hodson/OpenEaagles
// -----------------------------------------------------------------
// Remove a timer from the list
// -----------------------------------------------------------------
void Timer::removeFromTimerList(Timer* timer)
{
   lcLock( semaphore );

   // Find this timer in the list
   unsigned int found = MAX_TIMERS;
   for (unsigned int i = 0; i < nTimers && found == MAX_TIMERS; i++) {
      if (timers[i] == timer) found = i;
   }

   // If found then remove it by moving all timer in the list that are
   // beyond this timer down position
   if (found != MAX_TIMERS) {
      --nTimers;  // One less timer
      for (unsigned int i = found; i < nTimers; i++) {
         timers[i] = timers[i+1];
    }
}

   lcUnlock( semaphore );
}
コード例 #12
0
void MergingIrSensor::mergeIrReturns()
{
   int numRecords = storedMessagesQueue.entries();
   if (numRecords > 0) {

      //int* deleteArray = new int [numRecords];
      //if (deleteArray == 0) {
      //   if (isMessageEnabled(MSG_ERROR)) {
      //      std::cerr << "Error: Allocation memory failure in IrSensor::mergeIrReturns" << std::endl;
      //   }
      //}
      //else {
         //for (int i=0; i < numRecords; i++) {
         //   deleteArray[i] = 0;
         //}

         lcLock(storedMessagesLock);
         // Traverse the stored message queue using peek (). Examine every
         // message. Compare every stored message against every OTHER stored
         // message. If the two are too close together, merge the two signals
         // and mark the second message in the delete array.
         // Proceed through the loop, ignoring all messages marked "deleted"
         // in the delete array.
         numRecords = storedMessagesQueue.entries();

         if (isMessageEnabled(MSG_DEBUG)) {
            std::cout << "IrSensor: numRecords returned " << numRecords << std::endl;
         }

         for (int i=0; i < numRecords; i++) {
               //if (deleteArray[i] == 0) {  // Do not bother processing those marked
               // for deletion -- these have already been
               // merged and must be ignored.

            IrQueryMsg* currentMsg = storedMessagesQueue.peek0(i);

            // Do not bother processing those marked
            // for deletion -- these have already been
            // merged and must be ignored.
            if (currentMsg->getQueryMergeStatus()!= IrQueryMsg::MERGED_OUT) {

               for (int j = i+1; j < numRecords; j++) {

                  IrQueryMsg* nextMsg = storedMessagesQueue.peek0(j);
                  LCreal azimuthDelta = currentMsg->getRelativeAzimuth() - nextMsg->getRelativeAzimuth();
                  LCreal elevationDelta = currentMsg->getRelativeElevation()
                     - nextMsg->getRelativeElevation();

                  if (azimuthDelta < 0)
                     azimuthDelta = -azimuthDelta;

                  if (elevationDelta < 0)
                     elevationDelta = -elevationDelta;

                  if ((azimuthDelta < azimuthBin) &&
                     (elevationDelta < elevationBin)) { // two signals are too close together
                    // for the sensor to distinguish between them;
                    // we will merge the two signals based
                    // on their weighted signal-to-noise.
                    LCreal currentRatio = 0.0;
                    LCreal nextRatio = 0.0;

                    // find current ratio.
                    if (isMessageEnabled(MSG_DEBUG)) {
                       std::cout << "IrSensor: merging target " <<  nextMsg->getTarget()->getName()->getString()
                                 << " into target " <<currentMsg->getTarget()->getName()->getString()  << std::endl;
                    }

                    if (currentMsg->getSignalToNoiseRatio() >
                       currentMsg->getBackgroundNoiseRatio()) {

                          currentRatio = currentMsg->getSignalToNoiseRatio() +
                             currentMsg->getBackgroundNoiseRatio();

                    } else {
                       if (currentMsg->getSignalToNoiseRatio() < 0) {
                          currentRatio = -currentMsg->getSignalToNoiseRatio() -
                             currentMsg->getBackgroundNoiseRatio();
                       } else {
                          currentRatio = -currentMsg->getSignalToNoiseRatio() -
                             currentMsg->getBackgroundNoiseRatio();
                       } // signaltonoise < 0

                    } // if current signal > background

                    //now do the same thing for the next message.
                    if (nextMsg->getSignalToNoiseRatio() >
                       nextMsg->getBackgroundNoiseRatio()) {
                          nextRatio = nextMsg->getSignalToNoiseRatio() +
                             nextMsg->getBackgroundNoiseRatio();
                    } else {
                       if (nextMsg->getSignalToNoiseRatio() < 0) {
                          nextRatio = -nextMsg->getSignalToNoiseRatio() -
                             nextMsg->getBackgroundNoiseRatio();
                       } else {
                          nextRatio = -nextMsg->getSignalToNoiseRatio() -
                             nextMsg->getBackgroundNoiseRatio();
                       } // signaltonoise < 0

                    } // if next signal > background

                    // use ratios to find weights.
                    LCreal sumRatio = currentRatio + nextRatio;

                    const LCreal currentWeight = currentRatio / sumRatio;
                    const LCreal nextWeight = 1.0 - currentWeight;

                    //combine line-of-sight vector using weights
                    currentMsg->setLosVec((currentMsg->getLosVec() * currentWeight) +
                       (nextMsg->getLosVec() * nextWeight));

                    // combine position
                    currentMsg->setPosVec((currentMsg->getPosVec() * currentWeight) +
                       (nextMsg->getPosVec() * nextWeight));

                    // combine velocity
                    currentMsg->setVelocityVec((currentMsg->getVelocityVec() * currentWeight) +
                       (nextMsg->getVelocityVec() * nextWeight));

                    // combine acceleration
                    currentMsg->setAccelVec((currentMsg->getAccelVec() * currentWeight) +
                       (nextMsg->getAccelVec() * nextWeight));

                    // combine signal to noise ratios.
                    sumRatio = sumRatio - currentMsg->getBackgroundNoiseRatio();
                    if (sumRatio < 0)
                       sumRatio = -sumRatio;

                    currentMsg->setSignalToNoiseRatio(sumRatio);

                    //combine Azimuth and Elevation.
                    currentMsg->setAzimuthAoi((currentMsg->getAzimuthAoi() * currentWeight) +
                       nextMsg->getAzimuthAoi() * nextWeight);

                    currentMsg->setElevationAoi((currentMsg->getElevationAoi()* currentWeight) +
                       (nextMsg->getElevationAoi() * nextWeight));

                    currentMsg->setAngleAspect((currentMsg->getAngleAspect() * currentWeight) +
                       (nextMsg->getAngleAspect() * nextWeight));

                    currentMsg->setRelativeAzimuth((currentMsg->getRelativeAzimuth() * currentWeight) +
                       (nextMsg->getRelativeAzimuth() * nextWeight));

                    currentMsg->setRelativeElevation((currentMsg->getRelativeElevation() * currentWeight) +
                       (nextMsg->getRelativeElevation() * nextWeight));

                    // signal that this report has merged targets
                    currentMsg->setQueryMergeStatus(IrQueryMsg::MERGED);
                    nextMsg->setQueryMergeStatus(IrQueryMsg::MERGED_OUT);

                    //deleteArray[j] = 1;  // now that we have merged this signal with the
                    // Ith signal, it must be deleted. It will not
                    // be passed on to the track manager.

                    //if (isMessageEnabled(MSG_INFO)) {
                    //std::cout << "IrSensor: End Merge" << std::endl;
                    //}

                  } // if we merge
               } // end for j = i + 1;
            } // End if delete Array
            else { // debug - this target ws merged into another
               int x=0;
               x=x+1;
            }
         } // end for i = 0;
         lcUnlock(storedMessagesLock);
         //delete[] deleteArray;
      //} // newArray is not null.
   } // numRecords > 0
}
コード例 #13
0
ファイル: IrSeeker.cpp プロジェクト: azcbuell/OpenEaagles
//------------------------------------------------------------------------------
// 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();
}
コード例 #14
0
ファイル: Antenna.cpp プロジェクト: azcbuell/OpenEaagles
//------------------------------------------------------------------------------
// rfTransmit() -- Transmit a RF emission packet at all active players.
//------------------------------------------------------------------------------
void Antenna::rfTransmit(Emission* const xmit)
{
   // Need something to transmit and someone to send to
   Tdb* tdb = getCurrentTDB();
   Player* ownship = getOwnship();
   if (xmit == 0 || tdb == 0 || ownship == 0) {
      // Clean up and leave
      if (tdb != 0) tdb->unref();
      return;
   }

   // ---
   // Compute gimbal boresight data for our targets
   // ---
   unsigned int ntgts = tdb->computeBoresightData();
   if (ntgts > MAX_PLAYERS) ntgts = MAX_PLAYERS;

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

      // ---
      // Lookup gain from antenna gain pattern, compute antenna
      // effective gain and effective radiated power.    
      // ---
      bool haveGainTgt = false;
      double gainTgt[MAX_PLAYERS];
      if (gainPattern != 0) {
         Basic::Func1* gainFunc1 = dynamic_cast<Basic::Func1*>(gainPattern);
         Basic::Func2* gainFunc2 = dynamic_cast<Basic::Func2*>(gainPattern);
         if (gainFunc2 != 0) {
            // ---
            // Antenna pattern: 2D table (az & el off antenna boresight)
            // ---

            // Compute azimuth off boresight (radians)
            const double* aazr = tdb->getBoresightAzimuthErrors();

            // Compute elevation off boresight (radians)
            const double* aelr = tdb->getBoresightElevationErrors();

            // Lookup gain in 2D table and convert from dB
            double gainTgt0[MAX_PLAYERS];
            if (gainPatternDeg) {
               for (unsigned int i1 = 0; i1 < ntgts; i1++) {
                  gainTgt0[i1] = gainFunc2->f( (aazr[i1] * Basic::Angle::R2DCC), (aelr[i1] * Basic::Angle::R2DCC) )/10.0;
               }
            }
            else {
               for (unsigned int i1 = 0; i1 < ntgts; i1++) {
                  gainTgt0[i1] = gainFunc2->f( aazr[i1], aelr[i1] )/10.0f;
               }
            }
            pow10Array(gainTgt0, gainTgt, ntgts);
            haveGainTgt = true;
         }
         else if (gainFunc1 != 0) {
            // ---
            // Antenna Pattern: 1D table (off antenna boresight only
            // ---

            // Compute angles off antenna boresight (radians)
            const double* aar = tdb->getBoresightErrorAngles();

            // Lookup gain in 1D table and convert from dB
            double gainTgt0[MAX_PLAYERS];
            if (gainPatternDeg) {
               for (unsigned int i2 = 0; i2 < ntgts; i2++) {
                  gainTgt0[i2] = gainFunc1->f( aar[i2]*Basic::Angle::R2DCC )/10.0;
               }
            }
            else {
               for (unsigned int i2 = 0; i2 < ntgts; i2++) {
                  gainTgt0[i2] = gainFunc1->f( aar[i2] )/10.0f;
               }
            }
            pow10Array(gainTgt0, gainTgt, ntgts);
            haveGainTgt = true;
         }
      }
      if (!haveGainTgt) {
         // ---
         // No antenna pattern table
         // ---
         for (unsigned int i = 0; i < ntgts; i++) {
            gainTgt[i] = 1.0f;
         }
      }

      // Compute antenna effective gain
      double aeGain[MAX_PLAYERS];
      multArrayConst(gainTgt, getGain(), aeGain, ntgts);

      // Compute Effective Radiated Power (watts) (Equation 2-1)
      double erp[MAX_PLAYERS];
      multArrayConst(aeGain, xmit->getPower(), erp, ntgts);

      // Fetch the required data arrays from the TargetDataBlock
      const double* ranges = tdb->getTargetRanges();
      const double* rngRates = tdb->getTargetRangeRates();
      const osg::Vec3d* losO2T = tdb->getLosVectors();
      const osg::Vec3d* losT2O = tdb->getTargetLosVectors();
      Player** targets = tdb->getTargets();

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

         // Only of power exceeds an optional threshold
         if (erp[i] > threshold) {

            // Get a free emission packet
            Emission* em(0);
            if (recycle) {
               lcLock(freeEmLock);
               em = freeEmStack.pop();
               lcUnlock(freeEmLock);
            }

            bool cloned = false;
            if (em == 0) {
               // Otherwise, clone a new one 
               em = xmit->clone();
               cloned = true;
            }

            // Send the emission to the other player
            if (em != 0) {

               // a) Copy the template emission
               if (!cloned) *em = *xmit;

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

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

               em->setGimbalAzimuth( LCreal(getAzimuth()) );
               em->setGimbalElevation( LCreal(getElevation()) );
               em->setPower( LCreal(erp[i]) );
               em->setGain( LCreal(aeGain[i]) );
               em->setPolarization(getPolarization());
               em->setLocalPlayersOnly( isLocalPlayersOfInterestOnly() );

               // c) Send the emission to the target
               targets[i]->event(RF_EMISSION, em);

               // d) Recycle the emission
               bool recycled = false;
               if (recycle) {
                  lcLock(inUseEmLock);
                  if (inUseEmQueue.isNotFull()) {
                     // Store for future reference
                     inUseEmQueue.put(em);
                     recycled = true;
                  }
                  lcUnlock(inUseEmLock);
               }

               // or just forget it
               else {
                  em->unref();
              }

            }
            else {
               // When we couldn't get a free emission packet
               if (isMessageEnabled(MSG_ERROR)) {
                  std::cerr << "Antenna: OUT OF EMISSIONS!" << std::endl;
               }
            }
         }

      }
   }

   // Unref() the TDB
   tdb->unref();
}
コード例 #15
0
ファイル: Rwr.cpp プロジェクト: Stupefy/OpenEaagles
//------------------------------------------------------------------------------
// receive() -- process received emissions
//------------------------------------------------------------------------------
void Rwr::receive(const LCreal dt)
{
   BaseClass::receive(dt);

   // clear the back buffer
   clearRays(0);

   // Receiver losses
#if 0
   LCreal noise = getRfRecvNoise();
#else
   LCreal noise = getRfRecvNoise() * getRfReceiveLoss();
#endif

   // Process received emissions 
   TrackManager* tm = getTrackManager();
   Emission* em = 0;
   LCreal signal = 0;

   // Get an emission from the queue
   lcLock(packetLock);
   if (np > 0) {
      np--; // Decrement 'np', now the array index
      em = packets[np];
      signal = signals[np];
   }
   lcUnlock(packetLock);

   while (em != 0) {

      //std::cout << "Rwr::receive(" << em->getOwnship() << "): ";
      //std::cout << " pwr=" << em->getPower();
      //std::cout << " gain=" << em->getGain();
      //std::cout << " rl=" << rl;
      //std::cout << " pulses=" << pulses;
      //std::cout << " losses=" << losses;
      //std::cout << " signal=" << signal;
      //std::cout << " recvN=" << getRfRecvNoise();
      //std::cout << " sn=" << sn;
      //std::cout << " snDbl=" << snDbl;
      //std::cout << " thrs=" << getRfThreshold();
      //std::cout << std::endl;

      // CGB, if "signal <= 0.0", then "snDbl" is probably invalid
      if (signal > 0.0 && dt != 0.0) {

         // Signal over noise (equation 3-5)
         LCreal sn = signal / noise;
         LCreal snDbl = 10.0f * lcLog10(sn);

         // Is S/N above receiver threshold  ## dpg -- for now, don't include ECM emissions
         if (snDbl > getRfThreshold() && !em->isECM() && rptQueue.isNotFull()) {
            // Send report to the track manager
            if (tm != 0) {
               tm->newReport(em, snDbl);
            }

            // Get Angle Of Arrival
            LCreal aoa= em->getAzimuthAoi();

            // Store received power for real-beam display
            LCreal sigDbl = 10.0f * lcLog10(signal);
            LCreal signal10 = (sigDbl + 50.0f)/50.f;
            int idx = getRayIndex( static_cast<LCreal>(Basic::Angle::R2DCC * aoa) );
            rays[0][idx] = lim01(rays[0][idx] + signal10);
            //if (idx == 0 && getOwnship()->getID() == 1011) {
            //   std::cout << "sig = " << signal10 << std::endl;
            //}

            // Send to the track list processor
            em->ref();  // ref() for track list processing
            rptQueue.put(em);
         }
      }

      // finished
      em->unref();   // this unref() undoes the ref() done by RfSystem::rfReceivedEmission
      em = 0;


      // Get another emission from the queue
      lcLock(packetLock);
      if (np > 0) {
         np--;
         em = packets[np];
         signal = signals[np];
      }
      lcUnlock(packetLock);

   }

   // Transfer the rays
   xferRays();
}
コード例 #16
0
ファイル: Radar.cpp プロジェクト: jmc734/OpenEaagles
//------------------------------------------------------------------------------
// process() -- process the TWS reports
//------------------------------------------------------------------------------
void Radar::process(const LCreal dt)
{
   BaseClass::process(dt);

   // Find the track manager
   TrackManager* tm = getTrackManager();
   if (tm == nullptr) {
      // No track manager! Then just flush the input queue.
      lcLock(myLock);
      for (Emission* em = rptQueue.get(); em != nullptr; em = rptQueue.get()) {
         em->unref();
         rptSnQueue.get();
      }
      lcUnlock(myLock);
   }

   // ---
   // When end of scan, send all unsent reports to the track manager
   // ---
   if (endOfScanFlg) {

      endOfScanFlg = false;

      lcLock(myLock);
      for (unsigned int i = 0; i < numReports && i < MAX_REPORTS; i++) {
         if (tm != nullptr) {
            tm->newReport(reports[i], rptMaxSn[i]);
         }
         reports[i]->unref();
         reports[i] = nullptr;
         rptMaxSn[i] = 0;
      }
      numReports = 0;
      lcUnlock(myLock);
   }


   // ---
   // Process our returned emissions into reports for the track manager
   //   1) Match each emission with existing reports
   //   2) On emission/report matches, if the S/N value of the new emission
   //      is greater than the report, use the new emission
   //   3) Create new reports for unmatched emissions
   // ---
   lcLock(myLock);
   while (rptQueue.isNotEmpty()) {

      // Get the emission
      Emission* em = rptQueue.get();
      LCreal snDbl = rptSnQueue.get();

      if (em != nullptr) {
         // ---
         // 1) Match the emission with existing reports
         // ---
         int matched = -1;
         for (unsigned int i = 0; i < numReports && matched < 0; i++) {
            // Compare targets
            if ( em->getTarget() == reports[i]->getTarget() ) {
               // We have a match!!!
               matched = i;
            }
         }

         // ---
         // 2) On emission/report match
         // ---
         if (matched >= 0) {
            if (snDbl > rptMaxSn[matched]) {
               // When the S/N value of the new emission is greater than the report,
               // we use the new emission
               reports[matched]->unref();
               em->ref();
               reports[matched] = em;
               rptMaxSn[matched] = snDbl;
            }
         }


         // ---
         // 3) Create a new report entry for the unmatched emission
         // ---

         if (matched < 0 && numReports < MAX_REPORTS) {
            em->ref();
            reports[numReports] = em;
            rptMaxSn[numReports] = snDbl;
            numReports++;
         }
         // finished
         em->unref();
      }
   }
   lcUnlock(myLock);
}
コード例 #17
0
ファイル: Radar.cpp プロジェクト: jmc734/OpenEaagles
//------------------------------------------------------------------------------
// receive() -- process received emissions
//------------------------------------------------------------------------------
void Radar::receive(const LCreal dt)
{
   BaseClass::receive(dt);

   // Can't do anything without an antenna
   if (getAntenna() == nullptr) return;

   // Clear the next sweep
   csweep = computeSweepIndex( static_cast<LCreal>(Basic::Angle::R2DCC * getAntenna()->getAzimuth()) );
   clearSweep(csweep);

   // Compute noise level
   // CGB moved here from RfSystem
   // Basically, we're simulation Hannen's S/I equation from page 356 of his notes.
   // Where I is N + J. J is noise from jamming.
   // Receiver Loss affects the total I, so we have to wait until this point to account for it.
   const LCreal interference = (getRfRecvNoise() + jamSignal) * getRfReceiveLoss();
   const LCreal noise = getRfRecvNoise() * getRfReceiveLoss();
   currentJamSignal = jamSignal * getRfReceiveLoss();
   int countNumJammedEm = 0;

   // ---
   // Process Returned Emissions
   // ---

   Emission* em = nullptr;
   LCreal signal = 0;

   // Get an emission from the queue
   lcLock(packetLock);
   if (np > 0) {
      np--; // Decrement 'np', now the array index
      em = packets[np];
      signal = signals[np];
   }
   lcUnlock(packetLock);

   while (em != nullptr) {

      // exclude noise jammers (accounted for already in RfSystem::rfReceivedEmission)
      if (em->getTransmitter() == this || (em->isECM() && !em->isECMType(Emission::ECM_NOISE)) ) {

         // compute the return trip loss ...

         // Compute signal received
         LCreal rcs = em->getRCS();

         // Signal Equation (Equation 2-7)
         LCreal rl = em->getRangeLoss();
         signal *= (rcs * rl);

         // Integration gain
         signal *= rfIGain;

         // Range attenuation: we don't want the strong signal from short range targets
         LCreal maxRng = getRange() * Basic::Distance::NM2M;
         //LCreal maxRng4 = (maxRng*maxRng*maxRng*maxRng);
         //LCreal rng = (em->getRange());

         const LCreal s1 = 1.0;
         //if (rng > 0) {
         //    LCreal rng4 = (rng*rng*rng*rng);
         //    s1 = (rng4/maxRng4);
         //    if (s1 > 1.0f) s1 = 1.0f;
         //}
         signal *= s1;

         if (signal > 0.0) {

            // Signal/Noise  (Equation 2-9)
            const LCreal signalToInterferenceRatio = signal / interference;
            const LCreal signalToInterferenceRatioDbl = 10.0f * lcLog10(signalToInterferenceRatio);
            const LCreal signalToNoiseRatio = signal / noise;
            const LCreal signalToNoiseRatioDbl = 10.0f * lcLog10(signalToNoiseRatio);

            //std::cout << "Radar::receive(" << em->getTarget() << "): ";
            //std::cout << " pwr=" << em->getPower();
            //std::cout << " gain=" << em->getGain();
            //std::cout << " rl=" << rl;
            //std::cout << " rcs=" << rcs;
            //std::cout << " signal=" << signal;
            //std::cout << " recvN=" << getRfRecvNoise();
            //std::cout << " signalToInterferenceRatio=" << signalToInterferenceRatio;
            //std::cout << " signalToInterferenceRatioDbl=" << signalToInterferenceRatioDbl;
            //std::cout << " thrs=" << getRfThreshold();
            //std::cout << std::endl;

            // Is S/N above receiver threshold and within 125% of max range?
            // CGB, if "signal <= 0.0", then "signalToInterferenceRatioDbl" is probably invalid
            // we should probably do something smart with "signalToInterferenceRatioDbl" above as well.
            lcLock(myLock);
            if (signalToInterferenceRatioDbl >= getRfThreshold() && em->getRange() <= (maxRng*1.25) && rptQueue.isNotFull()) {

               // send the report to the track manager
               em->ref();
               rptQueue.put(em);
               rptSnQueue.put(signalToInterferenceRatioDbl);

               //std::cout << " (" << em->getRange() << ", " << signalToInterferenceRatioDbl << ", " << signalToInterferenceRatio << ", " << signalToInterferenceRatioDbl << ")";

               // Save signal for real-beam display
               int iaz = csweep;
               int irng = computeRangeIndex( em->getRange() );
               sweeps[iaz][irng] += (signalToInterferenceRatioDbl/100.0f);
               vclos[iaz][irng] = em->getRangeRate();

            } else if (signalToInterferenceRatioDbl < getRfThreshold() && signalToNoiseRatioDbl >= getRfThreshold()) {
               countNumJammedEm++;
            }
            lcUnlock(myLock);
         }
      }

      em->unref();   // this unref() undoes the ref() done by RfSystem::rfReceivedEmission
      em = nullptr;

      //if (np >= 0 && np < MAX_EMISSIONS) {
      //    packets[np] = 0;
      //    signals[np] = 0;
      //}

      // Get another emission from the queue
      lcLock(packetLock);
      if (np > 0) {
         np--;
         em = packets[np];
         signal = signals[np];
      }
      lcUnlock(packetLock);
   }
   //std::cout << std::endl;

   numberOfJammedEmissions = countNumJammedEm;

   // Set interference signal back to zero
   jamSignal = 0;
}