source: ntrip/trunk/BNC/src/PPP/ambres.cpp@ 10809

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