Changeset 11079 in ntrip for trunk/BNC/src/combination


Ignore:
Timestamp:
Oct 8, 2026, 11:47:35 AM (3 weeks ago)
Author:
stuerze
Message:

combi can be based on CoM

Location:
trunk/BNC/src/combination
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/BNC/src/combination/bnccomb.cpp

    r11067 r11079  
    296296  }
    297297
     298  // Reference point of the combination: with ACs of both kinds (APC streams
     299  // 'SSRA...', CoM streams 'SSRC...') and an ANTEX file, the combination is
     300  // done in the CoM frame and the orbits of the APC ACs are converted to
     301  // CoM; otherwise in the frame of the master AC (ACs of the other kind are
     302  // not used)
     303  // ------------------------------------------------------------------------
     304  bool hasAPC = false, hasCoM = false;
     305  for (const cmbAC* AC : _ACs) {
     306    if (AC->isAPC) hasAPC = true; else hasCoM = true;
     307  }
     308  _cmbCoM = (_antex && hasAPC && hasCoM);
     309  if (_cmbCoM) {
     310    for (QMap<char, bool>::iterator it = _masterIsAPC.begin(); it != _masterIsAPC.end(); ++it) {
     311      it.value() = false;
     312    }
     313    emit newMessage("bncComb: APC and CoM streams configured - combination in the CoM frame, "
     314                    "orbits of the APC streams converted to CoM", true);
     315  }
     316  else if (hasAPC && hasCoM) {
     317    emit newMessage("bncComb: APC and CoM streams configured, but no ANTEX file - only the streams "
     318                    "with the reference point of the master AC are combined", true);
     319  }
     320  if (!_antex && hasCoM) {
     321    emit newMessage("bncComb: CoM streams configured, but no ANTEX file - the combined orbits (INTERNAL) "
     322                    "may refer to the CoM, while the PPP assumes the APC", true);
     323  }
     324
    298325
    299326  // Bias SINEX File
    … …  
    610637      }
    611638    }
    612     if (acName.isEmpty() ||
    613         isAPC != _masterIsAPC[sys] ||
    614         excludeSat(newClk._prn, excludeSats)) {
     639    if (acName.isEmpty() || excludeSat(newClk._prn, excludeSats)) {
     640      continue;
     641    }
     642    if (!_cmbCoM && isAPC != _masterIsAPC[sys]) {
     643      bncTime& warned = _refPointWarned[acName + sys];
     644      if (!warned.valid() || newClk._time - warned >= 3600.0) {
     645        warned = newClk._time;
     646        emit newMessage("bncComb: " + acName.toLatin1() + " " + QByteArray(1, sys) + " not combined: its orbits refer to the " +
     647                        (isAPC ? "APC" : "CoM") + ", those of the master AC " + _masterOrbitAC[sys].toLatin1() +
     648                        " to the " + (isAPC ? "CoM" : "APC") +
     649                        " (an ANTEX file allows to combine both in the CoM frame)", true);
     650      }
    615651      continue;
    616652    }
    … …  
    949985    }
    950986
     987    // Orbits of an APC AC in a combination in the CoM frame
     988    // ------------------------------------------------------
     989    if (_cmbCoM) {
     990      const cmbAC* AC = 0;
     991      for (const cmbAC* ac : _ACs) {
     992        if (ac->name == acName) {
     993          AC = ac;
     994          break;
     995        }
     996      }
     997      if (AC && AC->isAPC && convertApcToCoM(_newCorr, AC) != success) {
     998        delete _newCorr; _newCorr = 0;
     999        continue;
     1000      }
     1001    }
     1002
    9511003    // Store correction into the buffer
    9521004    // --------------------------------
    … …  
    10471099              << AC->name.toLatin1().data()   << "\n";
    10481100          _masterOrbitAC[sys] = AC->name;
    1049           _masterIsAPC[sys]   = AC->isAPC;
     1101          _masterIsAPC[sys]   = _cmbCoM ? false : AC->isAPC;
    10501102          break;
    10511103        }
    … …  
    13201372}
    13211373
     1374// Convert the orbit correction of an APC AC to the satellite's CoM: the
     1375// antenna offset (ANTEX, single reference frequency, attitude as configured
     1376// for the AC) is added to the correction in radial, along-track and
     1377// cross-track direction. The clock correction is not affected.
     1378////////////////////////////////////////////////////////////////////////////
     1379t_irc bncComb::convertApcToCoM(cmbCorr* corr, const cmbAC* AC) {
     1380  corr->_eph->setOrbCorr(&corr->_orbCorr);
     1381  corr->_eph->setClkCorr(&corr->_clkCorr);
     1382  ColumnVector xc(6), vv(3);
     1383  if (corr->_eph->getCrd(corr->_time, xc, vv, true) != success) {
     1384    return failure;
     1385  }
     1386  bncAntex::e_attMode attMode = bncAntex::ATT_COMPUTED;
     1387  double              extYaw  = 0.0;
     1388  if (AC->attitudeSource == "SSR" && corr->_satYawAngleValid) {
     1389    attMode = bncAntex::ATT_EXTERNAL;
     1390    extYaw  = corr->_satYawAngle;
     1391  }
     1392  else if (AC->attitudeSource == "Nominal") {
     1393    attMode = bncAntex::ATT_NOMINAL;
     1394  }
     1395  double Mjd = corr->_time.mjd() + corr->_time.daysec() / 86400.0;
     1396  ColumnVector dx(3); dx = 0.0;
     1397  if (_antex->satCoMcorrection(corr->_prn, Mjd, xc.Rows(1,3), vv, dx, attMode, extYaw, AC->name) != success) {
     1398    if (_antex->warnNoSatEntry(corr->_prn, corr->_time)) {
     1399      emit newMessage("bncComb: no satellite antenna entry valid at " +
     1400                      QByteArray(corr->_time.datestr().c_str()) + " " + QByteArray(corr->_time.timestr().c_str()) +
     1401                      " for " + corr->_prn.mid(0,3).toLatin1() +
     1402                      " in ANTEX file - APC orbit of " + AC->name.toLatin1() + " not converted to CoM, not combined", true);
     1403    }
     1404    return failure;
     1405  }
     1406  // X = X_brdc - RSW(xr): X_CoM = X_APC - dx  =>  xr_CoM = xr_APC + RSW(dx)
     1407  ColumnVector dRAO(3);
     1408  XYZ_to_RSW(xc.Rows(1,3), vv, dx, dRAO);
     1409  corr->_orbCorr._xr += dRAO;
     1410  return success;
     1411}
     1412
    13221413// Report AC satellites rejected as outliers in most epochs
    13231414////////////////////////////////////////////////////////////////////////////
    … …  
    15441635      apc(2) = xc(2)+dx(2);
    15451636      apc(3) = xc(3)+dx(3);
     1637    }
     1638
     1639    // The combined corrections passed on to the PPP (INTERNAL) always refer
     1640    // to the APC: orbits combined in the CoM frame are converted
     1641    if (!masterIsAPC && _antex) {
     1642      ColumnVector dRAO(3);
     1643      XYZ_to_RSW(xc.Rows(1,3), vv, dx, dRAO);
     1644      orbCorrections.back()._xr -= dRAO;
    15461645    }
    15471646
  • trunk/BNC/src/combination/bnccomb.h

    r11075 r11079  
    280280  void checkBiasConsistency(bncTime epoTime, char sys, QTextStream& out);
    281281  void checkPersistentOutliers(bncTime epoTime, char sys, QTextStream& out);
     282  t_irc convertApcToCoM(cmbCorr* corr, const cmbAC* AC);
     283  bool                                       _cmbCoM;          // combination in the CoM frame, APC ACs converted
     284  QMap<QString, bncTime>                     _refPointWarned;  // last 'APC/CoM differs from master' warning per AC
    282285  struct t_outlierStat {
    283286    t_outlierStat() : numEpo(0) {}
Note: See TracChangeset for help on using the changeset viewer.