- Timestamp:
- Mar 14, 2008, 4:01:49 PM (17 years ago)
- Location:
- trunk/BNC
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/BNC/RTCM/RTCM2.cpp
r725 r728 49 49 // 2008/03/10 AHA Corrected extraction of antenna serial number 50 50 // 2008/03/10 AHA Corrected buffer length check in getPacket() 51 // 2008/03/11 AHA Added checks for data consistency in extraction routines52 51 // 2008/03/11 AHA isGPS-flag in RTCM2_Obs is now set to false on clear() 52 // 2008/03/13 AHA Added checks for data consistency in extraction routines 53 53 // 54 54 // (c) DLR/GSOC … … 296 296 297 297 if (buf.size()<5) { 298 // Ignore; users should avoid this case prior to calling get() 298 // Ignore; users should avoid this case prior to calling get() 299 299 300 #if ( DEBUG > 0 ) 300 301 cerr << "Error in get(): packet too short (" << buf.size() <<")" << endl; 301 302 #endif 303 302 304 return; 303 305 }; … … 341 343 void ThirtyBitWord::getHeader(string& buf) { 342 344 343 const int wordLen = 5; // Number of bytes representing a 30-bit word344 const int spare = 1; // Number of spare words for resync of parity345 // (same value as inRTCM2packet::getPacket())345 const unsigned int wordLen = 5; // Number of bytes representing a 30-bit word 346 const unsigned int spare = 1; // Number of spare words for resync of parity 347 // (same value as inRTCM2packet::getPacket()) 346 348 unsigned int i; 347 349 348 350 i=0; 351 // append spare word (to get correct parity) and first consecutive word 352 while (i<(spare+1)*wordLen) { 353 // Process byte 354 append(buf[i]); 355 // Increment count 356 i++; 357 }; 358 359 // start searching for preamble in first word after spare word 349 360 while (!isHeader() && i<buf.size() ) { 350 361 // Process byte … … 445 456 unsigned int n; 446 457 458 // Does the package content at least spare bytes and first header byte? 459 if (buf.size()<(spare+1)*wordLen) { 460 clear(); 461 return; 462 }; 463 447 464 // Try to read a full packet. Processed bytes are removed from the input 448 465 // buffer except for the latest spare*wordLen bytes to restore the parity 449 // bytes upon subseqeunt calls of getP Acket().466 // bytes upon subseqeunt calls of getPacket(). 450 467 451 468 // Locate and read the first header word … … 456 473 // termination of getPacket(). 457 474 clear(); 475 458 476 #if ( DEBUG > 0 ) 459 477 cerr << "Error in getPacket(): W.isHeader() = false for H1" << endl; 460 478 #endif 479 461 480 return; 462 481 }; … … 469 488 if (buf.size()<(spare+2)*wordLen) { 470 489 clear(); 490 471 491 #if ( DEBUG > 0 ) 472 492 cerr << "Error in getPacket(): buffer too short for complete H2" << endl; 473 493 #endif 494 474 495 return; 475 496 }; … … 483 504 clear(); 484 505 buf.erase(0,1); 506 485 507 #if ( DEBUG > 0 ) 486 508 cerr << "Error in getPacket(): W.validParity() = false for H2" << endl; 487 509 #endif 510 488 511 return; 489 512 }; 490 513 491 514 n = nDataWords(); 492 515 493 516 // Do we have enough bytes to read the next word? If not, the packet 494 517 // contents is cleared to indicate an unsuccessful termination. The … … 496 519 // for use in the next call of getPacket(). 497 520 if (buf.size()<(spare+2+n)*wordLen) { 498 clear(); 521 clear(); 522 499 523 #if ( DEBUG > 0 ) 500 524 cerr << "Error in getPacket(): buffer too short for complete " << n 501 525 << " DWs" << endl; 502 526 #endif 527 503 528 return; 504 529 }; … … 513 538 clear(); 514 539 buf.erase(0,1); 540 515 541 #if ( DEBUG > 0 ) 516 542 cerr << "Error in getPacket(): W.validParity() = false for DW" 517 543 << i << endl; 518 544 #endif 545 519 546 return; 520 547 }; … … 527 554 528 555 buf.erase(0,(n+2)*wordLen); 529 556 530 557 return; 531 558 … … 762 789 void RTCM2_23::extract(const RTCM2packet& P) { 763 790 764 int nad, nas; 765 766 // Check validity and packet type 791 unsigned int nad, nas; 792 793 const unsigned int nF1 = 8; // bits in first field (R,AF,SF,NAD) 794 const unsigned int nF2 =16; // bits in second field (SETUP ID,R,NAS) 795 const unsigned int nBits=24; // data bits in 30bit word 796 797 // Check validity, packet type and number of data words 767 798 768 799 validMsg = (P.valid()); … … 771 802 validMsg = (P.ID()==23); 772 803 if (!validMsg) return; 773 804 805 // Check number of data words (can nad be read in?) 806 807 validMsg = (P.nDataWords()>=1); 808 if (!validMsg){ 809 cerr << "RTCM2_23::extract: P.nDataWords()>=1" << endl; 810 return; 811 } 812 774 813 // Antenna descriptor 775 814 antType = ""; 776 815 nad = P.getUnsignedBits(3,5); 777 for (int i=0;i<nad;i++) 778 antType += (char)P.getUnsignedBits(8+i*8,8); 816 817 // Check number of data words (can antenna description be read in?) 818 validMsg = ( P.nDataWords() >= 819 (unsigned int)ceil((nF1+nad*8)/(double)nBits) ); 820 821 if (!validMsg) return; 822 823 for (unsigned int i=0;i<nad;i++) 824 antType += (char)P.getUnsignedBits(nF1+i*8,8); 779 825 780 826 // Optional antenna serial numbers 781 827 if (P.getUnsignedBits(2,1)==1) { 828 829 // Check number of data words (can nas be read in?) 830 831 validMsg = ( P.nDataWords() >= 832 (unsigned int)ceil((nF1+nad*8+nF2)/(double)nBits) ); 833 if (!validMsg) return; 834 782 835 nas = P.getUnsignedBits(19+8*nad,5); 836 837 // Check number of data words (can antenna serial number be read in?) 838 839 validMsg = ( P.nDataWords() >= 840 (unsigned int)ceil((nF1+nad*8+nF2+nas*8)/(double)nBits) ); 841 if (!validMsg) return; 842 783 843 antSN = ""; 784 for ( int i=0;i<nas;i++)785 antSN += (char)P.getUnsignedBits( 24+8*nad+i*8,8);844 for (unsigned int i=0;i<nas;i++) 845 antSN += (char)P.getUnsignedBits(nF1+8*nad+nF2+i*8,8); 786 846 }; 787 847 … … 962 1022 << P.nDataWords() << ") detected" << endl; 963 1023 #endif 1024 964 1025 return; 965 1026 }; … … 972 1033 << P.nDataWords() << ") detected" << endl; 973 1034 #endif 1035 974 1036 return; 975 1037 }; … … 1033 1095 if ( isL1 && !isGPS) availability.set(bit_L1cphGLO); 1034 1096 if (!isL1 && !isGPS) availability.set(bit_L2cphGLO); 1097 1098 #if ( DEBUG > 0 ) 1099 cerr << "RTCM2_Obs::extract(): availability " 1100 << bitset<8>(availability) << endl; 1101 #endif 1102 1035 1103 1036 1104 // Process all satellites … … 1148 1216 if ( isL1 && !isGPS) availability.set(bit_L1rngGLO); 1149 1217 if (!isL1 && !isGPS) availability.set(bit_L2rngGLO); 1218 1219 #if ( DEBUG > 0 ) 1220 cerr << "RTCM2_Obs::extract(): availability " 1221 << bitset<8>(availability) << endl; 1222 #endif 1150 1223 1151 1224 // Process all satellites -
trunk/BNC/bncgetthread.cpp
r727 r728 122 122 // Latency interval/average 123 123 // ------------------------ 124 _ latIntr = 86400;125 if ( settings.value(" latIntr").toString().isEmpty() ) { _latIntr = 0; }126 if ( settings.value(" latIntr").toString().indexOf("1 min") != -1 ) { _latIntr = 60; }127 if ( settings.value(" latIntr").toString().indexOf("5 min") != -1 ) { _latIntr = 300; }128 if ( settings.value(" latIntr").toString().indexOf("15 min") != -1 ) { _latIntr = 900; }129 if ( settings.value(" latIntr").toString().indexOf("1 hour") != -1 ) { _latIntr = 3600; }130 if ( settings.value(" latIntr").toString().indexOf("6 hours") != -1 ) { _latIntr = 21600; }131 if ( settings.value(" latIntr").toString().indexOf("1 day") != -1 ) { _latIntr = 86400; }124 _perfIntr = 86400; 125 if ( settings.value("perfIntr").toString().isEmpty() ) { _perfIntr = 0; } 126 if ( settings.value("perfIntr").toString().indexOf("1 min") != -1 ) { _perfIntr = 60; } 127 if ( settings.value("perfIntr").toString().indexOf("5 min") != -1 ) { _perfIntr = 300; } 128 if ( settings.value("perfIntr").toString().indexOf("15 min") != -1 ) { _perfIntr = 900; } 129 if ( settings.value("perfIntr").toString().indexOf("1 hour") != -1 ) { _perfIntr = 3600; } 130 if ( settings.value("perfIntr").toString().indexOf("6 hours") != -1 ) { _perfIntr = 21600; } 131 if ( settings.value("perfIntr").toString().indexOf("1 day") != -1 ) { _perfIntr = 86400; } 132 132 133 133 // RINEX writer … … 400 400 bool begCorrupt = false; 401 401 bool endCorrupt = false; 402 bool followSec = false; 402 403 int oldSecGPS= 0; 403 404 int newSecGPS = 0; 405 int numGaps = 0; 406 int diffSecGPS = 0; 404 407 int numLat = 0; 405 408 double sumLat = 0.; 409 double meanDiff = 0.; 406 410 double minLat = maxDt; 407 411 double maxLat = -maxDt; … … 582 586 wrongEpoch = false; 583 587 584 // Latency 585 // ------- 586 if (_ latIntr>0) {588 // Latency and completeness 589 // ------------------------ 590 if (_perfIntr>0) { 587 591 newSecGPS = static_cast<int>(obs->_o.GPSWeeks); 588 592 if (newSecGPS != oldSecGPS) { 589 if (newSecGPS % _ latIntr < oldSecGPS % _latIntr) {593 if (newSecGPS % _perfIntr < oldSecGPS % _perfIntr) { 590 594 if (numLat>0) { 591 emit( newMessage(QString("%1: Mean latency %2 sec, min %3, max %4, %5 epochs") 592 .arg(_staID.data()) 593 .arg(int(sumLat/numLat*100)/100.) 594 .arg(int(minLat*100)/100.) 595 .arg(int(maxLat*100)/100.) 596 .arg(numLat) 597 .toAscii()) ); 595 if (meanDiff>0.) { 596 emit( newMessage(QString("%1: Mean latency %2 sec, min %3, max %4, %5 epochs, %6 gaps") 597 .arg(_staID.data()) 598 .arg(int(sumLat/numLat*100)/100.) 599 .arg(int(minLat*100)/100.) 600 .arg(int(maxLat*100)/100.) 601 .arg(numLat) 602 .arg(numGaps) 603 .toAscii()) ); 604 } else { 605 emit( newMessage(QString("%1: Mean latency %2 sec, min %3, max %4, %5 epochs") 606 .arg(_staID.data()) 607 .arg(int(sumLat/numLat*100)/100.) 608 .arg(int(minLat*100)/100.) 609 .arg(int(maxLat*100)/100.) 610 .arg(numLat) 611 .toAscii()) ); 612 } 598 613 } 614 meanDiff = diffSecGPS/numLat; 615 diffSecGPS = 0; 616 numGaps = 0; 599 617 sumLat = 0.; 600 618 numLat = 0; 601 619 minLat = maxDt; 602 620 maxLat = -maxDt; 621 } 622 if (followSec) { 623 diffSecGPS += newSecGPS - oldSecGPS; 624 if (meanDiff>0.) { 625 if (newSecGPS - oldSecGPS > 1.5 * meanDiff) { 626 numGaps += 1; 627 } 628 } 603 629 } 604 630 curLat = sec - obs->_o.GPSWeeks + leapsec; … … 608 634 numLat += 1; 609 635 oldSecGPS = newSecGPS; 636 followSec = true; 610 637 } 611 638 } -
trunk/BNC/bncgetthread.h
r723 r728 89 89 int _adviseFail; 90 90 int _adviseReco; 91 int _ latIntr;91 int _perfIntr; 92 92 int _timeOut; 93 93 int _nextSleep; -
trunk/BNC/bnchelp.html
r726 r728 86 86 3.8.4. <a href=#pause>Pause</a><br> 87 87 3.8.5. <a href=#advscript>Advisory Script</a><br> 88 3.8.6. <a href=# latelog>LatencyLogging</a><br>88 3.8.6. <a href=#perflog>Performance Logging</a><br> 89 89 3.9. <a href=#mountpoints>Mountpoints</a><br> 90 90 3.9.1. <a href=#mountadd>Add Mountpoints</a><br> … … 448 448 </p> 449 449 450 <p><a name=" latelog"><h4>3.8.6 LatencyLogging - optional </h4></p>451 <p> 452 Latency is defined hereby the following equation:450 <p><a name="perflog"><h4>3.8.6 Performance Logging - optional </h4></p> 451 <p> 452 <u>Latency:</u> Latency is defined in BNC by the following equation: 453 453 </p> 454 454 <pre> … … 459 459 = Latency 460 460 </pre> 461 <p>BNC can average the latencies per stream over a certain period of GPS time. Mean latencies are calculated from the individual latencies of at most one (first incoming) observation per second. Mean latencies are recorded in the Log file/section at the end of each 'Latency logging' interval. Select a 'Latency logging' interval or select the empty option field if you do not want BNC to log latency information. Note that computing correct latencies requires the clock of the host computer to be properly synchronized. 461 <p> 462 BNC can average the latencies per stream over a certain period of GPS time, the 'Performance logging' interval. Mean latencies are calculated from the individual latencies of at most one (first incoming) observation per second. Note that computing correct latencies requires the clock of the host computer to be properly synchronized. 463 </p> 464 <p> 465 <u>Statistics:</u> BNC counts the number of GPS seconds covered by at least one observation. It also estimates an observation rate from all observations received throughout the first full 'Performance logging' interval. Based on this rate, BNC estimates the number of data gaps when appearing in subsequent intervals. 466 </p> 467 <p> 468 Latencies and statistical information can be recorded in the Log file/section at the end of each 'Performance logging' interval. Select a 'Performance logging' interval to activate this function or select the empty option field if you do not want BNC to log latencies and statistical information. 462 469 </p> 463 470 -
trunk/BNC/bncmain.cpp
r722 r728 85 85 settings.setValue("adviseFail", "15"); 86 86 settings.setValue("adviseReco", "5"); 87 settings.setValue(" latIntr","");87 settings.setValue("perfIntr", ""); 88 88 } 89 89 -
trunk/BNC/bncwindow.cpp
r726 r728 181 181 _adviseScriptLineEdit = new QLineEdit(settings.value("adviseScript").toString()); 182 182 183 _ latIntrComboBox = new QComboBox();184 _ latIntrComboBox->setMaximumWidth(9*ww);185 _ latIntrComboBox->setEditable(false);186 _ latIntrComboBox->addItems(QString(",1 min,5 min,15 min,1 hour,6 hours,1 day").split(","));187 int ll = _ latIntrComboBox->findText(settings.value("latIntr").toString());183 _perfIntrComboBox = new QComboBox(); 184 _perfIntrComboBox->setMaximumWidth(9*ww); 185 _perfIntrComboBox->setEditable(false); 186 _perfIntrComboBox->addItems(QString(",1 min,5 min,15 min,1 hour,6 hours,1 day").split(",")); 187 int ll = _perfIntrComboBox->findText(settings.value("perfIntr").toString()); 188 188 if (ll != -1) { 189 _ latIntrComboBox->setCurrentIndex(ll);189 _perfIntrComboBox->setCurrentIndex(ll); 190 190 } 191 191 … … 287 287 _logFileLineEdit->setWhatsThis(tr("Records of BNC's activities are shown in the Log section on the bottom of this window. They can be saved into a file when a valid path is specified in the 'Logfile (full path)' field.")); 288 288 _adviseScriptLineEdit->setWhatsThis(tr("<p>Specify the full path to a script or batch file to handle advisory notes generated in the event of corrupted streams or stream outages. The affected mountpoint and one of the comments 'Begin_Outage', 'End_Outage', 'Begin_Corrupted', or 'End_Corrupted' are passed on to the script as command line parameters.</p><p>The script can be configured to send an email to BNC's operator and/or to the affected stream provider. An empty option field (default) or invalid path means that you don't want to use this option.</p><p> Note that for using this function you need to specify the 'Observation rate'.</p>")); 289 _ latIntrComboBox->setWhatsThis(tr("<p>BNC can average all latencies per stream over a certain period of GPS time. The resulting mean latencies are recorded in the Log file/section at the end of each 'Latency logging' interval.</p><p>Select a 'Latency logging' interval or select the empty option field if you do not want BNC to log latencyinformation.</p>"));289 _perfIntrComboBox->setWhatsThis(tr("<p>BNC can average all latencies per stream over a certain period of GPS time. The resulting mean latencies are recorded in the Log file/section at the end of each 'Performance logging' interval together with results of a statistical evaluation (number of covered epochs, data gaps).</p><p>Select a 'Performance logging' interval or select the empty option field if you do not want BNC to log latencies and statistical information.</p>")); 290 290 _mountPointsTable->setWhatsThis(tr("<p>Streams selected for retrieval are listed in the 'Mountpoints' section. Clicking on 'Add Mountpoints' button will open a window that allows the user to select data streams from an NTRIP broadcaster according to their mountpoints. To remove a stream from the 'Mountpoints' list, highlight it by clicking on it and hit the 'Delete Mountpoints' button. You can also remove multiple mountpoints by highlighting them using +Shift and +Ctrl.</p><p>BNC automatically allocates one of its internal decoders to a stream based on the stream's 'format' and 'format-details' as given in the sourcetable. However, there might be cases where you need to override the automatic selection due to incorrect sourcetable for example. BNC allows users to manually select the required decoder by editing the decoder string. Double click on the 'decoder' field, enter your preferred decoder and then hit Enter. The accepted decoder strings are 'RTCM_2.x', 'RTCM_3.x', and 'RTIGS'.</p><p>In case you need to log the raw data as is, BNC allows users to by-pass its decoders and and directly save the input in daily log files. To do this specify the decoder string as 'ZERO'.</p><p>BNC can also retrieve streams from virtual reference stations (VRS). To initiate these streams, an approximate rover position needs to be sent in NMEA GGA message to the NTRIP broadcaster. In return, a user-specific data stream is generated, typically by a Network-RTK software. This stream is customized to the exact latitude and longitude as shown in the 'lat' and 'long' columns under 'Mountpoints'. These VRS streams are indicated by a 'yes' in the 'nmea' column under 'Mountpoints' as well as in the sourcetable. The default 'lat' and 'long' values are taken from the sourcetable. However, in most cases you would probably want to change this according to your requirement. Double click on 'lat' and 'long' fields, enter the values you wish to send and then hit Enter. The format is in positive north latitude degrees (e.g. for northern hemisphere: 52.436, for southern hemisphere: -24.567) and eastern longitude degrees (e.g.: 358.872 or -1.128). Only mountpoints with a 'yes' in its 'nmea' column can be edited. The position should preferably be a point within the coverage of the network.</p>")); 291 291 _log->setWhatsThis(tr("Records of BNC's activities are shown in the Log section. The message log covers the communication status between BNC and the NTRIP broadcaster as well as any problems that occur in the communication link, stream availability, stream delay, stream conversion etc.")); … … 378 378 aLayout->addWidget(new QLabel("Script (full path)"), 3, 0); 379 379 aLayout->addWidget(_adviseScriptLineEdit, 3, 1,1,3); 380 aLayout->addWidget(new QLabel(" Latency logging"),4, 0);381 aLayout->addWidget(_ latIntrComboBox,4, 1);382 aLayout->addWidget(new QLabel("Network monitoring, outages, handling of corrupted streams, mean latency."),5,0,1,4,Qt::AlignLeft);380 aLayout->addWidget(new QLabel("Performance logging"), 4, 0); 381 aLayout->addWidget(_perfIntrComboBox, 4, 1); 382 aLayout->addWidget(new QLabel("Network monitoring, outages, handling of corrupted streams, latencies, statistics."),5,0,1,4,Qt::AlignLeft); 383 383 agroup->setLayout(aLayout); 384 384 … … 540 540 settings.setValue("makePause", _makePauseCheckBox->checkState()); 541 541 settings.setValue("outFile", _outFileLineEdit->text()); 542 settings.setValue(" latIntr", _latIntrComboBox->currentText());542 settings.setValue("perfIntr", _perfIntrComboBox->currentText()); 543 543 settings.setValue("outPort", _outPortLineEdit->text()); 544 544 settings.setValue("outEphPort", _outEphPortLineEdit->text()); -
trunk/BNC/bncwindow.h
r722 r728 107 107 QSpinBox* _adviseRecoSpinBox; 108 108 QLineEdit* _adviseScriptLineEdit; 109 QComboBox* _ latIntrComboBox;109 QComboBox* _perfIntrComboBox; 110 110 QTableWidget* _mountPointsTable; 111 111
Note:
See TracChangeset
for help on using the changeset viewer.