source: ntrip/trunk/BNC/src/bncephuser.cpp@ 7847

Last change on this file since 7847 was 7847, checked in by stuerze, 6 years ago

QZSS ephemeris time of validity is extended because it is encoded together with GPS ephemerides and the validity for QZSS orbit parameters is 7200 second at minimum

File size: 8.3 KB
Line 
1// converting GNSS data streams from NTRIP broadcasters.
2//
3// Copyright (C) 2007
4// German Federal Agency for Cartography and Geodesy (BKG)
5// http://www.bkg.bund.de
6// Czech Technical University Prague, Department of Geodesy
7// http://www.fsv.cvut.cz
8//
9// Email: euref-ip@bkg.bund.de
10//
11// This program is free software; you can redistribute it and/or
12// modify it under the terms of the GNU General Public License
13// as published by the Free Software Foundation, version 2.
14//
15// This program is distributed in the hope that it will be useful,
16// but WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with this program; if not, write to the Free Software
22// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24/* -------------------------------------------------------------------------
25 * BKG NTRIP Client
26 * -------------------------------------------------------------------------
27 *
28 * Class: bncEphUser
29 *
30 * Purpose: Base for Classes that use Ephemerides
31 *
32 * Author: L. Mervart
33 *
34 * Created: 27-Jan-2011
35 *
36 * Changes:
37 *
38 * -----------------------------------------------------------------------*/
39
40#include <iostream>
41
42#include "bncephuser.h"
43#include "bnccore.h"
44
45using namespace std;
46
47// Constructor
48////////////////////////////////////////////////////////////////////////////
49bncEphUser::bncEphUser(bool connectSlots) {
50 if (connectSlots) {
51 connect(BNC_CORE, SIGNAL(newGPSEph(t_ephGPS)),
52 this, SLOT(slotNewGPSEph(t_ephGPS)), Qt::DirectConnection);
53
54 connect(BNC_CORE, SIGNAL(newGlonassEph(t_ephGlo)),
55 this, SLOT(slotNewGlonassEph(t_ephGlo)), Qt::DirectConnection);
56
57 connect(BNC_CORE, SIGNAL(newGalileoEph(t_ephGal)),
58 this, SLOT(slotNewGalileoEph(t_ephGal)), Qt::DirectConnection);
59
60 connect(BNC_CORE, SIGNAL(newSBASEph(t_ephSBAS)),
61 this, SLOT(slotNewSBASEph(t_ephSBAS)), Qt::DirectConnection);
62
63 connect(BNC_CORE, SIGNAL(newBDSEph(t_ephBDS)),
64 this, SLOT(slotNewBDSEph(t_ephBDS)), Qt::DirectConnection);
65 }
66}
67
68// Destructor
69////////////////////////////////////////////////////////////////////////////
70bncEphUser::~bncEphUser() {
71 QMapIterator<QString, deque<t_eph*> > it(_eph);
72 while (it.hasNext()) {
73 it.next();
74 const deque<t_eph*>& qq = it.value();
75 for (unsigned ii = 0; ii < qq.size(); ii++) {
76 delete qq[ii];
77 }
78 }
79}
80
81// New GPS Ephemeris
82////////////////////////////////////////////////////////////////////////////
83void bncEphUser::slotNewGPSEph(t_ephGPS eph) {
84 putNewEph(&eph, false);
85}
86
87// New Glonass Ephemeris
88////////////////////////////////////////////////////////////////////////////
89void bncEphUser::slotNewGlonassEph(t_ephGlo eph) {
90 putNewEph(&eph, false);
91}
92
93// New Galileo Ephemeris
94////////////////////////////////////////////////////////////////////////////
95void bncEphUser::slotNewGalileoEph(t_ephGal eph) {
96 putNewEph(&eph, false);
97}
98
99// New SBAS Ephemeris
100////////////////////////////////////////////////////////////////////////////
101void bncEphUser::slotNewSBASEph(t_ephSBAS eph) {
102 putNewEph(&eph, false);
103}
104
105// New BDS Ephemeris
106////////////////////////////////////////////////////////////////////////////
107void bncEphUser::slotNewBDSEph(t_ephBDS eph) {
108 putNewEph(&eph, false);
109}
110
111//
112////////////////////////////////////////////////////////////////////////////
113t_irc bncEphUser::putNewEph(t_eph* eph, bool check) {
114
115 QMutexLocker locker(&_mutex);
116
117 if (eph == 0) {
118 return failure;
119 }
120
121 if (check) {
122 checkEphemeris(eph);
123 }
124
125 const t_ephGPS* ephGPS = dynamic_cast<const t_ephGPS*>(eph);
126 const t_ephGlo* ephGlo = dynamic_cast<const t_ephGlo*>(eph);
127 const t_ephGal* ephGal = dynamic_cast<const t_ephGal*>(eph);
128 const t_ephSBAS* ephSBAS = dynamic_cast<const t_ephSBAS*>(eph);
129 const t_ephBDS* ephBDS = dynamic_cast<const t_ephBDS*>(eph);
130
131 t_eph* newEph = 0;
132
133 if (ephGPS) {
134 newEph = new t_ephGPS(*ephGPS);
135 }
136 else if (ephGlo) {
137 newEph = new t_ephGlo(*ephGlo);
138 }
139 else if (ephGal) {
140 newEph = new t_ephGal(*ephGal);
141 }
142 else if (ephSBAS) {
143 newEph = new t_ephSBAS(*ephSBAS);
144 }
145 else if (ephBDS) {
146 newEph = new t_ephBDS(*ephBDS);
147 }
148 else {
149 return failure;
150 }
151
152 QString prn(newEph->prn().toInternalString().c_str());
153
154 const t_eph* ephOld = ephLast(prn);
155
156 if (ephOld &&
157 (ephOld->checkState() == t_eph::bad ||
158 ephOld->checkState() == t_eph::outdated)) {
159 ephOld = 0;
160 }
161
162 if ((ephOld == 0 || newEph->isNewerThan(ephOld)) &&
163 (eph->checkState() != t_eph::bad ||
164 eph->checkState() != t_eph::outdated)) {
165 deque<t_eph*>& qq = _eph[prn];
166 qq.push_back(newEph);
167 if (qq.size() > _maxQueueSize) {
168 delete qq.front();
169 qq.pop_front();
170 }
171 ephBufferChanged();
172 return success;
173 }
174 else {
175 delete newEph;
176 return failure;
177 }
178}
179
180//
181////////////////////////////////////////////////////////////////////////////
182void bncEphUser::checkEphemeris(t_eph* eph) {
183
184 if (!eph || eph->checkState() == t_eph::ok || eph->checkState() == t_eph::bad) {
185 return;
186 }
187
188 // Simple Check - check satellite radial distance
189 // ----------------------------------------------
190 ColumnVector xc(4);
191 ColumnVector vv(3);
192 if (eph->getCrd(eph->TOC(), xc, vv, false) != success) {
193 eph->setCheckState(t_eph::bad);
194 return;
195 }
196
197 double rr = xc.Rows(1,3).norm_Frobenius();
198
199 const double MINDIST = 2.e7;
200 const double MAXDIST = 6.e7;
201 if (rr < MINDIST || rr > MAXDIST) {
202 eph->setCheckState(t_eph::bad);
203 return;
204 }
205
206 // Check whether the epoch is too far away the current time
207 // --------------------------------------------------------
208 bncTime toc = eph->TOC();
209 QDateTime now = currentDateAndTimeGPS();
210 bncTime currentTime(now.toString(Qt::ISODate).toStdString());
211 double timeDiff = fabs(toc - currentTime);
212
213 if (eph->type() == t_eph::GPS || t_eph::Galileo) {
214 if (timeDiff > 4*3600) { // update interval: 2h, data sets are valid for 4 hours
215 eph->setCheckState(t_eph::outdated);
216 return;
217 }
218 }
219 else if (eph->type() == t_eph::GLONASS) {
220 if (timeDiff > 1*3600) { // updated every 30 minutes
221 eph->setCheckState(t_eph::outdated);
222 return;
223 }
224 }
225 else if (eph->type() == t_eph::QZSS) {
226 if (timeDiff > 4*3600) { // orbit parameters are valid for 7200 seconds (at minimum)
227 eph->setCheckState(t_eph::outdated);
228 return;
229 }
230 }
231 else if (eph->type() == t_eph::SBAS) {
232 if (timeDiff > 600) { // maximum update interval: 300 sec
233 eph->setCheckState(t_eph::outdated);
234 return;
235 }
236 }
237 else if (eph->type() == t_eph::BDS) {
238 if (timeDiff > 6*3600) { // updates 1 (GEO) up to 6 hours
239 eph->setCheckState(t_eph::outdated);
240 return;
241 }
242 }
243
244
245 // Check consistency with older ephemerides
246 // ----------------------------------------
247 const double MAXDIFF = 1000.0;
248 QString prn = QString(eph->prn().toInternalString().c_str());
249 t_eph* ephL = ephLast(prn);
250 if (ephL) {
251 ColumnVector xcL(4);
252 ColumnVector vvL(3);
253 ephL->getCrd(eph->TOC(), xcL, vvL, false);
254
255 double dt = eph->TOC() - ephL->TOC();
256 double diff = (xc.Rows(1,3) - xcL.Rows(1,3)).norm_Frobenius();
257
258 // some lines to allow update of ephemeris data sets after outage
259 if (eph->type() == t_eph::GPS && dt > 4*3600) {
260 ephL->setCheckState(t_eph::outdated);
261 return;
262 }
263 else if (eph->type() == t_eph::Galileo && dt > 4*3600) {
264 ephL->setCheckState(t_eph::outdated);
265 return;
266 }
267 else if (eph->type() == t_eph::GLONASS && dt > 1*3600) {
268 ephL->setCheckState(t_eph::outdated);
269 return;
270 }
271 else if (eph->type() == t_eph::QZSS && dt > 4*3600) {
272 ephL->setCheckState(t_eph::outdated);
273 return;
274 }
275 else if (eph->type() == t_eph::SBAS && dt > 600) {
276 ephL->setCheckState(t_eph::outdated);
277 return;
278 }
279 else if (eph->type() == t_eph::BDS && dt > 6*3600) {
280 ephL->setCheckState(t_eph::outdated);
281 return;
282 }
283
284 if (diff < MAXDIFF) {
285 if (dt != 0.0) {
286 eph->setCheckState(t_eph::ok);
287 ephL->setCheckState(t_eph::ok);
288 }
289 }
290 else {
291 if (ephL->checkState() == t_eph::ok) {
292 eph->setCheckState(t_eph::bad);
293 }
294 }
295 }
296}
Note: See TracBrowser for help on using the repository browser.