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

Last change on this file since 6018 was 5884, checked in by mervart, 10 years ago
File size: 7.0 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: 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"
46#include "bncrinex.h"
47
48extern "C" {
49#include "rtcm3torinex.h"
50}
51
52using namespace std;
53
54// Constructor
55//////////////////////////////////////////////////////////////////////////////
56GPSDecoder::GPSDecoder() {
57 _rnx = 0;
58}
59
60// Destructor
61//////////////////////////////////////////////////////////////////////////////
62GPSDecoder::~GPSDecoder() {
63 delete _rnx;
64}
65
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 }
75 bncSettings settings;
76 if ( !settings.value("rnxPath").toString().isEmpty() ) {
77 _rnx = new bncRinex(staID, mountPoint, latitude, longitude,
78 nmea, ntripVersion);
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}
102
103//
104//////////////////////////////////////////////////////////////////////////////
105void t_obs::setMeasdata(QString rnxStr, float rnxVers, double value) {
106 int ie = iEntry(rnxStr, rnxVers);
107
108 if (ie != -1) {
109 _codetype[ie] = rnxStr.mid(1);
110 _measdata[ie] = value;
111 }
112}
113
114//
115//////////////////////////////////////////////////////////////////////////////
116double t_obs::measdata(QString rnxStr, float rnxVers) const {
117 int ie = iEntry(rnxStr, rnxVers);
118
119 if (ie != -1) {
120 return _measdata[ie];
121 }
122
123 return 0.0;
124}
125
126//
127//////////////////////////////////////////////////////////////////////////////
128QString t_obs::rnxStr(int iEntry) const {
129 QString str(1,' ');
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//////////////////////////////////////////////////////////////////////////////
142int t_obs::iEntry(QString rnxStr, float rnxVers, bool cmode) const {
143
144 int res = 0;
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 }
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 {
184 return -1;
185 }
186
187 // Frequency
188 // ---------
189 if (rnxStr[1] == '1') {
190 if (rnxStr.length() < 3) {
191 res += GNSSENTRY_TYPEC1;
192 }
193 else if (QString("ABCIQ").indexOf(rnxStr[2]) != -1) {
194 res += GNSSENTRY_TYPEC1;
195 }
196 else if (QString("SL").indexOf(rnxStr[2]) != -1) {
197 res += GNSSENTRY_TYPEC1N;
198 }
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 }
205 else if (rnxStr[2] == 'X') {
206 if (satSys == 'C' || satSys == 'E') {
207 res += GNSSENTRY_TYPEC1;
208 }
209 else {
210 res += GNSSENTRY_TYPEC1N;
211 }
212 }
213 else {
214 return -1;
215 }
216 }
217 else if (rnxStr[1] == '2') {
218 if (rnxStr.length() < 3) {
219 res += GNSSENTRY_TYPEC2;
220 }
221 else if (QString("PWY").indexOf(rnxStr[2]) != -1) {
222 res += GNSSENTRY_TYPEP2;
223 }
224 else if (QString("CSLX").indexOf(rnxStr[2]) != -1) {
225 res += GNSSENTRY_TYPEC2;
226 }
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') {
236 res += GNSSENTRY_TYPEC2;
237 }
238 else {
239 return -1;
240 }
241 }
242 else if (rnxStr[1] == '5') {
243 res += GNSSENTRY_TYPEC5;
244 }
245 else if (rnxStr[1] == '6') {
246 res += GNSSENTRY_TYPEC6;
247 }
248 else if (rnxStr[1] == '7') {
249 res += GNSSENTRY_TYPEC5B;
250 }
251 else if (rnxStr[1] == '8') {
252 res += GNSSENTRY_TYPEC5AB;
253 }
254 else {
255 return -1;
256 }
257
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
262 return res;
263}
Note: See TracBrowser for help on using the repository browser.