source: ntrip/trunk/BNC/src/pppMain.cpp@ 11052

Last change on this file since 11052 was 11052, checked in by stuerze, 3 days ago

reject malformed entries

File size: 10.7 KB
Line 
1
2// Part of BNC, a utility for retrieving decoding and
3// converting GNSS data streams from NTRIP broadcasters.
4//
5// Copyright (C) 2007
6// German Federal Agency for Cartography and Geodesy (BKG)
7// http://bkg.bund.de
8// Czech Technical University Prague, Department of Geodesy
9// http://www.fsv.cvut.cz
10//
11// Email: euref-ip@bkg.bund.de
12//
13// This program is free software; you can redistribute it and/or
14// modify it under the terms of the GNU General Public License
15// as published by the Free Software Foundation, version 2.
16//
17// This program is distributed in the hope that it will be useful,
18// but WITHOUT ANY WARRANTY; without even the implied warranty of
19// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20// GNU General Public License for more details.
21//
22// You should have received a copy of the GNU General Public License
23// along with this program; if not, write to the Free Software
24// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25
26/* -------------------------------------------------------------------------
27 * BKG NTRIP Client
28 * -------------------------------------------------------------------------
29 *
30 * Class: t_pppMain
31 *
32 * Purpose: Start of the PPP client(s)
33 *
34 * Author: L. Mervart
35 *
36 * Created: 29-Jul-2014
37 *
38 * Changes:
39 *
40 * -----------------------------------------------------------------------*/
41
42#include <iostream>
43
44#include "pppMain.h"
45#include "pppCrdFile.h"
46#include "bncsettings.h"
47#include "bnccore.h"
48
49using namespace BNC_PPP;
50using namespace std;
51
52// Constructor
53//////////////////////////////////////////////////////////////////////////////
54t_pppMain::t_pppMain() {
55 _running = false;
56}
57
58// Destructor
59//////////////////////////////////////////////////////////////////////////////
60t_pppMain::~t_pppMain() {
61 stop();
62 QListIterator<t_pppOptions*> iOpt(_options);
63 while (iOpt.hasNext()) {
64 delete iOpt.next();
65 }
66}
67
68//
69//////////////////////////////////////////////////////////////////////////////
70void t_pppMain::start() {
71 if (_running) {
72 return;
73 }
74
75 try {
76 readOptions();
77
78 QListIterator<t_pppOptions*> iOpt(_options);
79 while (iOpt.hasNext()) {
80 const t_pppOptions* opt = iOpt.next();
81 t_pppThread* pppThread = new t_pppThread(opt);
82 pppThread->start();
83 _pppThreads << pppThread;
84 _running = true;
85 }
86 }
87 catch (t_except exc) {
88 BNC_CORE->slotMessage(QByteArray::fromStdString(exc.what()), true);
89 _running = true;
90 stop();
91 }
92}
93
94//
95//////////////////////////////////////////////////////////////////////////////
96void t_pppMain::stop() {
97
98 if (!_running) {
99 return;
100 }
101
102 if (_realTime) {
103 QListIterator<t_pppThread*> it(_pppThreads);
104 while (it.hasNext()) {
105 t_pppThread* pppThread = it.next();
106 pppThread->exit();
107 if (BNC_CORE->mode() != t_bncCore::interactive) {
108 while(!pppThread->isFinished()) {
109 pppThread->wait();
110 }
111 delete pppThread;
112 }
113 }
114 _pppThreads.clear();
115 }
116
117 _running = false;
118}
119
120//
121//////////////////////////////////////////////////////////////////////////////
122void t_pppMain::readOptions() {
123
124 QListIterator<t_pppOptions*> iOpt(_options);
125 while (iOpt.hasNext()) {
126 delete iOpt.next();
127 }
128 _options.clear();
129
130 bncSettings settings;
131
132 _realTime = false;
133 if (settings.value("PPP/dataSource").toString() == "Real-Time Streams") {
134 _realTime = true;
135 }
136 else if (settings.value("PPP/dataSource").toString() == "RINEX Files") {
137 _realTime = false;
138 }
139 else {
140 return;
141 }
142
143 QListIterator<QString> iSta(settings.value("PPP/staTable").toStringList());
144 while (iSta.hasNext()) {
145 QStringList hlp = iSta.next().split(",");
146
147 if (hlp.size() < 10) {
148 throw t_except("pppMain: wrong option staTable");
149 }
150
151 t_pppOptions* opt = new t_pppOptions();
152
153 if (settings.value("PPP/logMode").toString() == "debug") {
154 opt->_logMode = t_pppOptions::debug;
155 }
156 else if (settings.value("PPP/logMode").toString() == "all") {
157 opt->_logMode = t_pppOptions::all;
158 }
159 else {
160 opt->_logMode = t_pppOptions::normal;
161 }
162
163 opt->_realTime = _realTime;
164 opt->_roverName = hlp[0].toStdString();
165
166 // Numeric Fields: reject malformed entries
167 // ----------------------------------------
168 double num[9];
169 for (int ii = 1; ii <= 8; ii++) {
170 bool ok;
171 num[ii] = hlp[ii].trimmed().toDouble(&ok);
172 if (!ok || num[ii] < 0.0) {
173 std::string msg = "pppMain: wrong option staTable: station "
174 + opt->_roverName + " field " + std::to_string(ii)
175 + " \"" + hlp[ii].toStdString() + "\"";
176 delete opt;
177 throw t_except(msg.c_str());
178 }
179 }
180 bool okPort;
181 int nmeaPort = hlp[9].trimmed().toInt(&okPort);
182 if (!okPort && !hlp[9].trimmed().isEmpty()) {
183 std::string msg = "pppMain: wrong option staTable: station "
184 + opt->_roverName + " NMEA port \""
185 + hlp[9].toStdString() + "\"";
186 delete opt;
187 throw t_except(msg.c_str());
188 }
189
190 opt->_aprSigCrd[0] = num[1]+1e-10;
191 opt->_aprSigCrd[1] = num[2]+1e-10;
192 opt->_aprSigCrd[2] = num[3]+1e-10;
193 opt->_noiseCrd[0] = num[4]+1e-10;
194 opt->_noiseCrd[1] = num[5]+1e-10;
195 opt->_noiseCrd[2] = num[6]+1e-10;
196 opt->_aprSigTrp = num[7];
197 opt->_noiseTrp = num[8];
198 opt->_nmeaPort = nmeaPort;
199
200 string trkStr = hlp[10].trimmed().toStdString();
201 if (trkStr.length() == 0) {
202 trkStr = "G:12&CWPSLX R:12&CP E:1&CBX E:5&QIX C:26&IQX";
203 }
204 opt->setTrkModes(trkStr);
205
206 if (_realTime) {
207 opt->_corrMount.assign(settings.value("PPP/corrMount").toString().toStdString());
208 opt->_isAPC = (opt->_corrMount.substr(0,4)=="SSRA");
209 opt->_biasMount.assign(settings.value("PPP/biasMount").toString().toStdString());
210 opt->_ionoMount.assign(settings.value("PPP/ionoMount").toString().toStdString());
211 }
212 else {
213 opt->_rinexObs.assign(settings.value("PPP/rinexObs").toString().toStdString());
214 opt->_rinexNav.assign(settings.value("PPP/rinexNav").toString().toStdString());
215 opt->_corrFile.assign(settings.value("PPP/corrFile").toString().toStdString());
216 QFileInfo tmp = QFileInfo(QString::fromStdString(opt->_corrFile));
217 opt->_isAPC = (tmp.baseName().mid(0,4)=="SSRA");
218 opt->_biasFile.assign(settings.value("PPP/biasFile").toString().toStdString());
219 opt->_ionoFile.assign(settings.value("PPP/ionoFile").toString().toStdString());
220 }
221
222 opt->_crdFile.assign(settings.value("PPP/crdFile").toString().toStdString());
223 opt->_antexFileName.assign(settings.value("PPP/antexFile").toString().toStdString());
224 opt->_blqFileName.assign(settings.value("PPP/blqFile").toString().toStdString());
225 opt->_sigmaC1 = settings.value("PPP/sigmaC1").toDouble(); if (opt->_sigmaC1 <= 0.0) opt->_sigmaC1 = 1.00;
226 opt->_sigmaL1 = settings.value("PPP/sigmaL1").toDouble(); if (opt->_sigmaL1 <= 0.0) opt->_sigmaL1 = 0.01;
227 opt->_sigmaGIM = settings.value("PPP/sigmaGIM").toDouble();if (opt->_sigmaGIM <= 0.0) opt->_sigmaGIM = 1.00;
228 opt->_corrWaitTime = settings.value("PPP/corrWaitTime").toDouble();
229 if (!_realTime || opt->_corrMount.empty()) {
230 opt->_corrWaitTime = 0;
231 }
232
233 opt->_pseudoObsIono = false;
234 opt->_refSatRequired = false;
235 // Pseudo Observations
236 if (settings.value("PPP/constraints").toString() == "no") {
237 opt->_pseudoObsIono = false;
238 opt->_refSatRequired = false;
239 opt->_ionoModelType = opt->est;
240 }
241 else if (settings.value("PPP/constraints").toString() == "Ionosphere: pseudo-obs") {
242 opt->_pseudoObsIono = true;
243 opt->_refSatRequired = true;
244 opt->_ionoModelType = opt->est;
245 }
246
247 opt->setLCs('G', settings.value("PPP/lcGPS") .toString().trimmed().toStdString());
248 opt->setLCs('R', settings.value("PPP/lcGLONASS").toString().trimmed().toStdString());
249 opt->setLCs('E', settings.value("PPP/lcGalileo").toString().trimmed().toStdString());
250 opt->setLCs('C', settings.value("PPP/lcBDS") .toString().trimmed().toStdString());
251
252 // Information from the coordinate file
253 // ------------------------------------
254 string crdFileName(settings.value("PPP/crdFile").toString().toStdString());
255 if (!crdFileName.empty()) {
256 vector<t_pppCrdFile::t_staInfo> staInfoVec;
257 t_pppCrdFile::readCrdFile(crdFileName, staInfoVec);
258 for (unsigned ii = 0; ii < staInfoVec.size(); ii++) {
259 const t_pppCrdFile::t_staInfo& staInfo = staInfoVec[ii];
260 if (staInfo._name == opt->_roverName) {
261 opt->_xyzAprRover[0] = staInfo._xyz[0];
262 opt->_xyzAprRover[1] = staInfo._xyz[1];
263 opt->_xyzAprRover[2] = staInfo._xyz[2];
264 opt->_neuEccRover[0] = staInfo._neuAnt[0];
265 opt->_neuEccRover[1] = staInfo._neuAnt[1];
266 opt->_neuEccRover[2] = staInfo._neuAnt[2];
267 opt->_velRover[0] = staInfo._velocity[0];
268 opt->_velRover[1] = staInfo._velocity[1];
269 opt->_velRover[2] = staInfo._velocity[2];
270 opt->_refEpochRover = staInfo._epoch;
271 opt->_antNameRover = staInfo._antenna;
272 opt->_recNameRover = staInfo._receiver;
273 break;
274 }
275 }
276 }
277
278 opt->_minObs = settings.value("PPP/minObs").toInt(); if (opt->_minObs < 4) opt->_minObs = 4;
279 opt->_minEle = settings.value("PPP/minEle").toDouble() * M_PI / 180.0;
280 opt->_maxResC1 = settings.value("PPP/maxResC1").toDouble(); if (opt->_maxResC1 <= 0.0) opt->_maxResC1 = 3.0;
281 opt->_maxResL1 = settings.value("PPP/maxResL1").toDouble(); if (opt->_maxResL1 <= 0.0) opt->_maxResL1 = 0.03;
282 opt->_eleWgtCode = (settings.value("PPP/eleWgtCode").toInt() != 0);
283 opt->_eleWgtPhase = (settings.value("PPP/eleWgtPhase").toInt() != 0);
284 opt->_seedingTime = settings.value("PPP/seedingTime").toDouble();
285
286 // Ambiguity Resolution
287 // --------------------
288 if (settings.value("PPP/arGPS").toInt() != 0) {
289 opt->_ar._systems.insert('G');
290 }
291 if (settings.value("PPP/arGalileo").toInt() != 0) {
292 opt->_ar._systems.insert('E');
293 }
294 if (settings.value("PPP/arBDS").toInt() != 0) {
295 opt->_ar._systems.insert('C');
296 }
297 opt->_ar._minEle = opt->_minEle;
298 opt->_ar._minNumEpo = settings.value("PPP/arMinNumEpo").toInt();
299 opt->_ar._minNumSat = settings.value("PPP/arMinNumSat").toInt();
300 opt->_ar._useYaw = (settings.value("PPP/arUseYaw").toInt() != 0);
301 opt->_ar._maxFrac = settings.value("PPP/arMaxFrac").toDouble();
302 opt->_ar._maxSig = settings.value("PPP/arMaxSig").toDouble();
303
304 // Some default values
305 // -------------------
306 opt->_aprSigClk = 1e3;
307 opt->_aprSigAmb = 1e3;
308 opt->_aprSigIon = 1e2;
309 opt->_aprSigCodeBias = 1e1;
310
311 _options << opt;
312 }
313}
314
Note: See TracBrowser for help on using the repository browser.