//----------------------------------------------------------------------------- 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++; } }
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; }
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; }
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; }