source: ntrip/trunk/BNC/src/GPSDecoder.cpp@ 5884

Last change on this file since 5884 was 5884, checked in by mervart, 10 years ago
File size: 7.0 KB
RevLine 
[3528]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: GPSDecoder
30 *
31 * Purpose: Decoder Base Class
32 *
33 * Author: L. Mervart
34 *
35 * Created: 16-Dec-2011
36 *
37 * Changes:
38 *
39 * -----------------------------------------------------------------------*/
40
41#include <iomanip>
42#include <cmath>
43
44#include "GPSDecoder.h"
45#include "bncsettings.h"
[5884]46#include "bncrinex.h"
[3528]47
[4439]48extern "C" {
[4440]49#include "rtcm3torinex.h"
[4439]50}
[4422]51
[3528]52using namespace std;
53
54// Constructor
55//////////////////////////////////////////////////////////////////////////////
56GPSDecoder::GPSDecoder() {
[3529]57 _rnx = 0;
58}
59
[5884]60// Destructor
61//////////////////////////////////////////////////////////////////////////////
62GPSDecoder::~GPSDecoder() {
63 delete _rnx;
64}
65
[3529]66// Initialize RINEX Writer
67//////////////////////////////////////////////////////////////////////////////
68void GPSDecoder::initRinex(const QByteArray& staID, const QUrl& mountPoint,
69 const QByteArray& latitude,
70 const QByteArray& longitude, const QByteArray& nmea,
71 const QByteArray& ntripVersion) {
72 if (_rnx) {
73 return;
74 }
[3528]75 bncSettings settings;
[3529]76 if ( !settings.value("rnxPath").toString().isEmpty() ) {
77 _rnx = new bncRinex(staID, mountPoint, latitude, longitude,
78 nmea, ntripVersion);
[3528]79 }
80}
81
82// Write RINEX Epoch
83//////////////////////////////////////////////////////////////////////////////
84void GPSDecoder::dumpRinexEpoch(const t_obs& obs, const QByteArray& format) {
85 if (_rnx) {
86 long iSec = long(floor(obs.GPSWeeks+0.5));
87 long obsTime = obs.GPSWeek * 7*24*3600 + iSec;
88 if (_rnx->samplingRate() == 0 || iSec % _rnx->samplingRate() == 0) {
89 _rnx->deepCopy(obs);
90 }
91 _rnx->dumpEpoch(format, obsTime);
92 }
93}
94
95// Set RINEX Reconnect Flag
96//////////////////////////////////////////////////////////////////////////////
97void GPSDecoder::setRinexReconnectFlag(bool flag) {
98 if (_rnx) {
99 _rnx->setReconnectFlag(flag);
100 }
101}
[4392]102
103//
104//////////////////////////////////////////////////////////////////////////////
[5367]105void t_obs::setMeasdata(QString rnxStr, float rnxVers, double value) {
[5551]106 int ie = iEntry(rnxStr, rnxVers);
[5367]107
[5368]108 if (ie != -1) {
109 _codetype[ie] = rnxStr.mid(1);
110 _measdata[ie] = value;
[5367]111 }
[4393]112}
[4392]113
114//
115//////////////////////////////////////////////////////////////////////////////
[5550]116double t_obs::measdata(QString rnxStr, float rnxVers) const {
[5551]117 int ie = iEntry(rnxStr, rnxVers);
[5549]118
119 if (ie != -1) {
120 return _measdata[ie];
[4403]121 }
[5549]122
[5529]123 return 0.0;
[4403]124}
[4392]125
[4403]126//
127//////////////////////////////////////////////////////////////////////////////
[5370]128QString t_obs::rnxStr(int iEntry) const {
[5380]129 QString str(1,' ');
[5370]130 switch(iEntry & 3) {
131 case GNSSENTRY_CODE: str[0] = 'C'; break;
132 case GNSSENTRY_PHASE: str[0] = 'L'; break;
133 case GNSSENTRY_DOPPLER: str[0] = 'D'; break;
134 case GNSSENTRY_SNR: str[0] = 'S'; break;
135 }
136 str += _codetype[iEntry];
137 return str.trimmed();
138}
139
140//
141//////////////////////////////////////////////////////////////////////////////
[5551]142int t_obs::iEntry(QString rnxStr, float rnxVers, bool cmode) const {
[5370]143
[5368]144 int res = 0;
[5551]145 bool tryagain = false;
146 QString rnxStrOrig = rnxStr;
147
148 if (rnxVers < 3.0) {
149 if (rnxStr == "C1") rnxStr = "C1C";
150 else if (rnxStr == "P1") rnxStr = "C1P";
151 else if (rnxStr == "C2") rnxStr = "C2C";
152 else if (rnxStr == "P2") rnxStr = "C2P";
153 if(cmode)
154 {
155 if (rnxStr == "S1") rnxStr = "S1C";
156 else if (rnxStr == "L1") rnxStr = "L1C";
157 else if (rnxStr == "S2") rnxStr = "S2C";
158 else if (rnxStr == "L2") rnxStr = "L2C";
159 }
160 else
161 {
162 if (rnxStr == "S1") {rnxStr = "S1P"; tryagain = true; }
163 else if (rnxStr == "L1") {rnxStr = "L1P"; tryagain = true; }
164 else if (rnxStr == "S2") {rnxStr = "S2P"; tryagain = true; }
165 else if (rnxStr == "L2") {rnxStr = "L2P"; tryagain = true; }
166 }
167 }
[5370]168
169 // Observation Type (Code, Phase, Doppler, SNR)
170 // --------------------------------------------
171 if (rnxStr[0] == 'C') {
172 res += GNSSENTRY_CODE;
173 }
174 else if (rnxStr[0] == 'L') {
175 res += GNSSENTRY_PHASE;
176 }
177 else if (rnxStr[0] == 'D') {
178 res += GNSSENTRY_DOPPLER;
179 }
180 else if (rnxStr[0] == 'S') {
181 res += GNSSENTRY_SNR;
182 }
183 else {
[5368]184 return -1;
185 }
[5370]186
187 // Frequency
188 // ---------
189 if (rnxStr[1] == '1') {
190 if (rnxStr.length() < 3) {
191 res += GNSSENTRY_TYPEC1;
[5355]192 }
[5374]193 else if (QString("ABCIQ").indexOf(rnxStr[2]) != -1) {
[5370]194 res += GNSSENTRY_TYPEC1;
195 }
[5374]196 else if (QString("SL").indexOf(rnxStr[2]) != -1) {
197 res += GNSSENTRY_TYPEC1N;
198 }
[5370]199 else if (QString("PWY").indexOf(rnxStr[2]) != -1) {
200 res += GNSSENTRY_TYPEP1;
201 }
202 else if (rnxStr[2] == 'Z') {
203 res += GNSSENTRY_TYPECSAIF;
204 }
[5374]205 else if (rnxStr[2] == 'X') {
[5375]206 if (satSys == 'C' || satSys == 'E') {
[5374]207 res += GNSSENTRY_TYPEC1;
208 }
209 else {
210 res += GNSSENTRY_TYPEC1N;
211 }
212 }
[5370]213 else {
214 return -1;
215 }
216 }
217 else if (rnxStr[1] == '2') {
218 if (rnxStr.length() < 3) {
[5549]219 res += GNSSENTRY_TYPEC2;
[5370]220 }
[5371]221 else if (QString("PWY").indexOf(rnxStr[2]) != -1) {
[5370]222 res += GNSSENTRY_TYPEP2;
223 }
[5371]224 else if (QString("CSLX").indexOf(rnxStr[2]) != -1) {
[5370]225 res += GNSSENTRY_TYPEC2;
226 }
[5375]227 else if (rnxStr[2] == 'I') {
228 if (satSys == 'C') {
229 res += GNSSENTRY_TYPEC1; // Compass: RINEX 3.01 "2I" corresponds to "1I" RINEX 3.02
230 }
231 else {
232 res += GNSSENTRY_TYPEC2;
233 }
234 }
235 else if (rnxStr[2] == 'Q') {
[5374]236 res += GNSSENTRY_TYPEC2;
[5368]237 }
[5370]238 else {
239 return -1;
240 }
241 }
242 else if (rnxStr[1] == '5') {
[5368]243 res += GNSSENTRY_TYPEC5;
[5370]244 }
245 else if (rnxStr[1] == '6') {
[5368]246 res += GNSSENTRY_TYPEC6;
[5370]247 }
248 else if (rnxStr[1] == '7') {
[5368]249 res += GNSSENTRY_TYPEC5B;
[5370]250 }
251 else if (rnxStr[1] == '8') {
[5368]252 res += GNSSENTRY_TYPEC5AB;
[5355]253 }
[5370]254 else {
255 return -1;
256 }
257
[5551]258 /* Note: We prefer P over C for Lx or Sx (i.e. we first try for P values) */
259 if(_codetype[res].isEmpty() && tryagain)
260 res = iEntry(rnxStrOrig, rnxVers, true);
261
[5368]262 return res;
[4392]263}
Note: See TracBrowser for help on using the repository browser.