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

Last change on this file since 7847 was 7847, checked in by stuerze, 8 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
RevLine 
[2904]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 *
[7716]36 * Changes:
[2904]37 *
38 * -----------------------------------------------------------------------*/
39
[2907]40#include <iostream>
41
[2904]42#include "bncephuser.h"
[5070]43#include "bnccore.h"
[2904]44
45using namespace std;
46
47// Constructor
48////////////////////////////////////////////////////////////////////////////
[3640]49bncEphUser::bncEphUser(bool connectSlots) {
50 if (connectSlots) {
[6434]51 connect(BNC_CORE, SIGNAL(newGPSEph(t_ephGPS)),
52 this, SLOT(slotNewGPSEph(t_ephGPS)), Qt::DirectConnection);
[7716]53
[6434]54 connect(BNC_CORE, SIGNAL(newGlonassEph(t_ephGlo)),
55 this, SLOT(slotNewGlonassEph(t_ephGlo)), Qt::DirectConnection);
[7716]56
[6434]57 connect(BNC_CORE, SIGNAL(newGalileoEph(t_ephGal)),
58 this, SLOT(slotNewGalileoEph(t_ephGal)), Qt::DirectConnection);
[6393]59
[6434]60 connect(BNC_CORE, SIGNAL(newSBASEph(t_ephSBAS)),
61 this, SLOT(slotNewSBASEph(t_ephSBAS)), Qt::DirectConnection);
[6595]62
[6598]63 connect(BNC_CORE, SIGNAL(newBDSEph(t_ephBDS)),
64 this, SLOT(slotNewBDSEph(t_ephBDS)), Qt::DirectConnection);
[3640]65 }
[2904]66}
67
68// Destructor
69////////////////////////////////////////////////////////////////////////////
70bncEphUser::~bncEphUser() {
[6443]71 QMapIterator<QString, deque<t_eph*> > it(_eph);
[2904]72 while (it.hasNext()) {
73 it.next();
[6443]74 const deque<t_eph*>& qq = it.value();
75 for (unsigned ii = 0; ii < qq.size(); ii++) {
76 delete qq[ii];
77 }
[2904]78 }
79}
80
[7716]81// New GPS Ephemeris
[2904]82////////////////////////////////////////////////////////////////////////////
[6432]83void bncEphUser::slotNewGPSEph(t_ephGPS eph) {
[6444]84 putNewEph(&eph, false);
[6394]85}
[7716]86
[6432]87// New Glonass Ephemeris
[6394]88////////////////////////////////////////////////////////////////////////////
[6432]89void bncEphUser::slotNewGlonassEph(t_ephGlo eph) {
[6444]90 putNewEph(&eph, false);
[6394]91}
[5133]92
[6432]93// New Galileo Ephemeris
[6394]94////////////////////////////////////////////////////////////////////////////
[6432]95void bncEphUser::slotNewGalileoEph(t_ephGal eph) {
[6444]96 putNewEph(&eph, false);
[2904]97}
98
[6432]99// New SBAS Ephemeris
[2904]100////////////////////////////////////////////////////////////////////////////
[6432]101void bncEphUser::slotNewSBASEph(t_ephSBAS eph) {
[6444]102 putNewEph(&eph, false);
[2904]103}
104
[6598]105// New BDS Ephemeris
[6595]106////////////////////////////////////////////////////////////////////////////
[6598]107void bncEphUser::slotNewBDSEph(t_ephBDS eph) {
[6595]108 putNewEph(&eph, false);
109}
110
[7716]111//
[2904]112////////////////////////////////////////////////////////////////////////////
[6519]113t_irc bncEphUser::putNewEph(t_eph* eph, bool check) {
[6435]114
[3670]115 QMutexLocker locker(&_mutex);
116
[6435]117 if (eph == 0) {
118 return failure;
119 }
[6395]120
[6518]121 if (check) {
122 checkEphemeris(eph);
123 }
124
[6435]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);
[6598]129 const t_ephBDS* ephBDS = dynamic_cast<const t_ephBDS*>(eph);
[6435]130
131 t_eph* newEph = 0;
132
133 if (ephGPS) {
134 newEph = new t_ephGPS(*ephGPS);
[3670]135 }
[6435]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 }
[6598]145 else if (ephBDS) {
146 newEph = new t_ephBDS(*ephBDS);
[6435]147 }
148 else {
149 return failure;
150 }
[3670]151
[6809]152 QString prn(newEph->prn().toInternalString().c_str());
[6435]153
[6443]154 const t_eph* ephOld = ephLast(prn);
155
[7208]156 if (ephOld &&
157 (ephOld->checkState() == t_eph::bad ||
158 ephOld->checkState() == t_eph::outdated)) {
[6981]159 ephOld = 0;
160 }
[7716]161
[6981]162 if ((ephOld == 0 || newEph->isNewerThan(ephOld)) &&
[7208]163 (eph->checkState() != t_eph::bad ||
164 eph->checkState() != t_eph::outdated)) {
[6443]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();
[3670]170 }
[6395]171 ephBufferChanged();
[6435]172 return success;
[3670]173 }
[6443]174 else {
[6566]175 delete newEph;
[6443]176 return failure;
177 }
[6395]178}
[3671]179
[7716]180//
[6518]181////////////////////////////////////////////////////////////////////////////
[6519]182void bncEphUser::checkEphemeris(t_eph* eph) {
[6518]183
[6519]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
[6521]199 const double MINDIST = 2.e7;
[6526]200 const double MAXDIST = 6.e7;
[6521]201 if (rr < MINDIST || rr > MAXDIST) {
[6519]202 eph->setCheckState(t_eph::bad);
203 return;
204 }
[6520]205
[6981]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) {
[7041]214 if (timeDiff > 4*3600) { // update interval: 2h, data sets are valid for 4 hours
[7208]215 eph->setCheckState(t_eph::outdated);
[6981]216 return;
217 }
218 }
219 else if (eph->type() == t_eph::GLONASS) {
220 if (timeDiff > 1*3600) { // updated every 30 minutes
[7208]221 eph->setCheckState(t_eph::outdated);
[6981]222 return;
223 }
224 }
225 else if (eph->type() == t_eph::QZSS) {
[7847]226 if (timeDiff > 4*3600) { // orbit parameters are valid for 7200 seconds (at minimum)
[7208]227 eph->setCheckState(t_eph::outdated);
[6981]228 return;
229 }
230 }
231 else if (eph->type() == t_eph::SBAS) {
[7041]232 if (timeDiff > 600) { // maximum update interval: 300 sec
[7208]233 eph->setCheckState(t_eph::outdated);
[6981]234 return;
235 }
236 }
237 else if (eph->type() == t_eph::BDS) {
238 if (timeDiff > 6*3600) { // updates 1 (GEO) up to 6 hours
[7208]239 eph->setCheckState(t_eph::outdated);
[6981]240 return;
241 }
242 }
243
244
[6521]245 // Check consistency with older ephemerides
246 // ----------------------------------------
[6526]247 const double MAXDIFF = 1000.0;
[6809]248 QString prn = QString(eph->prn().toInternalString().c_str());
[6521]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
[6981]258 // some lines to allow update of ephemeris data sets after outage
[7847]259 if (eph->type() == t_eph::GPS && dt > 4*3600) {
[7208]260 ephL->setCheckState(t_eph::outdated);
[6981]261 return;
262 }
[7716]263 else if (eph->type() == t_eph::Galileo && dt > 4*3600) {
[7208]264 ephL->setCheckState(t_eph::outdated);
[6981]265 return;
266 }
[7716]267 else if (eph->type() == t_eph::GLONASS && dt > 1*3600) {
[7208]268 ephL->setCheckState(t_eph::outdated);
[6981]269 return;
270 }
[7847]271 else if (eph->type() == t_eph::QZSS && dt > 4*3600) {
[7208]272 ephL->setCheckState(t_eph::outdated);
[6981]273 return;
274 }
[7847]275 else if (eph->type() == t_eph::SBAS && dt > 600) {
[7716]276 ephL->setCheckState(t_eph::outdated);
277 return;
278 }
[7847]279 else if (eph->type() == t_eph::BDS && dt > 6*3600) {
[7716]280 ephL->setCheckState(t_eph::outdated);
281 return;
282 }
[6981]283
[6521]284 if (diff < MAXDIFF) {
[6981]285 if (dt != 0.0) {
[6521]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 }
[6518]296}
Note: See TracBrowser for help on using the repository browser.