Changeset 10938 in ntrip for trunk/BNC


Ignore:
Timestamp:
Jun 18, 2026, 4:02:38 PM (3 days ago)
Author:
stuerze
Message:

bugfix regarding ionospheric constraints

Location:
trunk/BNC/src
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/BNC/src/PPP/pppClient.cpp

    r10805 r10938  
    230230
    231231  if (_opt->_pseudoObsIono) {
    232     vector<t_pppSatObs*>::iterator it = obsVector.begin();
    233     while (it != obsVector.end()) {
    234       t_pppSatObs* satObs = *it;
    235       pseudoObsIono = satObs->setPseudoObsIono(t_frequency::G1);
    236       it++;
     232
     233    // Select reference satellite per system: keep the current one if still
     234    // visible; only switch to highest elevation when the current one disappears
     235    // -------------------------------------------------------------------------
     236    map<char, t_pppSatObs*> refSatMap;
     237    map<char, t_pppSatObs*> bestEleMap;
     238    for (t_pppSatObs* satObs : obsVector) {
     239      satObs->resetReference();
     240      double stec = satObs->getIonoCodeDelay(t_frequency::G1);
     241      if (stec == 0.0) continue;
     242      char sys = satObs->prn().system();
     243      if (!bestEleMap.count(sys) || satObs->eleSat() > bestEleMap[sys]->eleSat()) {
     244        bestEleMap[sys] = satObs;
     245      }
     246      if (_refPrnMap.count(sys) && satObs->prn() == _refPrnMap[sys]) {
     247        refSatMap[sys] = satObs;
     248      }
     249    }
     250    for (auto& kv : bestEleMap) {
     251      if (!refSatMap.count(kv.first)) {
     252        refSatMap[kv.first] = kv.second;
     253      }
     254    }
     255    for (auto& kv : refSatMap) {
     256      _refPrnMap[kv.first] = kv.second->prn();
     257      kv.second->setAsReference();
     258    }
     259
     260    if (bestEleMap.empty()) {
     261      LOG << "GIM pseudo-obs unavailable: no valid STEC (vTec data missing?)" << endl;
     262    }
     263
     264    // Set STEC pseudo-observations (single-differenced vs reference satellite)
     265    // -------------------------------------------------------------------------
     266    int nGIM = 0;
     267    for (t_pppSatObs* satObs : obsVector) {
     268      char sys = satObs->prn().system();
     269      double stecRefSat = refSatMap.count(sys)
     270                          ? refSatMap[sys]->getIonoCodeDelay(t_frequency::G1)
     271                          : 0.0;
     272      if (satObs->setPseudoObsIono(t_frequency::G1, stecRefSat)) {
     273        pseudoObsIono = true;
     274        nGIM++;
     275      }
     276    }
     277    if (nGIM > 0) {
     278      LOG << "GIM pseudo-obs: " << nGIM << " satellites, ref:";
     279      for (auto& kv : refSatMap) {
     280        LOG << ' ' << kv.second->prn().toString();
     281      }
     282      LOG << endl;
    237283    }
    238284  }
     
    598644
    599645  LOG << "pppClient: reset" << endl;
     646  _refPrnMap.clear();
    600647  // to delete old orbit and clock corrections
    601648  delete _ephPool;
  • trunk/BNC/src/PPP/pppClient.h

    r10805 r10938  
    22#define PPPCLIENT_H
    33
     4#include <map>
    45#include <sstream>
    56#include <vector>
     
    7677  bool                      _pseudoObsIono;
    7778  bool                      _running;
     79  std::map<char, t_prn>     _refPrnMap;
    7880};
    7981
  • trunk/BNC/src/PPP/pppFilter.cpp

    r10805 r10938  
    229229            const t_lc LC = LCs[jj];
    230230            if (LC._type == t_lc::GIM) {
     231              if (!obs->isValid(LC)) continue;
    231232              ++iObs;
    232233            } else {
     
    264265    for (unsigned ii = 0; ii < usedObs.size(); ii++) {
    265266      const t_lc LC = usedTypes[ii];
     267      if (LC._type == t_lc::GIM) continue;   // GIM is a soft constraint; never reject as outlier
    266268      double res = fabs(vv[ii]);
    267269      if (res > usedObs[ii]->maxRes(LC)) {
  • trunk/BNC/src/PPP/pppParlist.cpp

    r10791 r10938  
    112112  }
    113113
    114   // Special Case - GIM
    115   // ------------------
     114  // Special Case - GIM (single-differenced: A[ION_ref]=+1, A[ION_i]=-1)
     115  // -------------------------------------------------------------------
    116116  if (obsLC._type == t_lc::GIM) {
    117117    if (_type == ion) {
    118       return 1.0;
    119     }
    120     else {
    121       return 0.0;
    122     }
     118      if (obs->prn() == _prn) {
     119        return -1.0;
     120      }
     121      if (_prn == _refPrn && _prn.system() == obs->prn().system()) {
     122        return  1.0;
     123      }
     124    }
     125    return 0.0;
    123126  }
    124127
     
    333336  }
    334337 
     338  // Reference satellite PRN per system (from satellite marked by preparePseudoObs)
     339  // -------------------------------------------------------------------------------
     340  if (OPT->_pseudoObsIono) {
     341    map<char, t_prn> refPrnMap;
     342    for (unsigned jj = 0; jj < obsVector.size(); jj++) {
     343      if (obsVector[jj]->isReference()) {
     344        refPrnMap[obsVector[jj]->prn().system()] = obsVector[jj]->prn();
     345      }
     346    }
     347    for (unsigned ii = 0; ii < required.size(); ii++) {
     348      if (required[ii]->type() == t_pppParam::ion) {
     349        char sys = required[ii]->prn().system();
     350        if (refPrnMap.count(sys)) {
     351          required[ii]->setRefPrn(refPrnMap[sys]);
     352        }
     353      }
     354    }
     355  }
     356
    335357  // Ambiguities
    336358  // -----------
  • trunk/BNC/src/PPP/pppParlist.h

    r10791 r10938  
    6464  }
    6565  void     setSystem(char sys) {_sys = sys;}
     66  t_prn    refPrn() const {return _refPrn;}
     67  void     setRefPrn(const t_prn& prn) {_refPrn = prn;}
    6668
    6769  static bool sortFunction(const t_pppParam* p1, const t_pppParam* p2) {
     
    9395  e_type       _type;
    9496  t_prn        _prn;
     97  t_prn        _refPrn;
    9598  char         _sys;
    9699  t_lc         _LC;
  • trunk/BNC/src/PPP/pppSatObs.cpp

    r10791 r10938  
    4545  _reference  = false;
    4646  _stecSat    = 0.0;
     47  _stecRefSat = 0.0;
    4748  for (unsigned ii = 0; ii < t_frequency::max; ii++) {
    4849    _obs[ii] = 0;
     
    265266  if (valid) *valid = true;
    266267
    267   // Pseudo observations
     268  // Pseudo observations (single-differenced: reference minus satellite)
    268269  if (LC._type == t_lc::GIM) {
    269     if (_stecSat == 0.0) {
     270    if (_stecSat == 0.0 || _stecRefSat == 0.0) {
    270271      if (valid) *valid = false;
    271272      return 0.0;
    272273    }
    273274    else {
    274       return _stecSat;
     275      return _stecRefSat - _stecSat;
    275276    }
    276277  }
     
    686687  }
    687688  else if (LC._type == t_lc::GIM) {
    688     cmpValue =  _stecSat;
     689    cmpValue = 0.0;
    689690  }
    690691  else {
     
    739740//
    740741////////////////////////////////////////////////////////////////////////////
    741 bool  t_pppSatObs::setPseudoObsIono(t_frequency::type freq) {
    742   bool pseudoObsIono = false;
     742bool  t_pppSatObs::setPseudoObsIono(t_frequency::type freq, double stecRefSat) {
    743743  _stecSat    = _model._ionoCodeDelay[freq];
    744   if (_stecSat) {
    745     pseudoObsIono = true;
    746   }
    747   return pseudoObsIono;
     744  _stecRefSat = stecRefSat;
     745  return (_stecSat != 0.0 && _stecRefSat != 0.0);
    748746}
    749747
  • trunk/BNC/src/PPP/pppSatObs.h

    r10791 r10938  
    4848    void                setRes(t_lc LC, double res);
    4949    double              getRes(t_lc LC) const;
    50     bool                setPseudoObsIono(t_frequency::type freq);
     50    bool                setPseudoObsIono(t_frequency::type freq, double stecRefSat);
     51    void                resetGIM() {_stecSat = 0.0;}
    5152    double              getIonoCodeDelay(t_frequency::type freq) {return _model._ionoCodeDelay[freq];}
    5253    double              getCodeBias(t_frequency::type freq) {return _model._codeBias[freq];}
     
    153154    double                 _signalPropagationTime;
    154155    double                 _stecSat;
     156    double                 _stecRefSat;
    155157    double                 _tropo0;
    156158  };
  • trunk/BNC/src/pppInclude.h

    r10805 r10938  
    151151    }
    152152    else if (_type == GIM) {
    153       out << t_frequency::toSystem(_frq1) << "GIM" ;
     153      out << "GIM" ;
    154154    }
    155155    return out.str();
Note: See TracChangeset for help on using the changeset viewer.