Changeset 11205 in ntrip


Ignore:
Timestamp:
Nov 13, 2026, 6:46:33 PM (less than one hour ago)
Author:
stuerze
Message:

kalman filter combination improved

Location:
trunk/BNC
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/BNC/CHANGELOG.md

    r11204 r11205  
    6262- FIXED: GLONASS ephemerides read from RINEX files left members not contained in RINEX (e.g. ln of string 5) uninitialized
    6363- FIXED: SP3, clock RINEX and Bias-SINEX files of the combination/upload: the last epoch, the SP3 'EOF' and the Bias-SINEX closing lines were missing at the end of BNC (files only closed after the end of the event loop); a run starting at 00:00 gave a SP3 header with leading blanks and the start time of the second epoch; the epoch at the start of a new file (e.g. 00:00:00) is the last epoch of the file before, too, also with sampling interval 0 (before only with uploadSamplClkRnx/uploadSamplSp3 > 0)
     64- FIXED: Combination (Kalman filter): the clock of a satellite not provided by all ACs depended on the history of the filter, as the AC offsets could be shifted against the satellite offsets; after a restart e.g. G13 (SVN83, provided by 4 of 6 ACs) was 1.4 m off in SSRA02IGS0. Additional condition: the satellite offsets of each AC sum up to zero
    6465- ADDED: Regression test suite ('tests'): example configurations and short raw captures replayed through BNC and compared with reference outputs
    6566- ADDED: macOS packaging script
  • trunk/BNC/src/bnchelp.html

    r11203 r11205  
    83238323    <tr>
    83248324      <td>&nbsp; AC_Offset </td>
    8325       <td>&nbsp; &nbsp; AC specific offset</td>
     8325      <td>&nbsp; &nbsp; AC specific offset per GNSS (clock datum of the AC)</td>
    83268326    </tr>
    83278327    <tr>
    83288328      <td>&nbsp; Sat_Offset</td>
    8329       <td>&nbsp; &nbsp; Satellite specific offset common to all ACs</td>
     8329      <td>&nbsp; &nbsp; Offset of the AC for a satellite (e.g. different realizations of the code biases)</td>
    83308330    </tr>
    83318331    <tr>
    … …  
    83358335  </table>
    83368336  </p>
    8337   These three parameter types differ in their statistical properties. The satellite clock offsets are assumed to be
    8338   static parameters
    8339   while AC specific and satellite specific offsets are stochastic parameters affected by white noise.
    8340   The solution is regularized by a set of minimal constraints. In case of a change of the 'SSR Provider ID',
     8337  These three parameter types differ in their statistical properties: the AC specific offsets and the combined clocks
     8338  are estimated anew every epoch (white noise), the satellite specific offsets are random walk parameters (1 cm per
     8339  10 seconds). The solution is regularized by minimal constraints: per epoch the combined clocks sum up to zero, the
     8340  satellite specific offsets of all ACs providing a satellite sum up to zero, and the satellite specific offsets of
     8341  each AC sum up to zero. The last condition makes the AC specific offset the mean clock difference of the AC; without
     8342  it, the combined clock of a satellite not provided by all ACs would depend on the history of the filter (e.g. after a
     8343  restart). In case of a change of the 'SSR Provider ID',
    83418344  'SSR Solution ID', or 'IOD SSR' (see section 'Upload Corrections'), the satellite clock offsets belonging to the
    83428345  corresponding analysis center are reset in the adjustment.
  • trunk/BNC/src/combination/bnccomb.cpp

    r11195 r11205  
    18701870  }
    18711871
    1872   const int nCon = (_method == filter) ? 1 + maxSat + excludedACs.size() : 0;
     1872  // ACs of this epoch, each with a zero-sum condition of its satellite offsets
     1873  QStringList epoACs;
     1874  for (int ii = 0; ii < corrs(sys).size(); ii++) {
     1875    if (!epoACs.contains(corrs(sys)[ii]->_acName)) {
     1876      epoACs << corrs(sys)[ii]->_acName;
     1877    }
     1878  }
     1879
     1880  const int nCon = (_method == filter) ? 1 + maxSat + epoACs.size() : 0;
    18731881
    18741882  AA.ReSize(nObs+nCon, nPar);  AA = 0.0;
    … …  
    19441952    int iCond = 1;
    19451953    QSet<int>     offExcluded; // offsets excluded from the zero-sum condition of their satellite
     1954    QSet<int>     offInDatum;  // offsets in the zero-sum condition of their satellite
    19461955    QSet<QString> acsInDatum;  // ACs with at least one offset in the zero-sum conditions
    19471956    // GNSS
    … …  
    19691978        if (offUsed.contains(iPar)) {
    19701979          AA(nObs+iCond, iPar) = 1.0;
     1980          offInDatum << iPar;
    19711981          acsInDatum.insert(_params[sys][iPar-1]->AC);
    19721982        }
    … …  
    19761986      }
    19771987    }
    1978     // ACs with all their offsets excluded from the zero-sum conditions above:
    1979     // the sum of their offsets is constrained to zero (otherwise not
    1980     // separable from the AC's epoch offset)
    1981     for (const QString& acName : excludedACs) {
     1988    // Zero-sum condition of the satellite offsets of each AC: without it, the
     1989    // AC epoch offsets can be shifted by a_i, compensated by the satellite
     1990    // offsets and, for a satellite not provided by all ACs, by its combined
     1991    // clock (shift: mean of a_i over the ACs providing it). This would leave
     1992    // the clocks of such satellites to the history of the filter (e.g. G13
     1993    // +1.4 m after a restart). With it, the AC epoch offset is the mean clock
     1994    // difference of the AC. Sum over the offsets in the satellite conditions
     1995    // above; for an AC with all its offsets excluded from them, over these
     1996    // (otherwise not separable from the AC's epoch offset).
     1997    for (const QString& acName : epoACs) {
    19821998      ++iCond;
    1983       if (acsInDatum.contains(acName)) {
    1984         continue;
    1985       }
    19861999      PP(nObs+iCond) = Ph;
    1987       for (int iPar : offExcluded) {
     2000      const QSet<int>& offAC = acsInDatum.contains(acName) ? offInDatum : offExcluded;
     2001      for (int iPar : offAC) {
    19882002        if (_params[sys][iPar-1]->AC == acName) {
    19892003          AA(nObs+iCond, iPar) = 1.0;
Note: See TracChangeset for help on using the changeset viewer.