Exemplo n.º 1
0
//-----------------------------------------------------------------------------
void RxSim::process()
{
   NavFramer nf;
   long int dataPoint =0;
   int count = 0;
   nf.debugLevel = debugLevel;
   nf.dump(cout);

   complex<float> s;
   int b=0;
   while (*input >> s)
   {
      if (b == band-1 || input->bands==1)
      {
         s *= gain;
         if (tr->process(s))
         {
            if (verboseLevel)
               tr->dump(cout);

               // Test code to skip input to speed up tracking.
               /*int count2 = 0;
            while(count2 < 3*16367)
            {
               count2++;
               *input >> s;
               }*/

// Following two if statements are specific to tracker updating every
// 1 ms.
            if(tr->navChange)
            {
               nf.process(*tr, dataPoint,
                          (float)tr->localReplica.getCodePhaseOffsetSec()*1e6);
               count = 0;
            }
            if(count == 20)
            {
               count = 0;
               nf.process(*tr, dataPoint,
                          (float)tr->localReplica.getCodePhaseOffsetSec()*1e6);
            }
            count++;
         }
      }
      b++;
      b %= input->bands;

      if (cc->localTime > timeLimit)
         break;

      dataPoint++;
   }
}
Exemplo n.º 2
0
void *Cfunction(void* p)
{
   Par *par = (Par*)p;
   
   EMLTracker *tr = par->tr;
   int *count = par->count;
   NavFramer *nf = par->nf;
   int bufferSize = par->bufferSize;
   int dp = par->dp - bufferSize;
   Buffer *b = par->s;
   bool v = par->v;
   
   int index = 0; 
   
   while(index < bufferSize + 1) // number of data points to track before join.
   {
      if (tr->process(b->arr[index]))
      {
         if(v)
            tr->dump(cout);
         
         if(tr->navChange)
         {
            nf->process(*tr, dp, 
                     (float)tr->localReplica.getCodePhaseOffsetSec()*1e6);
            *count = 0;
         }
         if(*count == 20)
         // The *20* depends on the tracker updating every C/A period.
         {
            *count = 0;
            nf->process(*tr, dp, 
                     (float)tr->localReplica.getCodePhaseOffsetSec()*1e6);
         }
         
         *count = *count + 1;
      }
      index++;
      dp++;
   } 
   pthread_exit(NULL);
   return NULL;
}
Exemplo n.º 3
0
bool RxSim::initialize(int argc, char *argv[]) throw()
{
   using namespace gpstk::StringUtils;

   CommandOptionWithAnyArg
      codeOpt('c', "code",
              "The code/carrier to track. ARG takes the form of "
              "code:carrier:prn:offset:doppler. Code is either c or p. "
              "Carrier is either 1 or 2. Prn is an integer between 1 and 32. "
              "Offset is a number in us, Doppler is a number in Hz. Currently, "
              "only one signal can be specified. For example, to track P code "
              "on L2 for PRN 3, with no initial time or doppler offset, "
              "specify -c p:2:3:0:0"),

      dllAlphaOpt('\0', "dllAlpha",
                  "The gain on the phase update for the code tracker. The "
                  "default is 1e-5 chips/tick"),

      dllBetaOpt('\0', "dllBeta",
                 "The gain on the frequency update for the code tracker. The "
                 "default is 1e-12 chips/tick"),

      pllAlphaOpt('\0', "pllAlpha",
                  "The gain on the phase update for the carrier tracker. The "
                  "default is 0.4 cycles/tick"),

      pllBetaOpt('\0', "pllBeta",
                 "The gain on the frequency update for the carrier tracker. "
                 "The default is 0.1 cycles / iad_period"),

      sampleRateOpt('r',"sample-rate",
                    "Specifies the nominal sample rate, in MHz.  The "
                    "default is 20 MHz."),

      interFreqOpt('x',"inter-freq",
                   "Specifies the intermediate frequency of the receiver,"
                   " in MHz.  Default is 0.42 MHz. If there is no down-"
                   "conversion, the IF should be the L1 or L2 carrier"
                   " frequency" ),

      quantizationOpt('q', "quantization",
                      "They quantization applied to the data. 1, 2 or f. "
                      "The default is f."),

      gainOpt('g', "gain",
              "Gain to apply to the if prior to digitization, in dB. Default is 0."),

      timeLimitOpt('t', "time-limit",
                  "Limit the amount of data to process. Specify time in ms. Defaults to all data."),

      inputOpt('i', "input",
               "Where to get the IQ samples from. The default is to use stdin.");

   CommandOptionWithNumberArg
      bandsOpt('b', "bands",
               "The number of complex samples per epoch. The default is 2.");

   if (!BasicFramework::initialize(argc,argv))
      return false;

   if (timeLimitOpt.getCount())
      timeLimit = asDouble(timeLimitOpt.getValue()[0]) * 1e-3;

   if (!codeOpt.getCount())
   {
      cout << "Must specify a code/carrier to track. Bye." << endl;
      return false;
   }

   string val=codeOpt.getValue()[0];
   const char delim(':');
   if (numWords(val, delim) != 5)
   {
      cout << "Error in code parameter:" << val << endl;
      return false;
   }

   string code =   lowerCase(word(val, 0, delim));
          band =       asInt(word(val, 1, delim));
   int    prn =        asInt(word(val, 2, delim));
   double offset =  asDouble(word(val, 3, delim)) * 1e-6;
   double doppler = asDouble(word(val, 4, delim));

   CodeGenerator* codeGenPtr;
   double chipFreq;
   switch (code[0])
   {
      case 'c':
         codeGenPtr = new CACodeGenerator(prn);
         chipFreq = CA_CHIP_FREQ_GPS;
         break;
      case 'p':
         codeGenPtr = new PCodeGenerator(prn);
         chipFreq = PY_CHIP_FREQ_GPS;
         break;
      default:
         cout << "Unsupported code: " << code << endl;
         return false;
   }

   if (sampleRateOpt.getCount())
      timeStep = 1/(asDouble(sampleRateOpt.getValue().front()) * 1e6 );

   if (interFreqOpt.getCount())
      interFreq = asDouble(interFreqOpt.getValue().front()) * 1e6;

   // Note that this object is responsible for destroying
   // the codeGenPtr object
   cc = new CCReplica(timeStep, chipFreq, interFreq, codeGenPtr);

   double chips = offset / cc->codeChipLen;
   cc->moveCodePhase(chips);

   cc->setCodeFreqOffsetHz(doppler);
   cc->setCarrierFreqOffsetHz(doppler);

   double spacing = 0.5 * cc->codeChipLen;
   if (spacing < timeStep)
      spacing = timeStep;

   tr = new EMLTracker(*cc, spacing);

   if (dllAlphaOpt.getCount())
      tr->dllAlpha = asDouble(dllAlphaOpt.getValue()[0]);

   if (dllBetaOpt.getCount())
      tr->dllBeta = asDouble(dllBetaOpt.getValue()[0]);

   if (pllAlphaOpt.getCount())
      tr->pllAlpha = asDouble(pllAlphaOpt.getValue()[0]);

   if (pllBetaOpt.getCount())
      tr->pllBeta = asDouble(pllBetaOpt.getValue()[0]);

   tr->debugLevel = debugLevel;

   char quantization='f';
   if (quantizationOpt.getCount())
      quantization = quantizationOpt.getValue()[0][0];

   switch (quantization)
   {
      case '1': input = new IQ1Stream(); break;
      case '2': input = new IQ2Stream(); break;
      case 'f':
      default:  input = new IQFloatStream(); break;
   }

   if (inputOpt.getCount())
   {
      input->open(inputOpt.getValue()[0].c_str());
   }
   else
   {
      using std::basic_ios;
      input->copyfmt(std::cin);
      input->clear(std::cin.rdstate());
      input->basic_ios<char>::rdbuf(std::cin.rdbuf());
      input->filename = "<stdin>";
   }

   if (bandsOpt.getCount())
      input->bands = asInt(bandsOpt.getValue()[0]);

   if (gainOpt.getCount())
   {
      double gainDb = StringUtils::asDouble(gainOpt.getValue()[0]);
      gain = exp10(gainDb/10.);
   }

   if (verboseLevel)
   {
      cout << "# Taking input from " << input->filename
           << " (" << input->bands << " samples/epoch)" << endl
           << "# Rx gain level: " << gain << endl;
      tr->dump(cout, 1);
   }

   return true;
}
Exemplo n.º 4
0
long int NavFramer::process(const EMLTracker& tr, long int dp, float cPO)
{
   // number of code chips that go into each bit
   const unsigned long chipsPerBit = 
      static_cast<unsigned long>(bitLength / tr.localReplica.codeChipLen);
   
   const CodeIndex now = tr.localReplica.codeGenPtr->getChipCount();
   const unsigned navCount = now/chipsPerBit;
   
// Code below can be uncommented if the NavFramer needs to count on it's own 
// to know when there is a new nav bit.  Right now it is only called when the
// tracker says there is one.
/*
   if (navCount == prevNavCount)
   {
         //cout << "skipping" << endl;
      return howCurrent;
   }
*/

      //cout << "doing" << endl;
   howCurrent = false;
   prevNavCount = navCount;
   navBuffer[navIndex] = tr.getNav();
   codeIndex[navIndex] = now;
   startDP.push_back(dp);
   codePO.push_back(cPO);
   navIndex++;
   navIndex %= navBuffer.size();
   lastEight <<= 1;
   lastEight[0] = tr.getNav();

   if (debugLevel>2)
      cout << "# t:" << fixed << setprecision(2)
           << tr.localReplica.localTime *1e3
           << " ms, n:" << tr.getNav() << endl;

   if (lastEight == eightBaker || ~lastEight == eightBaker)
   {
     //cout << "FOUND CANDIDATE" << endl ;
      Subframe sf;
      sf.ni = (navIndex-8) % 1500;
      sf.ci = codeIndex[sf.ni];
      sf.dataPoint = startDP[sf.ni];
      sf.prn = tr.prn;
      sf.codePO = codePO[sf.ni];
      sf.prevD30 = navBuffer[(navIndex-9)%1500];
      sf.t = tr.localReplica.localTime;
      sf.inverted = lastEight != eightBaker;
      if (debugLevel>1)
         cout << "# " << sf << endl;
      candidates.push_back(sf);
   }
   
   list<Subframe>::iterator sf;
   for (sf = candidates.begin(); sf != candidates.end(); )
   {
      if (navIndex - sf->ni >= 300)
      {
         sf->load(navBuffer);
         if (sf->checkParity())
         {
            subframes.push_back(*sf);
            how = sf->words[1];
               //if (debugLevel)
               //cout << *sf << endl;
               //if (debugLevel)
               //sf->dump(cout,1);
               howCurrent = true;

// Following block pulls nav data from subframes, just playing around for now.
/*
               long framesArrayFormat[10];
               int gpsWeek = 1433;
               double output[60];
               for(int k = 0; k < 10; k++)
               {
                  framesArrayFormat[k] = sf->words[k];
               }
               EngNav::subframeConvert(framesArrayFormat, gpsWeek, output);
   
               for(int i = 0; i < 60; i++)
                  cout << output[i] << endl;
*/
         }
         else
         {
            howCurrent = false;
            if (debugLevel>1)
            {
               cout << "# " << *sf << endl;
               sf->dump(cout, 1);
            }
         }
         candidates.erase(sf++);
      }
      else
         sf++;
   }
   return howCurrent;
}