Ignore:
Timestamp:
Oct 21, 2026, 2:10:49 AM (18 hours ago)
Author:
stuerze
Message:

attitude consideration on orbit comparison reactivated and improved

File:
1 edited

Legend:

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

    r11099 r11105  
    464464    }
    465465
    466     // Store the correction
     466    // Store the correction; the latest orbit of the previous IOD is kept as
     467    // well: the clocks of an epoch may be processed only after the orbits of
     468    // the next epoch have arrived, which already refer to a new IOD
    467469    // --------------------
    468470    QMap<t_prn, t_orbCorr>& storage = _orbCorrections[acName];
     471    if (storage.contains(orbCorr._prn) && storage[orbCorr._prn]._iod != orbCorr._iod) {
     472      _orbCorrectionsPrev[acName][orbCorr._prn] = storage[orbCorr._prn];
     473    }
    469474    storage[orbCorr._prn] = orbCorr;
    470475  }
    … …  
    823828    else {
    824829      QMap<t_prn, t_orbCorr>& storage = _orbCorrections[acName];
    825       if (!storage.contains(clkCorr._prn)  ||
    826            storage[clkCorr._prn]._iod != _newCorr->_iod) {
     830      QMap<t_prn, t_orbCorr>& prev    = _orbCorrectionsPrev[acName];
     831      if (storage.contains(clkCorr._prn) && storage[clkCorr._prn]._iod == _newCorr->_iod) {
     832        _newCorr->_orbCorr = storage[clkCorr._prn];
     833      }
     834      else if (prev.contains(clkCorr._prn) && prev[clkCorr._prn]._iod == _newCorr->_iod) {
     835        _newCorr->_orbCorr = prev[clkCorr._prn];
     836      }
     837      else {
    827838        delete _newCorr; _newCorr = 0;
    828839        continue;
    829       }
    830       else {
    831         _newCorr->_orbCorr = storage[clkCorr._prn];
    832840      }
    833841    }
    … …  
    955963        _newCorr->_satYawAngle      = pb._yaw + pb._yawRate * dt;
    956964        _newCorr->_satYawAngleValid = true;
    957 
    958         // _lambdaIF
    959         map<t_frequency::type, double> codeCoeff;
    960         double channel = double(_newCorr->_eph->slotNum());
    961         cmbRefSig::coeff(sys, cmbRefSig::cIF, channel, codeCoeff);
    962         map<t_frequency::type, double>::const_iterator it;
    963         for (it = codeCoeff.begin(); it != codeCoeff.end(); it++) {
    964           t_frequency::type frqType = it->first;
    965           double codeCoeff = it->second;
    966           _newCorr->_lambdaIF += codeCoeff * t_CST::c / t_CST::freq(frqType, channel);
    967         }
     965      }
     966    }
     967
     968    // _lambdaIF: ionosphere-free combination of the reference signals'
     969    // wavelengths (narrow-lane wavelength), scales the phase wind-up
     970    // -------------------------------------------------------------------
     971    {
     972      map<t_frequency::type, double> codeCoeff;
     973      double channel = double(_newCorr->_eph->slotNum());
     974      cmbRefSig::coeff(sys, cmbRefSig::cIF, channel, codeCoeff);
     975      map<t_frequency::type, double>::const_iterator it;
     976      for (it = codeCoeff.begin(); it != codeCoeff.end(); it++) {
     977        t_frequency::type frqType = it->first;
     978        double codeCoeff = it->second;
     979        _newCorr->_lambdaIF += codeCoeff * t_CST::c / t_CST::freq(frqType, channel);
    968980      }
    969981    }
    … …  
    982994        delete _newCorr; _newCorr = 0;
    983995        continue;
     996      }
     997    }
     998
     999    // Yaw angle of the AC's attitude, for the attitude consistency correction
     1000    // -----------------------------------------------------------------------
     1001    if (_antex && !_newCorr->_attYawValid) {
     1002      for (const cmbAC* ac : _ACs) {
     1003        if (ac->name == acName) {
     1004          attitudeYaw(_newCorr, ac);
     1005          break;
     1006        }
    9841007      }
    9851008    }
    … …  
    14321455  double Mjd = corr->_time.mjd() + corr->_time.daysec() / 86400.0;
    14331456  ColumnVector dx(3); dx = 0.0;
    1434   if (_antex->satCoMcorrection(corr->_prn, Mjd, xc.Rows(1,3), vv, dx, attMode, extYaw, AC->name) != success) {
     1457  if (_antex->satCoMcorrection(corr->_prn, Mjd, xc.Rows(1,3), vv, dx, attMode, extYaw, AC->name,
     1458                               &corr->_attYaw) != success) {
    14351459    if (_antex->warnNoSatEntry(corr->_prn, corr->_time)) {
    14361460      emit newMessage("bncComb: no satellite antenna entry valid at " +
    … …  
    14411465    return failure;
    14421466  }
     1467  corr->_attYawValid = true;
    14431468  // X = X_brdc - RSW(xr): X_CoM = X_APC - dx  =>  xr_CoM = xr_APC + RSW(dx)
    14441469  ColumnVector dRAO(3);
    … …  
    14461471  corr->_orbCorr._xr += dRAO;
    14471472  return success;
     1473}
     1474
     1475// Yaw angle of the attitude an AC uses (SSR yaw or attitude model)
     1476////////////////////////////////////////////////////////////////////////////
     1477// Only needed if the orbit is not converted from APC to CoM, which already
     1478// provides the yaw angle. Separate model state per AC (key AC + ":att").
     1479////////////////////////////////////////////////////////////////////////////
     1480void bncComb::attitudeYaw(cmbCorr* corr, const cmbAC* AC) {
     1481  if (AC->attitudeSource == "SSR" && corr->_satYawAngleValid) {
     1482    corr->_attYaw      = corr->_satYawAngle;
     1483    corr->_attYawValid = true;
     1484    return;
     1485  }
     1486  corr->_eph->setOrbCorr(&corr->_orbCorr);
     1487  corr->_eph->setClkCorr(&corr->_clkCorr);
     1488  ColumnVector xc(6), vv(3);
     1489  if (corr->_eph->getCrd(corr->_time, xc, vv, true) != success) {
     1490    return;
     1491  }
     1492  bncAntex::e_attMode attMode = (AC->attitudeSource == "Nominal") ? bncAntex::ATT_NOMINAL
     1493                                                                  : bncAntex::ATT_COMPUTED;
     1494  double Mjd = corr->_time.mjd() + corr->_time.daysec() / 86400.0;
     1495  ColumnVector dx(3); dx = 0.0;
     1496  if (_antex->satCoMcorrection(corr->_prn, Mjd, xc.Rows(1,3), vv, dx, attMode, 0.0,
     1497                               AC->name + ":att", &corr->_attYaw) == success) {
     1498    corr->_attYawValid = true;
     1499  }
    14481500}
    14491501
    … …  
    18281880    double dC_orb = DotProduct((corr->_satPos - masterCorr[prn]->_satPos), corr->_satPos);
    18291881    dC_orb /= masterCorr[prn]->_satPos.NormFrobenius();
    1830     double dC_att = (corr->_satYawAngle - masterCorr[prn]->_satYawAngle) / (2 * M_PI);
    1831     dC_att *= corr->_lambdaIF;
    1832     double dC_apriori_corr = dC_orb;// + dC_att; can be added if useful values are provided by the ACs
     1882    // Attitude: a yaw difference dpsi changes the phase wind-up of the
     1883    // ionosphere-free combination by lambda_IF * dpsi / 2pi, which is
     1884    // absorbed by the AC's clock (zero if both use the same attitude model)
     1885    double dC_att = 0.0;
     1886    if (corr->_attYawValid && masterCorr[prn]->_attYawValid) {
     1887      double dPsi = remainder(corr->_attYaw - masterCorr[prn]->_attYaw, 2.0 * M_PI);
     1888      dC_att = corr->_lambdaIF * dPsi / (2.0 * M_PI);
     1889    }
     1890    double dC_apriori_corr = dC_orb + dC_att;
    18331891
    18341892    // Clock referred to the ionosphere-free combination of the reference
Note: See TracChangeset for help on using the changeset viewer.