Changeset 11057 in ntrip for trunk


Ignore:
Timestamp:
Sep 30, 2026, 11:30:26 AM (2 days ago)
Author:
stuerze
Message:

bug fixes resulting from overall tests

Location:
trunk/BNC/src
Files:
21 edited

Legend:

Unmodified
Added
Removed
  • trunk/BNC/src/GPSDecoder.h

    r11022 r11057  
    5151
    5252  virtual int corrGPSEpochTime() const {return -1;}
     53
     54  // pass on all data still held back (e.g. at the end of a --file replay)
     55  virtual void flush() {}
    5356
    5457  void initRinex(const QByteArray& staID, const QUrl& mountPoint,
  • trunk/BNC/src/RTCM3/RTCM3Decoder.cpp

    r11049 r11057  
    7171  _rawFile = rawFile;
    7272
    73   connect(this, SIGNAL(newGPSEph(t_ephGPS)),     BNC_CORE, SLOT(slotNewGPSEph(t_ephGPS)));
    74   connect(this, SIGNAL(newGlonassEph(t_ephGlo)), BNC_CORE, SLOT(slotNewGlonassEph(t_ephGlo)));
    75   connect(this, SIGNAL(newGalileoEph(t_ephGal)), BNC_CORE, SLOT(slotNewGalileoEph(t_ephGal)));
    76   connect(this, SIGNAL(newSBASEph(t_ephSBAS)),   BNC_CORE, SLOT(slotNewSBASEph(t_ephSBAS)));
    77   connect(this, SIGNAL(newBDSEph(t_ephBDS)),     BNC_CORE, SLOT(slotNewBDSEph(t_ephBDS)));
     73  Qt::ConnectionType conType = BNC_CORE->decoderConnectionType();
     74  connect(this, SIGNAL(newGPSEph(t_ephGPS)),     BNC_CORE, SLOT(slotNewGPSEph(t_ephGPS)), conType);
     75  connect(this, SIGNAL(newGlonassEph(t_ephGlo)), BNC_CORE, SLOT(slotNewGlonassEph(t_ephGlo)), conType);
     76  connect(this, SIGNAL(newGalileoEph(t_ephGal)), BNC_CORE, SLOT(slotNewGalileoEph(t_ephGal)), conType);
     77  connect(this, SIGNAL(newSBASEph(t_ephSBAS)),   BNC_CORE, SLOT(slotNewSBASEph(t_ephSBAS)), conType);
     78  connect(this, SIGNAL(newBDSEph(t_ephBDS)),     BNC_CORE, SLOT(slotNewBDSEph(t_ephBDS)), conType);
    7879
    7980  _MessageSize = _SkipBytes = _BlockSize = _NeedBytes = 0;
    … …  
    8990  }
    9091  _coDecoders.clear();
     92}
     93
     94// Pass on the corrections still held back by the SSR decoders
     95////////////////////////////////////////////////////////////////////////////
     96void RTCM3Decoder::flush() {
     97  QMapIterator<QByteArray, RTCM3coDecoder*> it(_coDecoders);
     98  while (it.hasNext()) {
     99    it.next();
     100    it.value()->flush();
     101  }
    91102}
    92103
  • trunk/BNC/src/RTCM3/RTCM3Decoder.h

    r11047 r11057  
    4343  virtual t_irc Decode(char* buffer, int bufLen, std::vector<std::string>& errmsg);
    4444  virtual int corrGPSEpochTime() const;
     45  virtual void flush();
    4546  /**
    4647   * CRC24Q checksum calculation function (only full bytes supported).
  • trunk/BNC/src/RTCM3/RTCM3coDecoder.cpp

    r11047 r11057  
    7171  _out = 0;
    7272
     73  Qt::ConnectionType conType = BNC_CORE->decoderConnectionType();
    7374  connect(this, SIGNAL(newOrbCorrections(QList<t_orbCorr>)),
    74           BNC_CORE, SLOT(slotNewOrbCorrections(QList<t_orbCorr>)));
     75          BNC_CORE, SLOT(slotNewOrbCorrections(QList<t_orbCorr>)), conType);
    7576
    7677  connect(this, SIGNAL(newClkCorrections(QList<t_clkCorr>)),
    77           BNC_CORE, SLOT(slotNewClkCorrections(QList<t_clkCorr>)));
     78          BNC_CORE, SLOT(slotNewClkCorrections(QList<t_clkCorr>)), conType);
    7879
    7980  connect(this, SIGNAL(newCodeBiases(QList<t_satCodeBias>)),
    80           BNC_CORE, SLOT(slotNewCodeBiases(QList<t_satCodeBias>)));
     81          BNC_CORE, SLOT(slotNewCodeBiases(QList<t_satCodeBias>)), conType);
    8182
    8283  connect(this, SIGNAL(newPhaseBiases(QList<t_satPhaseBias>)),
    83           BNC_CORE, SLOT(slotNewPhaseBiases(QList<t_satPhaseBias>)));
     84          BNC_CORE, SLOT(slotNewPhaseBiases(QList<t_satPhaseBias>)), conType);
    8485
    8586  connect(this, SIGNAL(newTec(t_vTec)),
    86           BNC_CORE, SLOT(slotNewTec(t_vTec)));
     87          BNC_CORE, SLOT(slotNewTec(t_vTec)), conType);
    8788
    8889  connect(this, SIGNAL(newMetaData(t_metaData)),
    89           BNC_CORE, SLOT(slotNewMetaData(t_metaData)));
     90          BNC_CORE, SLOT(slotNewMetaData(t_metaData)), conType);
    9091
    9192  connect(this, SIGNAL(newSatAntennas(QList<t_satAntenna>)),
    92           BNC_CORE, SLOT(slotNewSatAntennas(QList<t_satAntenna>)));
     93          BNC_CORE, SLOT(slotNewSatAntennas(QList<t_satAntenna>)), conType);
    9394
    9495  connect(this, SIGNAL(providerIDChanged(QString)),
    95           BNC_CORE, SIGNAL(providerIDChanged(QString)));
     96          BNC_CORE, SIGNAL(providerIDChanged(QString)), conType);
    9697
    9798  connect(this, SIGNAL(newMessage(QByteArray,bool)),
    … …  
    784785  // Dump all older epochs
    785786  // ---------------------
     787  dumpEpochs(false);
     788}
     789
     790// Emit and write the collected corrections of all epochs older than
     791// _lastTime (all epochs if all is set, e.g. at the end of a replay)
     792////////////////////////////////////////////////////////////////////////////
     793void RTCM3coDecoder::dumpEpochs(bool all) {
    786794  QMutableMapIterator<bncTime, QList<t_orbCorr> > itOrb(_orbCorrections);
    787795  while (itOrb.hasNext()) {
    788796    itOrb.next();
    789     if (itOrb.key() < _lastTime) {
     797    if (all || itOrb.key() < _lastTime) {
    790798      emit newOrbCorrections(itOrb.value());
    791799      t_orbCorr::writeEpoch(_out, itOrb.value());
    … …  
    796804  while (itClk.hasNext()) {
    797805    itClk.next();
    798     if (itClk.key() < _lastTime) {
     806    if (all || itClk.key() < _lastTime) {
    799807      emit newClkCorrections(itClk.value());
    800808      t_clkCorr::writeEpoch(_out, itClk.value());
    … …  
    805813  while (itCB.hasNext()) {
    806814    itCB.next();
    807     if (itCB.key() < _lastTime) {
     815    if (all || itCB.key() < _lastTime) {
    808816      emit newCodeBiases(itCB.value());
    809817      t_satCodeBias::writeEpoch(_out, itCB.value());
    … …  
    814822  while (itPB.hasNext()) {
    815823    itPB.next();
    816     if (itPB.key() < _lastTime) {
     824    if (all || itPB.key() < _lastTime) {
    817825      emit newPhaseBiases(itPB.value());
    818826      t_satPhaseBias::writeEpoch(_out, itPB.value());
    … …  
    823831  while (itTec.hasNext()) {
    824832    itTec.next();
    825     if (itTec.key() < _lastTime) {
     833    if (all || itTec.key() < _lastTime) {
    826834      emit newTec(itTec.value());
    827835      t_vTec::write(_out, itTec.value());
    … …  
    832840  while (itMD.hasNext()) {
    833841    itMD.next();
    834     if (itMD.key() < _lastTime) {
     842    if (all || itMD.key() < _lastTime) {
    835843      emit newMetaData(itMD.value());
    836844      t_metaData::write(_out, itMD.value());
    … …  
    841849  while (itAnt.hasNext()) {
    842850    itAnt.next();
    843     if (itAnt.key() < _lastTime) {
     851    if (all || itAnt.key() < _lastTime) {
    844852      emit newSatAntennas(itAnt.value());
    845853      t_satAntenna::writeEpoch(_out, itAnt.value());
    846854      itAnt.remove();
    847855    }
     856  }
     857  if (all && _out) {
     858    _out->flush();
    848859  }
    849860}
    … …  
    11261137  else if (epoSecGlo != -1) {
    11271138    QDate date = dateAndTimeFromGPSweek(currentTime.gpsw(), currentTime.gpssec()).date();
    1128     if (_type == IGSssr) {
    1129       epoSecGlo = epoSecGlo + gnumleap(date.year(), date.month(), date.day());
    1130     }
     1139    // IGS-SSR: the SSR Epoch Time (IDF003, 20 bit) is given in one continuous
     1140    // time scale for all GNSS, i.e. GPS seconds of week also for GLONASS
     1141    // (IGS SSR v1.00) - no conversion
    11311142    if (_type == RTCMssr || _type == RTCMnewssr) {
    11321143      // Same GLONASS epoch wire convention (UTC+3h) as RTCMssr
    … …  
    11451156  }
    11461157  else if (epoSecBds != -1) {
    1147     epoSecBds += 14.0;
    1148     if (epoSecBds > 604800.0) {
    1149       epoSecBds -= 7.0*24.0*60.0*60.0;
     1158    // RTCM-SSR: BDT; IGS-SSR: GPS time scale for all GNSS (IDF003)
     1159    if (_type != IGSssr) {
     1160      epoSecBds += 14.0;
     1161      if (epoSecBds > 604800.0) {
     1162        epoSecBds -= 7.0*24.0*60.0*60.0;
     1163      }
    11501164    }
    11511165    _lastTime.set(currentWeek, epoSecBds);
  • trunk/BNC/src/RTCM3/RTCM3coDecoder.h

    r11047 r11057  
    4545  virtual t_irc Decode(char* buffer, int bufLen, std::vector<std::string>& errmsg);
    4646  virtual int corrGPSEpochTime() const {return int(_lastTime.gpssec());}
     47  virtual void flush() {dumpEpochs(true);}
    4748  virtual void initSsrFormatType(const e_type type) {
    4849    _type = type;
    … …  
    7374  void setEpochTime();
    7475  void sendResults();
     76  void dumpEpochs(bool all);
    7577  void reopen();
    7678  void checkProviderID();
  • trunk/BNC/src/bnccore.h

    r11039 r11057  
    4747  static t_bncCore* instance();
    4848  e_mode            mode() const {return _mode;}
     49  // Connection type for data signals (ephemerides, corrections) from a
     50  // decoder to this object, to be called in the thread the decoder emits
     51  // from. In batch post-processing (--file replay) the reading thread must
     52  // wait until the data are passed on, otherwise they reach the PPP in an
     53  // order depending on thread scheduling instead of the file order.
     54  Qt::ConnectionType decoderConnectionType() const {
     55    if (_mode == batchPostProcessing && QThread::currentThread() != thread()) {
     56      return Qt::BlockingQueuedConnection;
     57    }
     58    return Qt::AutoConnection;
     59  }
    4960  void              setGUIenabled(bool GUIenabled) {_GUIenabled = GUIenabled;}
    5061  void              setMode(e_mode mode) {_mode = mode;}
  • trunk/BNC/src/bncephuser.cpp

    r11047 r11057  
    253253
    254254  if (ephL && ephL->checkState() != t_eph::bad) {
     255    // Update of ephemeris data sets after an outage: if the time since the
     256    // last data set exceeds the system's update interval, the last one is
     257    // outdated and a consistency check against it (extrapolated over the
     258    // whole gap) is meaningless - it would reject the first new data set
     259    // after every gap. The new data set stays unchecked and serves as
     260    // reference for the next one.
     261    // -----------------------------------------------------------------
     262    double dt = eph->TOC() - ephL->TOC();
     263
     264    // update interval: 2h
     265    if      (eph->system() == t_eph::GPS     && dt >  7200.0) {
     266      ephL->setCheckState(t_eph::outdated);
     267      return;
     268    }
     269    // update interval: 3h
     270    else if (eph->system() == t_eph::Galileo && dt > 10800.0) {
     271      ephL->setCheckState(t_eph::outdated);
     272      return;
     273    }
     274    // updated every 30 minutes + 5 min
     275    else if (eph->system() == t_eph::GLONASS && dt >  2100.0) {
     276      ephL->setCheckState(t_eph::outdated);
     277      return;
     278    }
     279    // updated every ?
     280    else if (eph->system() == t_eph::QZSS    && dt >  3600.0) {
     281      ephL->setCheckState(t_eph::outdated);
     282      return;
     283    }
     284    // maximum update interval: 300 sec
     285    else if  (eph->system() == t_eph::SBAS   && dt >   600.0) {
     286      ephL->setCheckState(t_eph::outdated);
     287      return;
     288    }
     289    // updates 1h + 5 min
     290    else if  (eph->system() == t_eph::BDS    && dt >  3900.0) {
     291      ephL->setCheckState(t_eph::outdated);
     292      return;
     293    }
     294    // update interval: up to 24 hours
     295    else if  (eph->system() == t_eph::NavIC  && dt > 86400.0) {
     296      ephL->setCheckState(t_eph::outdated);
     297      return;
     298    }
     299
    255300    ColumnVector xcL(6);
    256301    ColumnVector vvL(3);
    … …  
    281326      }
    282327    }
    283 
    284     // some lines to allow update of ephemeris data sets after an outage
    285     // -----------------------------------------------------------------
    286     double dt = eph->TOC() - ephL->TOC();
    287 
    288     // update interval: 2h
    289     if      (eph->system() == t_eph::GPS     && dt >  7200.0) {
    290       ephL->setCheckState(t_eph::outdated);
    291       return;
    292     }
    293     // update interval: 3h
    294     else if (eph->system() == t_eph::Galileo && dt > 10800.0) {
    295       ephL->setCheckState(t_eph::outdated);
    296       return;
    297     }
    298     // updated every 30 minutes + 5 min
    299     else if (eph->system() == t_eph::GLONASS && dt >  2100.0) {
    300       ephL->setCheckState(t_eph::outdated);
    301       return;
    302     }
    303     // updated every ?
    304     else if (eph->system() == t_eph::QZSS    && dt >  3600.0) {
    305       ephL->setCheckState(t_eph::outdated);
    306       return;
    307     }
    308     // maximum update interval: 300 sec
    309     else if  (eph->system() == t_eph::SBAS   && dt >   600.0) {
    310       ephL->setCheckState(t_eph::outdated);
    311       return;
    312     }
    313     // updates 1h + 5 min
    314     else if  (eph->system() == t_eph::BDS    && dt >  3900.0) {
    315       ephL->setCheckState(t_eph::outdated);
    316       return;
    317     }
    318     // update interval: up to 24 hours
    319     else if  (eph->system() == t_eph::NavIC  && dt > 86400.0) {
    320       ephL->setCheckState(t_eph::outdated);
    321       return;
    322     }
    323   }
    324 }
    325 
     328  }
     329}
     330
  • trunk/BNC/src/bncgetthread.cpp

    r11021 r11057  
    483483        if (data.isEmpty() || BNC_CORE->sigintReceived) {
    484484          emit(newMessage("No more data or SIGINT/SIGTERM received", true));
     485          // pass on data the decoders still hold back (last epoch)
     486          QMapIterator<QString, GPSDecoder*> itFlush(_decodersRaw);
     487          while (itFlush.hasNext()) {
     488            itFlush.next();
     489            itFlush.value()->flush();
     490          }
    485491          BNC_CORE->stopPPP();
    486492          BNC_CORE->stopCombination();
  • trunk/BNC/src/bnchelp.html

    r11042 r11057  
    29922992  </p>
    29932993  <p>
     2994    For RINEX Version 3/4, the default set contains all signals BNC can decode from RTCM Version 3 MSM streams, each
     2995    with code, phase, Doppler and signal-to-noise ratio. As empty observations at the end of an observation record are
     2996    omitted (trailing blanks are removed as permitted by the RINEX format), the frequently tracked signals are listed
     2997    first to keep the records short.
     2998  </p>
     2999  <p>
    29943000    A skeleton file carrying only RINEX Version 2 style observation types (2-character codes, e.g. 'C1', 'L1') cannot
    29953001    supply the tracking-mode
    … …  
    34393445  </p>
    34403446  <p>
    3441     In case of a Quality Check the following type of Broadcast navigation messages is used per individulal GNSS:
     3447    In case of a Quality Check, BNC reads all types of Broadcast navigation messages contained in the RINEX Navigation
     3448    file(s), i.e. besides the legacy navigation messages listed in the following table also e.g. CNAV and CNAV-2
     3449    (GPS, QZSS), FNAV (Galileo), CNAV-1/2/3 (BeiDou) and L1NV (NavIC) messages from RINEX Version 4 files. If a
     3450    satellite's navigation file(s) contain several data sets with the same Time of Clock (TOC), e.g. an INAV and an
     3451    FNAV data set, only the first one is used. The following table lists the legacy navigation message types per
     3452    individual GNSS together with the corresponding RTCM message types:
    34423453  </p>
    34433454  <table>
    … …  
    35723583  </p>
    35733584  <p>
     3585    A satellite's elevation is computed for each epoch from the navigation data set with the TOC closest to the epoch
     3586    among the data sets which are valid at that epoch (see section 'Logfile' for the validity periods). If no data set
     3587    is valid, the data set with the closest TOC is used. If no usable data set is available at all, e.g. because the
     3588    satellite is missing in the navigation file(s), the satellite's observations are not excluded by the elevation
     3589    mask; in the 'Analyze' epoch-specific output, its elevation and azimuth are reported as '0.00'.
     3590  </p>
     3591  <p>
     3592    In case of 'Analyze', the navigation data sets are checked beforehand and data sets flagged as wrong are not used.
     3593    A satellite is considered unhealthy at an epoch if the valid data set with the TOC closest to that epoch is flagged
     3594    unhealthy. As its orbit might be erroneous, the observations of an unhealthy satellite are excluded from the
     3595    analysis at such epochs, in the same way as observations below the elevation mask.
     3596  </p>
     3597  <p>
    35743598    Default is '0 deg', meaning that no elevation mask is applied and all observations are used regardless of the
    35753599    involved satellite's elevation angle.
    … …  
    35883612    Note that logfiles from analyzing RINEX files may become quite large. Hence, BNC provides an option 'Summary only'
    35893613    to limit logfile content to some essential information in case 'Action' is set to 'Analyze'.
    3590     The following is an example for a RINEX quality check analysis logfile:
     3614    The following is an example for a RINEX quality check analysis logfile (excerpt, one hour of 30 sec RINEX
     3615    Version 4 data from station BRUX00BEL analyzed together with the station's own navigation file; the
     3616    unhealthy satellites E14 and R10 are excluded):
    35913617  </p>
    35923618  <pre><p style="font-family:Monospace">
    35933619QC Format Version  : 1.1
    35943620
    3595 Navigation File(s) : MAO000USA_R_20221720000_01D_MN.rnx
    3596 Ephemeris          : 1776 OK   3617 UNHEALTHY   116 WRONG
    3597                      MAO000USA_R_20221720000_01D_MN.rnx : WRONG EPH G09 LNAV: 2022 06 21 04 00 00
    3598                      MAO000USA_R_20221720000_01D_MN.rnx : WRONG EPH G09 LNAV: 2022 06 21 06 00 00
    3599                      MAO000USA_R_20221720000_01D_MN.rnx : WRONG EPH G09 LNAV: 2022 06 21 08 00 00
    3600                      MAO000USA_R_20221720000_01D_MN.rnx : WRONG EPH J07 LNAV: 2022 06 21 07 00 00
    3601                      MAO000USA_R_20221720000_01D_MN.rnx : WRONG EPH J07 LNAV: 2022 06 21 08 00 00
    3602                      MAO000USA_R_20221720000_01D_MN.rnx : WRONG EPH G09 LNAV: 2022 06 21 10 00 00
    3603 ..
    3604                      MAO000USA_R_20221720000_01D_MN.rnx : WRONG EPH C35 D1  : 2022 06 21 23 00 14
    3605                      MAO000USA_R_20221720000_01D_MN.rnx : WRONG EPH C26 D1  : 2022 06 21 23 00 14
    3606                      MAO000USA_R_20221720000_01D_MN.rnx : WRONG EPH C44 D1  : 2022 06 21 23 00 14
    3607                      MAO000USA_R_20221720000_01D_MN.rnx : WRONG EPH C24 D1  : 2022 06 21 23 00 14
    3608                      MAO000USA_R_20221720000_01D_MN.rnx : WRONG EPH C21 D1  : 2022 06 21 23 00 14
    3609                      MAO000USA_R_20221720000_01D_MN.rnx : WRONG EPH C12 D1  : 2022 06 21 23 00 14
    3610                      MAO000USA_R_20221720000_01D_MN.rnx : WRONG EPH C40 D1  : 2022 06 21 23 00 14
    3611                      MAO000USA_R_20221720000_01D_MN.rnx : WRONG EPH E11 FNAV: 2022 06 21 22 50 00
    3612                      MAO000USA_R_20221720000_01D_MN.rnx : WRONG EPH G08 LNAV: 2022 06 21 23 59 44
    3613                      MAO000USA_R_20221720000_01D_MN.rnx : WRONG EPH E11 FNAV: 2022 06 21 23 00 00
    3614                      MAO000USA_R_20221720000_01D_MN.rnx : WRONG EPH E11 FNAV: 2022 06 21 23 10 00
    3615                      MAO000USA_R_20221720000_01D_MN.rnx : WRONG EPH E11 FNAV: 2022 06 21 23 20 00
    3616                      MAO000USA_R_20221720000_01D_MN.rnx : WRONG EPH E11 FNAV: 2022 06 21 23 30 00
    3617                      MAO000USA_R_20221720000_01D_MN.rnx : WRONG EPH E25 FNAV: 2022 06 21 23 30 00
    3618                      MAO000USA_R_20221720000_01D_MN.rnx : WRONG EPH E11 FNAV: 2022 06 21 23 40 00
    3619                      MAO000USA_R_20221720000_01D_MN.rnx : WRONG EPH E25 FNAV: 2022 06 21 23 40 00
    3620 
    3621 Observation File   : MAO000USA_R_20221720000_01D_30S_MO.rnx
    3622 RINEX Version      : 4.00
    3623 Marker Name        : MAO0
    3624 Marker Number      : 40445M005
    3625 Receiver           : SEPT POLARX5
    3626 Antenna            : LEIAR25.R3      LEIT
    3627 Position XYZ       :  -5466067.2677  -2404332.8007   2242123.7442
    3628 Antenna dH/dE/dN   :   0.0000   0.0000   0.0000
    3629 Start Time         : 2022-06-21 00.00.00.0
    3630 End Time           : 2022-06-21 23.59.30.0
     3621Input Nav File     : BRUX00BEL_R_20262090800_01H_MN.rnx
     3622RINEX Version      : 4.01
     3623Ephemeris Check    : 227 OK   81 UNHEALTHY   0 WRONG
     3624
     3625Observation File   : BRUX00BEL_R_20262090800_01H_30S_MO.rnx
     3626RINEX Version      : 4.01
     3627Marker Name        : BRUX00BEL
     3628Marker Number      : 13101M010
     3629Receiver           : SEPT POLARX5TR
     3630Antenna            : JAVRINGANT_DM   SCIS
     3631Position XYZ       :   4027881.8468    306998.2610   4919498.6524
     3632Antenna dH/dE/dN   :   0.4689   0.0000   0.0010
     3633Start Time         : 2026-07-28 08.00.00.0
     3634End Time           : 2026-07-28 08.59.30.0
    36313635Interval           : 30 sec
     3636Minimum Elevation  : 0 deg
    36323637Observation Types C: C1P L1P D1P S1P C5P L5P D5P S5P C2I L2I D2I S2I C7I L7I D7I S7I C6I L6I D6I S6I C7D L7D D7D S7D
    3633 Observation Types E: C1C L1C D1C S1C C6C L6C D6C S6C C5Q L5Q D5Q S5Q C7Q L7Q D7Q S7Q C8Q L8Q D8Q S8Q
     3638Observation Types E: C1C L1C D1C S1C C6B L6B D6B S6B C5Q L5Q D5Q S5Q C7Q L7Q D7Q S7Q C8Q L8Q D8Q S8Q
    36343639Observation Types G: C1C L1C D1C S1C C1W S1W C2W L2W D2W S2W C2L L2L D2L S2L C5Q L5Q D5Q S5Q C1L L1L D1L S1L
    36353640Observation Types I: C5A L5A D5A S5A
    3636 Observation Types J: C1C L1C D1C S1C C2L L2L D2L S2L C5Q L5Q D5Q S5Q C1L L1L D1L S1L C1Z L1Z D1Z S1Z C5P L5P D5P S5P
    3637 Observation Types R: C1C L1C D1C S1C C1P L1P D1P S1P C2P L2P D2P S2P C2C L2C D2C S2C
    3638 Observation Types S: C1C L1C D1C S1C C5I L5I D5I S5I
    3639 Analysed GNSS      : 4    C E G J
    3640 
    3641   C: Satellites: 42
     3641Observation Types R: C1C L1C D1C S1C C1P L1P D1P S1P C2P L2P D2P S2P C2C L2C D2C S2C C3Q L3Q D3Q S3Q
     3642Analysed GNSS      : 4    C E G R
     3643
     3644  C: Satellites: 15
    36423645  C: Signals   : 6    1P 2I 5P 6I 7D 7I
    36433646
    3644       C:   1P: Observations      :  28217
    3645       C:   1P: Slips (file+found):       60 +      22
    3646       C:   1P: Gaps              :      147
    3647       C:   1P: Mean SNR          :     43.9
    3648       C:   1P: Mean Multipath    :     0.60
    3649 
    3650       C:   2I: Observations      :  43725
    3651       C:   2I: Slips (file+found):      124 +      32
    3652       C:   2I: Gaps              :      209
    3653       C:   2I: Mean SNR          :     44.8
    3654       C:   2I: Mean Multipath    :     0.66
    3655 
    3656       C:   5P: Observations      :  28373
    3657       C:   5P: Slips (file+found):       52 +       7
    3658       C:   5P: Gaps              :      100
    3659       C:   5P: Mean SNR          :     43.5
    3660       C:   5P: Mean Multipath    :     0.26
    3661 
    3662       C:   6I: Observations      :  43887
    3663       C:   6I: Slips (file+found):       95 +      15
    3664       C:   6I: Gaps              :      156
    3665       C:   6I: Mean SNR          :     44.6
    3666       C:   6I: Mean Multipath    :     0.29
    3667 
    3668       C:   7D: Observations      :  30073
    3669       C:   7D: Slips (file+found):       45 +      10
    3670       C:   7D: Gaps              :       28
    3671       C:   7D: Mean SNR          :     44.1
    3672       C:   7D: Mean Multipath    :     0.28
    3673 
    3674       C:   7I: Observations      :  11450
    3675       C:   7I: Slips (file+found):       23 +       0
    3676       C:   7I: Gaps              :       16
    3677       C:   7I: Mean SNR          :     43.0
    3678       C:   7I: Mean Multipath    :     0.00
    3679 
    3680   E: Satellites: 27
    3681   E: Signals   : 5    1C 5Q 6C 7Q 8Q
    3682 
    3683       E:   1C: Observations      :  28931
    3684       E:   1C: Slips (file+found):       49 +       6
    3685       E:   1C: Gaps              :       83
    3686       E:   1C: Mean SNR          :     42.7
    3687       E:   1C: Mean Multipath    :     0.43
    3688 
    3689       E:   5Q: Observations      :  27473
    3690       E:   5Q: Slips (file+found):       34 +       6
    3691       E:   5Q: Gaps              :       62
    3692       E:   5Q: Mean SNR          :     43.5
    3693       E:   5Q: Mean Multipath    :     0.22
    3694 
    3695       E:   6C: Observations      :  27564
    3696       E:   6C: Slips (file+found):       40 +       9
    3697       E:   6C: Gaps              :       77
    3698       E:   6C: Mean SNR          :     45.5
    3699       E:   6C: Mean Multipath    :     0.39
    3700 
    3701       E:   7Q: Observations      :  27504
    3702       E:   7Q: Slips (file+found):       35 +       7
    3703       E:   7Q: Gaps              :       55
    3704       E:   7Q: Mean SNR          :     44.2
    3705       E:   7Q: Mean Multipath    :     0.25
    3706 
    3707       E:   8Q: Observations      :  27099
    3708       E:   8Q: Slips (file+found):       48 +       9
    3709       E:   8Q: Gaps              :       35
    3710       E:   8Q: Mean SNR          :     47.1
    3711       E:   8Q: Mean Multipath    :     0.08
    3712 
    3713   G: Satellites: 32
     3647      C:   1P: Observations      :   1193 (    1490)    80.07 %
     3648      C:   1P: Slips (file+found):        4 +       0
     3649      C:   1P: Gaps              :        9
     3650      C:   1P: Mean SNR          :     40.7
     3651      C:   1P: Mean Multipath    :     0.33
     3652
     3653      C:   2I: Observations      :   1350 (    1490)    90.60 %
     3654      C:   2I: Slips (file+found):        5 +       0
     3655      C:   2I: Gaps              :        8
     3656      C:   2I: Mean SNR          :     41.9
     3657      C:   2I: Mean Multipath    :     0.36
     3658
     3659..
     3660
     3661  G: Satellites: 13
    37143662  G: Signals   : 6    1C 1L 1W 2L 2W 5Q
    37153663
    3716       G:   1C: Observations      :  33608 (   35429)    94.86 %
    3717       G:   1C: Slips (file+found):      120 +      40
    3718       G:   1C: Gaps              :      159
    3719       G:   1C: Mean SNR          :     43.8
    3720       G:   1C: Mean Multipath    :     0.56
    3721 
    3722       G:   1L: Observations      :   4975 (   35429)    14.04 %
    3723       G:   1L: Slips (file+found):       17 +       5
    3724       G:   1L: Gaps              :       17
    3725       G:   1L: Mean SNR          :     44.0
    3726       G:   1L: Mean Multipath    :     0.54
    3727 
    3728       G:   1W: Observations      :  32785 (   35429)    92.54 %
    3729       G:   1W: Slips (file+found):        0 +      41
    3730       G:   1W: Gaps              :       83
    3731       G:   1W: Mean SNR          :     33.5
    3732       G:   1W: Mean Multipath    :     0.55
    3733 
    3734       G:   2L: Observations      :  24939 (   35429)    70.39 %
    3735       G:   2L: Slips (file+found):       81 +      26
    3736       G:   2L: Gaps              :       95
    3737       G:   2L: Mean SNR          :     41.4
    3738       G:   2L: Mean Multipath    :     0.49
    3739 
    3740       G:   2W: Observations      :  32785 (   35429)    92.54 %
    3741       G:   2W: Slips (file+found):      110 +      44
    3742       G:   2W: Gaps              :       83
    3743       G:   2W: Mean SNR          :     33.5
    3744       G:   2W: Mean Multipath    :     0.32
    3745 
    3746       G:   5Q: Observations      :  17026 (   35429)    48.06 %
    3747       G:   5Q: Slips (file+found):       41 +       8
    3748       G:   5Q: Gaps              :       47
    3749       G:   5Q: Mean SNR          :     46.2
    3750       G:   5Q: Mean Multipath    :     0.26
    3751 
    3752   J: Satellites: 4
    3753   J: Signals   : 6    1C 1L 1Z 2L 5P 5Q
    3754 
    3755       J:   1C: Observations      :   9433 (    9493)    99.37 %
    3756       J:   1C: Slips (file+found):       64 +       7
    3757       J:   1C: Gaps              :       14
    3758       J:   1C: Mean SNR          :     38.0
    3759       J:   1C: Mean Multipath    :     0.71
    3760 
    3761       J:   1L: Observations      :   9438 (    9493)    99.42 %
    3762       J:   1L: Slips (file+found):       14 +      10
    3763       J:   1L: Gaps              :       10
    3764       J:   1L: Mean SNR          :     38.9
    3765       J:   1L: Mean Multipath    :     0.58
    3766 
    3767       J:   1Z: Observations      :   9428 (    9493)    99.32 %
    3768       J:   1Z: Slips (file+found):       20 +       7
    3769       J:   1Z: Gaps              :       16
    3770       J:   1Z: Mean SNR          :     40.6
    3771       J:   1Z: Mean Multipath    :     0.61
    3772 
    3773       J:   2L: Observations      :   9435 (    9493)    99.39 %
    3774       J:   2L: Slips (file+found):       12 +       9
    3775       J:   2L: Gaps              :       10
    3776       J:   2L: Mean SNR          :     38.9
    3777       J:   2L: Mean Multipath    :     0.58
    3778 
    3779       J:   5P: Observations      :   9443 (    9493)    99.47 %
    3780       J:   5P: Slips (file+found):       12 +      11
    3781       J:   5P: Gaps              :        8
    3782       J:   5P: Mean SNR          :     36.4
    3783       J:   5P: Mean Multipath    :     0.18
    3784 
    3785       J:   5Q: Observations      :   9457 (    9493)    99.62 %
    3786       J:   5Q: Slips (file+found):       12 +      11
    3787       J:   5Q: Gaps              :        7
    3788       J:   5Q: Mean SNR          :     41.4
    3789       J:   5Q: Mean Multipath    :     0.13
    3790 
    3791 > 2022 06 21 00 00  0.0000000 41  0.6
    3792 G08   0.00    0.00   9  L1C .. 44.1  C1C  . 0.58  C1W  . 0.59  L2W .. 40.6  C2W  . 0.77  L2L .. 37.3  C2L  . 0.74  L5Q .. 45.3  C5Q  . 0.33
    3793 G10  32.29   79.31   9  L1C .. 49.6  C1C  . 0.16  C1W  . 0.16  L2W .. 44.0  C2W  . 0.09  L2L .. 48.2  C2L  . 0.11  L5Q .. 51.6  C5Q  . 0.09
    3794 G16  54.18 -127.22   5  L1C .. 47.1  C1C  . 0.21  C1W  . 0.21  L2W .. 39.4  C2W  . 0.10
    3795 G21  15.13  -68.49   5  L1C .. 41.8  C1C  . 0.53  C1W  . 0.53  L2W .. 25.6  C2W  . 0.27
    3796 G22  26.49  158.25   5  L1C .. 44.6  C1C  . 0.27  C1W  . 0.27  L2W .. 30.1  C2W  . 0.29
    3797 G23   0.00    0.00  11  L1C .. 45.3  C1C  . 0.33  C1W  . 0.33  L2W .. 33.9  C2W  . 0.17  L2L .. 42.5  C2L  . 0.24  L5Q .. 46.3  C5Q  . 0.25  L1L .. 45.7  C1L  . 0.27
    3798 G26   0.00    0.00   9  L1C .. 46.7  C1C  . 0.28  C1W  . 0.29  L2W .. 36.8  C2W  . 0.09  L2L .. 43.7  C2L  . 0.21  L5Q .. 48.6  C5Q  . 0.10
    3799 G27   0.00    0.00   9  L1C .. 48.8  C1C  . 0.23  C1W  . 0.23  L2W .. 43.4  C2W  . 0.17  L2L .. 48.2  C2L  . 0.15  L5Q .. 51.9  C5Q  . 0.10
    3800 G31   0.00    0.00   7  L1C .. 35.7  C1C  . 4.35  C1W  . 4.31  L2W .. 18.4  C2W  . 4.31  L2L s. 31.1  C2L  . 0.00
    3801 G32   0.00    0.00   9  L1C .. 49.2  C1C  . 0.32  C1W  . 0.32  L2W .. 39.9  C2W  . 0.15  L2L .. 44.6  C2L  . 0.16  L5Q .. 48.0  C5Q  . 0.09
    3802 E02  43.91 -107.45  10  L1C .. 47.6  C1C  . 0.27  L6C .. 50.3  C6C  . 0.23  L5Q .. 48.5  C5Q  . 0.11  L7Q .. 48.8  C7Q  . 0.14  L8Q .. 51.7  C8Q  . 0.02
    3803 E03   2.45 -161.42  10  L1C .. 37.7  C1C  . 0.74  L6C .. 37.4  C6C  . 0.48  L5Q .. 36.9  C5Q  . 0.14  L7Q .. 37.6  C7Q  . 0.18  L8Q .. 40.3  C8Q  . 0.16
    3804 E04   8.83   44.72   7  C1C  . 0.00  C6C  . 0.00  L5Q .. 28.5  C5Q  . 0.00  C7Q  . 0.00  L8Q .. 31.2  C8Q  . 0.00
    3805 E05  37.64  160.08  10  L1C .. 46.5  C1C  . 0.13  L6C .. 49.7  C6C  . 0.12  L5Q .. 47.0  C5Q  . 0.12  L7Q .. 47.5  C7Q  . 0.10  L8Q .. 50.3  C8Q  . 0.03
    3806 E09  42.44   89.19  10  L1C .. 47.7  C1C  . 0.20  L6C .. 50.7  C6C  . 0.13  L5Q .. 48.1  C5Q  . 0.09  L7Q .. 48.9  C7Q  . 0.19  L8Q .. 51.5  C8Q  . 0.04
    3807 E11  20.61   64.05  10  L1C .. 41.7  C1C  . 0.14  L6C .. 42.8  C6C  . 0.14  L5Q .. 39.0  C5Q  . 0.14  L7Q .. 39.2  C7Q  . 0.12  L8Q .. 42.1  C8Q  . 0.03
    3808 E25  29.05 -169.12  10  L1C .. 44.2  C1C  . 0.36  L6C .. 47.6  C6C  . 0.26  L5Q .. 45.0  C5Q  . 0.13  L7Q .. 46.0  C7Q  . 0.20  L8Q .. 48.5  C8Q  . 0.07
    3809 E30  18.32  -53.65  10  L1C .. 42.8  C1C  . 0.34  L6C .. 46.1  C6C  . 0.37  L5Q .. 42.7  C5Q  . 0.26  L7Q .. 43.5  C7Q  . 0.32  L8Q .. 46.1  C8Q  . 0.03
    3810 E34  26.84  -52.94  10  L1C .. 45.5  C1C  . 0.36  L6C .. 46.7  C6C  . 0.59  L5Q .. 44.1  C5Q  . 0.22  L7Q .. 44.6  C7Q  . 0.21  L8Q .. 47.4  C8Q  . 0.05
    3811 E36  44.38   10.32  10  L1C .. 47.1  C1C  . 0.23  L6C .. 50.4  C6C  . 0.14  L5Q .. 48.4  C5Q  . 0.18  L7Q .. 49.1  C7Q  . 0.13  L8Q .. 51.7  C8Q  . 0.04
    3812 J02  25.68  -71.42  12  L1C .. 43.6  C1C  . 0.60  L2L .. 40.0  C2L  . 0.83  L5Q .. 44.4  C5Q  . 0.06  L1L .. 43.6  C1L  . 0.71  L1Z .. 43.4  C1Z  . 0.64  L5P .. 40.8  C5P  . 0.09
    3813 J03  18.88  -66.71  12  L1C .. 41.0  C1C  . 0.45  L2L .. 40.3  C2L  . 0.58  L5Q .. 42.9  C5Q  . 0.17  L1L .. 41.7  C1L  . 0.49  L1Z .. 41.4  C1Z  . 0.47  L5P .. 39.4  C5P  . 0.17
    3814 J04   6.08 -127.48  12  L1C .. 39.3  C1C  . 1.18  L2L .. 38.2  C2L  . 1.45  L5Q .. 39.2  C5Q  . 0.59  L1L .. 38.7  C1L  . 1.31  L1Z .. 40.4  C1Z  . 1.21  L5P .. 35.0  C5P  . 0.60
    3815 J07   3.70  -94.81  11  C1C  . 0.51  L2L .. 37.0  C2L  . 0.20  L5Q .. 39.5  C5Q  . 0.09  L1L .. 32.7  C1L  . 0.21  L1Z .. 38.9  C1Z  . 0.25  L5P .. 30.9  C5P  . 0.16
    3816 C01  20.30 -102.21   6  L2I .. 41.8  C2I  . 0.00  L7I .. 42.6  C7I  . 0.00  L6I .. 40.1  C6I  . 0.00
    3817 C04  35.59 -109.87   6  L2I .. 44.5  C2I  . 0.00  L7I .. 45.4  C7I  . 0.00  L6I .. 44.6  C6I  . 0.00
    3818 C11  18.91  -42.10   6  L2I .. 39.0  C2I  . 0.00  L7I .. 46.1  C7I  . 0.00  L6I .. 44.6  C6I  . 0.00
    3819 C12  51.55    8.60   6  L2I .. 48.5  C2I  . 0.00  L7I .. 51.5  C7I  . 0.00  L6I .. 50.9  C6I  . 0.00
    3820 C14   7.32 -150.82   6  L2I .. 37.8  C2I  . 0.00  L7I .. 40.9  C7I  . 0.00  L6I .. 41.4  C6I  . 0.00
    3821 C21  75.79  138.30  10  L1P .. 49.0  C1P  . 0.14  L5P .. 51.9  C5P  . 0.06  L2I .. 50.8  C2I  . 0.25  L6I .. 52.5  C6I  . 0.08  L7D .. 51.0  C7D  . 0.07
    3822 C22  36.50   44.63  10  L1P .. 47.4  C1P  . 0.30  L5P .. 47.4  C5P  . 0.16  L2I .. 49.6  C2I  . 0.26  L6I .. 49.9  C6I  . 0.25  L7D .. 47.3  C7D  . 0.21
    3823 C24  16.27 -139.62  10  L1P .. 43.9  C1P  . 0.74  L5P .. 42.8  C5P  . 0.12  L2I .. 44.7  C2I  . 0.71  L6I .. 43.5  C6I  . 0.16  L7D .. 42.6  C7D  . 0.19
    3824 C25   8.87  -85.45  10  L1P .. 38.0  C1P  . 1.84  L5P .. 40.3  C5P  . 0.29  L2I .. 41.7  C2I  . 1.50  L6I .. 41.5  C6I  . 0.37  L7D .. 39.8  C7D  . 0.35
    3825 C26   4.25  177.77  10  L1P .. 40.0  C1P  . 0.75  L5P .. 37.8  C5P  . 0.28  L2I .. 41.7  C2I  . 0.66  L6I .. 40.5  C6I  . 0.22  L7D .. 37.7  C7D  . 0.28
    3826 C34  36.24  -28.48  10  L1P .. 46.7  C1P  . 0.36  L5P .. 42.5  C5P  . 0.23  L2I .. 48.9  C2I  . 0.44  L6I .. 48.1  C6I  . 0.21  L7D .. 42.3  C7D  . 0.38
    3827 C35  16.68  103.11  10  L1P .. 41.8  C1P  . 0.44  L5P .. 41.5  C5P  . 0.20  L2I .. 43.3  C2I  . 0.34  L6I .. 43.0  C6I  . 0.19  L7D .. 40.9  C7D  . 0.21
    3828 C40  10.26  -34.76  10  L1P .. 42.4  C1P  . 0.36  L5P .. 37.4  C5P  . 0.32  L2I .. 43.1  C2I  . 0.45  L6I .. 39.4  C6I  . 0.54  L7D .. 38.4  C7D  . 0.31
    3829 C42  30.61 -156.42  10  L1P .. 46.0  C1P  . 0.34  L5P .. 46.6  C5P  . 0.17  L2I .. 47.7  C2I  . 0.33  L6I .. 48.1  C6I  . 0.08  L7D .. 46.1  C7D  . 0.14
    3830 C44  53.90   52.53  10  L1P .. 48.1  C1P  . 0.18  L5P .. 49.4  C5P  . 0.11  L2I .. 50.9  C2I  . 0.34  L6I .. 50.9  C6I  . 0.15  L7D .. 48.9  C7D  . 0.10
    3831 C57   0.00    0.00   4  L2I .. 48.1  C2I  . 0.00  L6I .. 48.2  C6I  . 0.00
    3832 C59  15.79 -100.68   6  L2I .. 43.8  C2I  . 0.00  L6I .. 41.7  C6I  . 0.00  L7D .. 41.5  C7D  . 0.00
    3833 > 2022 06 21 00 00 30.0000000 41  0.6
     3664      G:   1C: Observations      :   1215 (    1302)    93.32 %
     3665      G:   1C: Slips (file+found):        4 +       0
     3666      G:   1C: Gaps              :        4
     3667      G:   1C: Mean SNR          :     42.7
     3668      G:   1C: Mean Multipath    :     0.27
     3669
     3670      G:   1L: Observations      :    328 (    1302)    25.19 %
     3671      G:   1L: Slips (file+found):        4 +       0
     3672      G:   1L: Gaps              :        1
     3673      G:   1L: Mean SNR          :     42.0
     3674      G:   1L: Mean Multipath    :     0.27
     3675
     3676      G:   1W: Observations      :   1169 (    1302)    89.78 %
     3677      G:   1W: Slips (file+found):        0 +       0
     3678      G:   1W: Gaps              :        0
     3679      G:   1W: Mean SNR          :     35.4
     3680      G:   1W: Mean Multipath    :     0.24
     3681
     3682      G:   2L: Observations      :    924 (    1302)    70.97 %
     3683      G:   2L: Slips (file+found):        4 +       0
     3684      G:   2L: Gaps              :        2
     3685      G:   2L: Mean SNR          :     41.0
     3686      G:   2L: Mean Multipath    :     0.29
     3687
     3688      G:   2W: Observations      :   1169 (    1302)    89.78 %
     3689      G:   2W: Slips (file+found):        3 +       0
     3690      G:   2W: Gaps              :        0
     3691      G:   2W: Mean SNR          :     35.4
     3692      G:   2W: Mean Multipath    :     0.22
     3693
     3694      G:   5Q: Observations      :    809 (    1302)    62.14 %
     3695      G:   5Q: Slips (file+found):        2 +       0
     3696      G:   5Q: Gaps              :        1
     3697      G:   5Q: Mean SNR          :     46.4
     3698      G:   5Q: Mean Multipath    :     0.17
     3699
     3700  R: Satellites: 11
     3701  R: Signals   : 5    1C 1P 2C 2P 3Q
     3702
     3703      R:   1C: Observations      :   1036 (    1063)    97.46 %
     3704      R:   1C: Slips (file+found):        6 +       1
     3705      R:   1C: Gaps              :        2
     3706      R:   1C: Mean SNR          :     45.8
     3707      R:   1C: Mean Multipath    :     0.45
     3708
     3709..
     3710
     3711> 2026 07 28 08 00  0.0000000 40  0.8
     3712G01  69.73  -69.71  11  L1C .. 49.8  C1C  . 0.08  C1W  . 0.09  L2W .. 45.1  C2W  . 0.02  L2L .. 51.4  C2L  . 0.07  L5Q .. 55.3  C5Q  . 0.02  L1L .. 49.2  C1L  . 0.08
     3713G02  80.53   79.07   5  L1C .. 50.8  C1C  . 0.09  C1W  . 0.09  L2W .. 47.4  C2W  . 0.02
     3714G03  37.67 -134.30   9  L1C .. 45.3  C1C  . 0.17  C1W  . 0.17  L2W .. 45.0  C2W  . 0.06  L2L .. 42.7  C2L  . 0.18  L5Q .. 49.7  C5Q  . 0.06
     3715R09  12.37  -91.67   8  L1C .. 42.0  C1C  . 0.84  L1P .. 40.8  C1P  . 0.69  L2P .. 39.4  C2P  . 0.38  L2C .. 40.4  C2C  . 0.38
     3716R11   5.51    3.88  10  L1C .. 39.6  C1C  . 0.56  L1P .. 39.1  C1P  . 0.65  L2P .. 36.4  C2P  . 0.51  L2C .. 36.8  C2C  . 0.42  L3Q .. 35.9  C3Q  . 0.22
     3717E13  76.44  -53.73  10  L1C .. 48.4  C1C  . 0.05  L6B .. 53.8  C6B  . 0.03  L5Q .. 51.7  C5Q  . 0.02  L7Q .. 52.5  C7Q  . 0.02  L8Q .. 55.1  C8Q  . 0.01
     3718E15  43.04   81.40  10  L1C .. 45.1  C1C  . 0.07  L6B .. 49.5  C6B  . 0.06  L5Q .. 47.8  C5Q  . 0.03  L7Q .. 48.4  C7Q  . 0.05  L8Q .. 51.2  C8Q  . 0.01
    38343719...
    38353720</p>
    38363721</pre>
     3722
     3723  <p>
     3724    <b>The summary output</b>
     3725  </p>
     3726
     3727  <p>
     3728    The line 'Ephemeris Check' reports how many navigation data sets were read from the RINEX Navigation file(s) and
     3729    classified as 'OK', 'UNHEALTHY' or 'WRONG':
     3730  </p>
     3731  <ul>
     3732    <li>'UNHEALTHY': The data set's health information flags the satellite as unhealthy. For GPS and QZSS CNAV data sets
     3733      the health word contains one flag per signal (L1, L2, L5; bits 52-54 of Message Type 10). Such a data set is
     3734      considered unhealthy only if the L1 or L2 flag is set; an L5-only flag, as it is common for satellites with a
     3735      not yet fully operational L5 signal, is ignored.</li>
     3736    <li>'WRONG': The data set failed a plausibility check. It is considered wrong if the satellite's radial distance
     3737      at TOC is not between 20,000 km and 60,000 km, or if satellite position or clock at its TOC differ by more than
     3738      10 m (100 m for BeiDou and SBAS) from those computed with the preceding data set of the same satellite, or if
     3739      a data set only repeats the preceding one with a different TOC. Wrong data sets are listed in the logfile and
     3740      ignored for the analysis.</li>
     3741  </ul>
     3742  <p>
     3743    The comparison with the preceding data set is skipped if the time between both data sets exceeds the nominal
     3744    update interval of the respective GNSS (GPS 2 h, Galileo 3 h, GLONASS 35 min, QZSS 1 h, BeiDou 65 min,
     3745    SBAS 10 min, NavIC 24 h). The preceding data set is then considered outdated, while the new one is accepted and
     3746    serves as reference for the following data sets. This way, the first data set after an outage, e.g. after the
     3747    satellite was not tracked for some hours, is not rejected.
     3748  </p>
     3749
     3750  <p>
     3751    For each signal, the line 'Observations' contains the number of observations in the RINEX Observation file
     3752    (after applying the 'Minimum Elevation' mask) and, if a RINEX Navigation file is specified, the number of
     3753    expected observations in brackets followed by the ratio of both numbers in percent. The number of expected
     3754    observations is computed per satellite system: For each satellite with at least one navigation data set and for
     3755    each epoch between start and end of the observation file at the file's sampling interval, an observation is
     3756    expected if
     3757  </p>
     3758  <ul>
     3759    <li>a navigation data set is valid at that epoch, and</li>
     3760    <li>the satellite's elevation is at least the 'Minimum Elevation'.</li>
     3761  </ul>
     3762  <p>
     3763    A data set is considered valid within the following periods around its TOC: GPS -2 h to +4 h, Galileo 0 to
     3764    +4 h, GLONASS -35 min to +35 min, QZSS -1 h to +2 h, BeiDou 0 to +65 min, SBAS -10 min to +10 min, NavIC
     3765    -24 h to +24 h. Among several valid data sets, the one with the closest TOC is used. Wrong or outdated data sets
     3766    are not used. Epochs at which a satellite is unhealthy (see section 'Minimum Elevation') do not count as
     3767    expected, consistent with the exclusion of its observations at such epochs.
     3768  </p>
     3769  <p>
     3770    Note that
     3771  </p>
     3772  <ul>
     3773    <li>the number of expected observations is the same for all signals of a satellite system. Signals which are not
     3774      transmitted by all satellites of a system (e.g. GPS L1C or L5) therefore show a lower percentage;</li>
     3775    <li>the number of expected observations and the percentage are only reported if each observed satellite of the
     3776      respective system has at least one navigation data set in the RINEX Navigation file(s);</li>
     3777    <li>a station's own navigation file usually only contains data sets for satellites which were tracked by the
     3778      station. Epochs without a valid data set, e.g. of satellites which were not tracked at all for a longer
     3779      period, do not count as expected. Using a merged navigation file (e.g. BRDC00WRD_S_...) is therefore
     3780      recommended to assess the completeness of observation data.</li>
     3781  </ul>
     3782
    38373783
    38383784  <p>
  • trunk/BNC/src/bncrinex.cpp

    r11047 r11057  
    581581    rnxSat.prn = satObs._prn;
    582582
    583     // Initialize all observations mentioned in skeleton header
    584     // --------------------------------------------------------
     583    // Initialize all observations mentioned in the output header
     584    // (from the skeleton or, if none is usable, the default header;
     585    // _sklHeader is empty or holds 2-char types in the latter case)
     586    // ----------------------------------------------------------
    585587    char sys = rnxSat.prn.system();
    586     for (int iType = 0; iType < _sklHeader.nTypes(sys); iType++) {
    587       QString type = _sklHeader.obsType(sys, iType);
     588    for (int iType = 0; iType < _header.nTypes(sys); iType++) {
     589      QString type = _header.obsType(sys, iType);
    588590      t_rnxObsFile::t_rnxObs rnxObs; // create an empty observation
    589591      rnxSat.obs[type] = rnxObs;
  • trunk/BNC/src/bncutils.cpp

    r11027 r11057  
    303303  }
    304304  // update interval: up to 24 hours
    305   else if (eph->system() == t_eph::NavIC   && (fabs(dt > 86400.0))) {
     305  else if (eph->system() == t_eph::NavIC   && (fabs(dt) > 86400.0)) {
    306306    return true;
    307307  }
  • trunk/BNC/src/ephemeris.cpp

    r10998 r11057  
    648648    }
    649649  }
     650
     651  // CNAV/CNAV-2 records carry no separate t_oe: t_oe = t_oc
     652  // (RINEX 4.02 Tables A9/A11, IS-GPS-200 30.3.4.4, IS-GPS-800 3.5.3.7.1).
     653  // NavIC L1NV (RINEX 4.02 Table A31): single reference epoch t_oec for
     654  // ephemeris and clock (NavIC L1 SPS ICD 6.2.1.6, Appendices A and B).
     655  // ---------------------------------------------------------------------
     656  if (type() == t_eph::CNAV || type() == t_eph::CNV2 || type() == t_eph::L1NV) {
     657    _TOEweek = _TOC.gpsw();
     658    _TOEsec  = _TOC.gpssec();
     659  }
    650660}
    651661
    … …  
    672682
    673683  double n = n0 + _Delta_n;
     684
     685  // CNAV/CNAV-2 (IS-GPS-200 Table 30-II) and NavIC L1NV (NavIC L1 SPS
     686  // ICD Appendix A): semi-major axis and mean motion difference are
     687  // time-variable, A_k = A0 + Adot*tk and
     688  // n_A = n0 + Delta_n0 + 1/2*Delta_n0_dot*tk.
     689  // n0 is computed from A0 for GPS/QZSS but from A_k for NavIC L1NV.
     690  double A    = a0;
     691  double Adot = 0.0;
     692  if (type() == t_eph::CNAV || type() == t_eph::CNV2 || type() == t_eph::L1NV) {
     693    Adot = _ADOT;
     694    A   += _ADOT * tk;
     695    n   += 0.5 * _Delta_n_dot * tk;
     696    if (type() == t_eph::L1NV) {
     697      n += sqrt(gmGRS / (A * A * A)) - n0;
     698    }
     699  }
     700
    674701  double M = _M0 + n * tk;
    675702  double E = M;
    … …  
    688715  double sin2u0 = sin(2 * u0);
    689716  double cos2u0 = cos(2 * u0);
    690   double r = a0 * (1 - _e * cos(E)) + _Crc * cos2u0 + _Crs * sin2u0;
     717  double r = A * (1 - _e * cos(E)) + _Crc * cos2u0 + _Crs * sin2u0;
    691718  double i = _i0 + _IDOT * tk + _Cic * cos2u0 + _Cis * sin2u0;
    692719  double u = u0 + _Cuc * cos2u0 + _Cus * sin2u0;
    … …  
    715742  double dotom = _OMEGADOT - omegaEarth;
    716743  double doti = _IDOT + (-_Cic * sin2u0 + _Cis * cos2u0) * 2 * dotv;
    717   double dotr = a0 * _e * sin(E) * dEdM * n
     744  double dotr = A * _e * sin(E) * dEdM * n + Adot * (1 - _e * cos(E))
    718745      + (-_Crc * sin2u0 + _Crs * cos2u0) * 2 * dotv;
    719746  double dotx = dotr * cos(u) - r * sin(u) * dotu;
    … …  
    740767  }
    741768  else {
    742     xc[3] -= 4.442807633e-10 * _e * sqrt(a0) * sin(E);
     769    xc[3] -= 4.442807633e-10 * _e * sqrt(A) * sin(E);
    743770  }
    744771
    … …  
    10871114      switch (type()) {
    10881115        case  t_eph::LNAV:
    1089         case  t_eph::CNAV:
    10901116        case  t_eph::CNV2:
    10911117          if (_health == 0.0) {
     1118            return 0;
     1119          }
     1120          else {
     1121            return 1;
     1122          }
     1123          break;
     1124        case  t_eph::CNAV:
     1125          // RINEX 4: bits 52(MSB)-54(LSB) of msg 10 = L1, L2, L5 health.
     1126          // An L5-only flag (value 1, common while L5 is not fully
     1127          // operational) does not make orbit/clock unusable; the data set
     1128          // is unhealthy if L1 or L2 is flagged.
     1129          if ((int(_health) & 0x6) == 0) {
    10921130            return 0;
    10931131          }
  • trunk/BNC/src/pppMain.cpp

    r11052 r11057  
    8181      t_pppThread* pppThread = new t_pppThread(opt);
    8282      pppThread->start();
     83      // In batch post-processing (--file replay), the data source must not
     84      // start before the PPP client is connected, otherwise the data read
     85      // in the meantime get lost (a varying amount, depending on thread
     86      // scheduling).
     87      if (BNC_CORE->mode() == t_bncCore::batchPostProcessing) {
     88        pppThread->waitUntilReady();
     89      }
    8390      _pppThreads << pppThread;
    8491      _running = true;
  • trunk/BNC/src/pppThread.cpp

    r11022 r11057  
    7878  try {
    7979    _pppRun = new t_pppRun(_opt);
     80    _ready.release();
    8081    if (_opt->_realTime) {
    8182      QThread::exec();
    … …  
    8788  catch (t_except exc) {
    8889    _pppRun = 0;
     90    _ready.release();
    8991    emit newMessage(QByteArray(exc.what().c_str()), true);
    9092  }
  • trunk/BNC/src/pppThread.h

    r6137 r11057  
    1919  virtual void run();
    2020  static void msleep(unsigned long msecs){QThread::msleep(msecs);}
     21  // blocks until t_pppRun is created and connected (or creation failed)
     22  void waitUntilReady() {_ready.acquire();}
    2123
    2224 signals:
    … …  
    2628  const t_pppOptions* _opt;
    2729  t_pppRun*           _pppRun;
     30  QSemaphore          _ready;
    2831};
    2932
  • trunk/BNC/src/rinex/reqcanalyze.cpp

    r11023 r11057  
    131131  // ----------------
    132132  t_reqcEdit::readEphemerides(_navFileNames, _ephs, _logStream, _checkEph);
     133  t_reqcEdit::indexEphemerides(_ephs, _ephsByPrn);
    133134
    134135  // Loop over all RINEX Files
    … …  
    207208          continue;
    208209        }
     210        // observations of unhealthy satellites are excluded, as those
     211        // below the elevation mask (see also setExpectedObs)
     212        if (_navFileNames.size() && unhealthyAt(rnxSat.prn, _currEpo->tt)) {
     213          continue;
     214        }
    209215        t_satObs satObs;
    210216        t_rnxObsFile::setObsFromRnx(obsFile, _currEpo, rnxSat, satObs);
    … …  
    266272    }
    267273
    268     t_eph* eph = 0;
    269     for (int ie = 0; ie < _ephs.size(); ie++) {
    270       if (_ephs[ie]->prn() == prn) {
    271         eph = _ephs[ie];
    272         break;
    273       }
    274     }
     274    if (unhealthyAt(prn, _currEpo->tt)) {
     275      continue;
     276    }
     277    t_eph* eph = ephForTime(prn, _currEpo->tt);
    275278    if (eph) {
    276279      ColumnVector xSat(6);
    … …  
    328331                             t_qcSat& qcSat) {
    329332
    330   t_eph* eph = 0;
    331   for (int ie = 0; ie < _ephs.size(); ie++) {
    332     if (_ephs[ie]->prn() == satObs._prn) {
    333       eph = _ephs[ie];
    334       break;
    335     }
    336   }
     333  t_eph* eph = ephForTime(satObs._prn, epoTime);
    337334  if (eph) {
    338335    ColumnVector xc(6);
    … …  
    976973                                   double interval, const ColumnVector& xyzSta) {
    977974  for(QMap<t_prn, int>::iterator it = _numExpObs.begin(); it != _numExpObs.end(); it++) {
    978     t_eph* eph = 0;
     975    bool navAvail = false;
    979976    for (int ie = 0; ie < _ephs.size(); ie++) {
    980977      if (_ephs[ie]->prn() == it.key()) {
    981         eph = _ephs[ie];
     978        navAvail = true;
    982979        break;
    983980      }
    984981    }
    985     if (eph) {
     982    if (navAvail) {
    986983      int numExpObs = 0;
    987984      bncTime epoTime;
    988985      for (epoTime = startTime - interval; epoTime < endTime; epoTime = epoTime + interval) {
     986        // an observation is only expected if a valid ephemeris exists,
     987        // the satellite is healthy (unhealthy satellite-epochs are also
     988        // excluded from the observations, see analyzeFile) and above
     989        // the elevation mask
     990        if (unhealthyAt(it.key(), epoTime)) {
     991          continue;
     992        }
     993        t_eph* eph = ephForTime(it.key(), epoTime, true);
     994        if (!eph) {
     995          continue;
     996        }
    989997        ColumnVector xc(6);
    990998        ColumnVector vv(3);
    … …  
    10071015  }
    10081016}
     1017
     1018// A satellite is considered unhealthy at epoch tt if the valid navigation
     1019// data set closest to tt is flagged unhealthy. Its orbit is not used then
     1020// (the geometry may be erroneous) and its observations are excluded.
     1021////////////////////////////////////////////////////////////////////////////
     1022bool t_reqcAnalyze::unhealthyAt(const t_prn& prn, const bncTime& tt) const {
     1023  t_eph* eph = ephForTime(prn, tt, true, true);
     1024  return eph && eph->checkState() == t_eph::unhealthy;
     1025}
     1026
     1027// Ephemeris of the given satellite for epoch tt, see t_reqcEdit::ephForTime
     1028////////////////////////////////////////////////////////////////////////////
     1029t_eph* t_reqcAnalyze::ephForTime(const t_prn& prn, const bncTime& tt,
     1030                                 bool validOnly, bool allowUnhealthy) const {
     1031  return t_reqcEdit::ephForTime(_ephsByPrn.value(prn), prn, tt, validOnly, allowUnhealthy);
     1032}
  • trunk/BNC/src/rinex/reqcanalyze.h

    r11023 r11057  
    194194  void   setExpectedObs(const bncTime& startTime, const bncTime& endTime,
    195195                        double interval, const ColumnVector& xyzSta);
     196
     197  t_eph* ephForTime(const t_prn& prn, const bncTime& tt, bool validOnly = false,
     198                    bool allowUnhealthy = false) const;
     199
     200  bool   unhealthyAt(const t_prn& prn, const bncTime& tt) const;
    196201
    197202  void   analyzeMultipath();
    … …  
    219224  QStringList                _defaultSignalTypes;
    220225  QVector<t_eph*>            _ephs;
     226  QMap<t_prn, QVector<t_eph*> > _ephsByPrn;
    221227  t_rnxObsFile::t_rnxEpo*    _currEpo;
    222228  t_qcFile                   _qcFile;
  • trunk/BNC/src/rinex/reqcedit.cpp

    r11023 r11057  
    230230  if (_minEle > 0.0 && _ephs.isEmpty()) {
    231231    t_reqcEdit::readEphemerides(_navFileNames, _ephs, _logStream, _checkEph);
     232    t_reqcEdit::indexEphemerides(_ephs, _ephsByPrn);
    232233  }
    233234
    … …  
    546547    const t_rnxObsFile::t_rnxSat& rnxSat = epo->rnxSat[iSat];
    547548
    548     t_eph* eph = 0;
    549     for (int ie = 0; ie < _ephs.size(); ie++) {
    550       if (_ephs[ie]->prn() == rnxSat.prn) {
    551         eph = _ephs[ie];
    552         break;
    553       }
    554     }
     549    t_eph* eph = ephForTime(_ephsByPrn.value(rnxSat.prn), rnxSat.prn, epo->tt);
    555550    if (eph) {
    556551      ColumnVector xc(6);
    … …  
    567562  }
    568563  epo->rnxSat = keptSats;
     564}
     565
     566// Ephemeris of the given satellite for epoch tt: the one with TOC closest
     567// to tt among those valid at tt (see outDatedBcep). If none is valid,
     568// return 0 when validOnly is set, otherwise the one with TOC closest to tt.
     569// Only ephemerides accepted by t_eph::getCrd are considered (not bad or
     570// outdated; unhealthy ones only if allowUnhealthy is set, to be used with
     571// getCrd(..., ignoreHealth = true)).
     572// Using the first ephemeris of the day for all epochs gives wrong
     573// geometry late in the day and, for GLONASS, integrations over many
     574// hours (t_ephGlo::position integrates from TOC on every call).
     575////////////////////////////////////////////////////////////////////////////
     576t_eph* t_reqcEdit::ephForTime(const QVector<t_eph*>& ephs, const t_prn& prn,
     577                              const bncTime& tt, bool validOnly,
     578                              bool allowUnhealthy) {
     579  t_eph* bestValid   = 0;
     580  t_eph* bestAny     = 0;
     581  double bestValidDt = 0.0;
     582  double bestAnyDt   = 0.0;
     583  for (int ie = 0; ie < ephs.size(); ie++) {
     584    t_eph* eph = ephs[ie];
     585    if (eph->prn() != prn) {
     586      continue;
     587    }
     588    if (eph->checkState() == t_eph::bad      ||
     589        eph->checkState() == t_eph::outdated ||
     590        (eph->checkState() == t_eph::unhealthy && !allowUnhealthy)) {
     591      continue;
     592    }
     593    double dt = fabs(tt - eph->TOC());
     594    if (bestAny == 0 || dt < bestAnyDt) {
     595      bestAny   = eph;
     596      bestAnyDt = dt;
     597    }
     598    if (!outDatedBcep(eph, tt) && (bestValid == 0 || dt < bestValidDt)) {
     599      bestValid   = eph;
     600      bestValidDt = dt;
     601    }
     602  }
     603  if (bestValid || validOnly) {
     604    return bestValid;
     605  }
     606  return bestAny;
     607}
     608
     609// Group ephemerides by satellite (speeds up ephForTime)
     610////////////////////////////////////////////////////////////////////////////
     611void t_reqcEdit::indexEphemerides(const QVector<t_eph*>& ephs,
     612                                  QMap<t_prn, QVector<t_eph*> >& ephsByPrn) {
     613  ephsByPrn.clear();
     614  for (int ie = 0; ie < ephs.size(); ie++) {
     615    ephsByPrn[ephs[ie]->prn()].append(ephs[ie]);
     616  }
    569617}
    570618
  • trunk/BNC/src/rinex/reqcedit.h

    r11023 r11057  
    5656                                QVector<t_eph*>& ephs,
    5757                                QTextStream* log, bool checkEph);
     58  static void indexEphemerides(const QVector<t_eph*>& ephs,
     59                               QMap<t_prn, QVector<t_eph*> >& ephsByPrn);
     60  static t_eph* ephForTime(const QVector<t_eph*>& ephs, const t_prn& prn,
     61                           const bncTime& tt, bool validOnly = false,
     62                           bool allowUnhealthy = false);
    5863
    5964 private:
    … …  
    8287  QMap<QString, QMap<int, int> > _lli;
    8388  QVector<t_eph*>        _ephs;
     89  QMap<t_prn, QVector<t_eph*> > _ephsByPrn;
    8490};
    8591
  • trunk/BNC/src/rinex/rnxobsfile.cpp

    r11023 r11057  
    349349  }
    350350  else {
    351     _obsTypes['G'] << "C1C" << "L1C"  << "S1C"
    352                    << "C1W" << "L1W"  << "S1W"
    353                    << "C2X" << "L2X"  << "S2X"
    354                    << "C2W" << "L2W"  << "S2W"
    355                    << "C5X" << "L5X"  << "S5X";
    356 
    357     _obsTypes['J'] << "C1C" << "L1C"  << "S1C"
    358                    << "C1Z" << "L1Z"  << "S1Z"
    359                    << "C1X" << "L1X"  << "S1X"
    360                    << "C2L" << "L2L"  << "S2L"
    361                    << "C2X" << "L2X"  << "S2X"
    362                    << "C5Q" << "L5Q"  << "S5Q"
    363                    << "C5X" << "L5X"  << "S5X"
    364                    << "C6L" << "L6L"  << "S6L";
    365 
    366     _obsTypes['R'] << "C1C" << "L1C" << "S1C"
    367                    << "C1P" << "L1P" << "S1P"
    368                    << "C2C" << "L2C" << "S2C"
    369                    << "C2P" << "L2P" << "S2P"
    370                    << "C3I" << "L3I" << "S3I"
    371                    << "C4X" << "L4X" << "S4X"
    372                    << "C6X" << "L6X" << "S6X";
    373 
    374     _obsTypes['E'] << "C1C" << "L1C" << "S1C"
    375                    << "C1X" << "L1X" << "S1X"
    376                    << "C5Q" << "L5Q" << "S5Q"
    377                    << "C5X" << "L5X" << "S5X"
    378                    << "C6C" << "L6C" << "S6C"
    379                    << "C6X" << "L6X" << "S6X"
    380                    << "C7Q" << "L7Q" << "S7Q"
    381                    << "C7X" << "L7X" << "S7X"
    382                    << "C8Q" << "L8Q" << "S8Q"
    383                    << "C8X" << "L8X" << "S8X";
    384 
    385     _obsTypes['S'] << "C1C" << "L1C" << "S1C"
    386                    << "C5I" << "L5I" << "S5I"
    387                    << "C5Q" << "L5Q" << "S5Q"
    388                    << "C5X" << "L5X" << "S5X";
    389 
    390     _obsTypes['C'] << "C2I" << "L2I" << "S2I"
    391                    << "C2Q" << "L2Q" << "S2Q"
    392                    << "C2X" << "L2X" << "S2X"
    393                    << "C6I" << "L6I" << "S6I"
    394                    << "C6Q" << "L6Q" << "S6Q"
    395                    << "C6X" << "L6X" << "S6X"
    396                    << "C7I" << "L7I" << "S7I"
    397                    << "C7Q" << "L7Q" << "S7Q"
    398                    << "C7X" << "L7X" << "S7X";
    399 
    400     _obsTypes['I'] << "C5A" << "L5A" << "S5A"
    401                    << "C9A" << "L9A" << "S9A";
     351    // All signals the RTCM3 MSM decoder can deliver (see RTCM3Decoder.cpp),
     352    // each with code, phase, Doppler and SNR. Empty observations are blank
     353    // padded up to the last non-empty one of a record, so the order keeps
     354    // records short: per system first the signals most receivers track
     355    // (Q/C/L/P tracking modes), then the combined 'X' modes, then rarely
     356    // used ones.
     357    QMap<char, QStringList> sigCodes;
     358    sigCodes['G'] << "1C" << "1W" << "2W" << "2L" << "2S" << "5Q" << "1L"
     359                  << "2X" << "5X" << "1X"
     360                  << "5I" << "1S" << "1P" << "2C" << "2P";
     361    sigCodes['R'] << "1C" << "1P" << "2C" << "2P" << "3Q"
     362                  << "3X" << "4X" << "6X"
     363                  << "3I" << "4A" << "4B" << "6A" << "6B";
     364    sigCodes['E'] << "1C" << "5Q" << "7Q" << "8Q" << "6C"
     365                  << "1X" << "5X" << "7X" << "8X" << "6X"
     366                  << "1B" << "5I" << "7I" << "8I" << "6B" << "1A" << "1Z" << "6A" << "6Z";
     367    sigCodes['J'] << "1C" << "2L" << "5Q" << "1L"
     368                  << "2X" << "5X" << "1X"
     369                  << "2S" << "5I" << "1S" << "1E" << "1Z" << "6L" << "6S" << "6X";
     370    sigCodes['C'] << "2I" << "7I" << "6I" << "5P" << "1P" << "7D"
     371                  << "2X" << "7X" << "6X" << "5X" << "1X"
     372                  << "2Q" << "7Q" << "6Q" << "5D" << "1D";
     373    sigCodes['S'] << "1C" << "5I" << "5Q" << "5X";
     374    sigCodes['I'] << "5A" << "9A";
     375
     376    QMapIterator<char, QStringList> it(sigCodes);
     377    while (it.hasNext()) {
     378      it.next();
     379      for (int ii = 0; ii < it.value().size(); ii++) {
     380        const QString& sig = it.value()[ii];
     381        _obsTypes[it.key()] << "C" + sig << "L" + sig << "D" + sig << "S" + sig;
     382      }
     383    }
    402384  }
    403385}
    … …  
    15281510    char sys = rnxSat.prn.system();
    15291511
     1512    // If all observation types are given as v3 types, a direct lookup is
     1513    // equivalent to the (slow) matching loops below
     1514    // --------------------------------------------------------------------
     1515    bool allTypesV3 = true;
     1516    QMapIterator<QString, t_rnxObs> itChk(rnxSat.obs);
     1517    while (itChk.hasNext() && allTypesV3) {
     1518      itChk.next();
     1519      if (itChk.key().length() != 3 || type2to3(sys, itChk.key()) != itChk.key()) {
     1520        allTypesV3 = false;
     1521      }
     1522    }
     1523
    15301524    std::vector <const t_rnxObs*> hlp(header.nTypes(sys));
    15311525    for (int iTypeV3 = 0; iTypeV3 < header.nTypes(sys); iTypeV3++) {
    15321526      hlp[iTypeV3] = 0;
    15331527      QString typeV3 = header.obsType(sys, iTypeV3);
     1528      if (allTypesV3) {
     1529        QMap<QString, t_rnxObs>::const_iterator itV3 = rnxSat.obs.constFind(typeV3);
     1530        if (itV3 != rnxSat.obs.constEnd() && itV3.value().value != 0.0) {
     1531          hlp[iTypeV3] = &itV3.value();
     1532        }
     1533        continue;
     1534      }
    15341535      QMapIterator<QString, t_rnxObs> itObs(rnxSat.obs);
    15351536
    … …  
    15591560
    15601561    if (header.nTypes(sys)) {
    1561       *stream << rnxSat.prn.toString().c_str();
     1562      QString record = rnxSat.prn.toString().c_str();
    15621563      for (int iTypeV3 = 0; iTypeV3 < header.nTypes(sys); iTypeV3++) {
    15631564        const t_rnxObs* rnxObs = hlp[iTypeV3];
    15641565        if (rnxObs == 0) {
    1565           *stream << QString().leftJustified(16);
     1566          record += QString().leftJustified(16);
    15661567        }
    15671568        else {
    1568           *stream << QString("%1").arg(rnxObs->value, 14, 'f', 3);
     1569          record += QString("%1").arg(rnxObs->value, 14, 'f', 3);
    15691570          if (rnxObs->lli != 0.0) {
    1570             *stream << QString("%1").arg(rnxObs->lli, 1);
     1571            record += QString("%1").arg(rnxObs->lli, 1);
    15711572          }
    15721573          else {
    1573             *stream << ' ';
     1574            record += ' ';
    15741575          }
    15751576          if (rnxObs->snr != 0.0) {
    1576             *stream << QString("%1").arg(rnxObs->snr, 1);
     1577            record += QString("%1").arg(rnxObs->snr, 1);
    15771578          }
    15781579          else {
    1579             *stream << ' ';
     1580            record += ' ';
    15801581          }
    15811582        }
    15821583      }
    1583       *stream << Qt::endl;
     1584      // Trailing blanks can be removed from the records (RINEX 4.02, 4.)
     1585      int len = record.length();
     1586      while (len > 3 && record[len-1] == ' ') {
     1587        len--;
     1588      }
     1589      record.truncate(len);
     1590      *stream << record << Qt::endl;
    15841591    }
    15851592  }
  • trunk/BNC/src/upload/bncrtnetuploadcaster.cpp

    r10994 r11057  
    350350    memset(&co, 0, sizeof(co));
    351351    co.EpochTime[CLOCKORBIT_SATGPS] = static_cast<int>(epoTime.gpssec());
    352     double gt = epoTime.gpssec() - gnumleap(year, month, day);
    353     if (_ssrFormat == "RTCM-SSR") {
    354         gt += 3 * 3600;
    355     }
    356     co.EpochTime[CLOCKORBIT_SATGLONASS] = static_cast<int>(fmod(gt, 86400.0));
     352    if (_ssrFormat == "IGS-SSR") {
     353      // SSR Epoch Time (IDF003) in one continuous time scale for all GNSS:
     354      // GPS seconds of week also for GLONASS and BDS (IGS SSR v1.00)
     355      co.EpochTime[CLOCKORBIT_SATGLONASS] = static_cast<int>(epoTime.gpssec());
     356      co.EpochTime[CLOCKORBIT_SATBDS] = static_cast<int>(epoTime.gpssec());
     357    }
     358    else {
     359      // RTCM-SSR (old and new): GLONASS Epoch Time DF386, seconds since the
     360      // beginning of the GLONASS day (GLONASS time = UTC(SU) + 3h)
     361      double gt = epoTime.gpssec() - gnumleap(year, month, day) + 3 * 3600;
     362      co.EpochTime[CLOCKORBIT_SATGLONASS] = static_cast<int>(fmod(gt, 86400.0));
     363      co.EpochTime[CLOCKORBIT_SATBDS] = static_cast<int>(epoTime.bdssec());
     364    }
    357365    co.EpochTime[CLOCKORBIT_SATGALILEO] = static_cast<int>(epoTime.gpssec());
    358366    co.EpochTime[CLOCKORBIT_SATQZSS] = static_cast<int>(epoTime.gpssec());
    359367    co.EpochTime[CLOCKORBIT_SATSBAS] = static_cast<int>(epoTime.gpssec());
    360     co.EpochTime[CLOCKORBIT_SATBDS] = static_cast<int>(epoTime.bdssec());
    361368    co.Supplied[_ssrCorr->COBOFS_CLOCK] = 1;
    362369    co.Supplied[_ssrCorr->COBOFS_ORBIT] = 1;
Note: See TracChangeset for help on using the changeset viewer.