Changeset 11066 in ntrip


Ignore:
Timestamp:
Oct 5, 2026, 12:31:32 PM (24 hours ago)
Author:
stuerze
Message:

further fixes and initial import for ssr qc

Location:
trunk/BNC/src
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/BNC/src/bncantex.cpp

    r11047 r11066  
    6868  }
    6969  _maps.clear();
     70  QMapIterator<QString, QVector<t_antMap*> > itSat(_satMaps);
     71  while (itSat.hasNext()) {
     72    itSat.next();
     73    for (int ii = 0; ii < itSat.value().size(); ii++) {
     74      delete itSat.value()[ii];
     75    }
     76  }
     77  _satMaps.clear();
    7078}
    7179
    … …  
    141149t_irc bncAntex::readFile(const QString& fileName) {
    142150
     151  _fileName = fileName;
    143152  QFile inFile(fileName);
    144153  inFile.open(QIODevice::ReadOnly | QIODevice::Text);
    … …  
    176185          _satBlocks[newAntMap->antName].append(satBlock);
    177186        }
    178         if (_maps.contains(newAntMap->antName)) {
    179           delete _maps[newAntMap->antName];
    180         }
    181         _maps[newAntMap->antName] = newAntMap;
     187        if (newAntMap->isSat) {
     188          _satMaps[newAntMap->antName].append(newAntMap);
     189        }
     190        else {
     191          if (_maps.contains(newAntMap->antName)) {
     192            delete _maps[newAntMap->antName];
     193          }
     194          _maps[newAntMap->antName] = newAntMap;
     195        }
    182196        newAntMap = 0;
    183197      }
    … …  
    199213            line.indexOf("NavIC") == 0 ){
    200214          newAntMap->antName = line.mid(20,3);
     215          newAntMap->isSat   = true;
    201216          if (line.indexOf("BLOCK I") == 0) {
    202217            // Extract GPS block type: "BLOCK IIF   " → "IIF"
    … …  
    789804  }
    790805
    791   QMap<QString, t_antMap*>::const_iterator it = _maps.find(prn.mid(0,3));
    792   if (it != _maps.end()) {
    793     t_antMap* map = it.value();
     806  bncTime epoch;
     807  epoch.setmjd(Mjd);
     808  const t_antMap* map = satMap(prn, epoch);
     809  if (map) {
    794810    if (map->frqMap.find(frqType) != map->frqMap.end()) {
    795811
    796       double* neu = map->frqMap[frqType]->neu;
     812      const double* neu = map->frqMap[frqType]->neu;
    797813
    798814      // Unit Vectors sz, sy, sx
    … …  
    879895////////////////////////////////////////////////////////////////////////////
    880896double bncAntex::satCorr(const QString& prn, t_frequency::type frqType,
    881                          double elTx, double azTx, bool& found) const {
    882 
    883   if (_maps.find(prn.mid(0,3)) == _maps.end()) {
     897                         double elTx, double azTx, bool& found,
     898                         const bncTime& epoch) const {
     899
     900  const t_antMap* map = satMap(prn, epoch);
     901  if (!map) {
    884902    found = false;
    885903    return 0.0;
    886904  };
    887 
    888   t_antMap* map = _maps[prn.mid(0,3)];
    889905
    890906  if (map->frqMap.find(frqType) == map->frqMap.end()) {
    … …  
    964980}
    965981
     982// Satellite antenna entry valid at the given epoch (the last entry of the
     983// PRN if the epoch is not valid), 0 if there is none
     984////////////////////////////////////////////////////////////////////////////
     985const bncAntex::t_antMap* bncAntex::satMap(const QString& prn, const bncTime& epoch) const {
     986  QMap<QString, QVector<t_antMap*> >::const_iterator it = _satMaps.find(prn.mid(0,3));
     987  if (it == _satMaps.end() || it.value().isEmpty()) {
     988    return 0;
     989  }
     990  const QVector<t_antMap*>& maps = it.value();
     991  if (!epoch.valid()) {
     992    return maps.last();
     993  }
     994  for (int ii = maps.size() - 1; ii >= 0; ii--) {
     995    const t_antMap* map = maps[ii];
     996    if ((!map->validFrom.valid() || !(epoch < map->validFrom)) &&
     997        (!map->validTo.valid()   || epoch < map->validTo)) {
     998      return map;
     999    }
     1000  }
     1001  return 0;
     1002}
     1003
     1004// File name, number of satellite entries and the latest satellite entry,
     1005// which identifies the version of the file
     1006////////////////////////////////////////////////////////////////////////////
     1007QString bncAntex::info() const {
     1008  int     numSat = 0;
     1009  bncTime latest;
     1010  QString latestPrn;
     1011  QMapIterator<QString, QVector<t_antMap*> > it(_satMaps);
     1012  while (it.hasNext()) {
     1013    it.next();
     1014    for (int ii = 0; ii < it.value().size(); ii++) {
     1015      const t_antMap* map = it.value()[ii];
     1016      ++numSat;
     1017      if (map->validFrom.valid() && (!latest.valid() || latest < map->validFrom)) {
     1018        latest    = map->validFrom;
     1019        latestPrn = it.key();
     1020      }
     1021    }
     1022  }
     1023  QString str = QString("ANTEX file %1: %2 receiver and %3 satellite antenna entries")
     1024                .arg(_fileName).arg(_maps.size()).arg(numSat);
     1025  if (latest.valid()) {
     1026    str += QString(", latest satellite entry %1 valid from %2").arg(latestPrn)
     1027           .arg(QString::fromStdString(latest.datestr()));
     1028  }
     1029  return str;
     1030}
     1031
     1032// True if a missing satellite antenna entry has to be reported (at most once
     1033// per hour and PRN)
     1034////////////////////////////////////////////////////////////////////////////
     1035bool bncAntex::warnNoSatEntry(const QString& prn, const bncTime& epoch) const {
     1036  bncTime& warned = _noSatEntryWarned[prn.mid(0,3)];
     1037  if (!warned.valid() || !epoch.valid() || epoch - warned >= 3600.0) {
     1038    warned = epoch;
     1039    return true;
     1040  }
     1041  return false;
     1042}
     1043
    9661044// Satellite block type valid at the given epoch
    9671045////////////////////////////////////////////////////////////////////////////
  • trunk/BNC/src/bncantex.h

    r11047 r11066  
    4343  QString snxCodeSinexString(const std::string& antName);
    4444  double  satCorr(const QString& prn, t_frequency::type frqType,
    45                   double eleSat, double azSat, bool& found) const;
     45                  double eleSat, double azSat, bool& found,
     46                  const bncTime& epoch = bncTime()) const;
    4647  double  rcvCorr(const std::string& antName, t_frequency::type frqType,
    4748                  double eleSat, double azSat, bool& found) const;
    … …  
    5051  // empty if unknown
    5152  QString satBlockType(const QString& prn, const bncTime& epoch) const;
     53  QString info() const;
     54  bool    hasSatEntry(const QString& prn, const bncTime& epoch) const {return satMap(prn, epoch) != 0;}
     55  bool    warnNoSatEntry(const QString& prn, const bncTime& epoch) const;
    5256
    5357  // Attitude model selection for satCoMcorrection().
    … …  
    178182      dZen    = 0.0;
    179183      snxCode = "";
     184      isSat   = false;
    180185    }
    181186    ~t_antMap() {
    … …  
    192197    double                             dZen;
    193198    QString                            snxCode;
     199    bool                               isSat;
    194200    QMap<t_frequency::type, t_frqMap*> frqMap;
    195201    bncTime                            validFrom;
    … …  
    197203  };
    198204
    199   QMap<QString, t_antMap*> _maps;
    200 
    201   // Block type history per satellite PRN. _maps keeps only the last ANTEX
    202   // entry per PRN, which is wrong for epochs before a PRN was reassigned.
     205  const t_antMap* satMap(const QString& prn, const bncTime& epoch) const;
     206
     207  QString                  _fileName;
     208  QMap<QString, t_antMap*> _maps;     // receiver antennas
     209  // All entries per satellite PRN (a PRN is reassigned to new satellites),
     210  // the entry valid at the epoch is selected via VALID FROM / VALID UNTIL
     211  QMap<QString, QVector<t_antMap*> > _satMaps;
     212  mutable QMap<QString, bncTime>     _noSatEntryWarned; // last warning per PRN
     213
     214  // Block type history per satellite PRN
    203215  struct t_satBlock {
    204216    bncTime validFrom;
  • trunk/BNC/src/bnccore.cpp

    r11039 r11066  
    4545
    4646#include "bnccore.h"
     47#include "ssrQc.h"
    4748#include "bncutils.h"
    4849#include "bncrinex.h"
    … …  
    106107
    107108  _pppMain = new BNC_PPP::t_pppMain();
     109  _ssrQc   = 0;
    108110  qRegisterMetaType< QVector<double> >      ("QVector<double>");
    109111  qRegisterMetaType<bncTime>                ("bncTime");
    … …  
    144146
    145147  bncComb::destruct();
     148  delete _ssrQc;
    146149
    147150  delete _pppMain;
    … …  
    830833}
    831834
     835// SSR QC of the decoded correction streams (optional)
     836////////////////////////////////////////////////////////////////////////////
     837void t_bncCore::initSsrQc() {
     838  delete _ssrQc; _ssrQc = 0;
     839  bncSettings settings;
     840  QString fileName = settings.value("ssrQcFile").toString();
     841  if (fileName.isEmpty()) {
     842    return;
     843  }
     844  expandEnvVar(fileName);
     845  QStringList hlp = settings.value("ssrQcIntr").toString().split(' ', Qt::SkipEmptyParts);
     846  double interval = 3600.0;
     847  if (hlp.size() == 2) {
     848    double fac = (hlp[1] == "min") ? 60.0 : (hlp[1] == "hour") ? 3600.0 : (hlp[1] == "day") ? 86400.0 : 0.0;
     849    if (hlp[0].toDouble() * fac > 0.0) {
     850      interval = hlp[0].toDouble() * fac;
     851    }
     852  }
     853  _ssrQc = new t_ssrQc(fileName, interval);
     854}
     855
     856// Writes the final SSR QC report
     857////////////////////////////////////////////////////////////////////////////
     858void t_bncCore::stopSsrQc() {
     859  delete _ssrQc; _ssrQc = 0;
     860}
     861
    832862//
    833863////////////////////////////////////////////////////////////////////////////
  • trunk/BNC/src/bnccore.h

    r11057 r11066  
    3232
    3333class bncComb;
     34class t_ssrQc;
    3435class bncTableItem;
    3536namespace BNC_PPP {
    … …  
    7374  void             initCombination();
    7475  void             stopCombination();
     76  void             initSsrQc();
     77  void             stopSsrQc();
    7578  const QString&   pgmName() {return _pgmName;}
    7679  const QString&   userName() {return _userName;}
    … …  
    172175  mutable QMutex         _mutexDateAndTimeGPS;
    173176  BNC_PPP::t_pppMain*    _pppMain;
     177  t_ssrQc*               _ssrQc;
    174178  bncEphUser             _ephUser;
    175179};
  • trunk/BNC/src/bncgetthread.cpp

    r11057 r11066  
    491491          BNC_CORE->stopPPP();
    492492          BNC_CORE->stopCombination();
     493          BNC_CORE->stopSsrQc();
    493494          sleep(2);
    494495          ::exit(5);
  • trunk/BNC/src/bnchelp.html

    r11064 r11066  
    147147    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2.8.2 <a href="#corrint">Interval</a><br>
    148148    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2.8.3 <a href="#corrport">Port</a><br>
     149    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2.8.4 <a href="#ssrqc">QC Logfile, QC Interval</a><br>
    149150    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2.8.4 <a href="#corrwait">Wait for Full Corr Epoch</a><br>
    150151    &nbsp; &nbsp; &nbsp; 2.9 <a href="#syncout"><b>Feed Engine</b></a><br>
    … …  
    49974998    falls back to using ANTEX-based satellite antenna corrections instead.
    49984999  </p>
     5000  <p>
     5001    <b>SSR epoch times:</b> In IGS-SSR, the SSR Epoch Time (IDF003) of all GNSS is given in GPS seconds of week. In
     5002    RTCM-SSR, the GLONASS epoch time (DF386) is given in GLONASS time (UTC+3h) as seconds of day, the BDS epoch time
     5003    (DF465) in BDT. Some encoders use other conventions for IGS-SSR. BNC recognises them by comparison with the GPS or
     5004    Galileo epoch of the same stream, converts the epochs and writes a warning to the logfile at most once per hour
     5005    per stream and system:
     5006  </p>
     5007  <ul>
     5008    <li>'IGS-SSR GLONASS epoch time in outdated convention (UTC seconds of day ...)': the convention of older BNC
     5009      versions; the SSR encoder should be updated.</li>
     5010    <li>'IGS-SSR GLONASS epoch time erroneously encoded (UTC seconds of week ...)': UTC instead of GPS time; the SSR
     5011      encoder should be corrected.</li>
     5012    <li>'IGS-SSR BDS epoch time in outdated convention (BDT ...)': BDT instead of GPS time; the SSR encoder should be
     5013      updated.</li>
     5014  </ul>
     5015  <p>
     5016    In addition, the orbit and clock epochs of all systems of a stream, converted to GPS time, are compared with the
     5017    latest GPS orbit and clock epoch of the same stream. A difference of more than 120 seconds points to another
     5018    erroneous encoding and is reported as 'X SSR epoch time ... differs by ... s from the GPS SSR epoch time of the
     5019    stream - erroneously encoded?'. Such epochs are not converted. Code and phase biases are not checked, as they may
     5020    be sent with the epoch of their last update.
     5021  </p>
    49995022
    50005023  <p>
    … …  
    50325055  <p><img src="IMG/Figure17.png" width=1000 /></p>
    50335056  <p>Figure 17: Example for pulling, saving and output of Broadcast Corrections using BNC</p>
     5057
     5058  <p>
     5059  <h4 id="ssrqc">2.8.4 QC Logfile, QC Interval - optional</h4>
     5060  </p>
     5061  <p>
     5062    BNC can check the quality of all Broadcast Correction streams it decodes, in real time or when reading a raw file
     5063    ('--file'). Specify the full path to a 'QC Logfile' to activate this function, and select the 'QC Interval' for
     5064    the reports (default: 1 hour). At the end of each interval and at the end of the program, a report is written per
     5065    stream and system. Broadcast ephemerides must be received as well, e.g. via stream 'BCEP00BKG0'.
     5066  </p>
     5067  <p>
     5068    A table lists per system and message type (ORBIT, CLOCK, CODE_BIAS, PHASE_BIAS):
     5069  </p>
     5070  <ul>
     5071    <li>the number of epochs,</li>
     5072    <li>the update interval as declared in the messages (SSR Update Interval), the median and the maximum of the
     5073      actual intervals,</li>
     5074    <li>the number of gaps, i.e. intervals longer than twice the larger of declared and median interval,</li>
     5075    <li>the number of epochs older than the previous one (out of order),</li>
     5076    <li>the latency, median and maximum, i.e. the time of the decoded output minus the epoch time. Note that BNC
     5077      passes on the corrections of an epoch when the next epoch arrives; the latency therefore includes one update
     5078      interval. When reading a raw file, the times of the file are used,</li>
     5079    <li>the number of satellites.</li>
     5080  </ul>
     5081  <p>
     5082    It is followed by the findings per system, only lines with findings are listed:
     5083  </p>
     5084  <ul>
     5085    <li>a declared update interval differing from the actual one (BNC uses it e.g. to detect outdated
     5086      corrections),</li>
     5087    <li>satellites with a healthy, current broadcast ephemeris without orbit corrections, clock corrections, code
     5088      biases or phase biases (the latter two only if the stream provides them for the system),</li>
     5089    <li>orbit and clock corrections referring to an IOD of no received broadcast ephemeris, to an unhealthy
     5090      broadcast ephemeris, or to a satellite without broadcast ephemeris (number of corrections in brackets),</li>
     5091    <li>the code bias signals provided, satellites without code biases of the reference signals (GPS C1W/C2W, GLONASS
     5092      C1P/C2P, Galileo C1C/C5Q, BDS C2I/C6I, QZSS C1C/C2L), and the standard deviation and maximum of the
     5093      ionosphere-free combination B_IF of the reference signal biases. A B_IF varying between the satellites is
     5094      legitimate if the clocks are estimated with other signals, but must then be consistent with the clocks
     5095      (see section 'Combination'),</li>
     5096    <li>clock jumps, i.e. clock changes between consecutive epochs (same IOD) beyond the clock rate of more than
     5097      0.5 m,</li>
     5098    <li>the largest radial and along-/cross-track orbit corrections. Their size mainly reflects the quality of the
     5099      broadcast ephemerides; a value differing from that of other streams for the same satellite points to a
     5100      problem of the stream.</li>
     5101  </ul>
     5102  <p>
     5103    Example:
     5104  </p>
     5105  <pre>
     5106Stream SSRA00GMV0
     5107  Sys Type        Epochs  Interval nom/med/max [s]  Gaps  Out-of-order  Latency med/max [s]  Sats
     5108  G   ORBIT           47         1 /   5.0 /    5.0     0             0      11.0 /   12.0     32
     5109  ...
     5110  G ORBIT: declared update interval 1 s, actual 5.0 s
     5111  G corrections referring to an IOD of no received broadcast ephemeris: G10(94) G22(94) G29(94)
     5112  G code bias signals: 1C 1P 1W 2L 2P 2S 2W 5Q
     5113  G ionosphere-free combination B_IF of the reference signal biases: std. dev. 0.586 m, max |B_IF| 2.058 m (32 satellites)
     5114  G largest orbit corrections: radial 1.06 m (G11), along/cross 2.05 m (G11)
     5115</pre>
     5116  <p>
     5117    Errors in the encoding of the SSR epoch times are reported by the decoder itself in the BNC logfile (see section
     5118    'Broadcast Corrections').
     5119  </p>
    50345120
    50355121  <p>
    … …  
    61736259    Default value for 'ANTEX file' is an empty option field, meaning that you do not want to correct observations for
    61746260    Antenna Phase Center offsets and variations.
     6261  </p>
     6262  <p>
     6263    A satellite PRN is reassigned to new satellites over time, therefore an ANTEX file contains several entries per
     6264    PRN with their validity ('VALID FROM' / 'VALID UNTIL'). BNC uses the entry valid at the epoch processed, so that
     6265    the same ANTEX file can be used for current and for older data. At startup, BNC logs the ANTEX file name, the
     6266    number of receiver and satellite antenna entries and the latest satellite entry, e.g.
     6267  </p>
     6268  <pre>
     6269ANTEX file Input/igs20.atx: 515 receiver and 405 satellite antenna entries, latest satellite entry R26 valid from 2026-09-26
     6270</pre>
     6271  <p>
     6272    The date of the latest satellite entry identifies the version of the file. Use the current IGS ANTEX file and update
     6273    it promptly when new satellites are announced, ideally at the same time as the providers of the corrections, as
     6274    their orbits and clocks refer to the antenna offsets of their own ANTEX file.
     6275    If there is no satellite antenna entry valid at the epoch for a satellite, e.g. a new satellite in an outdated
     6276    ANTEX file, its observations are not corrected for the satellite antenna offset and the message
     6277    'ANTEX: no satellite antenna entry valid at ... - ANTEX file outdated?' is written to the PPP logfile, at most once
     6278    per hour and satellite.
    61756279  </p>
    61766280  <p>
    … …  
    79168020    Hence, the ionosphere-free linear combination of code biases for the IGS reference signals is determined
    79178021    from the supplied code biases and subtracted from the clocks before combination.
     8022    This requires the code biases of both reference signals of a system. If an AC provides none or only one of them
     8023    for a satellite, its clock cannot be referred to the reference signals. It is still combined, but, as long as
     8024    other ACs provide referred clocks for this satellite, it is excluded from the clock datum like the clocks of an AC
     8025    with inconsistent biases (see below): its satellite offset absorbs the difference, and the combined clock is
     8026    defined by the referred clocks only. The message '... provides no code biases for the ... reference signal(s)
     8027    ...' naming the missing signal(s) is written to the logfile at most once per hour per AC and system.
    79188028    The combined satellite clocks are consistent to IGS clocks, which means ionosphere-free clocks based on the defined
    79198029    reference signals
    … …  
    79318041  </p>
    79328042  <p>
    7933     In the combination (method 'Filter') such errors are absorbed by the satellite-specific clock offsets estimated
    7934     for each AC, which consequently follow B_IF of that AC from satellite to satellite. BNC uses this to check the
    7935     consistency, separately for each AC and system:
     8043    In the combination (method 'Filter') such errors show up in the satellite-specific clock offsets estimated for
     8044    each AC, which consequently follow B_IF of that AC from satellite to satellite. As the offsets of all ACs of a
     8045    satellite are constrained to sum up to zero, they absorb only part of the error: with N ACs, the offset of the
     8046    inconsistent AC takes up about (N-1)/N of it, while about 1/N goes into the combined clock. BNC uses the offsets
     8047    to check the consistency, separately for each AC and system:
    79368048  </p>
    79378049  <ul>
    … …  
    79528064  <pre>
    79538065bncComb: BKG E code biases (C1C/C5Q) seem inconsistent with its clocks: satellite offsets follow the bias
    7954 combination B_IF (27 satellites, B_IF spread 0.084 m, slope 0.60, correlation 0.88)
     8066combination B_IF (27 satellites, B_IF spread 0.084 m, slope 0.60, correlation 0.88), AC excluded from the clock datum
    79558067</pre>
    79568068  <p>
    7957     The AC is still used in the combination, its offsets absorb most of the error. Nevertheless, the code biases
    7958     sent out by this AC should be corrected by its provider: either biases estimated together with the clocks
    7959     should be used, or the external biases have to be aligned to the clocks per satellite (b' = b - B_IF of the
    7960     reference signals, SSR sign convention). The check is not applied with the 'Single-Epoch' method.
    7961   </p>
     8069    Such an AC is therefore excluded from the clock datum of the respective system: its satellite offsets are no
     8070    longer part of the zero-sum conditions (their own sum is constrained to zero instead), and the satellite offsets
     8071    of all ACs of this system are re-initialized. The combined clocks are then defined by the consistent ACs only,
     8072    while the offsets of the excluded AC take up its error completely (a regression slope of about 1 at the
     8073    following checks). The AC is still used in the combination: it contributes its epoch-wise clock variations and
     8074    is counted for the minimum of 2 ACs per satellite. A satellite observed by excluded ACs only is combined with
     8075    the zero-sum condition of all its ACs as before, and if no consistent AC provides corrections for a system, the
     8076    exclusion is not applied. The checks continue: as soon as a check finds no inconsistency any more (or B_IF no
     8077    longer varies noticeably between the satellites, e.g. after the provider has aligned its biases), the AC is
     8078    used for the clock datum again, which is reported in both logfiles. A smaller weight factor of the AC would not
     8079    help instead: the weights act on the epoch-wise clock variations, while the satellite-specific constant part is
     8080    fixed by the zero-sum conditions, independent of the weights.
     8081  </p>
     8082  <p>
     8083    Nevertheless, the code biases sent out by this AC should be corrected by its provider: either biases estimated
     8084    together with the clocks should be used, or the external biases have to be aligned to the clocks per satellite
     8085    (b' = b - B_IF of the reference signals, SSR sign convention). The check is not applied with the 'Single-Epoch' method.
     8086  </p>
     8087  <p>
     8088    <b>Persistent outliers:</b>
     8089    A clock correction whose residual exceeds 'Maximal Residuum' is rejected as outlier. If an AC's clock for a single
     8090    satellite differs persistently from those of the other ACs, its satellite offset cannot absorb the difference, since
     8091    the offsets of all ACs of a satellite sum up to zero, and the correction is rejected again in every epoch. This
     8092    protects the combined clock, but it is worth to be reported to the AC. Therefore, once per hour and system, BNC
     8093    reports all AC satellites rejected in at least half of their epochs of the last hour (minimum 10 epochs), in the
     8094    combination logfile and in the BNC logfile, e.g.
     8095  </p>
     8096  <pre>
     8097bncComb: SHA G26 rejected as outlier in 99% of 720 epochs in the last hour (median residual 1.08 m)
     8098</pre>
    79628099  <p>
    79638100    This convention allows the ionosphere-free linear combination of the two OSBs of the reference signals to be set to
    … …  
    92679404    If you do not specify an ANTEX file, the SP3 file will contain orbit information which is referred to Antenna Phase
    92689405    Center (APC) instead of CoM.
     9406  </p>
     9407  <p>
     9408    A satellite PRN is reassigned to new satellites over time, therefore an ANTEX file contains several entries per
     9409    PRN with their validity ('VALID FROM' / 'VALID UNTIL'). BNC uses the entry valid at the epoch processed, so that
     9410    the same ANTEX file can be used for current and for older data. At startup, BNC logs the ANTEX file name, the
     9411    number of receiver and satellite antenna entries and the latest satellite entry, e.g.
     9412  </p>
     9413  <pre>
     9414ANTEX file Input/igs20.atx: 515 receiver and 405 satellite antenna entries, latest satellite entry R26 valid from 2026-09-26
     9415</pre>
     9416  <p>
     9417    The date of the latest satellite entry identifies the version of the file. Use the current IGS ANTEX file and update
     9418    it promptly when new satellites are announced, ideally at the same time as the providers of the corrections, as
     9419    their orbits and clocks refer to the antenna offsets of their own ANTEX file.
     9420    If there is no satellite antenna entry valid at the epoch for a satellite, its orbit cannot be referred to CoM;
     9421    the satellite is then not part of the combined product, and the message
     9422    'bncComb: no satellite antenna entry valid at ... - ANTEX file outdated? Satellite not combined' is written to the
     9423    logfile, at most once per hour and satellite.
    92699424  </p>
    92709425  <p>
  • trunk/BNC/src/bncmain.cpp

    r11021 r11066  
    6868    BNC_CORE->stopPPP();
    6969    BNC_CORE->stopCombination();
     70    BNC_CORE->stopSsrQc();
    7071#ifndef WIN32
    7172    sleep(2);
    … …  
    8182    BNC_CORE->stopPPP();
    8283    BNC_CORE->stopCombination();
     84    BNC_CORE->stopSsrQc();
    8385#ifndef WIN32
    8486    sleep(2);
    … …  
    208210        "   corrIntr {File interval [character string: 1 min|2 min|5 min|10 min|15 min|30 min|1 hour|1 day]}\n"
    209211        "   corrPort {Output port [integer number]}\n"
     212        "   ssrQcFile {SSR QC logfile, full path [character string]}\n"
     213        "   ssrQcIntr {SSR QC report interval [character string: 5 min|15 min|30 min|1 hour|1 day]}\n"
    210214        "\n"
    211215        "Feed Engine Panel keys:\n"
    … …  
    548552        BNC_CORE->setPortCorr(settings.value("corrPort").toInt());
    549553        BNC_CORE->initCombination();
     554        BNC_CORE->initSsrQc();
    550555
    551556        BNC_CORE->connect(caster, SIGNAL(getThreadsFinished()), app->instance(), SLOT(quit()));
    … …  
    592597        BNC_CORE->stopPPP();
    593598        BNC_CORE->stopCombination();
     599        BNC_CORE->stopSsrQc();
    594600#ifndef WIN32
    595601        sleep(2);
  • trunk/BNC/src/bncsettings.cpp

    r10753 r11066  
    138138        setValue_p("corrIntr", "1 day");
    139139        setValue_p("corrPort", "");
     140        setValue_p("ssrQcFile", "");
     141        setValue_p("ssrQcIntr", "1 hour");
    140142        // Feed Engine
    141143        setValue_p("outPort", "");
  • trunk/BNC/src/bncwindow.cpp

    r11022 r11066  
    298298  }
    299299  _corrPortLineEdit = new QLineEdit(settings.value("corrPort").toString());
     300  _ssrQcFileLineEdit = new QLineEdit(settings.value("ssrQcFile").toString());
     301  _ssrQcIntrComboBox = new QComboBox();
     302  _ssrQcIntrComboBox->setEditable(false);
     303  _ssrQcIntrComboBox->addItems(QString("5 min,15 min,30 min,1 hour,1 day").split(","));
     304  bi = _ssrQcIntrComboBox->findText(settings.value("ssrQcIntr").toString());
     305  if (bi != -1) {
     306    _ssrQcIntrComboBox->setCurrentIndex(bi);
     307  }
     308  else {
     309    _ssrQcIntrComboBox->setCurrentIndex(_ssrQcIntrComboBox->findText("1 hour"));
     310  }
     311  connect(_ssrQcFileLineEdit, SIGNAL(textChanged(const QString&)),
     312          this, SLOT(slotBncTextChanged()));
    300313
    301314  connect(_corrPathLineEdit, SIGNAL(textChanged(const QString&)),
    … …  
    894907  _corrIntrComboBox->setMaximumWidth(9 * ww);
    895908  _corrPortLineEdit->setMaximumWidth(9 * ww);
     909  _ssrQcIntrComboBox->setMaximumWidth(9 * ww);
    896910
    897911  cLayout->addWidget(new QLabel("Saving Broadcast Ephemeris correction files and correction output through IP port.<br>"), 0, 0, 1, 70);
    … …  
    902916  cLayout->addWidget(new QLabel("Port"), 3, 0);
    903917  cLayout->addWidget(_corrPortLineEdit, 3, 1);
    904   cLayout->addWidget(new QLabel(""), 4, 1);
     918  cLayout->addWidget(new QLabel("QC Logfile"), 4, 0);
     919  cLayout->addWidget(_ssrQcFileLineEdit, 4, 1, 1, 30);
     920  cLayout->addWidget(new QLabel("QC Interval"), 5, 0);
     921  cLayout->addWidget(_ssrQcIntrComboBox, 5, 1);
     922  cLayout->addWidget(new QLabel(""), 6, 1);
    905923  cLayout->setRowStretch(7, 999);
    906924  cgroup->setLayout(cLayout);
    … …  
    15701588  _corrPathLineEdit->setWhatsThis(tr("<p>Specify a directory for saving Broadcast Ephemeris Correction files.</p><p>If the specified directory does not exist, BNC will not create the files. <i>[key: corrPath]</i></p>"));
    15711589  _corrIntrComboBox->setWhatsThis(tr("<p>Select the length of Broadcast Ephemeris Correction files. <i>[key: corrIntr]</i></p>"));
     1590  _ssrQcFileLineEdit->setWhatsThis(tr("<p>Specify the full path to a logfile for the quality control of all decoded Broadcast Correction streams: epochs, update intervals, gaps, latency, completeness, IODs, code biases of the reference signals, clock jumps and orbit correction size.</p><p>Default is an empty option field, meaning that no SSR QC is done. <i>[key: ssrQcFile]</i></p>"));
     1591  _ssrQcIntrComboBox->setWhatsThis(tr("<p>Select the interval of the SSR QC reports. <i>[key: ssrQcIntr]</i></p>"));
    15721592  _corrPortLineEdit->setWhatsThis(tr("<p>BNC can produce Broadcast Ephemeris Corrections on your local host through an IP port.</p><p>Specify a port number here to activate this function. <i>[key: corrPort]</i></p>"));
    15731593
    … …  
    18431863  delete _corrPathLineEdit;
    18441864  delete _corrIntrComboBox;
     1865  delete _ssrQcFileLineEdit;
     1866  delete _ssrQcIntrComboBox;
    18451867  delete _corrPortLineEdit;
    18461868  delete _outPortLineEdit;
    … …  
    23692391  settings.setValue("corrPath", _corrPathLineEdit->text());
    23702392  settings.setValue("corrIntr", _corrIntrComboBox->currentText());
     2393  settings.setValue("ssrQcFile", _ssrQcFileLineEdit->text());
     2394  settings.setValue("ssrQcIntr", _ssrQcIntrComboBox->currentText());
    23712395  settings.setValue("corrPort", _corrPortLineEdit->text());
    23722396  // Feed Engine
    … …  
    25382562  BNC_CORE->setPortCorr(_corrPortLineEdit->text().toInt());
    25392563  BNC_CORE->initCombination();
     2564  BNC_CORE->initSsrQc();
    25402565
    25412566  connect(_caster, SIGNAL(getThreadsFinished()), this, SLOT(slotGetThreadsFinished()));
    … …  
    26072632    BNC_CORE->stopPPP();
    26082633    BNC_CORE->stopCombination();
     2634    BNC_CORE->stopSsrQc();
    26092635    delete _caster;    _caster = 0; BNC_CORE->setCaster(0);
    26102636    delete _casterEph; _casterEph = 0;
    … …  
    29002926    enable = !_corrPathLineEdit->text().isEmpty() || !_corrPortLineEdit->text().isEmpty();
    29012927    enableWidget(enable, _corrIntrComboBox);
     2928  }
     2929  if (sender() == 0 || sender() == _ssrQcFileLineEdit) {
     2930    enableWidget(!_ssrQcFileLineEdit->text().isEmpty(), _ssrQcIntrComboBox);
    29022931  }
    29032932
  • trunk/BNC/src/bncwindow.h

    r11022 r11066  
    151151    QLineEdit* _ephPathLineEdit;
    152152    QLineEdit* _corrPathLineEdit;
     153    QLineEdit* _ssrQcFileLineEdit;
    153154    QLineEdit* _miscMountLineEdit;
    154155    QLineEdit* _miscPortLineEdit;
    … …  
    182183    QComboBox* _ephIntrComboBox;
    183184    QComboBox* _corrIntrComboBox;
     185    QComboBox* _ssrQcIntrComboBox;
    184186    QComboBox* _rnxSamplComboBox;
    185187    QComboBox* _rnxSkelExtComboBox;
Note: See TracChangeset for help on using the changeset viewer.