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

Last change on this file since 11096 was 11079, checked in by stuerze, 3 weeks ago

combi can be based on CoM

File size: 11.1 KB
RevLine 
[5714]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)
[11022]7// http://bkg.bund.de
[5714]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 *
[7278]38 * Changes:
[5714]39 *
40 * -----------------------------------------------------------------------*/
41
[5717]42#include <iostream>
43
[5714]44#include "pppMain.h"
[5911]45#include "pppCrdFile.h"
[5714]46#include "bncsettings.h"
[11052]47#include "bnccore.h"
[5714]48
[5814]49using namespace BNC_PPP;
[5714]50using namespace std;
51
52// Constructor
53//////////////////////////////////////////////////////////////////////////////
54t_pppMain::t_pppMain() {
[5762]55 _running = false;
[5714]56}
57
58// Destructor
59//////////////////////////////////////////////////////////////////////////////
60t_pppMain::~t_pppMain() {
[5900]61 stop();
[5975]62 QListIterator<t_pppOptions*> iOpt(_options);
63 while (iOpt.hasNext()) {
64 delete iOpt.next();
65 }
[5714]66}
67
[7278]68//
[5714]69//////////////////////////////////////////////////////////////////////////////
[5946]70void t_pppMain::start() {
[5719]71 if (_running) {
72 return;
73 }
74
[5764]75 try {
76 readOptions();
[5719]77
[5810]78 QListIterator<t_pppOptions*> iOpt(_options);
[5764]79 while (iOpt.hasNext()) {
[5810]80 const t_pppOptions* opt = iOpt.next();
[5946]81 t_pppThread* pppThread = new t_pppThread(opt);
82 pppThread->start();
[11057]83 // In batch post-processing (--file replay), the data source must not
84 // start before the PPP client is connected, otherwise the data read
85 // in the meantime get lost (a varying amount, depending on thread
86 // scheduling).
87 if (BNC_CORE->mode() == t_bncCore::batchPostProcessing) {
88 pppThread->waitUntilReady();
89 }
[5813]90 _pppThreads << pppThread;
[5764]91 _running = true;
92 }
[5719]93 }
[5825]94 catch (t_except exc) {
[11052]95 BNC_CORE->slotMessage(QByteArray::fromStdString(exc.what()), true);
[5765]96 _running = true;
[5900]97 stop();
[5764]98 }
[5716]99}
100
[7278]101//
[5716]102//////////////////////////////////////////////////////////////////////////////
[5900]103void t_pppMain::stop() {
[5871]104
[5719]105 if (!_running) {
106 return;
107 }
[5730]108
[5972]109 if (_realTime) {
110 QListIterator<t_pppThread*> it(_pppThreads);
111 while (it.hasNext()) {
112 t_pppThread* pppThread = it.next();
113 pppThread->exit();
[7856]114 if (BNC_CORE->mode() != t_bncCore::interactive) {
115 while(!pppThread->isFinished()) {
116 pppThread->wait();
117 }
118 delete pppThread;
[9252]119 }
[5972]120 }
[5975]121 _pppThreads.clear();
[8905]122 }
[5730]123
[5719]124 _running = false;
[5716]125}
126
[7278]127//
[5716]128//////////////////////////////////////////////////////////////////////////////
[5714]129void t_pppMain::readOptions() {
130
[5810]131 QListIterator<t_pppOptions*> iOpt(_options);
[5736]132 while (iOpt.hasNext()) {
133 delete iOpt.next();
134 }
[5714]135 _options.clear();
136
137 bncSettings settings;
138
[5971]139 _realTime = false;
[5714]140 if (settings.value("PPP/dataSource").toString() == "Real-Time Streams") {
[5971]141 _realTime = true;
[5714]142 }
143 else if (settings.value("PPP/dataSource").toString() == "RINEX Files") {
[5971]144 _realTime = false;
[5714]145 }
146 else {
[7278]147 return;
[5714]148 }
149
[5736]150 QListIterator<QString> iSta(settings.value("PPP/staTable").toStringList());
151 while (iSta.hasNext()) {
152 QStringList hlp = iSta.next().split(",");
[5714]153
[9559]154 if (hlp.size() < 10) {
[5825]155 throw t_except("pppMain: wrong option staTable");
[5714]156 }
157
[5810]158 t_pppOptions* opt = new t_pppOptions();
[5714]159
[10791]160 if (settings.value("PPP/logMode").toString() == "debug") {
161 opt->_logMode = t_pppOptions::debug;
[10251]162 }
[10791]163 else if (settings.value("PPP/logMode").toString() == "all") {
164 opt->_logMode = t_pppOptions::all;
165 }
166 else {
167 opt->_logMode = t_pppOptions::normal;
168 }
169
170 opt->_realTime = _realTime;
171 opt->_roverName = hlp[0].toStdString();
172
[11052]173 // Numeric Fields: reject malformed entries
174 // ----------------------------------------
175 double num[9];
176 for (int ii = 1; ii <= 8; ii++) {
177 bool ok;
178 num[ii] = hlp[ii].trimmed().toDouble(&ok);
179 if (!ok || num[ii] < 0.0) {
180 std::string msg = "pppMain: wrong option staTable: station "
181 + opt->_roverName + " field " + std::to_string(ii)
182 + " \"" + hlp[ii].toStdString() + "\"";
183 delete opt;
184 throw t_except(msg.c_str());
185 }
186 }
187 bool okPort;
188 int nmeaPort = hlp[9].trimmed().toInt(&okPort);
189 if (!okPort && !hlp[9].trimmed().isEmpty()) {
190 std::string msg = "pppMain: wrong option staTable: station "
191 + opt->_roverName + " NMEA port \""
192 + hlp[9].toStdString() + "\"";
193 delete opt;
194 throw t_except(msg.c_str());
195 }
196
197 opt->_aprSigCrd[0] = num[1]+1e-10;
198 opt->_aprSigCrd[1] = num[2]+1e-10;
199 opt->_aprSigCrd[2] = num[3]+1e-10;
200 opt->_noiseCrd[0] = num[4]+1e-10;
201 opt->_noiseCrd[1] = num[5]+1e-10;
202 opt->_noiseCrd[2] = num[6]+1e-10;
203 opt->_aprSigTrp = num[7];
204 opt->_noiseTrp = num[8];
205 opt->_nmeaPort = nmeaPort;
206
[10791]207 string trkStr = hlp[10].trimmed().toStdString();
208 if (trkStr.length() == 0) {
209 trkStr = "G:12&CWPSLX R:12&CP E:1&CBX E:5&QIX C:26&IQX";
210 }
211 opt->setTrkModes(trkStr);
212
[5971]213 if (_realTime) {
[7850]214 opt->_corrMount.assign(settings.value("PPP/corrMount").toString().toStdString());
[11079]215 // the combined corrections (INTERNAL) always refer to the APC
216 opt->_isAPC = (opt->_corrMount.substr(0,4)=="SSRA" || opt->_corrMount == "INTERNAL");
[10791]217 opt->_biasMount.assign(settings.value("PPP/biasMount").toString().toStdString());
[9599]218 opt->_ionoMount.assign(settings.value("PPP/ionoMount").toString().toStdString());
[5714]219 }
220 else {
[7850]221 opt->_rinexObs.assign(settings.value("PPP/rinexObs").toString().toStdString());
222 opt->_rinexNav.assign(settings.value("PPP/rinexNav").toString().toStdString());
223 opt->_corrFile.assign(settings.value("PPP/corrFile").toString().toStdString());
[9481]224 QFileInfo tmp = QFileInfo(QString::fromStdString(opt->_corrFile));
225 opt->_isAPC = (tmp.baseName().mid(0,4)=="SSRA");
[10791]226 opt->_biasFile.assign(settings.value("PPP/biasFile").toString().toStdString());
[9599]227 opt->_ionoFile.assign(settings.value("PPP/ionoFile").toString().toStdString());
[5714]228 }
229
[7850]230 opt->_crdFile.assign(settings.value("PPP/crdFile").toString().toStdString());
[7962]231 opt->_antexFileName.assign(settings.value("PPP/antexFile").toString().toStdString());
232 opt->_blqFileName.assign(settings.value("PPP/blqFile").toString().toStdString());
[10250]233 opt->_sigmaC1 = settings.value("PPP/sigmaC1").toDouble(); if (opt->_sigmaC1 <= 0.0) opt->_sigmaC1 = 1.00;
234 opt->_sigmaL1 = settings.value("PPP/sigmaL1").toDouble(); if (opt->_sigmaL1 <= 0.0) opt->_sigmaL1 = 0.01;
[10638]235 opt->_sigmaGIM = settings.value("PPP/sigmaGIM").toDouble();if (opt->_sigmaGIM <= 0.0) opt->_sigmaGIM = 1.00;
[5714]236 opt->_corrWaitTime = settings.value("PPP/corrWaitTime").toDouble();
[7943]237 if (!_realTime || opt->_corrMount.empty()) {
238 opt->_corrWaitTime = 0;
239 }
[10251]240
[8905]241 opt->_pseudoObsIono = false;
242 opt->_refSatRequired = false;
[10251]243 // Pseudo Observations
244 if (settings.value("PPP/constraints").toString() == "no") {
[8961]245 opt->_pseudoObsIono = false;
[10251]246 opt->_refSatRequired = false;
247 opt->_ionoModelType = opt->est;
[8905]248 }
[10251]249 else if (settings.value("PPP/constraints").toString() == "Ionosphere: pseudo-obs") {
250 opt->_pseudoObsIono = true;
251 opt->_refSatRequired = true;
252 opt->_ionoModelType = opt->est;
[8905]253 }
[10791]254
255 opt->setLCs('G', settings.value("PPP/lcGPS") .toString().trimmed().toStdString());
256 opt->setLCs('R', settings.value("PPP/lcGLONASS").toString().trimmed().toStdString());
257 opt->setLCs('E', settings.value("PPP/lcGalileo").toString().trimmed().toStdString());
258 opt->setLCs('C', settings.value("PPP/lcBDS") .toString().trimmed().toStdString());
[10251]259
[5911]260 // Information from the coordinate file
261 // ------------------------------------
[7850]262 string crdFileName(settings.value("PPP/crdFile").toString().toStdString());
[5911]263 if (!crdFileName.empty()) {
264 vector<t_pppCrdFile::t_staInfo> staInfoVec;
265 t_pppCrdFile::readCrdFile(crdFileName, staInfoVec);
266 for (unsigned ii = 0; ii < staInfoVec.size(); ii++) {
267 const t_pppCrdFile::t_staInfo& staInfo = staInfoVec[ii];
268 if (staInfo._name == opt->_roverName) {
269 opt->_xyzAprRover[0] = staInfo._xyz[0];
270 opt->_xyzAprRover[1] = staInfo._xyz[1];
271 opt->_xyzAprRover[2] = staInfo._xyz[2];
272 opt->_neuEccRover[0] = staInfo._neuAnt[0];
273 opt->_neuEccRover[1] = staInfo._neuAnt[1];
274 opt->_neuEccRover[2] = staInfo._neuAnt[2];
[11019]275 opt->_velRover[0] = staInfo._velocity[0];
276 opt->_velRover[1] = staInfo._velocity[1];
277 opt->_velRover[2] = staInfo._velocity[2];
278 opt->_refEpochRover = staInfo._epoch;
[5911]279 opt->_antNameRover = staInfo._antenna;
[7523]280 opt->_recNameRover = staInfo._receiver;
[5911]281 break;
282 }
283 }
284 }
285
[9783]286 opt->_minObs = settings.value("PPP/minObs").toInt(); if (opt->_minObs < 4) opt->_minObs = 4;
[5959]287 opt->_minEle = settings.value("PPP/minEle").toDouble() * M_PI / 180.0;
[10638]288 opt->_maxResC1 = settings.value("PPP/maxResC1").toDouble(); if (opt->_maxResC1 <= 0.0) opt->_maxResC1 = 3.0;
289 opt->_maxResL1 = settings.value("PPP/maxResL1").toDouble(); if (opt->_maxResL1 <= 0.0) opt->_maxResL1 = 0.03;
[5959]290 opt->_eleWgtCode = (settings.value("PPP/eleWgtCode").toInt() != 0);
291 opt->_eleWgtPhase = (settings.value("PPP/eleWgtPhase").toInt() != 0);
292 opt->_seedingTime = settings.value("PPP/seedingTime").toDouble();
293
[10791]294 // Ambiguity Resolution
295 // --------------------
296 if (settings.value("PPP/arGPS").toInt() != 0) {
297 opt->_ar._systems.insert('G');
298 }
299 if (settings.value("PPP/arGalileo").toInt() != 0) {
300 opt->_ar._systems.insert('E');
301 }
302 if (settings.value("PPP/arBDS").toInt() != 0) {
303 opt->_ar._systems.insert('C');
304 }
305 opt->_ar._minEle = opt->_minEle;
306 opt->_ar._minNumEpo = settings.value("PPP/arMinNumEpo").toInt();
307 opt->_ar._minNumSat = settings.value("PPP/arMinNumSat").toInt();
308 opt->_ar._useYaw = (settings.value("PPP/arUseYaw").toInt() != 0);
309 opt->_ar._maxFrac = settings.value("PPP/arMaxFrac").toDouble();
310 opt->_ar._maxSig = settings.value("PPP/arMaxSig").toDouble();
311
[5793]312 // Some default values
313 // -------------------
[10791]314 opt->_aprSigClk = 1e3;
315 opt->_aprSigAmb = 1e3;
316 opt->_aprSigIon = 1e2;
317 opt->_aprSigCodeBias = 1e1;
[5793]318
[5714]319 _options << opt;
320 }
321}
322
Note: See TracBrowser for help on using the repository browser.