source: ntrip/trunk/BNC/src/orbComp/sp3Comp.cpp@ 6344

Last change on this file since 6344 was 6344, checked in by mervart, 9 years ago
File size: 12.2 KB
Line 
1// Part of BNC, a utility for retrieving decoding and
2// converting GNSS data streams from NTRIP broadcasters.
3//
4// Copyright (C) 2007
5// German Federal Agency for Cartography and Geodesy (BKG)
6// http://www.bkg.bund.de
7// Czech Technical University Prague, Department of Geodesy
8// http://www.fsv.cvut.cz
9//
10// Email: euref-ip@bkg.bund.de
11//
12// This program is free software; you can redistribute it and/or
13// modify it under the terms of the GNU General Public License
14// as published by the Free Software Foundation, version 2.
15//
16// This program is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU General Public License for more details.
20//
21// You should have received a copy of the GNU General Public License
22// along with this program; if not, write to the Free Software
23// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
25/* -------------------------------------------------------------------------
26 * BKG NTRIP Client
27 * -------------------------------------------------------------------------
28 *
29 * Class: t_sp3Comp
30 *
31 * Purpose: Compare SP3 Files
32 *
33 * Author: L. Mervart
34 *
35 * Created: 24-Nov-2014
36 *
37 * Changes:
38 *
39 * -----------------------------------------------------------------------*/
40
41#include <iostream>
42#include "sp3Comp.h"
43#include "bnccore.h"
44#include "bncsettings.h"
45#include "bncutils.h"
46
47using namespace std;
48
49// Constructor
50////////////////////////////////////////////////////////////////////////////
51t_sp3Comp::t_sp3Comp(QObject* parent) : QThread(parent) {
52
53 bncSettings settings;
54 _sp3FileNames = settings.value("sp3CompFile").toString().split(',', QString::SkipEmptyParts);
55 for (int ii = 0; ii < _sp3FileNames.size(); ii++) {
56 expandEnvVar(_sp3FileNames[ii]);
57 }
58 _logFileName = settings.value("sp3CompOutLogFile").toString(); expandEnvVar(_logFileName);
59 _logFile = 0;
60 _log = 0;
61}
62
63// Destructor
64////////////////////////////////////////////////////////////////////////////
65t_sp3Comp::~t_sp3Comp() {
66 delete _log;
67 delete _logFile;
68}
69
70//
71////////////////////////////////////////////////////////////////////////////
72void t_sp3Comp::run() {
73
74 // Open Log File
75 // -------------
76 _logFile = new QFile(_logFileName);
77 if (_logFile->open(QIODevice::WriteOnly | QIODevice::Text)) {
78 _log = new QTextStream();
79 _log->setDevice(_logFile);
80 }
81 if (!_log) {
82 emit finished();
83 return;
84 }
85
86 for (int ii = 0; ii < _sp3FileNames.size(); ii++) {
87 *_log << "SP3 File " << ii+1 << ": " << _sp3FileNames[ii] << endl;
88 }
89 if (_sp3FileNames.size() != 2) {
90 *_log << "ERROR: sp3Comp requires two input SP3 files" << endl;
91 emit finished();
92 return;
93 }
94
95
96 // Exit (thread)
97 // -------------
98 if (BNC_CORE->mode() != t_bncCore::interactive) {
99 qApp->exit(0);
100 }
101 else {
102 emit finished();
103 deleteLater();
104 }
105}
106
107//// Satellite Index in clkSats set
108//////////////////////////////////////////////////////////////////////////////////
109//int satIndex(const set<GPSS::t_prn>& clkSats, const GPSS::t_prn& prn) {
110// int ret = 0;
111// for (set<GPSS::t_prn>::const_iterator it = clkSats.begin(); it != clkSats.end(); it++) {
112// if ( *it == prn) {
113// return ret;
114// }
115// ++ret;
116// }
117// cerr << "satellite not found in used Sats " << prn << endl;
118// exit(1);
119//}
120//
121//// Estimate Clock Offsets
122//////////////////////////////////////////////////////////////////////////////////
123//void processClocks(const set<GPSS::t_prn>& clkSats, vector<t_epoch*>& epochs,
124// map<string, t_stat>& stat) {
125//
126// if (clkSats.size() == 0) {
127// return;
128// }
129//
130// int nPar = epochs.size() + clkSats.size();
131// SymmetricMatrix NN(nPar); NN = 0.0;
132// ColumnVector bb(nPar); bb = 0.0;
133//
134// // Create Matrix A'A and vector b
135// // ------------------------------
136// for (unsigned ie = 0; ie < epochs.size(); ie++) {
137// const GPSS::t_gpstime& tt = epochs[ie]->_tt;
138// const map<GPSS::t_prn, double>& dc = epochs[ie]->_dc;
139// Matrix AA(dc.size(), nPar); AA = 0.0;
140// ColumnVector ll(dc.size()); ll = 0.0;
141// map<GPSS::t_prn, double>::const_iterator it; int ii;
142// for (it = dc.begin(), ii = 0; it != dc.end(); it++, ii++) {
143// const GPSS::t_prn& prn = it->first;
144// int index = epochs.size() + satIndex(clkSats, prn);
145// AA[ii][ie] = 1.0; // epoch-specfic offset (common for all satellites)
146// AA[ii][index] = 1.0; // satellite-specific offset (common for all epochs)
147// ll[ii] = it->second;
148// }
149// SymmetricMatrix dN; dN << AA.t() * AA;
150// NN += dN;
151// bb += AA.t() * ll;
152// }
153//
154// // Regularize NN
155// // -------------
156// RowVector HH(nPar);
157// HH.columns(1, epochs.size()) = 0.0;
158// HH.columns(epochs.size()+1, nPar) = 1.0;
159// SymmetricMatrix dN; dN << HH.t() * HH;
160// NN += dN;
161//
162// // Estimate Parameters
163// // -------------------
164// ColumnVector xx = NN.i() * bb;
165//
166// // Compute clock residuals
167// // -----------------------
168// for (unsigned ie = 0; ie < epochs.size(); ie++) {
169// const GPSS::t_gpstime& tt = epochs[ie]->_tt;
170// map<GPSS::t_prn, double>& dc = epochs[ie]->_dc;
171// for (map<GPSS::t_prn, double>::iterator it = dc.begin(); it != dc.end(); it++) {
172// const GPSS::t_prn& prn = it->first;
173// int index = epochs.size() + satIndex(clkSats, prn);
174// dc[prn] = it->second - xx[ie] - xx[index];
175// stat[prn]._offset = xx[index];
176// }
177// }
178//}
179//
180//// Program
181//////////////////////////////////////////////////////////////////////////////////
182//int main(int argc, char* argv[]) {
183//
184// GPSS::t_sysout* sysout = new GPSS::t_sysout("", 0, false);
185// GPSS::rtnet_core_log = sysout->getSysoutCore();
186//
187// // Parse Input Options
188// // -------------------
189// map<string, string> OPT;
190// parseCmdLine(argc, argv, OPT);
191// if (OPT.find("sp3File1") == OPT.end() || OPT.find("sp3File2") == OPT.end()) {
192// cerr << "usage: sp3comp --sp3File1 <fileName> --sp3File2 <fileName> " << endl;
193// return 1;
194// }
195//
196// // Synchronize reading of two sp3 files
197// // ------------------------------------
198// vector<GPSS::t_prn> prnList;
199// for (unsigned prn = 1; prn <= GPSS::t_prn::MAXPRN; prn++) {
200// prnList.push_back(GPSS::t_prn(prn));
201// }
202// GPSS::t_sp3 in1(prnList); if (in1.assignFile(OPT["sp3File1"].c_str())) return 1;
203// GPSS::t_sp3 in2(prnList); if (in2.assignFile(OPT["sp3File2"].c_str())) return 1;
204//
205// vector<t_epoch*> epochs;
206// set<GPSS::t_prn> clkSats;
207// while (true) {
208// in1.readNextEpoch();
209// GPSS::t_gpstime tt = in1.etime();
210// if (!tt.valid()) {
211// break;
212// }
213// if (in2.readEpoch(tt) == t_irc::success) {
214// t_epoch* epo = new t_epoch; epo->_tt = tt;
215// bool epochOK = false;
216// for (unsigned iPrn = 1; iPrn <= GPSS::t_prn::MAXPRN; iPrn++) {
217// GPSS::t_prn prn(iPrn);
218// ColumnVector xyz1(3), xyz2(3);
219// ColumnVector vel1(3), vel2(3);
220// double clk1, clk2;
221// bool posSet1, posSet2;
222// bool clkSet1, clkSet2;
223// bool velSet1, velSet2;
224// if (in1.position(prn, xyz1[0], xyz1[1], xyz1[2], posSet1, clk1, clkSet1,
225// vel1[0], vel1[1], vel1[2], velSet1) == 0 &&
226// in2.position(prn, xyz2[0], xyz2[1], xyz2[2], posSet2, clk2, clkSet2,
227// vel1[0], vel1[1], vel1[2], velSet1) == 0) {
228// if (posSet1 && posSet2) {
229// epochOK = true;
230// epo->_dr[prn] = xyz1 - xyz2;
231// epo->_xyz[prn] = xyz1;
232// if (clkSet1 && clkSet2) {
233// epo->_dc[prn] = (clk1 - clk2) * t_genConst::c;
234// clkSats.insert(prn);
235// }
236// }
237// }
238// }
239// if (epochOK) {
240// epochs.push_back(epo);
241// }
242// else {
243// delete epo;
244// }
245// }
246// if (in1.finished()) {
247// break;
248// }
249// }
250//
251// // Transform xyz into radial, along-track, and out-of-plane
252// // --------------------------------------------------------
253// for (unsigned ie = 0; ie < epochs.size(); ie++) {
254// t_epoch* epoch = epochs[ie];
255// t_epoch* epoch2 = 0;
256// if (ie == 0 && epochs.size() > 1) {
257// epoch2 = epochs[ie+1];
258// }
259// else {
260// epoch2 = epochs[ie-1];
261// }
262// double dt = epoch->_tt - epoch2->_tt;
263// map<GPSS::t_prn, ColumnVector>& dr = epoch->_dr;
264// map<GPSS::t_prn, ColumnVector>& xyz = epoch->_xyz;
265// map<GPSS::t_prn, ColumnVector>& xyz2 = epoch2->_xyz;
266// for (map<GPSS::t_prn, ColumnVector>::const_iterator it = dr.begin(); it != dr.end(); it++) {
267// const GPSS::t_prn& prn = it->first;
268// if (xyz2.find(prn) != xyz2.end()) {
269// const ColumnVector dx = dr[prn];
270// const ColumnVector& x1 = xyz[prn];
271// const ColumnVector& x2 = xyz2[prn];
272// ColumnVector vel = (x1 - x2) / dt;
273// GPSS::t_astro::XYZ_to_RSW(x1, vel, dx, dr[prn]);
274// }
275// else {
276// cerr << "not found: " << prn << endl;
277// }
278// }
279// }
280//
281// map<string, t_stat> stat;
282//
283// // Estimate Clock Offsets
284// // ----------------------
285// processClocks(clkSats, epochs, stat);
286//
287// // Print Residuals
288// // ---------------
289// const string all = "ZZZ";
290//
291// cout.setf(ios::fixed);
292// cout << "!\n! MJD PRN radial along out clk clkRed iPRN"
293// "\n! ----------------------------------------------------------------\n";
294// for (unsigned ii = 0; ii < epochs.size(); ii++) {
295// const t_epoch* epo = epochs[ii];
296// const map<GPSS::t_prn, ColumnVector>& dr = epochs[ii]->_dr;
297// const map<GPSS::t_prn, double>& dc = epochs[ii]->_dc;
298// for (map<GPSS::t_prn, ColumnVector>::const_iterator it = dr.begin(); it != dr.end(); it++) {
299// const GPSS::t_prn& prn = it->first;
300// const ColumnVector& rao = it->second;
301// cout << setprecision(6) << epo->_tt.mjddec() << ' ' << prn << ' '
302// << setw(7) << setprecision(4) << rao[0] << ' '
303// << setw(7) << setprecision(4) << rao[1] << ' '
304// << setw(7) << setprecision(4) << rao[2] << " ";
305// stat[prn]._rao += SP(rao, rao); // Schur product
306// stat[prn]._nr += 1;
307// stat[all]._rao += SP(rao, rao);
308// stat[all]._nr += 1;
309// if (dc.find(prn) != dc.end()) {
310// double clkRes = dc.find(prn)->second;
311// double clkResRed = clkRes - it->second[0]; // clock minus radial component
312// cout << setw(7) << setprecision(4) << clkRes << ' '
313// << setw(7) << setprecision(4) << clkResRed;
314// stat[prn]._dc += clkRes * clkRes;
315// stat[prn]._dcRed += clkResRed * clkResRed;
316// stat[prn]._nc += 1;
317// stat[all]._dc += clkRes * clkRes;
318// stat[all]._dcRed += clkResRed * clkResRed;
319// stat[all]._nc += 1;
320// }
321// else {
322// cout << " . . ";
323// }
324// cout << " " << setw(2) << int(prn) << endl;
325// }
326// delete epo;
327// }
328//
329// // Print Summary
330// // -------------
331// cout << "!\n! RMS:\n";
332// for (map<string, t_stat>::iterator it = stat.begin(); it != stat.end(); it++) {
333// const string& prn = it->first;
334// t_stat& stat = it->second;
335// if (stat._nr > 0) {
336// stat._rao[0] = sqrt(stat._rao[0] / stat._nr);
337// stat._rao[1] = sqrt(stat._rao[1] / stat._nr);
338// stat._rao[2] = sqrt(stat._rao[2] / stat._nr);
339// if (prn == all) {
340// cout << "!\n! Total ";
341// }
342// else {
343// cout << "! " << prn << ' ';
344// }
345// cout << setw(7) << setprecision(4) << stat._rao[0] << ' '
346// << setw(7) << setprecision(4) << stat._rao[1] << ' '
347// << setw(7) << setprecision(4) << stat._rao[2] << " ";
348// if (stat._nc > 0) {
349// stat._dc = sqrt(stat._dc / stat._nc);
350// stat._dcRed = sqrt(stat._dcRed / stat._nc);
351// cout << setw(7) << setprecision(4) << stat._dc << ' '
352// << setw(7) << setprecision(4) << stat._dcRed;
353// if (prn != all) {
354// cout << " offset " << setw(7) << setprecision(4) << stat._offset;
355// }
356// }
357// else {
358// cout << " . . ";
359// }
360// cout << endl;
361// }
362// }
363//
364// return 0;
365//}
Note: See TracBrowser for help on using the repository browser.