Changeset 1555 in ntrip
- Timestamp:
- Feb 2, 2009, 12:35:36 PM (16 years ago)
- Location:
- trunk/BNC
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/BNC/bnc.pro
r1535 r1555 2 2 # Switch to debug configuration 3 3 # ----------------------------- 4 CONFIG -= debug5 CONFIG += release4 CONFIG += debug 5 CONFIG -= release 6 6 7 7 DEFINES += NO_RTCM3_MAIN -
trunk/BNC/bncgetthread.cpp
r1554 r1555 72 72 const QByteArray& format) { 73 73 74 _format = format;75 76 int iSep = rawInpFileName.lastIndexOf(QDir::separator());77 _staID = rawInpFileName.mid(iSep+1,4);78 79 initialize();80 81 _inspSegm = 0;82 83 74 _rawInpFile = new QFile(rawInpFileName); 84 75 _rawInpFile->open(QIODevice::ReadOnly); 85 86 if (!_rnx) {87 cerr << "no RINEX path specified" << endl;88 ::exit(1); 89 }76 _format = format; 77 _staID = rawInpFileName.mid( 78 rawInpFileName.lastIndexOf(QDir::separator())+1,4); 79 80 initialize(); 90 81 } 91 82 … … 98 89 const QByteArray& nmea, 99 90 const QByteArray& ntripVersion, int iMount) { 100 101 setTerminationEnabled(true); 102 103 _mountPoint = mountPoint; 104 _staID = mountPoint.path().mid(1).toAscii(); 105 _format = format; 106 _latitude = latitude; 107 _longitude = longitude; 108 _nmea = nmea; 91 _rawInpFile = 0; 92 _mountPoint = mountPoint; 93 _staID = mountPoint.path().mid(1).toAscii(); 94 _format = format; 95 _latitude = latitude; 96 _longitude = longitude; 97 _nmea = nmea; 109 98 _ntripVersion = ntripVersion; 110 _iMount = iMount; // index in mountpoints array99 _iMount = iMount; // index in mountpoints array 111 100 112 101 initialize(); 113 102 } 114 103 115 // Initialization 104 // Initialization (common part of the constructor) 116 105 //////////////////////////////////////////////////////////////////////////// 117 106 void bncGetThread::initialize() { 118 107 119 108 setTerminationEnabled(true); 109 120 110 bncApp* app = (bncApp*) qApp; 121 app->connect(this, SIGNAL(newMessage(QByteArray,bool)), 122 app, SLOT(slotMessage(const QByteArray,bool))); 111 112 connect(this, SIGNAL(newMessage(QByteArray,bool)), 113 app, SLOT(slotMessage(const QByteArray,bool))); 123 114 124 115 _isToBeDeleted = false; 125 _decoder = 0; 126 _query = 0; 127 _timeOut = 20*1000; // 20 seconds 128 _nextSleep = 1; // 1 second 129 _rawInpFile = 0; 130 _rawOutFile = 0; 131 _staID_orig = _staID; 116 _decoder = 0; 117 _query = 0; 118 _nextSleep = 0; 119 _rawOutFile = 0; 120 _staID_orig = _staID; 132 121 133 122 // Check name conflict … … 153 142 } 154 143 155 // Notice threshold156 // ----------------157 _inspSegm = 50;158 if ( settings.value("obsRate").toString().isEmpty() ) { _inspSegm = 0; }159 if ( settings.value("obsRate").toString().indexOf("5 Hz") != -1 ) { _inspSegm = 2; }160 if ( settings.value("obsRate").toString().indexOf("1 Hz") != -1 ) { _inspSegm = 10; }161 if ( settings.value("obsRate").toString().indexOf("0.5 Hz") != -1 ) { _inspSegm = 20; }162 if ( settings.value("obsRate").toString().indexOf("0.2 Hz") != -1 ) { _inspSegm = 40; }163 if ( settings.value("obsRate").toString().indexOf("0.1 Hz") != -1 ) { _inspSegm = 50; }164 _adviseFail = settings.value("adviseFail").toInt();165 _adviseReco = settings.value("adviseReco").toInt();166 _makePause = false;167 if ( Qt::CheckState(settings.value("makePause").toInt()) == Qt::Checked) {_makePause = true; }168 _adviseScript = settings.value("adviseScript").toString();169 expandEnvVar(_adviseScript);170 171 // Latency interval/average172 // ------------------------173 _perfIntr = 86400;174 if ( settings.value("perfIntr").toString().isEmpty() ) { _perfIntr = 0; }175 if ( settings.value("perfIntr").toString().indexOf("2 sec") != -1 ) { _perfIntr = 2; }176 if ( settings.value("perfIntr").toString().indexOf("10 sec") != -1 ) { _perfIntr = 10; }177 if ( settings.value("perfIntr").toString().indexOf("1 min") != -1 ) { _perfIntr = 60; }178 if ( settings.value("perfIntr").toString().indexOf("5 min") != -1 ) { _perfIntr = 300; }179 if ( settings.value("perfIntr").toString().indexOf("15 min") != -1 ) { _perfIntr = 900; }180 if ( settings.value("perfIntr").toString().indexOf("1 hour") != -1 ) { _perfIntr = 3600; }181 if ( settings.value("perfIntr").toString().indexOf("6 hours") != -1 ) { _perfIntr = 21600; }182 if ( settings.value("perfIntr").toString().indexOf("1 day") != -1 ) { _perfIntr = 86400; }183 184 // RTCM message types185 // ------------------186 _checkMountPoint = settings.value("miscMount").toString();187 188 144 // RINEX writer 189 145 // ------------ … … 191 147 if ( settings.value("rnxPath").toString().isEmpty() ) { 192 148 _rnx = 0; 149 if (_rawInpFile) { 150 cerr << "no RINEX path specified" << endl; 151 ::exit(1); 152 } 193 153 } 194 154 else { … … 196 156 _longitude, _nmea); 197 157 } 198 _rnx_set_position = false; 199 200 connect(((bncApp*)qApp), SIGNAL(newEphGPS(gpsephemeris)), 201 this, SLOT(slotNewEphGPS(gpsephemeris))); 202 158 159 // Serial Port 160 // ----------- 203 161 if (settings.value("serialMountPoint").toString() == _staID) { 204 162 _serialPort = new QextSerialPort( … … 288 246 // _rawOutFile->open(QIODevice::WriteOnly); 289 247 248 249 // Instantiate the decoder 250 // ----------------------- 251 if (_format.indexOf("RTCM_2") != -1) { 252 emit(newMessage(_staID + ": Get data in RTCM 2.x format", true)); 253 _decoder = new RTCM2Decoder(_staID.data()); 254 } 255 else if (_format.indexOf("RTCM_3") != -1) { 256 emit(newMessage(_staID + ": Get data in RTCM 3.x format", true)); 257 _decoder = new RTCM3Decoder(_staID); 258 connect((RTCM3Decoder*) _decoder, SIGNAL(newMessage(QByteArray,bool)), 259 this, SIGNAL(newMessage(QByteArray,bool))); 260 } 261 else if (_format.indexOf("RTIGS") != -1) { 262 emit(newMessage(_staID + ": Get data in RTIGS format", true)); 263 _decoder = new RTIGSDecoder(); 264 } 265 else if (_format.indexOf("GPSS") != -1 || _format.indexOf("BNC") != -1) { 266 emit(newMessage(_staID + ": Get Data in GPSS format", true)); 267 _decoder = new gpssDecoder(); 268 } 269 else if (_format.indexOf("ZERO") != -1) { 270 emit(newMessage(_staID + ": Get data in original format", true)); 271 _decoder = new bncZeroDecoder(_staID); 272 } 273 else { 274 emit(newMessage(_staID + ": Unknown data format " + _format, true)); 275 _isToBeDeleted = true; 276 delete this; 277 } 278 290 279 msleep(100); //sleep 0.1 sec 291 280 } … … 311 300 } 312 301 313 // InitRun302 // Run 314 303 //////////////////////////////////////////////////////////////////////////// 315 t_irc bncGetThread::initRun() { 316 304 void bncGetThread::run() { 305 306 while (true) { 307 try { 308 if (_isToBeDeleted) { 309 QThread::exit(0); 310 this->deleteLater(); 311 return; 312 } 313 314 if (tryReconnect() != success) { 315 continue; 316 } 317 318 // Delete old observations 319 // ----------------------- 320 QListIterator<p_obs> itOld(_decoder->_obsList); 321 while (itOld.hasNext()) { 322 delete itOld.next(); 323 } 324 _decoder->_obsList.clear(); 325 326 // Read Data 327 // --------- 328 QByteArray data; 329 if (_query) { 330 _query->waitForReadyRead(data); 331 } 332 else if (_rawInpFile) { 333 const qint64 maxBytes = 1024; 334 data = _rawInpFile->read(maxBytes); 335 if (data.isEmpty()) { 336 cout << "no more data" << endl; 337 ::exit(0); 338 } 339 } 340 qint64 nBytes = data.size(); 341 342 // Timeout, reconnect 343 // ------------------ 344 if (nBytes == 0) { 345 emit(newMessage(_staID + ": Data timeout, reconnecting", true)); 346 continue; 347 } 348 else { 349 emit newBytes(_staID, nBytes); 350 } 351 352 // Output Data 353 // ----------- 354 if (_rawOutFile) { 355 _rawOutFile->write(data); 356 _rawOutFile->flush(); 357 } 358 if (_serialPort) { 359 _serialPort->write(data); 360 } 361 362 // Decode Data 363 // ----------- 364 vector<string> errmsg; 365 _decoder->Decode(data.data(), data.size(), errmsg); 366 367 // Perform various scans and checks 368 // -------------------------------- 369 scanRTCM(); 370 checkLatency(); 371 372 // Loop over all observations (observations output) 373 // ------------------------------------------------ 374 QListIterator<p_obs> it(_decoder->_obsList); 375 while (it.hasNext()) { 376 p_obs obs = it.next(); 377 378 // Check observation epoch 379 // ----------------------- 380 if (!_rawInpFile && !dynamic_cast<gpssDecoder*>(_decoder)) { 381 int week; 382 double sec; 383 currentGPSWeeks(week, sec); 384 const double secPerWeek = 7.0 * 24.0 * 3600.0; 385 386 if (week < obs->_o.GPSWeek) { 387 week += 1; 388 sec -= secPerWeek; 389 } 390 if (week > obs->_o.GPSWeek) { 391 week -= 1; 392 sec += secPerWeek; 393 } 394 double dt = fabs(sec - obs->_o.GPSWeeks); 395 const double maxDt = 600.0; 396 if (week != obs->_o.GPSWeek || dt > maxDt) { 397 emit( newMessage(_staID + ": Wrong observation epoch(s)", true) ); 398 delete obs; 399 continue; 400 } 401 } 402 403 // RINEX Output 404 // ------------ 405 if (_rnx) { 406 long iSec = long(floor(obs->_o.GPSWeeks+0.5)); 407 long newTime = obs->_o.GPSWeek * 7*24*3600 + iSec; 408 if (_samplingRate == 0 || iSec % _samplingRate == 0) { 409 _rnx->deepCopy(obs); 410 } 411 _rnx->dumpEpoch(newTime); 412 } 413 414 // Emit new observation signal 415 // --------------------------- 416 bool firstObs = (obs == _decoder->_obsList.first()); 417 obs->_status = t_obs::posted; 418 emit newObs(_staID, firstObs, obs); 419 } 420 _decoder->_obsList.clear(); 421 } 422 catch (const char* msg) { 423 emit(newMessage(_staID + msg, true)); 424 tryReconnect(); 425 } 426 catch (...) { 427 emit(newMessage(_staID + "unknown exception", true)); 428 tryReconnect(); 429 } 430 } 431 } 432 433 // Try Re-Connect 434 //////////////////////////////////////////////////////////////////////////// 435 t_irc bncGetThread::tryReconnect() { 436 437 // Easy Return 438 // ----------- 439 if (_query && _query->status() == bncNetQuery::running) { 440 _nextSleep = 0; 441 return success; 442 } 443 444 // Start a new query 445 // ----------------- 317 446 if (!_rawInpFile) { 447 448 sleep(_nextSleep); 449 if (_nextSleep == 0) { 450 _nextSleep = 1; 451 } 452 else { 453 _nextSleep = 2 * _nextSleep; 454 if (_nextSleep > 256) { 455 _nextSleep = 256; 456 } 457 } 458 318 459 delete _query; 319 460 if (_ntripVersion == "R") { … … 338 479 } 339 480 340 // Instantiate the filter341 // ----------------------342 if (!_decoder) {343 if (_format.indexOf("RTCM_2") != -1) {344 emit(newMessage(_staID + ": Get data in RTCM 2.x format", true));345 _decoder = new RTCM2Decoder(_staID.data());346 }347 else if (_format.indexOf("RTCM_3") != -1) {348 emit(newMessage(_staID + ": Get data in RTCM 3.x format", true));349 _decoder = new RTCM3Decoder(_staID);350 connect((RTCM3Decoder*) _decoder, SIGNAL(newMessage(QByteArray,bool)),351 this, SIGNAL(newMessage(QByteArray,bool)));352 }353 else if (_format.indexOf("RTIGS") != -1) {354 emit(newMessage(_staID + ": Get data in RTIGS format", true));355 _decoder = new RTIGSDecoder();356 }357 else if (_format.indexOf("GPSS") != -1 || _format.indexOf("BNC") != -1) {358 emit(newMessage(_staID + ": Get Data in GPSS format", true));359 _decoder = new gpssDecoder();360 }361 else if (_format.indexOf("ZERO") != -1) {362 emit(newMessage(_staID + ": Get data in original format", true));363 _decoder = new bncZeroDecoder(_staID);364 }365 else {366 emit(newMessage(_staID + ": Unknown data format " + _format, true));367 if (_rawInpFile) {368 cerr << "Uknown data format" << endl;369 delete this;370 }371 else {372 return fatal;373 }374 }375 }376 return success;377 }378 379 // Run380 ////////////////////////////////////////////////////////////////////////////381 void bncGetThread::run() {382 383 const double maxDt = 600.0; // Check observation epoch384 bool wrongEpoch = false;385 bool decode = true;386 int numSucc = 0;387 int secSucc = 0;388 int secFail = 0;389 int initPause = 30; // Initial pause for corrupted streams390 int currPause = 0;391 bool begCorrupt = false;392 bool endCorrupt = false;393 bool followSec = false;394 int oldSecGPS= 0;395 int newSecGPS = 0;396 int numGaps = 0;397 int diffSecGPS = 0;398 int numLat = 0;399 double sumLat = 0.;400 double sumLatQ = 0.;401 double meanDiff = 0.;402 double minLat = maxDt;403 double maxLat = -maxDt;404 double curLat = 0.;405 406 _decodeTime = QDateTime::currentDateTime();407 _decodeSucc = QDateTime::currentDateTime();408 t_irc irc = initRun();409 410 if (irc == fatal) {411 QThread::exit(1);412 this->deleteLater();413 return;414 }415 else if (irc != success) {416 emit(newMessage(_staID + ": initRun failed, reconnecting", true));417 tryReconnect();418 }419 420 if (initPause < _inspSegm) {421 initPause = _inspSegm;422 }423 if(!_makePause) {initPause = 0;}424 currPause = initPause;425 426 // Read Incoming Data427 // ------------------428 while (true) {429 if (_isToBeDeleted) {430 QThread::exit(0);431 this->deleteLater();432 return;433 }434 try {435 if (_query && _query->status() != bncNetQuery::running) {436 emit(newMessage(_staID + ": Internet query not running, reconnecting", true));437 tryReconnect();438 }439 440 QListIterator<p_obs> it(_decoder->_obsList);441 while (it.hasNext()) {442 delete it.next();443 }444 _decoder->_obsList.clear();445 446 qint64 nBytes = 0;447 448 QByteArray data;449 450 if (_query) {451 _query->waitForReadyRead(data);452 nBytes = data.size();453 }454 else if (_rawInpFile) {455 const qint64 maxBytes = 1024;456 nBytes = maxBytes;457 }458 459 if (nBytes > 0) {460 emit newBytes(_staID, nBytes);461 462 if (_rawInpFile) {463 data = _rawInpFile->read(nBytes);464 if (data.isEmpty()) {465 cout << "no more data" << endl;466 ::exit(0);467 }468 }469 470 if (_rawOutFile) {471 _rawOutFile->write(data);472 _rawOutFile->flush();473 }474 475 if (_serialPort) {476 _serialPort->write(data);477 }478 479 if (_inspSegm<1) {480 vector<string> errmsg;481 _decoder->Decode(data.data(), data.size(), errmsg);482 #ifdef DEBUG_RTCM2_2021483 for (unsigned ii = 0; ii < errmsg.size(); ii++) {484 emit newMessage(_staID + ": " + errmsg[ii].c_str(), false);485 }486 #endif487 }488 else {489 490 // Decode data491 // -----------492 if (!_decodePause.isValid() ||493 _decodePause.secsTo(QDateTime::currentDateTime()) >= currPause ) {494 495 if (decode) {496 vector<string> errmsg;497 if ( _decoder->Decode(data.data(), data.size(), errmsg) == success ) {498 numSucc += 1;499 }500 if ( _decodeTime.secsTo(QDateTime::currentDateTime()) > _inspSegm ) {501 decode = false;502 }503 #ifdef DEBUG_RTCM2_2021504 for (unsigned ii = 0; ii < errmsg.size(); ii++) {505 emit newMessage(_staID + ": " + errmsg[ii].c_str(), false);506 }507 #endif508 }509 510 // Check - once per inspect segment511 // --------------------------------512 if (!decode) {513 _decodeTime = QDateTime::currentDateTime();514 if (numSucc>0) {515 secSucc += _inspSegm;516 _decodeSucc = QDateTime::currentDateTime();517 if (secSucc > _adviseReco * 60) {518 secSucc = _adviseReco * 60 + 1;519 }520 numSucc = 0;521 currPause = initPause;522 _decodePause.setDate(QDate());523 _decodePause.setTime(QTime());524 }525 else {526 secFail += _inspSegm;527 secSucc = 0;528 if (secFail > _adviseFail * 60) {529 secFail = _adviseFail * 60 + 1;530 }531 if (!_decodePause.isValid() || !_makePause) {532 _decodePause = QDateTime::currentDateTime();533 }534 else {535 _decodePause.setDate(QDate());536 _decodePause.setTime(QTime());537 secFail = secFail + currPause - _inspSegm;538 currPause = currPause * 2;539 if (currPause > 960) {540 currPause = 960;541 }542 }543 }544 545 // End corrupt threshold546 // ---------------------547 if ( begCorrupt && !endCorrupt && secSucc > _adviseReco * 60 ) {548 _endDateCor = QDateTime::currentDateTime().addSecs(- _adviseReco * 60).toUTC().date().toString("yy-MM-dd");549 _endTimeCor = QDateTime::currentDateTime().addSecs(- _adviseReco * 60).toUTC().time().toString("hh:mm:ss");550 emit(newMessage((_staID + ": Recovery threshold exceeded, corruption ended "551 + _endDateCor + " " + _endTimeCor).toAscii(), true));552 callScript(("End_Corrupted " + _endDateCor + " " + _endTimeCor + " Begin was " + _begDateCor + " " + _begTimeCor).toAscii());553 endCorrupt = true;554 begCorrupt = false;555 secFail = 0;556 }557 else {558 559 // Begin corrupt threshold560 // -----------------------561 if ( !begCorrupt && secFail > _adviseFail * 60 ) {562 _begDateCor = _decodeSucc.toUTC().date().toString("yy-MM-dd");563 _begTimeCor = _decodeSucc.toUTC().time().toString("hh:mm:ss");564 emit(newMessage((_staID + ": Failure threshold exceeded, corrupted since "565 + _begDateCor + " " + _begTimeCor).toAscii(), true));566 callScript(("Begin_Corrupted " + _begDateCor + " " + _begTimeCor).toAscii());567 begCorrupt = true;568 endCorrupt = false;569 secSucc = 0;570 numSucc = 0;571 }572 }573 decode = true;574 }575 }576 }577 578 // End outage threshold579 // --------------------580 if ( _decodeStart.isValid() && _decodeStart.secsTo(QDateTime::currentDateTime()) > _adviseReco * 60 ) {581 _decodeStart.setDate(QDate());582 _decodeStart.setTime(QTime());583 if (_inspSegm>0) {584 _endDateOut = QDateTime::currentDateTime().addSecs(- _adviseReco * 60).toUTC().date().toString("yy-MM-dd");585 _endTimeOut = QDateTime::currentDateTime().addSecs(- _adviseReco * 60).toUTC().time().toString("hh:mm:ss");586 emit(newMessage((_staID + ": Recovery threshold exceeded, outage ended "587 + _endDateOut + " " + _endTimeOut).toAscii(), true));588 callScript(("End_Outage " + _endDateOut + " " + _endTimeOut + " Begin was " + _begDateOut + " " + _begTimeOut).toAscii());589 }590 }591 592 // RTCM scan output593 // ----------------594 if ( _checkMountPoint == _staID || _checkMountPoint == "ALL" ) {595 bncSettings settings;596 if ( Qt::CheckState(settings.value("scanRTCM").toInt()) == Qt::Checked) {597 598 // RTCMv3 message types599 // --------------------600 if (0<_decoder->_typeList.size()) {601 QString type;602 for (int ii=0;ii<_decoder->_typeList.size();ii++) {603 type = QString("%1 ").arg(_decoder->_typeList[ii]);604 emit(newMessage(_staID + ": Received message type " + type.toAscii(), true));605 }606 }607 608 // RTCMv3 antenna descriptor609 // -------------------------610 if (0<_decoder->_antType.size()) {611 QString ant1;612 for (int ii=0;ii<_decoder->_antType.size();ii++) {613 ant1 = QString("%1 ").arg(_decoder->_antType[ii]);614 emit(newMessage(_staID + ": Antenna descriptor " + ant1.toAscii(), true));615 }616 }617 }618 }619 620 // Antenna Coordinates621 // -------------------622 for (int ii=0; ii <_decoder->_antList.size(); ii++) {623 QByteArray antT;624 if (_decoder->_antList[ii].type == GPSDecoder::t_antInfo::ARP) {625 antT = "ARP";626 }627 else if (_decoder->_antList[ii].type == GPSDecoder::t_antInfo::APC) {628 antT = "APC";629 }630 emit(newAntCrd(_staID, _decoder->_antList[ii].xx,631 _decoder->_antList[ii].yy, _decoder->_antList[ii].zz,632 antT));633 }634 635 _decoder->_typeList.clear();636 _decoder->_antType.clear();637 _decoder->_antList.clear();638 639 // Loop over all observations (observations output)640 // ------------------------------------------------641 QListIterator<p_obs> it(_decoder->_obsList);642 while (it.hasNext()) {643 p_obs obs = it.next();644 645 // Check observation epoch646 // -----------------------647 if (!_rawInpFile && !dynamic_cast<gpssDecoder*>(_decoder)) {648 int week;649 double sec;650 currentGPSWeeks(week, sec);651 const double secPerWeek = 7.0 * 24.0 * 3600.0;652 653 if (week < obs->_o.GPSWeek) {654 week += 1;655 sec -= secPerWeek;656 }657 if (week > obs->_o.GPSWeek) {658 week -= 1;659 sec += secPerWeek;660 }661 double dt = fabs(sec - obs->_o.GPSWeeks);662 if (week != obs->_o.GPSWeek || dt > maxDt) {663 if (!wrongEpoch) {664 emit( newMessage(_staID + ": Wrong observation epoch(s)", true) );665 wrongEpoch = true;666 }667 delete obs;668 continue;669 }670 else {671 wrongEpoch = false;672 673 // Latency and completeness674 // ------------------------675 if (_perfIntr>0) {676 if ( _checkMountPoint == _staID || _checkMountPoint == "ALL" ) {677 newSecGPS = static_cast<int>(obs->_o.GPSWeeks);678 if (newSecGPS != oldSecGPS) {679 if (newSecGPS % _perfIntr < oldSecGPS % _perfIntr) {680 if (numLat>0) {681 if (meanDiff>0.) {682 emit( newMessage(QString("%1: Mean latency %2 sec, min %3, max %4, rms %5, %6 epochs, %7 gaps")683 .arg(_staID.data())684 .arg(int(sumLat/numLat*100)/100.)685 .arg(int(minLat*100)/100.)686 .arg(int(maxLat*100)/100.)687 .arg(int((sqrt((sumLatQ - sumLat * sumLat / numLat)/numLat))*100)/100.)688 .arg(numLat)689 .arg(numGaps)690 .toAscii(), true) );691 } else {692 emit( newMessage(QString("%1: Mean latency %2 sec, min %3, max %4, rms %5, %6 epochs")693 .arg(_staID.data())694 .arg(int(sumLat/numLat*100)/100.)695 .arg(int(minLat*100)/100.)696 .arg(int(maxLat*100)/100.)697 .arg(int((sqrt((sumLatQ - sumLat * sumLat / numLat)/numLat))*100)/100.)698 .arg(numLat)699 .toAscii(), true) );700 }701 }702 meanDiff = diffSecGPS/numLat;703 diffSecGPS = 0;704 numGaps = 0;705 sumLat = 0.;706 sumLatQ = 0.;707 numLat = 0;708 minLat = maxDt;709 maxLat = -maxDt;710 }711 if (followSec) {712 diffSecGPS += newSecGPS - oldSecGPS;713 if (meanDiff>0.) {714 if (newSecGPS - oldSecGPS > 1.5 * meanDiff) {715 numGaps += 1;716 }717 }718 }719 curLat = sec - obs->_o.GPSWeeks;720 sumLat += curLat;721 sumLatQ += curLat * curLat;722 if (curLat < minLat) minLat = curLat;723 if (curLat >= maxLat) maxLat = curLat;724 numLat += 1;725 oldSecGPS = newSecGPS;726 followSec = true;727 }728 }729 }730 }731 }732 733 // RINEX Output734 // ------------735 if (_rnx) {736 bool dump = true;737 738 //// // RTCMv2 XYZ739 //// // ----------740 //// RTCM2Decoder* decoder2 = dynamic_cast<RTCM2Decoder*>(_decoder);741 //// if ( decoder2 && !_rnx_set_position ) {742 //// double stax, stay, staz;743 //// double dL1[3], dL2[3];744 //// if ( decoder2->getStaCrd(stax, stay, staz,745 //// dL1[0], dL1[1], dL1[2],746 //// dL2[0], dL2[1], dL2[2]) == success ) {747 ////748 //// if ( _checkMountPoint == _staID || _checkMountPoint == "ALL" ) {749 //// QString ant1;750 //// ant1 = QString("%1 ").arg(stax,0,'f',4);751 //// emit(newMessage(_staID + ": ARP X " + ant1.toAscii() + "m" ));752 //// ant1 = QString("%1 ").arg(stay,0,'f',4);753 //// emit(newMessage(_staID + ": ARP Y " + ant1.toAscii() + "m" ));754 //// ant1 = QString("%1 ").arg(staz,0,'f',4);755 //// emit(newMessage(_staID + ": ARP Z " + ant1.toAscii() + "m" ));756 //// ant1 = QString("%1 ").arg(dL1[0],0,'f',4);757 //// emit(newMessage(_staID + ": L1 APC DX " + ant1.toAscii() + "m" ));758 //// ant1 = QString("%1 ").arg(dL1[1],0,'f',4);759 //// emit(newMessage(_staID + ": L1 APC DY " + ant1.toAscii() + "m" ));760 //// ant1 = QString("%1 ").arg(dL1[2],0,'f',4);761 //// emit(newMessage(_staID + ": L1 APC DZ " + ant1.toAscii() + "m" ));762 //// ant1 = QString("%1 ").arg(dL2[0],0,'f',4);763 //// emit(newMessage(_staID + ": L2 APC DX " + ant1.toAscii() + "m" ));764 //// ant1 = QString("%1 ").arg(dL2[1],0,'f',4);765 //// emit(newMessage(_staID + ": L2 APC DY " + ant1.toAscii() + "m" ));766 //// ant1 = QString("%1 ").arg(dL2[2],0,'f',4);767 //// emit(newMessage(_staID + ": L2 APC DZ " + ant1.toAscii() + "m" ));768 //// }769 //// _rnx_set_position = true;770 //// }771 //// }772 773 if ( dump ) {774 long iSec = long(floor(obs->_o.GPSWeeks+0.5));775 long newTime = obs->_o.GPSWeek * 7*24*3600 + iSec;776 if (_samplingRate == 0 || iSec % _samplingRate == 0) {777 _rnx->deepCopy(obs);778 }779 _rnx->dumpEpoch(newTime);780 }781 }782 783 // Emit new observation signal784 // ---------------------------785 bool firstObs = (obs == _decoder->_obsList.first());786 obs->_status = t_obs::posted;787 emit newObs(_staID, firstObs, obs);788 }789 _decoder->_obsList.clear();790 791 }792 793 // Timeout, reconnect794 // ------------------795 else {796 emit(newMessage(_staID + ": Data timeout, reconnecting", true));797 tryReconnect();798 }799 }800 catch (const char* msg) {801 emit(newMessage(_staID + msg, true));802 tryReconnect();803 }804 }805 }806 807 // Try Re-Connect808 ////////////////////////////////////////////////////////////////////////////809 void bncGetThread::tryReconnect() {810 481 if (_rnx) { 811 482 _rnx->setReconnectFlag(true); 812 483 } 813 if ( !_decodeStart.isValid()) { 814 _decodeStop = QDateTime::currentDateTime(); 815 } 816 while (1) { 817 sleep(_nextSleep); 818 if ( initRun() == success ) { 819 if ( !_decodeStop.isValid()) { 820 _decodeStart = QDateTime::currentDateTime(); 821 } 822 break; 823 } 824 else { 825 826 // Begin outage threshold 827 // ---------------------- 828 if ( _decodeStop.isValid() && _decodeStop.secsTo(QDateTime::currentDateTime()) > _adviseFail * 60 ) { 829 _decodeStop.setDate(QDate()); 830 _decodeStop.setTime(QTime()); 831 if (_inspSegm>0) { 832 _begDateOut = _decodeTime.toUTC().date().toString("yy-MM-dd"); 833 _begTimeOut = _decodeTime.toUTC().time().toString("hh:mm:ss"); 834 emit(newMessage((_staID + ": Failure threshold exceeded, outage since " 835 + _begDateOut + " " + _begTimeOut).toAscii(), true)); 836 callScript(("Begin_Outage " + _begDateOut + " " + _begTimeOut).toAscii()); 837 } 838 } 839 _nextSleep *= 2; 840 if (_nextSleep > 256) { 841 _nextSleep = 256; 842 } 843 _nextSleep += rand() % 6; 844 } 845 } 846 _nextSleep = 1; 847 } 848 849 // Call advisory notice script 850 //////////////////////////////////////////////////////////////////////////// 851 void bncGetThread::callScript(const char* _comment) { 852 QMutexLocker locker(&_mutex); 853 if (!_adviseScript.isEmpty()) { 854 msleep(1); 855 #ifdef WIN32 856 QProcess::startDetached(_adviseScript, QStringList() << _staID << _comment) ; 857 #else 858 QProcess::startDetached("nohup", QStringList() << _adviseScript << _staID << _comment) ; 859 #endif 860 } 484 485 return success; 486 } 487 488 // RTCM scan output 489 ////////////////////////////////////////////////////////////////////////////// 490 void bncGetThread::scanRTCM() { 491 492 bncSettings settings; 493 if ( Qt::CheckState(settings.value("scanRTCM").toInt()) == Qt::Checked) { 494 495 // RTCMv3 message types 496 // -------------------- 497 for (int ii = 0; ii <_decoder->_typeList.size(); ii++) { 498 QString type = QString("%1 ").arg(_decoder->_typeList[ii]); 499 emit(newMessage(_staID + ": Received message type " + type.toAscii(), true)); 500 } 501 502 // RTCMv3 antenna descriptor 503 // ------------------------- 504 for (int ii=0;ii<_decoder->_antType.size();ii++) { 505 QString ant1 = QString("%1 ").arg(_decoder->_antType[ii]); 506 emit(newMessage(_staID + ": Antenna descriptor " + ant1.toAscii(), true)); 507 } 508 509 // Antenna Coordinates 510 // ------------------- 511 for (int ii=0; ii <_decoder->_antList.size(); ii++) { 512 QByteArray antT; 513 if (_decoder->_antList[ii].type == GPSDecoder::t_antInfo::ARP) { 514 antT = "ARP"; 515 } 516 else if (_decoder->_antList[ii].type == GPSDecoder::t_antInfo::APC) { 517 antT = "APC"; 518 } 519 emit(newAntCrd(_staID, _decoder->_antList[ii].xx, 520 _decoder->_antList[ii].yy, _decoder->_antList[ii].zz, 521 antT)); 522 } 523 } 524 525 _decoder->_typeList.clear(); 526 _decoder->_antType.clear(); 527 _decoder->_antList.clear(); 861 528 } 862 529 863 530 // 864 531 ////////////////////////////////////////////////////////////////////////////// 865 void bncGetThread::slotNewEphGPS(gpsephemeris gpseph) { 866 RTCM2Decoder* decoder = dynamic_cast<RTCM2Decoder*>(_decoder); 867 868 if ( decoder ) { 869 QMutexLocker locker(&_mutex); 870 871 string storedPRN; 872 vector<int> IODs; 873 874 if ( decoder->storeEph(gpseph, storedPRN, IODs) ) { 875 #ifdef DEBUG_RTCM2_2021 876 QString msg = _staID + QString(": Stored eph %1 IODs").arg(storedPRN.c_str()); 877 878 for (unsigned ii = 0; ii < IODs.size(); ii++) { 879 msg += QString(" %1").arg(IODs[ii],4); 880 } 881 882 emit(newMessage(msg.toAscii(), false)); 883 #endif 884 } 885 } 886 } 532 void bncGetThread::checkLatency() { 533 //// // Notice threshold 534 //// // ---------------- 535 //// _inspSegm = 50; 536 //// if ( settings.value("obsRate").toString().isEmpty() ) { _inspSegm = 0; } 537 //// if ( settings.value("obsRate").toString().indexOf("5 Hz") != -1 ) { _inspSegm = 2; } 538 //// if ( settings.value("obsRate").toString().indexOf("1 Hz") != -1 ) { _inspSegm = 10; } 539 //// if ( settings.value("obsRate").toString().indexOf("0.5 Hz") != -1 ) { _inspSegm = 20; } 540 //// if ( settings.value("obsRate").toString().indexOf("0.2 Hz") != -1 ) { _inspSegm = 40; } 541 //// if ( settings.value("obsRate").toString().indexOf("0.1 Hz") != -1 ) { _inspSegm = 50; } 542 //// _adviseFail = settings.value("adviseFail").toInt(); 543 //// _adviseReco = settings.value("adviseReco").toInt(); 544 //// _makePause = false; 545 //// if ( Qt::CheckState(settings.value("makePause").toInt()) == Qt::Checked) {_makePause = true; } 546 //// _adviseScript = settings.value("adviseScript").toString(); 547 //// expandEnvVar(_adviseScript); 548 //// 549 //// // Latency interval/average 550 //// // ------------------------ 551 //// _perfIntr = 86400; 552 //// if ( settings.value("perfIntr").toString().isEmpty() ) { _perfIntr = 0; } 553 //// if ( settings.value("perfIntr").toString().indexOf("2 sec") != -1 ) { _perfIntr = 2; } 554 //// if ( settings.value("perfIntr").toString().indexOf("10 sec") != -1 ) { _perfIntr = 10; } 555 //// if ( settings.value("perfIntr").toString().indexOf("1 min") != -1 ) { _perfIntr = 60; } 556 //// if ( settings.value("perfIntr").toString().indexOf("5 min") != -1 ) { _perfIntr = 300; } 557 //// if ( settings.value("perfIntr").toString().indexOf("15 min") != -1 ) { _perfIntr = 900; } 558 //// if ( settings.value("perfIntr").toString().indexOf("1 hour") != -1 ) { _perfIntr = 3600; } 559 //// if ( settings.value("perfIntr").toString().indexOf("6 hours") != -1 ) { _perfIntr = 21600; } 560 //// if ( settings.value("perfIntr").toString().indexOf("1 day") != -1 ) { _perfIntr = 86400; } 561 //// 562 //// // RTCM message types 563 //// // ------------------ 564 //// _checkMountPoint = settings.value("miscMount").toString(); 565 //// 566 //// 567 //// const double maxDt = 600.0; // Check observation epoch 568 //// bool wrongEpoch = false; 569 //// bool decode = true; 570 //// int numSucc = 0; 571 //// int secSucc = 0; 572 //// int secFail = 0; 573 //// int initPause = 30; // Initial pause for corrupted streams 574 //// int currPause = 0; 575 //// bool begCorrupt = false; 576 //// bool endCorrupt = false; 577 //// bool followSec = false; 578 //// int oldSecGPS= 0; 579 //// int newSecGPS = 0; 580 //// int numGaps = 0; 581 //// int diffSecGPS = 0; 582 //// int numLat = 0; 583 //// double sumLat = 0.; 584 //// double sumLatQ = 0.; 585 //// double meanDiff = 0.; 586 //// double minLat = maxDt; 587 //// double maxLat = -maxDt; 588 //// double curLat = 0.; 589 //// 590 //// 591 //// _decodeTime = QDateTime::currentDateTime(); 592 //// _decodeSucc = QDateTime::currentDateTime(); 593 //// 594 //// // Check - once per inspect segment 595 //// // -------------------------------- 596 //// if (!decode) { 597 //// _decodeTime = QDateTime::currentDateTime(); 598 //// if (numSucc>0) { 599 //// secSucc += _inspSegm; 600 //// _decodeSucc = QDateTime::currentDateTime(); 601 //// if (secSucc > _adviseReco * 60) { 602 //// secSucc = _adviseReco * 60 + 1; 603 //// } 604 //// numSucc = 0; 605 //// currPause = initPause; 606 //// _decodePause.setDate(QDate()); 607 //// _decodePause.setTime(QTime()); 608 //// } 609 //// else { 610 //// secFail += _inspSegm; 611 //// secSucc = 0; 612 //// if (secFail > _adviseFail * 60) { 613 //// secFail = _adviseFail * 60 + 1; 614 //// } 615 //// if (!_decodePause.isValid() || !_makePause) { 616 //// _decodePause = QDateTime::currentDateTime(); 617 //// } 618 //// else { 619 //// _decodePause.setDate(QDate()); 620 //// _decodePause.setTime(QTime()); 621 //// secFail = secFail + currPause - _inspSegm; 622 //// currPause = currPause * 2; 623 //// if (currPause > 960) { 624 //// currPause = 960; 625 //// } 626 //// } 627 //// } 628 //// 629 //// // End corrupt threshold 630 //// // --------------------- 631 //// if ( begCorrupt && !endCorrupt && secSucc > _adviseReco * 60 ) { 632 //// _endDateCor = QDateTime::currentDateTime().addSecs(- _adviseReco * 60).toUTC().date().toString("yy-MM-dd"); 633 //// _endTimeCor = QDateTime::currentDateTime().addSecs(- _adviseReco * 60).toUTC().time().toString("hh:mm:ss"); 634 //// emit(newMessage((_staID + ": Recovery threshold exceeded, corruption ended " 635 //// + _endDateCor + " " + _endTimeCor).toAscii(), true)); 636 //// callScript(("End_Corrupted " + _endDateCor + " " + _endTimeCor + " Begin was " + _begDateCor + " " + _begTimeCor).toAscii()); 637 //// endCorrupt = true; 638 //// begCorrupt = false; 639 //// secFail = 0; 640 //// } 641 //// else { 642 //// 643 //// // Begin corrupt threshold 644 //// // ----------------------- 645 //// if ( !begCorrupt && secFail > _adviseFail * 60 ) { 646 //// _begDateCor = _decodeSucc.toUTC().date().toString("yy-MM-dd"); 647 //// _begTimeCor = _decodeSucc.toUTC().time().toString("hh:mm:ss"); 648 //// emit(newMessage((_staID + ": Failure threshold exceeded, corrupted since " 649 //// + _begDateCor + " " + _begTimeCor).toAscii(), true)); 650 //// callScript(("Begin_Corrupted " + _begDateCor + " " + _begTimeCor).toAscii()); 651 //// begCorrupt = true; 652 //// endCorrupt = false; 653 //// secSucc = 0; 654 //// numSucc = 0; 655 //// } 656 //// } 657 //// decode = true; 658 //// } 659 //// } 660 //// } 661 //// 662 //// // End outage threshold 663 //// // -------------------- 664 //// if ( _decodeStart.isValid() && _decodeStart.secsTo(QDateTime::currentDateTime()) > _adviseReco * 60 ) { 665 //// _decodeStart.setDate(QDate()); 666 //// _decodeStart.setTime(QTime()); 667 //// if (_inspSegm>0) { 668 //// _endDateOut = QDateTime::currentDateTime().addSecs(- _adviseReco * 60).toUTC().date().toString("yy-MM-dd"); 669 //// _endTimeOut = QDateTime::currentDateTime().addSecs(- _adviseReco * 60).toUTC().time().toString("hh:mm:ss"); 670 //// emit(newMessage((_staID + ": Recovery threshold exceeded, outage ended " 671 //// + _endDateOut + " " + _endTimeOut).toAscii(), true)); 672 //// callScript(("End_Outage " + _endDateOut + " " + _endTimeOut + " Begin was " + _begDateOut + " " + _begTimeOut).toAscii()); 673 //// } 674 //// } 675 //// 676 //// else { 677 //// wrongEpoch = false; 678 //// 679 //// // Latency and completeness 680 //// // ------------------------ 681 //// if (_perfIntr>0) { 682 //// if ( _checkMountPoint == _staID || _checkMountPoint == "ALL" ) { 683 //// newSecGPS = static_cast<int>(obs->_o.GPSWeeks); 684 //// if (newSecGPS != oldSecGPS) { 685 //// if (newSecGPS % _perfIntr < oldSecGPS % _perfIntr) { 686 //// if (numLat>0) { 687 //// if (meanDiff>0.) { 688 //// emit( newMessage(QString("%1: Mean latency %2 sec, min %3, max %4, rms %5, %6 epochs, %7 gaps") 689 //// .arg(_staID.data()) 690 //// .arg(int(sumLat/numLat*100)/100.) 691 //// .arg(int(minLat*100)/100.) 692 //// .arg(int(maxLat*100)/100.) 693 //// .arg(int((sqrt((sumLatQ - sumLat * sumLat / numLat)/numLat))*100)/100.) 694 //// .arg(numLat) 695 //// .arg(numGaps) 696 //// .toAscii(), true) ); 697 //// } else { 698 //// emit( newMessage(QString("%1: Mean latency %2 sec, min %3, max %4, rms %5, %6 epochs") 699 //// .arg(_staID.data()) 700 //// .arg(int(sumLat/numLat*100)/100.) 701 //// .arg(int(minLat*100)/100.) 702 //// .arg(int(maxLat*100)/100.) 703 //// .arg(int((sqrt((sumLatQ - sumLat * sumLat / numLat)/numLat))*100)/100.) 704 //// .arg(numLat) 705 //// .toAscii(), true) ); 706 //// } 707 //// } 708 //// meanDiff = diffSecGPS/numLat; 709 //// diffSecGPS = 0; 710 //// numGaps = 0; 711 //// sumLat = 0.; 712 //// sumLatQ = 0.; 713 //// numLat = 0; 714 //// minLat = maxDt; 715 //// maxLat = -maxDt; 716 //// } 717 //// if (followSec) { 718 //// diffSecGPS += newSecGPS - oldSecGPS; 719 //// if (meanDiff>0.) { 720 //// if (newSecGPS - oldSecGPS > 1.5 * meanDiff) { 721 //// numGaps += 1; 722 //// } 723 //// } 724 //// } 725 //// curLat = sec - obs->_o.GPSWeeks; 726 //// sumLat += curLat; 727 //// sumLatQ += curLat * curLat; 728 //// if (curLat < minLat) minLat = curLat; 729 //// if (curLat >= maxLat) maxLat = curLat; 730 //// numLat += 1; 731 //// oldSecGPS = newSecGPS; 732 //// followSec = true; 733 //// } 734 //// } 735 //// } 736 //// 737 } -
trunk/BNC/bncgetthread.h
r1525 r1555 67 67 void newObs(QByteArray staID, bool firstObs, p_obs obs); 68 68 void newAntCrd(QByteArray staID, double xx, double yy, double zz, QByteArray antType); 69 void error(QByteArray staID);70 69 void newMessage(QByteArray msg, bool showOnScreen); 71 72 public slots:73 void slotNewEphGPS(gpsephemeris gpseph);74 70 75 71 protected: … … 78 74 private: 79 75 void initialize(); 80 t_irc initRun(); 81 void message(const QString&); 82 void tryReconnect(); 83 void callScript(const char* _comment); 84 GPSDecoder* _decoder; 85 bncNetQuery* _query; 86 QUrl _mountPoint; 87 QByteArray _staID; 88 QByteArray _staID_orig; 89 QByteArray _format; 90 QByteArray _latitude; 91 QByteArray _longitude; 92 QByteArray _nmea; 93 QByteArray _ntripVersion; 94 QString _adviseScript; 95 QString _begDateCor; 96 QString _begTimeCor; 97 QString _begDateOut; 98 QString _begTimeOut; 99 QString _endDateCor; 100 QString _endTimeCor; 101 QString _endDateOut; 102 QString _endTimeOut; 103 QString _checkMountPoint; 104 bool _makePause; 105 int _obsRate; 106 int _inspSegm; 107 int _adviseFail; 108 int _adviseReco; 109 int _perfIntr; 110 int _timeOut; 111 int _nextSleep; 112 int _iMount; 113 int _samplingRate; 114 bncRinex* _rnx; 115 bool _rnx_set_position; 116 QDateTime _decodeFailure; 117 QDateTime _decodeStart; 118 QDateTime _decodeStop; 119 QDateTime _decodePause; 120 QDateTime _decodeTime; 121 QDateTime _decodeSucc; 122 QMutex _mutex; 123 QFile* _rawOutFile; 124 QFile* _rawInpFile; 76 t_irc tryReconnect(); 77 void checkLatency(); 78 void scanRTCM(); 79 80 GPSDecoder* _decoder; 81 bncNetQuery* _query; 82 QUrl _mountPoint; 83 QByteArray _staID; 84 QByteArray _staID_orig; 85 QByteArray _format; 86 QByteArray _latitude; 87 QByteArray _longitude; 88 QByteArray _nmea; 89 QByteArray _ntripVersion; 90 int _nextSleep; 91 int _iMount; 92 int _samplingRate; 93 bncRinex* _rnx; 94 QFile* _rawOutFile; 95 QFile* _rawInpFile; 125 96 QextSerialPort* _serialPort; 126 bool _isToBeDeleted;97 bool _isToBeDeleted; 127 98 }; 128 99
Note:
See TracChangeset
for help on using the changeset viewer.