| 1 | #include <set>
|
|---|
| 2 | #include <algorithm>
|
|---|
| 3 | #include <math.h>
|
|---|
| 4 | #include <newmatio.h>
|
|---|
| 5 |
|
|---|
| 6 | #include "ambres.h"
|
|---|
| 7 | #include "bncutils.h"
|
|---|
| 8 | #include "lambda.h"
|
|---|
| 9 | #include "pppClient.h"
|
|---|
| 10 |
|
|---|
| 11 | using namespace std;
|
|---|
| 12 | using namespace BNC_PPP;
|
|---|
| 13 |
|
|---|
| 14 | //
|
|---|
| 15 | //////////////////////////////////////////////////////////////////////////////////////////
|
|---|
| 16 | AmbRes::AmbRes() {
|
|---|
| 17 | reset();
|
|---|
| 18 | }
|
|---|
| 19 |
|
|---|
| 20 | //
|
|---|
| 21 | //////////////////////////////////////////////////////////////////////////////////////////
|
|---|
| 22 | AmbRes::~AmbRes() {
|
|---|
| 23 | }
|
|---|
| 24 |
|
|---|
| 25 | //
|
|---|
| 26 | //////////////////////////////////////////////////////////////////////////////////////////
|
|---|
| 27 | bool AmbRes::isResolvable(const t_pppParam* amb) {
|
|---|
| 28 | if ( amb->ambNumEpo() >= OPT->_ar._minNumEpo && amb->ambEleSat() >= OPT->_ar._minEle) {
|
|---|
| 29 | return true;
|
|---|
| 30 | }
|
|---|
| 31 | else {
|
|---|
| 32 | return false;
|
|---|
| 33 | }
|
|---|
| 34 | }
|
|---|
| 35 |
|
|---|
| 36 | //
|
|---|
| 37 | //////////////////////////////////////////////////////////////////////////////////////////
|
|---|
| 38 | bool AmbRes::isFixable(double xx, double sigma, bool* checked) {
|
|---|
| 39 | if (OPT->_ar._maxFrac <= 0.0 || OPT->_ar._maxSig <= 0.0) {
|
|---|
| 40 | if (checked) {
|
|---|
| 41 | *checked = false;
|
|---|
| 42 | }
|
|---|
| 43 | return true;
|
|---|
| 44 | }
|
|---|
| 45 | else {
|
|---|
| 46 | if (checked) {
|
|---|
| 47 | *checked = true;
|
|---|
| 48 | }
|
|---|
| 49 | return ( fabs(xx - nint(xx)) <= OPT->_ar._maxFrac && sigma <= OPT->_ar._maxSig );
|
|---|
| 50 | }
|
|---|
| 51 | }
|
|---|
| 52 |
|
|---|
| 53 | //
|
|---|
| 54 | //////////////////////////////////////////////////////////////////////////////////////////
|
|---|
| 55 | void AmbRes::addToGroup(const t_pppParam* amb) {
|
|---|
| 56 | t_lc LC = amb->LC();
|
|---|
| 57 | char sys = amb->prn().system();
|
|---|
| 58 | AmbGroup* p_ambGroup = 0;
|
|---|
| 59 | for (AmbGroup& ambGroup : _ambGroups) {
|
|---|
| 60 | if (ambGroup._system == sys && ambGroup._LC == LC) {
|
|---|
| 61 | p_ambGroup = &ambGroup;
|
|---|
| 62 | break;
|
|---|
| 63 | }
|
|---|
| 64 | }
|
|---|
| 65 | if (!p_ambGroup) {
|
|---|
| 66 | _ambGroups.emplace_back(AmbGroup(sys, LC));
|
|---|
| 67 | p_ambGroup = &_ambGroups.back();
|
|---|
| 68 | }
|
|---|
| 69 | p_ambGroup->_zdAmbs.push_back(ZdAmb(amb));
|
|---|
| 70 |
|
|---|
| 71 | _numZdAmbs += 1;
|
|---|
| 72 | }
|
|---|
| 73 |
|
|---|
| 74 | // Select Reference Ambiguity
|
|---|
| 75 | ////////////////////////////////////////////////////////////////////////////////////////////
|
|---|
| 76 | void AmbRes::selectReference(AmbGroup& ambGroup) {
|
|---|
| 77 |
|
|---|
| 78 | // Compute sum of variances of all double-difference ambiguities
|
|---|
| 79 | // -------------------------------------------------------------
|
|---|
| 80 | double minVarSum = 0.0;
|
|---|
| 81 | for (const ZdAmb& zdAmb1 : ambGroup._zdAmbs) {
|
|---|
| 82 | int i1 = zdAmb1.index();
|
|---|
| 83 | double varSum = 0.0;
|
|---|
| 84 | for (const ZdAmb& zdAmb2 : ambGroup._zdAmbs) {
|
|---|
| 85 | int i2 = zdAmb2.index();
|
|---|
| 86 | varSum += _QQ[i1][i1] - 2.0 * _QQ(i1+1,i2+1) + _QQ[i2][i2];
|
|---|
| 87 | }
|
|---|
| 88 | if (ambGroup._zdAmbRef == 0 || minVarSum > varSum) {
|
|---|
| 89 | ambGroup._zdAmbRef = &zdAmb1;
|
|---|
| 90 | minVarSum = varSum;
|
|---|
| 91 | }
|
|---|
| 92 | }
|
|---|
| 93 | }
|
|---|
| 94 |
|
|---|
| 95 | //
|
|---|
| 96 | //////////////////////////////////////////////////////////////////////////////////////////
|
|---|
| 97 | t_irc AmbRes::run(const bncTime& epoTime,
|
|---|
| 98 | const std::vector<t_pppParam*>& params,
|
|---|
| 99 | SymmetricMatrix& QFinal,
|
|---|
| 100 | ColumnVector& xFinal,
|
|---|
| 101 | double& fixRatio,
|
|---|
| 102 | std::ostream& msg) {
|
|---|
| 103 | reset();
|
|---|
| 104 | fixRatio = 0.0;
|
|---|
| 105 |
|
|---|
| 106 | msg << string(epoTime) << " Ambiguity Resolution (BIE)" << endl;
|
|---|
| 107 |
|
|---|
| 108 | // Resolvable ambiguities
|
|---|
| 109 | // ----------------------
|
|---|
| 110 | map<char, set<t_prn>> usedPrns;
|
|---|
| 111 | for (char system : OPT->_ar._systems) {
|
|---|
| 112 | for (const auto& par : params) {
|
|---|
| 113 | if (par->type() == t_pppParam::amb && par->prn().system() == system) {
|
|---|
| 114 | if (isResolvable(par)) {
|
|---|
| 115 | addToGroup(par);
|
|---|
| 116 | }
|
|---|
| 117 | }
|
|---|
| 118 | }
|
|---|
| 119 | }
|
|---|
| 120 |
|
|---|
| 121 | // Remove Groups with less than 2 ambiguities
|
|---|
| 122 | // ------------------------------------------
|
|---|
| 123 | auto iGrp = _ambGroups.begin();
|
|---|
| 124 | while (iGrp != _ambGroups.end()) {
|
|---|
| 125 | if (iGrp->_zdAmbs.size() < 2) {
|
|---|
| 126 | _numZdAmbs -= iGrp->_zdAmbs.size();
|
|---|
| 127 | iGrp = _ambGroups.erase(iGrp);
|
|---|
| 128 | }
|
|---|
| 129 | else {
|
|---|
| 130 | ++iGrp;
|
|---|
| 131 | }
|
|---|
| 132 | }
|
|---|
| 133 |
|
|---|
| 134 | // Check number of zero-difference ambiguities
|
|---|
| 135 | // -------------------------------------------
|
|---|
| 136 | bool hasEnoughAmbs = false;
|
|---|
| 137 | for (const auto& ambGroup : _ambGroups) {
|
|---|
| 138 | if (int(ambGroup._zdAmbs.size()) >= OPT->_ar._minNumSat) {
|
|---|
| 139 | hasEnoughAmbs = true;
|
|---|
| 140 | break;
|
|---|
| 141 | }
|
|---|
| 142 | }
|
|---|
| 143 | if (!hasEnoughAmbs) {
|
|---|
| 144 | msg << " not enough resolvable ambiguities" << endl;
|
|---|
| 145 | return t_irc::failure;
|
|---|
| 146 | }
|
|---|
| 147 |
|
|---|
| 148 | // Construct the variance-covariance matrix of ambiguities
|
|---|
| 149 | // -------------------------------------------------------
|
|---|
| 150 | Matrix ZD(_numZdAmbs, params.size()); ZD = 0.0;
|
|---|
| 151 | int idx = -1;
|
|---|
| 152 | for (auto& ambGroup : _ambGroups) {
|
|---|
| 153 | for (auto& zdAmb : ambGroup._zdAmbs) {
|
|---|
| 154 | idx += 1;
|
|---|
| 155 | zdAmb.setIndex(idx);
|
|---|
| 156 | ZD[idx][zdAmb.indexGlobal()] = 1.0;
|
|---|
| 157 | }
|
|---|
| 158 | }
|
|---|
| 159 | _xx = ZD * xFinal;
|
|---|
| 160 | _QQ << ZD * QFinal * ZD.t();
|
|---|
| 161 |
|
|---|
| 162 | // Select and Constrain Reference Ambiguities
|
|---|
| 163 | // ------------------------------------------
|
|---|
| 164 | Matrix HH(_ambGroups.size(), _numZdAmbs); HH = 0.0;
|
|---|
| 165 | ColumnVector hh(_ambGroups.size());
|
|---|
| 166 | for (unsigned iGrp = 0; iGrp < _ambGroups.size(); ++iGrp) {
|
|---|
| 167 | AmbGroup& ambGroup = _ambGroups[iGrp];
|
|---|
| 168 | selectReference(ambGroup);
|
|---|
| 169 | HH[iGrp][ambGroup._zdAmbRef->index()] = 1.0;
|
|---|
| 170 | hh[iGrp] = nint(_xx[ambGroup._zdAmbRef->index()]);
|
|---|
| 171 | }
|
|---|
| 172 | DiagonalMatrix PP(HH.nrows()); PP = 1.0 / (sigCon * sigCon);
|
|---|
| 173 | kalman(HH, hh, PP, _QQ, _xx);
|
|---|
| 174 |
|
|---|
| 175 | // Perform the Lambda (BIE) Search
|
|---|
| 176 | // -------------------------------
|
|---|
| 177 | ColumnVector xBie;
|
|---|
| 178 | SymmetricMatrix covBie;
|
|---|
| 179 | Lambda::search(_xx, _QQ, xBie, covBie);
|
|---|
| 180 | if (xBie.Nrows() == 0) {
|
|---|
| 181 | msg << " BIE search: failed" << endl;
|
|---|
| 182 | return t_irc::failure;
|
|---|
| 183 | }
|
|---|
| 184 |
|
|---|
| 185 | // Print BIE Results
|
|---|
| 186 | // -----------------
|
|---|
| 187 | printBieResults(xBie, covBie, msg);
|
|---|
| 188 |
|
|---|
| 189 | // Constrain ambiguities
|
|---|
| 190 | // ---------------------
|
|---|
| 191 | setConstraints(QFinal, xFinal, xBie, covBie, fixRatio, msg);
|
|---|
| 192 |
|
|---|
| 193 | return t_irc::success;
|
|---|
| 194 | }
|
|---|
| 195 |
|
|---|
| 196 | // Print single-difference ambiguities and AR results
|
|---|
| 197 | ////////////////////////////////////////////////////////////////////////////////////////////
|
|---|
| 198 | void AmbRes::printBieResults(const ColumnVector& xBie, const SymmetricMatrix& covBie,
|
|---|
| 199 | ostream& msg) const {
|
|---|
| 200 | msg.setf(ios::fixed);
|
|---|
| 201 | for (const AmbGroup& ambGroup : _ambGroups) {
|
|---|
| 202 | msg << " Group " << ambGroup._LC.toString() << endl;
|
|---|
| 203 |
|
|---|
| 204 | for (const ZdAmb& zdAmb: ambGroup._zdAmbs) {
|
|---|
| 205 | int idx = zdAmb.index();
|
|---|
| 206 | msg << " " << zdAmb.prn().toString() << ' ' << setw(7) << setprecision(2) << _xx[idx];
|
|---|
| 207 | if (&zdAmb == ambGroup._zdAmbRef) {
|
|---|
| 208 | msg << " ref";
|
|---|
| 209 | }
|
|---|
| 210 | else {
|
|---|
| 211 | msg << " +- ";
|
|---|
| 212 | }
|
|---|
| 213 | msg << setw(6) << setprecision(2) << sqrtMod(_QQ[idx][idx]) << ' '
|
|---|
| 214 | << setw(7) << setprecision(2) << xBie[idx] << ' '
|
|---|
| 215 | << setw(9) << setprecision(6) << sqrtMod(covBie[idx][idx]);
|
|---|
| 216 | if (isFixable(xBie[idx], sqrtMod(covBie[idx][idx]))) {
|
|---|
| 217 | msg << " fix ";
|
|---|
| 218 | }
|
|---|
| 219 | msg << endl;
|
|---|
| 220 | }
|
|---|
| 221 | }
|
|---|
| 222 | }
|
|---|
| 223 |
|
|---|
| 224 | //
|
|---|
| 225 | ////////////////////////////////////////////////////////////////////////////////////////////
|
|---|
| 226 | void AmbRes::setConstraints(SymmetricMatrix& QFinal, ColumnVector& xFinal,
|
|---|
| 227 | const ColumnVector& xBie, const SymmetricMatrix& covBie,
|
|---|
| 228 | double& fixRatio, ostream& /*msg*/) {
|
|---|
| 229 |
|
|---|
| 230 | fixRatio = 0.0;
|
|---|
| 231 |
|
|---|
| 232 | vector<unique_ptr<const RowVector>> CC;
|
|---|
| 233 | vector<double> cc;
|
|---|
| 234 | vector<double> Sc;
|
|---|
| 235 | int numSdAmbs = 0;
|
|---|
| 236 | int numFixSdAll = 0;
|
|---|
| 237 | for (const AmbGroup& ambGroup : _ambGroups) {
|
|---|
| 238 | numSdAmbs += ambGroup._zdAmbs.size() - 1;
|
|---|
| 239 | for (const ZdAmb& zdAmb : ambGroup._zdAmbs) {
|
|---|
| 240 | int idx = zdAmb.index();
|
|---|
| 241 | if (isFixable(xBie[idx], sqrtMod(covBie[idx][idx]))) {
|
|---|
| 242 | if (ambGroup._zdAmbRef->indexGlobal() != zdAmb.indexGlobal()) {
|
|---|
| 243 | numFixSdAll += 1;
|
|---|
| 244 | }
|
|---|
| 245 | RowVector* pCC;
|
|---|
| 246 | CC.emplace_back(pCC = new RowVector(xFinal.Nrows()));
|
|---|
| 247 | cc.push_back(xBie[idx]);
|
|---|
| 248 | Sc.push_back(sigCon);
|
|---|
| 249 | (*pCC) = 0.0;
|
|---|
| 250 | (*pCC)[zdAmb.indexGlobal()] = 1.0;
|
|---|
| 251 | }
|
|---|
| 252 | }
|
|---|
| 253 | }
|
|---|
| 254 | if (CC.size() > 0) {
|
|---|
| 255 | kalman(CC, cc, Sc, QFinal, xFinal);
|
|---|
| 256 | }
|
|---|
| 257 | if (numSdAmbs > 0) {
|
|---|
| 258 | fixRatio = double(numFixSdAll) / double(numSdAmbs);
|
|---|
| 259 | }
|
|---|
| 260 | }
|
|---|