예제 #1
0
//------------------------------------------------------------------------------
// 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;
}
예제 #2
0
//------------------------------------------------------------------------------
// 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);
}
예제 #3
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();
}