예제 #1
0
파일: iqdump.cpp 프로젝트: ianmartin/GPSTk
bool IQDump::initialize(int argc, char *argv[]) throw()
{
   using namespace gpstk::StringUtils;

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

      quantizationOpt('q', "quantization",
                      "What type of IQ stream; 1, 2 or f. The default is f."),

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

   CommandOptionNoArg
      statsOpt('s', "stats", "Compute stats on values.");

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

   stats = statsOpt.getCount()>0;

   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 (debugLevel)
      cout << "Taking input from: " << input->filename << endl
           << "IQStream type: " << input->desc << endl;

   input->debugLevel = debugLevel;

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

   return true;
}
예제 #2
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;
}
예제 #3
0
파일: acquire.cpp 프로젝트: ianmartin/GPSTk
//-----------------------------------------------------------------------------
bool Acquire::initialize(int argc, char *argv[]) throw()
{
   using namespace gpstk::StringUtils;

   CommandOptionWithAnyArg
      bandsOpt('b',"bands",
               "The number of complex samples per epoch.  The default is 2. "),
      
      periodsOpt('p',"CA-periods",
                 "The number of C/A periods to consider.  Default is one, "
                 "odd values recommended because of possible NAV change."),

      sampleRateOpt('r',"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."),

      quantizationOpt('q', "quantization",
                   "The quantization applied to the data. 1, 2 or f. "
                      "The default is f."),
      
      prnOpt('c',"PRN",
             "The PRN of the code to acquire. Enter 0 to acquire "
             "all PRN codes (1 through 32). Default is 1."),

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

      searchWidthOpt('w',"search-width",
                     "Width of the doppler search in Hz. "
                     "For example, 20000 would search from -10000 to 10000 Hz. "
                     "Default is 20000."),

      binWidthOpt('f',"bin-width",
                  "Width of the frequency bins in Hz. Default is 200. "
                  "Bin width should be at most 1000Hz/numPeriods, so "
                  "the default is for up to 5 periods."),

      heightOpt('z',"height",
                "The cutoff correlation height for acquisition.  This only "
                "affects our output.  A SNR measure should replace this "
                "eventually.  Default is 40");
   

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

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

   if (periodsOpt.getCount())
   {
      periods = asInt(periodsOpt.getValue()[0]);
      numSamples = sampleRate*1e-3*periods;
   }
   
   if (sampleRateOpt.getCount())
   {
      sampleRate = asDouble(sampleRateOpt.getValue().front()) * 1e6;
      numSamples = sampleRate*1e-3*periods;
   }

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

   if (prnOpt.getCount())
      prn = asInt(prnOpt.getValue()[0]);

   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(searchWidthOpt.getCount())
   {
      freqSearchWidth = asDouble(searchWidthOpt.getValue().front());
      bins = freqSearchWidth / freqBinWidth + 1;
   }

   if(binWidthOpt.getCount())
   {
      freqBinWidth = asDouble(binWidthOpt.getValue().front());
      bins = freqSearchWidth / freqBinWidth + 1;
   }

   if(heightOpt.getCount())
   {
      height = asInt(heightOpt.getValue().front());
   }
                
   

   return true;
}
예제 #4
0
파일: corltr.cpp 프로젝트: JC5005/GPSTk
bool Corltr::initialize(int argc, char *argv[]) throw()
{
   using namespace gpstk::StringUtils;

   CommandOptionWithAnyArg
      windowOpt('w', "window",
                "Specifies how wide a window to use, in us. The default "
                "is 1023 us."),

      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",
                      "The quantization applied to the data. 1, 2 or f. "
                      "The default is f."),

      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"),

      freqErrOpt('f', "freq-err",
                 "Specify the frequency error on the local receiver's "
                 "oscilator, in ppm. The default is 0 ppm"),

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

   CommandOptionWithNumberArg
      stepsOpt('s', "steps",
               "The number of 1/4 chip steps to take. Defaults to 4092."),

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

   CommandOptionNoArg
      peakOnlyOpt('p', "peak",
                  "Only output the peak correlation/snr values.");

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

   peakOnly = peakOnlyOpt.getCount()>0;

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

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

   if (windowOpt.getCount())
      window = asDouble(windowOpt.getValue().front()) * 1e-6;
   else
      window = 1.023e-3;

   if (freqErrOpt.getCount())
      freqErr = StringUtils::asDouble(freqErrOpt.getValue()[0]) * 1e-6;
   else
      freqErr = 0;

   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 (verboseLevel)
      cout << "# IQStream type: " << input->desc << endl;

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

   if (stepsOpt.getCount())
      steps = asInt(stepsOpt.getValue()[0]);

   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));
   int    band =       asInt(word(val, 1, delim));
#pragma unused(band)
   int    prn =        asInt(word(val, 2, delim));
          offset =  asDouble(word(val, 3, delim)) * 1e-6;
          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;
   }
   cc = new CCReplica(timeStep, chipFreq, interFreq, codeGenPtr);

   return true;
}
예제 #5
0
파일: gpsSim.cpp 프로젝트: JC5005/GPSTk
bool GpsSim::initialize(int argc, char *argv[]) throw()
{
   CommandOptionWithAnyArg
      codeOpt('c', "code",
              "Generate the signal defined by the argument. ARG takes "
              "the form of code:carrier:prn:offset:doppler:nav. Code is either "
              "c, p, or cp. Carrier is either 1 or 2. Prn is an integer between 1 "
              "and 32. Offset is a number in microseconds. Doppler is a number "
              "in Hz. Nav is 0, c, p, or cp. For example, to generate C/A on L1 for "
              "PRN 15 with zero time-offset, zero doppler, a dummy nav signal "
              "on both C/A and P, then specify -c c:1:15:0:p.  This option "
              "may be repeated to simulate multiple signals.");

   CommandOptionNoArg
      codeOnlyOpt('\0', "code-only",
                  "Only generate the codes. No carrier, no hetrodyning.");

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

   CommandOptionWithAnyArg
      interFreqOpt('x',"inter-freq",
                   "Specifies the intermediate frequency of the receiver,"
                   " in MHz.  Default is 0.42 MHz.");

   CommandOptionWithAnyArg
      quantizationOpt('q', "quantization",
                      "What type of IQ stream; 1, 2 or f. The default is f.");

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

   CommandOptionWithAnyArg
      noiseGainOpt('n', "noise",
                   "Specify the gain (in dB) for the receiver's noise. The "
                   "default is 0 dB");

   CommandOptionWithAnyArg
      freqErrOpt('f', "freq-err",
                 "Specify the frequency error on the local receiver's "
                 "oscilator, in ppm. The default is 0 ppm");

   CommandOptionWithAnyArg
      runTimeOpt('t', "run-time",
                 "How long (in ms) to run the simulation for. The default is 20 ms");

   CommandOptionWithAnyArg
      outputOpt('o', "output",
                 "Where to write the output. The default is stdout");

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

   using namespace gpstk::StringUtils;

   char quantization='f';
   if (quantizationOpt.getCount())
      quantization = quantizationOpt.getValue()[0][0];
   switch (quantization)
   {
      case '1': output = new IQ1Stream(); break;
      case '2': output = new IQ2Stream(); break;
      case 'f':
      default:  output = new IQFloatStream(); break;
   }

   if (sampleRateOpt.getCount()){
      rx_sample_rate = asDouble(sampleRateOpt.getValue().front()) * 1e6;
      time_step = 1.0/rx_sample_rate;
      samples_per_period = rx_sample_rate / 1e6;}

   if (interFreqOpt.getCount()){
      interFreq = asDouble(interFreqOpt.getValue().front()) * 1e6;
      rx_L1_LO = gpstk::L1_FREQ_GPS - interFreq;
      rx_L2_LO = gpstk::L2_FREQ_GPS - interFreq;}

   if (outputOpt.getCount())
   {
      output->open(outputOpt.getValue()[0].c_str(), ios::out);
   }
   else
   {
      using std::basic_ios;
      output->copyfmt(std::cout);
      output->clear(std::cout.rdstate());
      output->basic_ios<char>::rdbuf(std::cout.rdbuf());
      output->filename = "<stdout>";
   }
   if (debugLevel)
      cout << "Writing data to " << output->filename << endl;

   if (gainOpt.getCount())
   {
      double gainDb = StringUtils::asDouble(gainOpt.getValue()[0]);
      gain = exp10(gainDb/10);
      if (debugLevel)
         cout << "# Rx gain level: " << gainDb << " db ("
              << gain << ")" << endl;
   }

   if (noiseGainOpt.getCount())
   {
      double gain_local = StringUtils::asDouble(noiseGainOpt.getValue()[0]);
      noise_amplitude *= exp10(gain_local/10);
      if (debugLevel)
         cout << "# Noise level: " << gain_local << " db" << endl;
   }

   if (codeOnlyOpt.getCount())
      codeOnly = true;

   if (freqErrOpt.getCount())
      freqErr = StringUtils::asDouble(freqErrOpt.getValue()[0]) * 1e-6;
   else
      freqErr = 0;

   if (debugLevel)
      cout << "# Receiver frequency error: " << freqErr * 1e6 << " ppm" << endl;

   if (runTimeOpt.getCount())
   {
      double rt = asDouble(runTimeOpt.getValue()[0]);
      periods_to_generate = static_cast<long unsigned>(rt*1.0e6);
   }

   if (debugLevel)
      cout << "# Running for : " << periods_to_generate
           << " periods (" << 1e3 * periods_to_generate/1.0e6
           << " msec)" << endl;

   // Compute the local oscilator frequencies, units seem to be radians/sample
   omega_lo.resize(LO_COUNT);
   omega_lo[0] = 2.0*gpstk::PI*rx_L1_LO/rx_sample_rate;
   omega_lo[1] = 2.0*gpstk::PI*rx_L2_LO/rx_sample_rate;

   vector<double> lo(LO_COUNT);
   lo[0] = omega_lo[0]/time_step / 2 /PI;
   lo[1] = omega_lo[1]/time_step / 2 /PI;

   if (debugLevel)
      cout << "# LO 1: " << setw(7) << lo[0] * 1e-6<< " MHz"
           <<    "  2: " << setw(7) << lo[1] * 1e-6<< " MHz"
           <<  endl
           << "# IF 1: " << setw(7) << (L1_FREQ_GPS - lo[0]) * 1e-3<< " kHz"
           <<    "  2: " << setw(7) << (L2_FREQ_GPS - lo[1]) * 1e-3<< " kHz"
           <<  endl;

   for (int i=0; i < codeOpt.getCount(); i++)
   {
      string val=codeOpt.getValue()[i];
      const char delim(':');
      if (numWords(val, delim) != 6)
      {
         cout << "Error in code parameter:" << val << endl;
         exit(-1);
      }

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

      if (code.size() > 2 || nav.size() > 2 || band <1 || band > LO_COUNT ||
          prn < 1 || prn >32)
      {
         cout << "code:" << code << " band:" << band << " prn:" << prn
              << " offset:" << offset << " nav:" << nav << endl
              << "Error in specifying code. Ignoring this code." << endl;
         exit(-1);
      }

      // This is the number of P code chips in one sample. If this
      // is not around or less than 1/2, we have a problem
      double sampleRate = 1.0/(rx_sample_rate); //sec
      double chips_per_sample_base = gpstk::PY_CHIP_FREQ_GPS * sampleRate;

      switch(band)
      {
         case 1: doppler *= sampleRate / L1_MULT_GPS; break;
         case 2: doppler *= sampleRate / L2_MULT_GPS; break;
      }

      doppler *= 1-freqErr;
      chips_per_sample_base *= 1-freqErr;

      // Create and configure the SV source
      SVSource* src = new SVSource(prn, band);
      src->zchips_per_sample = chips_per_sample_base;
      src->doppler = doppler;
      src->ca_modulation = isLike(code, "c");
      src->p_modulation = isLike(code, "p");
      src->ca_nav = isLike(nav, "c") && src->ca_modulation;
      src->p_nav = isLike(nav, "p") && src->p_modulation;
      src->p_amplitude = p_amplitude;
      src->ca_amplitude = ca_amplitude;
      // offset needs to be provided to the SVSource in units of P chips
      src->slewZChipFraction(offset * gpstk::PY_CHIP_FREQ_GPS * 1.0e-6);

      if (codeOnlyOpt.getCount())
         src->code_only = true;

      if (debugLevel)
         src->dump(cout);

      sv_sources.push_back(src);
   }
   return true;

}