Ignore:
Timestamp:
Oct 16, 2026, 10:19:51 AM (29 hours ago)
Author:
stuerze
Message:

Bias check is added in ssrQC, refernce signals are configurable now

File:
1 edited

Legend:

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

    r11023 r11087  
    4040
    4141#include "bncbiassnx.h"
     42#include "ssrRefSig.h"
    4243
    4344#include <iostream>
    … …  
    4849// Constructor
    4950////////////////////////////////////////////////////////////////////////////
    50 bncBiasSnx::bncBiasSnx() {
     51bncBiasSnx::bncBiasSnx(bool allGnss) {
    5152  bncSettings settings;
     53  if (allGnss) {
     54    for (char sys : QString("GRECJSI").toLatin1()) {
     55      _useGnss[sys] = true;
     56    }
     57    return;
     58  }
    5259  _useGnss['G'] = (Qt::CheckState(settings.value("cmbGps").toInt()) == Qt::Checked) ? true : false;
    5360  _useGnss['R'] = (Qt::CheckState(settings.value("cmbGlo").toInt()) == Qt::Checked) ? true : false;
    … …  
    307314}
    308315
    309 //
     316// DCBs (OSB_A - OSB_B) used to derive the code biases from the default
     317// reference signals (see t_ssrRefSig), in the order of evaluation
     318////////////////////////////////////////////////////////////////////////////
     319static const QVector<QPair<QString, QString> >& defaultDcbs(char sys) {
     320  static QMap<char, QVector<QPair<QString, QString> > > dcbs;
     321  static QMutex mutex;
     322  QMutexLocker locker(&mutex);
     323  if (dcbs.isEmpty()) {
     324    auto add = [](QVector<QPair<QString, QString> >& vv, const char* list) {
     325      for (const QString& dcb : QString(list).split(' ', Qt::SkipEmptyParts)) {
     326        vv.append(qMakePair(dcb.section('-', 0, 0), dcb.section('-', 1, 1)));
     327      }
     328    };
     329    add(dcbs['G'], "1C-1W 1C-5Q 1C-5X 1C-2W 2C-2W 2W-2S 2W-2L 2W-2X");
     330    add(dcbs['R'], "1C-1P 2C-2P");
     331    add(dcbs['E'], "1C-6C 1C-7Q 1C-8Q");
     332    add(dcbs['C'], "2I-7I 1X-6I 1X-7Z 1X-8X 1X-5X 1P-6I 1P-5P 1D-6I 1D-5D");
     333    add(dcbs['J'], "1C-1X 1X-2X 1C-5X");
     334  }
     335  static const QVector<QPair<QString, QString> > none;
     336  return dcbs.contains(sys) ? dcbs[sys] : none;
     337}
     338
     339// Satellite code biases (OSB) from the DCBs, referred to the reference
     340// signals of the clocks: aIF1 * OSB_ref1 + aIF2 * OSB_ref2 = 0
    310341////////////////////////////////////////////////////////////////////////////
    311342void bncBiasSnx::determineSsrSatCodeBiases(QString prn, double aIF1, double aIF2,
    312343                                           t_satCodeBias& satCodeBias) {
    313   std::string rnxType2ch;
    314   double value;
    315   if (_snxSatCodeBiasMap.contains(prn)) {
    316     char sys = prn.at(0).toLatin1();
    317     QMap<QString, double>& cb = _snxSatCodeBiasMap[prn]->_biasMap;
    318     switch (sys) {
    319       case 'G':
    320         if  (cb.contains("C1W-C2W")) {
    321           double dcb_1W2W = cb.find("C1W-C2W").value();
    322           rnxType2ch = "1W";
    323           value =  aIF2 * dcb_1W2W;
    324           setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    325           rnxType2ch = "2W";
    326           value = -aIF1 * dcb_1W2W;
    327           setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    328           if   (cb.contains("C1C-C1W")) {
    329             double dcb_1C1W = cb.find("C1C-C1W").value();
    330             rnxType2ch = "1C";
    331             value = dcb_1C1W + aIF2 * dcb_1W2W;
    332             setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    333             if  (cb.contains("C1C-C5Q")) {
    334               double dcb_1C5Q = cb.find("C1C-C5Q").value();
    335               rnxType2ch = "5Q";
    336               value = dcb_1C1W + aIF2 * dcb_1W2W - dcb_1C5Q;
    337               setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    338             }
    339             if  (cb.contains("C1C-C5X")) {
    340               double dcb_1C5X = cb.find("C1C-C5X").value();
    341               rnxType2ch = "5X";
    342               value = dcb_1C1W + aIF2 * dcb_1W2W - dcb_1C5X;
    343               setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    344             }
    345           }
    346           else {
    347             if  (cb.contains("C1C-C2W")) {
    348               double dcb_1C2W = cb.find("C1C-C2W").value();
    349               rnxType2ch = "1C";
    350               value = dcb_1C2W - aIF1 * dcb_1W2W;
    351               setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    352             }
    353           }
    354           if   (cb.contains("C2C-C2W")) {
    355             double dcb_2C2W = cb.find("C2C-C2W").value();
    356             rnxType2ch = "2C";
    357             value = dcb_2C2W - aIF1 * dcb_1W2W;
    358             setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    359           }
    360           if   (cb.contains("C2W-C2S")) {
    361             double dcb_2W2S = cb.find("C2W-C2S").value();
    362             rnxType2ch = "2S";
    363             value = -aIF1 * dcb_1W2W - dcb_2W2S;
    364             setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    365           }
    366           if   (cb.contains("C2W-C2L")) {
    367             double dcb_2W2L = cb.find("C2W-C2L").value();
    368             rnxType2ch = "2L";
    369             value = -aIF1 * dcb_1W2W - dcb_2W2L;
    370             setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    371           }
    372           if   (cb.contains("C2W-C2X")) {
    373             double dcb_2W2X = cb.find("C2W-C2X").value();
    374             rnxType2ch = "2X";
    375             value = -aIF1 * dcb_1W2W - dcb_2W2X;
    376             setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    377           }
    378         }
    379         break;
    380       case 'R':
    381         if  (cb.contains("C1P-C2P")) {
    382           double dcb_1P2P = cb.find("C1P-C2P").value();
    383           rnxType2ch = "1P";
    384           value =  aIF2 * dcb_1P2P;
    385           setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    386           rnxType2ch = "2P";
    387           value = -aIF1 * dcb_1P2P;
    388           setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    389           if   (cb.contains("C1C-C1P")) {
    390             double dcb_1C1P = cb.find("C1C-C1P").value();
    391             rnxType2ch = "1C";
    392             value = dcb_1C1P + aIF2 * dcb_1P2P;
    393             setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    394           }
    395           if   (cb.contains("C2C-C2P")) {
    396             double dcb_2C2P = cb.find("C2C-C2P").value();
    397             rnxType2ch = "2C";
    398             value = dcb_2C2P - aIF1 * dcb_1P2P;
    399             setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    400           }
    401         }
    402         break;
    403       case 'E':
    404         if  (cb.contains("C1C-C5Q")) {
    405           double dcb_1C5Q = cb.find("C1C-C5Q").value();
    406           rnxType2ch = "5Q";
    407           value = -aIF1 * dcb_1C5Q;
    408           setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    409           rnxType2ch = "1C";
    410           value =  aIF2 * dcb_1C5Q;
    411           setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    412           if  (cb.contains("C1C-C6C")) {
    413             double dcb_1C6C = cb.find("C1C-C6C").value();
    414             rnxType2ch = "6C";
    415             value = aIF2 * dcb_1C5Q - dcb_1C6C;
    416             setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    417           }
    418           if  (cb.contains("C1C-C7Q")) {
    419             double dcb_1C7Q = cb.find("C1C-C7Q").value();
    420             rnxType2ch = "7Q";
    421             value = aIF2 * dcb_1C5Q - dcb_1C7Q;
    422             setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    423           }
    424           if  (cb.contains("C1C-C8Q")) {
    425             double dcb_1C8Q = cb.find("C1C-C8Q").value();
    426             rnxType2ch = "8Q";
    427             value = aIF2 * dcb_1C5Q - dcb_1C8Q;
    428             setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    429           }
    430         }
    431         break;
    432       case 'C':
    433         if  (cb.contains("C2I-C6I")) {
    434           double dcb_2I6I = cb.find("C2I-C6I").value();
    435           rnxType2ch = "2I";
    436           value =  aIF2 * dcb_2I6I;
    437           setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    438           rnxType2ch = "6I";
    439           value = -aIF1 * dcb_2I6I;
    440           setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    441           if (cb.contains("C2I-C7I")) {
    442             double dcb_2I7I = cb.find("C2I-C7I").value();
    443             rnxType2ch = "7I";
    444             value = aIF2 * dcb_2I6I - dcb_2I7I;
    445             setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    446           }
    447           if (cb.contains("C1X-C6I")) {
    448             double dcb_1X6I = cb.find("C1X-C6I").value();
    449             rnxType2ch = "1X";
    450             value = dcb_1X6I - aIF1 * dcb_2I6I;
    451             setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    452             if (cb.contains("C1X-C7Z")) {
    453               double dcb_1X7Z = cb.find("C1X-C7Z").value();
    454               rnxType2ch = "7Z";
    455               value = dcb_1X6I - aIF1 * dcb_2I6I - dcb_1X7Z;
    456               setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    457             }
    458             if (cb.contains("C1X-C8X")) {
    459               double dcb_1X8X = cb.find("C1X-C8X").value();
    460               rnxType2ch = "8X";
    461               value = dcb_1X6I - aIF1 * dcb_2I6I - dcb_1X8X;
    462               setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    463             }
    464             if (cb.contains("C1X-C5X")) {
    465               double dcb_1X5X = cb.find("C1X-C5X").value();
    466               rnxType2ch = "5X";
    467               value = dcb_1X6I - aIF1 * dcb_2I6I - dcb_1X5X;
    468               setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    469             }
    470           }
    471           if (cb.contains("C1P-C6I")) {
    472             double dcb_1P6I = cb.find("C1P-C6I").value();
    473             rnxType2ch = "1P";
    474             value = dcb_1P6I - aIF1 * dcb_2I6I;
    475             setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    476             if (cb.contains("C1P-C5P")) {
    477               double dcb_1P5P = cb.find("C1P-C5P").value();
    478               rnxType2ch = "5P";
    479               value = dcb_1P6I - aIF1 * dcb_2I6I - dcb_1P5P;
    480               setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    481             }
    482           }
    483           if (cb.contains("C1D-C6I")) {
    484             double dcb_1D6I = cb.find("C1D-C6I").value();
    485             rnxType2ch = "1D";
    486             value = dcb_1D6I - aIF1 * dcb_2I6I;
    487             setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    488             if (cb.contains("C1D-C5D")) {
    489               double dcb_1D5D = cb.find("C1D-C5D").value();
    490               rnxType2ch = "5D";
    491               value = dcb_1D6I - aIF1 * dcb_2I6I - dcb_1D5D;
    492               setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    493             }
    494           }
    495         }
    496         break;
    497       case 'J':
    498         if (cb.contains("C1C-C2L")) {
    499           double dcb_1C2L = cb.find("C1C-C2L").value();
    500           rnxType2ch = "1C";
    501           value =  aIF2 * dcb_1C2L;
    502           setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    503           rnxType2ch = "2L";
    504           value = -aIF1 * dcb_1C2L;
    505           setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    506           if (cb.contains("C1C-C1X")) {
    507             double dcb_1C1X = cb.find("C1C-C1X").value();
    508             rnxType2ch = "1X";
    509             value =  aIF2 * dcb_1C2L - dcb_1C1X;
    510             setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    511             if (cb.contains("C1X-C2X")) {
    512               double dcb_1X2X = cb.find("C1X-C2X").value();
    513               rnxType2ch = "2X";
    514               value =  aIF2 * dcb_1C2L - dcb_1C1X - dcb_1X2X;
    515               setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    516             }
    517           }
    518           if (cb.contains("C1C-C5X")) {
    519             double dcb_1C5X = cb.find("C1C-C5X").value();
    520             rnxType2ch = "5X";
    521             value =  aIF2 * dcb_1C2L - dcb_1C5X;
    522             setSsrSatCodeBias(rnxType2ch, value, satCodeBias);
    523           }
    524         }
    525         break;
    526       default:
    527         break;
    528     }
    529   }
    530   return;
     344  if (!_snxSatCodeBiasMap.contains(prn)) {
     345    return;
     346  }
     347  char sys = prn.at(0).toLatin1();
     348  t_ssrRefSig::t_pair pair;
     349  if (!t_ssrRefSig::get(sys, pair)) {
     350    return;
     351  }
     352  const QString ref1 = QString::fromStdString(pair.sig1());
     353  const QString ref2 = QString::fromStdString(pair.sig2());
     354  const QMap<QString, double>& cb = _snxSatCodeBiasMap[prn]->_biasMap;
     355  auto dcb = [&cb](const QString& sig1, const QString& sig2, double& value) {
     356    QString key = "C" + sig1 + "-C" + sig2;
     357    if (cb.contains(key)) {
     358      value = cb[key];
     359      return true;
     360    }
     361    return false;
     362  };
     363
     364  QMap<QString, double> osb;
     365  QStringList           order;
     366
     367  // Default reference signals: the DCB of the reference signals and the
     368  // DCBs of the IGS conventions, evaluated in one pass as before
     369  if (t_ssrRefSig::isDefault(sys)) {
     370    const QVector<QPair<QString, QString> >& dcbs = defaultDcbs(sys);
     371    double dcbRef;
     372    if (dcbs.isEmpty() || !dcb(ref1, ref2, dcbRef)) {
     373      return;
     374    }
     375    osb[ref1] =  aIF2 * dcbRef;
     376    osb[ref2] = -aIF1 * dcbRef;
     377    if (sys == 'E') {   // order of the output as before
     378      order << ref2 << ref1;
     379    }
     380    else {
     381      order << ref1 << ref2;
     382    }
     383    for (const QPair<QString, QString>& dd : dcbs) {
     384      double value;
     385      if (!dcb(dd.first, dd.second, value)) {
     386        continue;
     387      }
     388      if (osb.contains(dd.first) && !osb.contains(dd.second)) {
     389        osb[dd.second] = osb[dd.first] - value;
     390        order << dd.second;
     391      }
     392      else if (osb.contains(dd.second) && !osb.contains(dd.first)) {
     393        osb[dd.first] = value + osb[dd.second];
     394        order << dd.first;
     395      }
     396    }
     397  }
     398
     399  // Other reference signals: all DCBs of the satellite, the DCB of the
     400  // reference signals may also be derived via other signals
     401  else {
     402    QMap<QString, double> rel;   // OSB - OSB_ref1
     403    QStringList           relOrder;
     404    rel[ref1] = 0.0;
     405    relOrder << ref1;
     406    bool changed = true;
     407    while (changed) {
     408      changed = false;
     409      QMapIterator<QString, double> it(cb);
     410      while (it.hasNext()) {
     411        it.next();
     412        QStringList hlp = it.key().split('-');
     413        if (hlp.size() != 2 || hlp[0].size() != 3 || hlp[1].size() != 3) {
     414          continue;
     415        }
     416        QString sigA = hlp[0].mid(1);
     417        QString sigB = hlp[1].mid(1);
     418        if (rel.contains(sigA) && !rel.contains(sigB)) {
     419          rel[sigB] = rel[sigA] - it.value();
     420          relOrder << sigB;
     421          changed = true;
     422        }
     423        else if (rel.contains(sigB) && !rel.contains(sigA)) {
     424          rel[sigA] = rel[sigB] + it.value();
     425          relOrder << sigA;
     426          changed = true;
     427        }
     428      }
     429    }
     430    if (!rel.contains(ref2)) {
     431      return;
     432    }
     433    double osbRef1 = -aIF2 * rel[ref2];
     434    order << ref1 << ref2;
     435    for (const QString& sig : relOrder) {
     436      osb[sig] = osbRef1 + rel[sig];
     437      if (sig != ref1 && sig != ref2) {
     438        order << sig;
     439      }
     440    }
     441  }
     442
     443  for (const QString& sig : order) {
     444    setSsrSatCodeBias(sig.toStdString(), osb[sig], satCodeBias);
     445  }
    531446}
    532447
Note: See TracChangeset for help on using the changeset viewer.