| [1025] | 1 | #include <sstream>
|
|---|
| [2234] | 2 | #include <iostream>
|
|---|
| [1025] | 3 | #include <iomanip>
|
|---|
| [1239] | 4 | #include <cstring>
|
|---|
| [1025] | 5 |
|
|---|
| [2234] | 6 | #include <newmatio.h>
|
|---|
| 7 |
|
|---|
| [1025] | 8 | #include "ephemeris.h"
|
|---|
| [2221] | 9 | #include "bncutils.h"
|
|---|
| [2285] | 10 | #include "bnctime.h"
|
|---|
| [5070] | 11 | #include "bnccore.h"
|
|---|
| [5839] | 12 | #include "bncutils.h"
|
|---|
| [6141] | 13 | #include "satObs.h"
|
|---|
| [6044] | 14 | #include "pppInclude.h"
|
|---|
| [6400] | 15 | #include "pppModel.h"
|
|---|
| [10533] | 16 | #include "RTCM3/bits.h"
|
|---|
| [1025] | 17 |
|
|---|
| 18 | using namespace std;
|
|---|
| 19 |
|
|---|
| [5749] | 20 | // Constructor
|
|---|
| 21 | ////////////////////////////////////////////////////////////////////////////
|
|---|
| 22 | t_eph::t_eph() {
|
|---|
| [6518] | 23 | _checkState = unchecked;
|
|---|
| [10587] | 24 | _type = undefined;
|
|---|
| [10577] | 25 | _orbCorr = 0;
|
|---|
| 26 | _clkCorr = 0;
|
|---|
| [5749] | 27 | }
|
|---|
| [7278] | 28 | // Destructor
|
|---|
| 29 | ////////////////////////////////////////////////////////////////////////////
|
|---|
| 30 | t_eph::~t_eph() {
|
|---|
| 31 | if (_orbCorr)
|
|---|
| 32 | delete _orbCorr;
|
|---|
| 33 | if (_clkCorr)
|
|---|
| 34 | delete _clkCorr;
|
|---|
| 35 | }
|
|---|
| [5749] | 36 |
|
|---|
| [7481] | 37 | //
|
|---|
| [5749] | 38 | ////////////////////////////////////////////////////////////////////////////
|
|---|
| [10577] | 39 | void t_eph::setOrbCorr(const t_orbCorr *orbCorr) {
|
|---|
| [7888] | 40 | if (_orbCorr) {
|
|---|
| 41 | delete _orbCorr;
|
|---|
| 42 | _orbCorr = 0;
|
|---|
| 43 | }
|
|---|
| [6141] | 44 | _orbCorr = new t_orbCorr(*orbCorr);
|
|---|
| [5749] | 45 | }
|
|---|
| 46 |
|
|---|
| [7481] | 47 | //
|
|---|
| [5749] | 48 | ////////////////////////////////////////////////////////////////////////////
|
|---|
| [10577] | 49 | void t_eph::setClkCorr(const t_clkCorr *clkCorr) {
|
|---|
| [7888] | 50 | if (_clkCorr) {
|
|---|
| 51 | delete _clkCorr;
|
|---|
| 52 | _clkCorr = 0;
|
|---|
| 53 | }
|
|---|
| [6141] | 54 | _clkCorr = new t_clkCorr(*clkCorr);
|
|---|
| [5749] | 55 | }
|
|---|
| 56 |
|
|---|
| [7481] | 57 | //
|
|---|
| [5749] | 58 | ////////////////////////////////////////////////////////////////////////////
|
|---|
| [10577] | 59 | t_irc t_eph::getCrd(const bncTime &tt, ColumnVector &xc, ColumnVector &vv,
|
|---|
| 60 | bool useCorr) const {
|
|---|
| [6518] | 61 |
|
|---|
| [10628] | 62 | if (_checkState == bad ||
|
|---|
| 63 | _checkState == unhealthy ||
|
|---|
| 64 | _checkState == outdated) {
|
|---|
| [6518] | 65 | return failure;
|
|---|
| 66 | }
|
|---|
| [8903] | 67 |
|
|---|
| [8542] | 68 | xc.ReSize(6);
|
|---|
| [5749] | 69 | vv.ReSize(3);
|
|---|
| [6213] | 70 | if (position(tt.gpsw(), tt.gpssec(), xc.data(), vv.data()) != success) {
|
|---|
| 71 | return failure;
|
|---|
| 72 | }
|
|---|
| [5789] | 73 | if (useCorr) {
|
|---|
| [5839] | 74 | if (_orbCorr && _clkCorr) {
|
|---|
| [10954] | 75 | // Refuse to extrapolate a correction far beyond its own declared
|
|---|
| 76 | // update interval - without this, a single missed/dropped
|
|---|
| 77 | // correction message (network blip, encoder hiccup, ...) gets
|
|---|
| 78 | // extrapolated via its rate term (_dotXr/_dotDClk) forever, with no
|
|---|
| 79 | // warning, producing an unbounded, silently growing position error.
|
|---|
| 80 | // ----------------------------------------------------------------
|
|---|
| 81 | // _updateInt defaults to 0 (1s) when not explicitly set by the
|
|---|
| 82 | // source stream, so a pure multiple of it would be far too strict -
|
|---|
| 83 | // floor it at MIN_STALE_BOUND so normal, slightly slower-than-1Hz
|
|---|
| 84 | // streams are not falsely flagged.
|
|---|
| 85 | const double MAX_STALE_FACTOR = 3.0;
|
|---|
| 86 | const double MIN_STALE_BOUND = 60.0; // [s]
|
|---|
| 87 | double maxAgeO = max(MIN_STALE_BOUND, MAX_STALE_FACTOR * ssrUpdateInt[_orbCorr->_updateInt]);
|
|---|
| 88 | double maxAgeC = max(MIN_STALE_BOUND, MAX_STALE_FACTOR * ssrUpdateInt[_clkCorr->_updateInt]);
|
|---|
| 89 | if (fabs(tt - _orbCorr->_time) > maxAgeO ||
|
|---|
| 90 | fabs(tt - _clkCorr->_time) > maxAgeC) {
|
|---|
| 91 | return failure;
|
|---|
| 92 | }
|
|---|
| 93 |
|
|---|
| [5849] | 94 | double dtO = tt - _orbCorr->_time;
|
|---|
| [6556] | 95 | if (_orbCorr->_updateInt) {
|
|---|
| [8903] | 96 | dtO -= (0.5 * ssrUpdateInt[_orbCorr->_updateInt]);
|
|---|
| [6556] | 97 | }
|
|---|
| [5839] | 98 | ColumnVector dx(3);
|
|---|
| [5849] | 99 | dx[0] = _orbCorr->_xr[0] + _orbCorr->_dotXr[0] * dtO;
|
|---|
| 100 | dx[1] = _orbCorr->_xr[1] + _orbCorr->_dotXr[1] * dtO;
|
|---|
| 101 | dx[2] = _orbCorr->_xr[2] + _orbCorr->_dotXr[2] * dtO;
|
|---|
| 102 |
|
|---|
| [10577] | 103 | RSW_to_XYZ(xc.Rows(1, 3), vv.Rows(1, 3), dx, dx);
|
|---|
| [5849] | 104 |
|
|---|
| [5839] | 105 | xc[0] -= dx[0];
|
|---|
| 106 | xc[1] -= dx[1];
|
|---|
| 107 | xc[2] -= dx[2];
|
|---|
| [5849] | 108 |
|
|---|
| [7133] | 109 | ColumnVector dv(3);
|
|---|
| [10577] | 110 | RSW_to_XYZ(xc.Rows(1, 3), vv.Rows(1, 3), _orbCorr->_dotXr, dv);
|
|---|
| [7133] | 111 |
|
|---|
| 112 | vv[0] -= dv[0];
|
|---|
| 113 | vv[1] -= dv[1];
|
|---|
| 114 | vv[2] -= dv[2];
|
|---|
| 115 |
|
|---|
| [5849] | 116 | double dtC = tt - _clkCorr->_time;
|
|---|
| [6556] | 117 | if (_clkCorr->_updateInt) {
|
|---|
| [8903] | 118 | dtC -= (0.5 * ssrUpdateInt[_clkCorr->_updateInt]);
|
|---|
| [6556] | 119 | }
|
|---|
| [10992] | 120 |
|
|---|
| 121 | xc[3] += _clkCorr->_dClk + _clkCorr->_dotDClk * dtC + _clkCorr->_dotDotDClk * dtC * dtC;
|
|---|
| [10577] | 122 | } else {
|
|---|
| [5839] | 123 | return failure;
|
|---|
| 124 | }
|
|---|
| [5749] | 125 | }
|
|---|
| 126 | return success;
|
|---|
| 127 | }
|
|---|
| 128 |
|
|---|
| [6801] | 129 | //
|
|---|
| 130 | //////////////////////////////////////////////////////////////////////////////
|
|---|
| [10603] | 131 | void t_eph::setType(QString typeStr) {
|
|---|
| 132 |
|
|---|
| 133 | if (typeStr == "LNAV") {
|
|---|
| 134 | _type = t_eph::LNAV;
|
|---|
| 135 | } else if (typeStr == "FDMA") {
|
|---|
| 136 | _type = t_eph::FDMA;
|
|---|
| 137 | } else if (typeStr == "FNAV") {
|
|---|
| 138 | _type = t_eph::FNAV;
|
|---|
| 139 | } else if (typeStr == "INAV") {
|
|---|
| 140 | _type = t_eph::INAV;
|
|---|
| 141 | } else if (typeStr == "D1") {
|
|---|
| 142 | _type = t_eph::D1;
|
|---|
| 143 | } else if (typeStr == "D2") {
|
|---|
| 144 | _type = t_eph::D2;
|
|---|
| 145 | } else if (typeStr == "SBAS") {
|
|---|
| 146 | _type = t_eph::SBASL1;
|
|---|
| 147 | } else if (typeStr == "CNAV") {
|
|---|
| 148 | _type = t_eph::CNAV;
|
|---|
| 149 | } else if (typeStr == "CNV1") {
|
|---|
| 150 | _type = t_eph::CNV1;
|
|---|
| 151 | } else if (typeStr == "CNV2") {
|
|---|
| 152 | _type = t_eph::CNV2;
|
|---|
| 153 | } else if (typeStr == "CNV3") {
|
|---|
| 154 | _type = t_eph::CNV3;
|
|---|
| 155 | } else if (typeStr == "L1NV") {
|
|---|
| 156 | _type = t_eph::L1NV;
|
|---|
| 157 | } else if (typeStr == "L1OC") {
|
|---|
| 158 | _type = t_eph::L1OC;
|
|---|
| 159 | } else if (typeStr == "L3OC") {
|
|---|
| 160 | _type = t_eph::L3OC;
|
|---|
| 161 | } else {
|
|---|
| 162 | _type = t_eph::undefined;
|
|---|
| 163 | }
|
|---|
| 164 |
|
|---|
| 165 | }
|
|---|
| 166 |
|
|---|
| 167 |
|
|---|
| 168 | //
|
|---|
| 169 | //////////////////////////////////////////////////////////////////////////////
|
|---|
| [10587] | 170 | QString t_eph::typeStr(e_type type, const t_prn &prn, double version) {
|
|---|
| 171 | QString typeStr = "";
|
|---|
| [10577] | 172 | QString epochStart;
|
|---|
| 173 | QString eolStr;
|
|---|
| [9765] | 174 |
|
|---|
| [10577] | 175 | if (version < 4.0) {
|
|---|
| [10587] | 176 | return typeStr;
|
|---|
| [10577] | 177 | }
|
|---|
| [9765] | 178 |
|
|---|
| [10587] | 179 | if (version == 99.0) { // log output for OUTDATED, WRONG or UNHEALTHY satellites
|
|---|
| [10577] | 180 | epochStart = "";
|
|---|
| 181 | eolStr = "";
|
|---|
| 182 | } else {
|
|---|
| 183 | epochStart = "> ";
|
|---|
| 184 | eolStr = "\n";
|
|---|
| 185 | }
|
|---|
| [9765] | 186 |
|
|---|
| [10577] | 187 | QString ephStr = QString("EPH %1 ").arg(prn.toString().c_str());
|
|---|
| [10587] | 188 | switch (type) {
|
|---|
| [10577] | 189 | case undefined:
|
|---|
| [10587] | 190 | typeStr = epochStart + ephStr + "unknown" + eolStr;
|
|---|
| [10577] | 191 | break;
|
|---|
| 192 | case LNAV:
|
|---|
| [10587] | 193 | typeStr = epochStart + ephStr + "LNAV" + eolStr;
|
|---|
| [10577] | 194 | break;
|
|---|
| 195 | case FDMA:
|
|---|
| [10599] | 196 | case FDMA_M:
|
|---|
| [10587] | 197 | typeStr = epochStart + ephStr + "FDMA" + eolStr;
|
|---|
| [10577] | 198 | break;
|
|---|
| 199 | case FNAV:
|
|---|
| [10587] | 200 | typeStr = epochStart + ephStr + "FNAV" + eolStr;
|
|---|
| [10577] | 201 | break;
|
|---|
| [10587] | 202 | case INAV:
|
|---|
| 203 | typeStr = epochStart + ephStr + "INAV" + eolStr;
|
|---|
| [10577] | 204 | break;
|
|---|
| 205 | case D1:
|
|---|
| [10587] | 206 | typeStr = epochStart + ephStr + "D1 " + eolStr;
|
|---|
| [10577] | 207 | break;
|
|---|
| 208 | case D2:
|
|---|
| [10587] | 209 | typeStr = epochStart + ephStr + "D2 " + eolStr;
|
|---|
| [10577] | 210 | break;
|
|---|
| 211 | case SBASL1:
|
|---|
| [10587] | 212 | typeStr = epochStart + ephStr + "SBAS" + eolStr;
|
|---|
| [10577] | 213 | break;
|
|---|
| 214 | case CNAV:
|
|---|
| [10587] | 215 | typeStr = epochStart + ephStr + "CNAV" + eolStr;
|
|---|
| [10577] | 216 | break;
|
|---|
| 217 | case CNV1:
|
|---|
| [10587] | 218 | typeStr = epochStart + ephStr + "CNV1" + eolStr;
|
|---|
| [10577] | 219 | break;
|
|---|
| 220 | case CNV2:
|
|---|
| [10587] | 221 | typeStr = epochStart + ephStr + "CNV2" + eolStr;
|
|---|
| [10577] | 222 | break;
|
|---|
| 223 | case CNV3:
|
|---|
| [10587] | 224 | typeStr = epochStart + ephStr + "CNV3" + eolStr;
|
|---|
| [10577] | 225 | break;
|
|---|
| 226 | case L1NV:
|
|---|
| [10587] | 227 | typeStr = epochStart + ephStr + "L1NV" + eolStr;
|
|---|
| [10577] | 228 | break;
|
|---|
| 229 | case L1OC:
|
|---|
| [10587] | 230 | typeStr = epochStart + ephStr + "L1OC" + eolStr;
|
|---|
| [10577] | 231 | break;
|
|---|
| 232 | case L3OC:
|
|---|
| [10587] | 233 | typeStr = epochStart + ephStr + "L3OC" + eolStr;
|
|---|
| [10577] | 234 | break;
|
|---|
| [9765] | 235 | }
|
|---|
| [10587] | 236 | return typeStr;
|
|---|
| [10577] | 237 | }
|
|---|
| [9765] | 238 |
|
|---|
| 239 | //
|
|---|
| 240 | //////////////////////////////////////////////////////////////////////////////
|
|---|
| [10577] | 241 | QString t_eph::rinexDateStr(const bncTime &tt, const t_prn &prn,
|
|---|
| 242 | double version) {
|
|---|
| [6801] | 243 | QString prnStr(prn.toString().c_str());
|
|---|
| 244 | return rinexDateStr(tt, prnStr, version);
|
|---|
| 245 | }
|
|---|
| 246 |
|
|---|
| 247 | //
|
|---|
| 248 | //////////////////////////////////////////////////////////////////////////////
|
|---|
| [10577] | 249 | QString t_eph::rinexDateStr(const bncTime &tt, const QString &prnStr,
|
|---|
| 250 | double version) {
|
|---|
| [6801] | 251 |
|
|---|
| 252 | QString datStr;
|
|---|
| 253 |
|
|---|
| 254 | unsigned year, month, day, hour, min;
|
|---|
| [10577] | 255 | double sec;
|
|---|
| [6801] | 256 | tt.civil_date(year, month, day);
|
|---|
| 257 | tt.civil_time(hour, min, sec);
|
|---|
| 258 |
|
|---|
| 259 | QTextStream out(&datStr);
|
|---|
| 260 |
|
|---|
| 261 | if (version < 3.0) {
|
|---|
| [10577] | 262 | QString prnHlp = prnStr.mid(1, 2);
|
|---|
| 263 | if (prnHlp[0] == '0')
|
|---|
| 264 | prnHlp[0] = ' ';
|
|---|
| 265 | out << prnHlp
|
|---|
| 266 | << QString(" %1 %2 %3 %4 %5%6").arg(year % 100, 2, 10, QChar('0')).arg(
|
|---|
| 267 | month, 2).arg(day, 2).arg(hour, 2).arg(min, 2).arg(sec, 5, 'f', 1);
|
|---|
| [10587] | 268 | }
|
|---|
| 269 | else if (version == 99) {
|
|---|
| [10577] | 270 | out
|
|---|
| 271 | << QString(" %1 %2 %3 %4 %5 %6").arg(year, 4).arg(month, 2, 10,
|
|---|
| 272 | QChar('0')).arg(day, 2, 10, QChar('0')).arg(hour, 2, 10, QChar('0')).arg(
|
|---|
| 273 | min, 2, 10, QChar('0')).arg(int(sec), 2, 10, QChar('0'));
|
|---|
| [10587] | 274 | }
|
|---|
| 275 | else {
|
|---|
| [10577] | 276 | out << prnStr
|
|---|
| 277 | << QString(" %1 %2 %3 %4 %5 %6").arg(year, 4).arg(month, 2, 10,
|
|---|
| 278 | QChar('0')).arg(day, 2, 10, QChar('0')).arg(hour, 2, 10, QChar('0')).arg(
|
|---|
| 279 | min, 2, 10, QChar('0')).arg(int(sec), 2, 10, QChar('0'));
|
|---|
| [6801] | 280 | }
|
|---|
| 281 |
|
|---|
| 282 | return datStr;
|
|---|
| 283 | }
|
|---|
| 284 |
|
|---|
| 285 | // Constructor
|
|---|
| 286 | //////////////////////////////////////////////////////////////////////////////
|
|---|
| [10603] | 287 | t_ephGPS::t_ephGPS(double rnxVersion, const QStringList &lines, QString typeStr) {
|
|---|
| [10614] | 288 |
|
|---|
| [10603] | 289 | setType(typeStr);
|
|---|
| [10614] | 290 |
|
|---|
| [10587] | 291 | int nLines = 8; // LNAV
|
|---|
| 292 | // Source RINEX version < 4
|
|---|
| 293 | if (type() == t_eph::undefined) {
|
|---|
| 294 | _type = t_eph::LNAV;
|
|---|
| 295 | }
|
|---|
| 296 |
|
|---|
| 297 | if (type() == t_eph::CNAV ||
|
|---|
| 298 | type() == t_eph::L1NV) {
|
|---|
| [9786] | 299 | nLines += 1;
|
|---|
| 300 | }
|
|---|
| [10587] | 301 | if (type() == t_eph::CNV2) {
|
|---|
| [9786] | 302 | nLines += 2;
|
|---|
| 303 | }
|
|---|
| 304 |
|
|---|
| [6801] | 305 | if (lines.size() != nLines) {
|
|---|
| 306 | _checkState = bad;
|
|---|
| 307 | return;
|
|---|
| 308 | }
|
|---|
| 309 |
|
|---|
| 310 | // RINEX Format
|
|---|
| 311 | // ------------
|
|---|
| 312 | int fieldLen = 19;
|
|---|
| [10587] | 313 | double statusflags = 0.0;
|
|---|
| [6801] | 314 |
|
|---|
| 315 | int pos[4];
|
|---|
| [10577] | 316 | pos[0] = (rnxVersion <= 2.12) ? 3 : 4;
|
|---|
| [6801] | 317 | pos[1] = pos[0] + fieldLen;
|
|---|
| 318 | pos[2] = pos[1] + fieldLen;
|
|---|
| 319 | pos[3] = pos[2] + fieldLen;
|
|---|
| 320 |
|
|---|
| [10587] | 321 | // Read nLines lines
|
|---|
| 322 | // ------------------
|
|---|
| [6801] | 323 | for (int iLine = 0; iLine < nLines; iLine++) {
|
|---|
| 324 | QString line = lines[iLine];
|
|---|
| 325 |
|
|---|
| [10577] | 326 | if (iLine == 0) {
|
|---|
| [8204] | 327 | QTextStream in(line.left(pos[1]).toLatin1());
|
|---|
| [10577] | 328 | int year, month, day, hour, min;
|
|---|
| [6801] | 329 | double sec;
|
|---|
| 330 |
|
|---|
| [7139] | 331 | QString prnStr, n;
|
|---|
| [6880] | 332 | in >> prnStr;
|
|---|
| [7639] | 333 |
|
|---|
| [10587] | 334 | if (prnStr.size() == 1 &&
|
|---|
| 335 | (prnStr[0] == 'G' ||
|
|---|
| 336 | prnStr[0] == 'J' ||
|
|---|
| 337 | prnStr[0] == 'I')) {
|
|---|
| [7139] | 338 | in >> n;
|
|---|
| 339 | prnStr.append(n);
|
|---|
| [6880] | 340 | }
|
|---|
| [7639] | 341 |
|
|---|
| [10587] | 342 | if ( prnStr.at(0) == 'G') {
|
|---|
| [6801] | 343 | _prn.set('G', prnStr.mid(1).toInt());
|
|---|
| [10577] | 344 | } else if (prnStr.at(0) == 'J') {
|
|---|
| [6801] | 345 | _prn.set('J', prnStr.mid(1).toInt());
|
|---|
| [10577] | 346 | } else if (prnStr.at(0) == 'I') {
|
|---|
| [8168] | 347 | _prn.set('I', prnStr.mid(1).toInt());
|
|---|
| [10577] | 348 | } else {
|
|---|
| [6801] | 349 | _prn.set('G', prnStr.toInt());
|
|---|
| 350 | }
|
|---|
| [10599] | 351 | _prn.setFlag(type());
|
|---|
| [6801] | 352 |
|
|---|
| [10599] | 353 | in >> year >> month >> day >> hour >> min >> sec;
|
|---|
| 354 |
|
|---|
| [10577] | 355 | if (year < 80) {
|
|---|
| [6801] | 356 | year += 2000;
|
|---|
| [10577] | 357 | } else if (year < 100) {
|
|---|
| [6801] | 358 | year += 1900;
|
|---|
| 359 | }
|
|---|
| 360 |
|
|---|
| 361 | _TOC.set(year, month, day, hour, min, sec);
|
|---|
| 362 |
|
|---|
| [10577] | 363 | if ( readDbl(line, pos[1], fieldLen, _clock_bias)
|
|---|
| 364 | || readDbl(line, pos[2], fieldLen, _clock_drift)
|
|---|
| 365 | || readDbl(line, pos[3], fieldLen, _clock_driftrate)) {
|
|---|
| [6801] | 366 | _checkState = bad;
|
|---|
| 367 | return;
|
|---|
| 368 | }
|
|---|
| 369 | }
|
|---|
| [9786] | 370 | // =====================
|
|---|
| 371 | // BROADCAST ORBIT - 1
|
|---|
| 372 | // =====================
|
|---|
| [10577] | 373 | else if (iLine == 1) {
|
|---|
| [10587] | 374 | if (type() == t_eph::CNAV ||
|
|---|
| 375 | type() == t_eph::CNV2 ||
|
|---|
| 376 | type() == t_eph::L1NV) {
|
|---|
| [10577] | 377 | if ( readDbl(line, pos[0], fieldLen, _ADOT)
|
|---|
| 378 | || readDbl(line, pos[1], fieldLen, _Crs)
|
|---|
| 379 | || readDbl(line, pos[2], fieldLen, _Delta_n)
|
|---|
| 380 | || readDbl(line, pos[3], fieldLen, _M0)) {
|
|---|
| [9786] | 381 | _checkState = bad;
|
|---|
| 382 | return;
|
|---|
| 383 | }
|
|---|
| [10587] | 384 | } else { // LNAV
|
|---|
| [10577] | 385 | if ( readDbl(line, pos[0], fieldLen, _IODE)
|
|---|
| 386 | || readDbl(line, pos[1], fieldLen, _Crs)
|
|---|
| 387 | || readDbl(line, pos[2], fieldLen, _Delta_n)
|
|---|
| 388 | || readDbl(line, pos[3], fieldLen, _M0)) {
|
|---|
| 389 | _checkState = bad;
|
|---|
| 390 | return;
|
|---|
| 391 | }
|
|---|
| [9786] | 392 | }
|
|---|
| [6801] | 393 | }
|
|---|
| [9786] | 394 | // =====================
|
|---|
| 395 | // BROADCAST ORBIT - 2
|
|---|
| 396 | // =====================
|
|---|
| [10577] | 397 | else if (iLine == 2) {
|
|---|
| 398 | if ( readDbl(line, pos[0], fieldLen, _Cuc)
|
|---|
| 399 | || readDbl(line, pos[1], fieldLen, _e)
|
|---|
| 400 | || readDbl(line, pos[2], fieldLen, _Cus)
|
|---|
| 401 | || readDbl(line, pos[3], fieldLen, _sqrt_A)) {
|
|---|
| [6801] | 402 | _checkState = bad;
|
|---|
| 403 | return;
|
|---|
| 404 | }
|
|---|
| 405 | }
|
|---|
| [9786] | 406 | // =====================
|
|---|
| 407 | // BROADCAST ORBIT - 3
|
|---|
| 408 | // =====================
|
|---|
| [10577] | 409 | else if (iLine == 3) {
|
|---|
| [10587] | 410 | if (type() == t_eph::CNAV ||
|
|---|
| 411 | type() == t_eph::CNV2) {
|
|---|
| [10577] | 412 | if ( readDbl(line, pos[0], fieldLen, _top)
|
|---|
| 413 | || readDbl(line, pos[1], fieldLen, _Cic)
|
|---|
| 414 | || readDbl(line, pos[2], fieldLen, _OMEGA0)
|
|---|
| 415 | || readDbl(line, pos[3], fieldLen, _Cis)) {
|
|---|
| [9786] | 416 | _checkState = bad;
|
|---|
| 417 | return;
|
|---|
| 418 | }
|
|---|
| [10587] | 419 | } else if (type() == t_eph::L1NV) {
|
|---|
| [10577] | 420 | if ( readDbl(line, pos[0], fieldLen, _IODE)
|
|---|
| 421 | || readDbl(line, pos[1], fieldLen, _Cic)
|
|---|
| 422 | || readDbl(line, pos[2], fieldLen, _OMEGA0)
|
|---|
| 423 | || readDbl(line, pos[3], fieldLen, _Cis)) {
|
|---|
| [9786] | 424 | _checkState = bad;
|
|---|
| 425 | return;
|
|---|
| 426 | }
|
|---|
| [10587] | 427 | } else { // LNAV
|
|---|
| [10577] | 428 | if ( readDbl(line, pos[0], fieldLen, _TOEsec)
|
|---|
| 429 | || readDbl(line, pos[1], fieldLen, _Cic)
|
|---|
| 430 | || readDbl(line, pos[2], fieldLen, _OMEGA0)
|
|---|
| 431 | || readDbl(line, pos[3], fieldLen, _Cis)) {
|
|---|
| 432 | _checkState = bad;
|
|---|
| 433 | return;
|
|---|
| 434 | }
|
|---|
| [9786] | 435 | }
|
|---|
| [6801] | 436 | }
|
|---|
| [9786] | 437 | // =====================
|
|---|
| 438 | // BROADCAST ORBIT - 4
|
|---|
| 439 | // =====================
|
|---|
| [10577] | 440 | else if (iLine == 4) {
|
|---|
| 441 | if ( readDbl(line, pos[0], fieldLen, _i0)
|
|---|
| 442 | || readDbl(line, pos[1], fieldLen, _Crc)
|
|---|
| 443 | || readDbl(line, pos[2], fieldLen, _omega)
|
|---|
| 444 | || readDbl(line, pos[3], fieldLen, _OMEGADOT)) {
|
|---|
| [6801] | 445 | _checkState = bad;
|
|---|
| 446 | return;
|
|---|
| 447 | }
|
|---|
| 448 | }
|
|---|
| [9786] | 449 | // =====================
|
|---|
| 450 | // BROADCAST ORBIT - 5
|
|---|
| 451 | // =====================
|
|---|
| [10619] | 452 | else if (iLine == 5 && system() != t_eph::NavIC) {
|
|---|
| [10587] | 453 | if (type() == t_eph::CNAV ||
|
|---|
| 454 | type() == t_eph::CNV2) {
|
|---|
| [10577] | 455 | if ( readDbl(line, pos[0], fieldLen, _IDOT)
|
|---|
| 456 | || readDbl(line, pos[1], fieldLen, _Delta_n_dot)
|
|---|
| 457 | || readDbl(line, pos[2], fieldLen, _URAI_NED0)
|
|---|
| 458 | || readDbl(line, pos[3], fieldLen, _URAI_NED1)) {
|
|---|
| [9786] | 459 | _checkState = bad;
|
|---|
| 460 | return;
|
|---|
| 461 | }
|
|---|
| [6801] | 462 | }
|
|---|
| [10587] | 463 | else { // LNAV
|
|---|
| [10577] | 464 | if ( readDbl(line, pos[0], fieldLen, _IDOT)
|
|---|
| 465 | || readDbl(line, pos[1], fieldLen, _L2Codes)
|
|---|
| 466 | || readDbl(line, pos[2], fieldLen, _TOEweek)
|
|---|
| 467 | || readDbl(line, pos[3], fieldLen, _L2PFlag)) {
|
|---|
| [9786] | 468 | _checkState = bad;
|
|---|
| 469 | return;
|
|---|
| 470 | }
|
|---|
| 471 | }
|
|---|
| [10619] | 472 | } else if (iLine == 5 && system() == t_eph::NavIC) {
|
|---|
| [10587] | 473 | if (type() == t_eph::LNAV) {
|
|---|
| [10577] | 474 | if ( readDbl(line, pos[0], fieldLen, _IDOT)
|
|---|
| 475 | || readDbl(line, pos[2], fieldLen, _TOEweek)) {
|
|---|
| 476 | _checkState = bad;
|
|---|
| 477 | return;
|
|---|
| 478 | }
|
|---|
| [8168] | 479 | }
|
|---|
| [10587] | 480 | else if (type() == t_eph::L1NV) {
|
|---|
| [10577] | 481 | if ( readDbl(line, pos[0], fieldLen, _IDOT)
|
|---|
| 482 | || readDbl(line, pos[1], fieldLen, _Delta_n_dot)
|
|---|
| 483 | || readDbl(line, pos[3], fieldLen, _RSF)) {
|
|---|
| 484 | _checkState = bad;
|
|---|
| 485 | return;
|
|---|
| 486 | }
|
|---|
| 487 | }
|
|---|
| [8168] | 488 | }
|
|---|
| [9786] | 489 | // =====================
|
|---|
| 490 | // BROADCAST ORBIT - 6
|
|---|
| 491 | // =====================
|
|---|
| [10619] | 492 | else if (iLine == 6 && system() != t_eph::NavIC) {
|
|---|
| [10587] | 493 | if (type() == t_eph::CNAV ||
|
|---|
| 494 | type() == t_eph::CNV2) {
|
|---|
| [10577] | 495 | if ( readDbl(line, pos[0], fieldLen, _URAI_ED)
|
|---|
| 496 | || readDbl(line, pos[1], fieldLen, _health)
|
|---|
| 497 | || readDbl(line, pos[2], fieldLen, _TGD)
|
|---|
| 498 | || readDbl(line, pos[3], fieldLen, _URAI_NED2)) {
|
|---|
| [9786] | 499 | _checkState = bad;
|
|---|
| 500 | return;
|
|---|
| 501 | }
|
|---|
| [10587] | 502 | } else { // LNAV
|
|---|
| [10577] | 503 | if ( readDbl(line, pos[0], fieldLen, _ura)
|
|---|
| 504 | || readDbl(line, pos[1], fieldLen, _health)
|
|---|
| 505 | || readDbl(line, pos[2], fieldLen, _TGD)
|
|---|
| 506 | || readDbl(line, pos[3], fieldLen, _IODC)) {
|
|---|
| [9786] | 507 | _checkState = bad;
|
|---|
| 508 | return;
|
|---|
| 509 | }
|
|---|
| 510 | }
|
|---|
| [6801] | 511 | }
|
|---|
| [10619] | 512 | else if (iLine == 6 && system() == t_eph::NavIC) {
|
|---|
| [10587] | 513 | if (type() == t_eph::LNAV) {
|
|---|
| [10577] | 514 | if ( readDbl(line, pos[0], fieldLen, _ura)
|
|---|
| 515 | || readDbl(line, pos[1], fieldLen, _health)
|
|---|
| 516 | || readDbl(line, pos[2], fieldLen, _TGD)) {
|
|---|
| 517 | _checkState = bad;
|
|---|
| 518 | return;
|
|---|
| 519 | }
|
|---|
| [8168] | 520 | }
|
|---|
| [10587] | 521 | else if (type() == t_eph::L1NV) {
|
|---|
| [10577] | 522 | int i = 0;
|
|---|
| 523 | (!_RSF) ? i = 2 : i = 3;
|
|---|
| 524 | if ( readDbl(line, pos[0], fieldLen, _URAI)
|
|---|
| 525 | || readDbl(line, pos[1], fieldLen, _health)
|
|---|
| 526 | || readDbl(line, pos[i], fieldLen, _TGD)) {
|
|---|
| 527 | _checkState = bad;
|
|---|
| 528 | return;
|
|---|
| 529 | }
|
|---|
| [10587] | 530 | _ura = accuracyFromIndex(int(_URAI), system());
|
|---|
| [10577] | 531 | }
|
|---|
| [8168] | 532 | }
|
|---|
| [9786] | 533 | // =====================
|
|---|
| 534 | // BROADCAST ORBIT - 7
|
|---|
| 535 | // =====================
|
|---|
| [10577] | 536 | else if (iLine == 7) {
|
|---|
| [10587] | 537 | if (type() == t_eph::LNAV) {
|
|---|
| [10577] | 538 | if (readDbl(line, pos[0], fieldLen, _TOT)) {
|
|---|
| [9786] | 539 | _checkState = bad;
|
|---|
| 540 | return;
|
|---|
| [10587] | 541 | }
|
|---|
| [10619] | 542 | if (system() != t_eph::NavIC) {
|
|---|
| [10587] | 543 | double fitIntervalRnx;
|
|---|
| 544 | if (readDbl(line, pos[1], fieldLen, fitIntervalRnx)) {
|
|---|
| 545 | //fit interval BLK, do nothing
|
|---|
| 546 | _flags_unknown = true;
|
|---|
| 547 | } else {
|
|---|
| 548 | _flags_unknown = false;
|
|---|
| 549 | if (system() == t_eph::GPS) { // in RINEX specified always as time period for GPS
|
|---|
| [9786] | 550 | _fitInterval = fitIntervalRnx;
|
|---|
| 551 | }
|
|---|
| [10587] | 552 | else if (system() == t_eph::QZSS) { // specified as flag for QZSS
|
|---|
| [10577] | 553 | if (rnxVersion == 3.02) {
|
|---|
| 554 | _fitInterval = fitIntervalRnx; // specified as time period
|
|---|
| 555 | } else {
|
|---|
| 556 | _fitInterval = fitIntervalFromFlag(fitIntervalRnx, _IODC, t_eph::QZSS);
|
|---|
| 557 | }
|
|---|
| [9786] | 558 | }
|
|---|
| [8934] | 559 | }
|
|---|
| [8927] | 560 | }
|
|---|
| [8925] | 561 | }
|
|---|
| [10587] | 562 | else if (type() == t_eph::CNAV ||
|
|---|
| 563 | type() == t_eph::CNV2) {
|
|---|
| [10577] | 564 | if ( readDbl(line, pos[0], fieldLen, _ISC_L1CA)
|
|---|
| 565 | || readDbl(line, pos[1], fieldLen, _ISC_L2C)
|
|---|
| 566 | || readDbl(line, pos[2], fieldLen, _ISC_L5I5)
|
|---|
| 567 | || readDbl(line, pos[3], fieldLen, _ISC_L5Q5)) {
|
|---|
| [9786] | 568 | _checkState = bad;
|
|---|
| 569 | return;
|
|---|
| 570 | }
|
|---|
| 571 | }
|
|---|
| [10587] | 572 | else if (type() == t_eph::L1NV) {
|
|---|
| [10577] | 573 | if (!_RSF) {
|
|---|
| 574 | if ( readDbl(line, pos[0], fieldLen, _ISC_S)
|
|---|
| 575 | || readDbl(line, pos[1], fieldLen, _ISC_L1D)) {
|
|---|
| 576 | _checkState = bad;
|
|---|
| 577 | return;
|
|---|
| 578 | }
|
|---|
| 579 | } else {
|
|---|
| 580 | if ( readDbl(line, pos[2], fieldLen, _ISC_L1P)
|
|---|
| 581 | || readDbl(line, pos[3], fieldLen, _ISC_L1D)) {
|
|---|
| 582 | _checkState = bad;
|
|---|
| 583 | return;
|
|---|
| 584 | }
|
|---|
| 585 | }
|
|---|
| 586 | }
|
|---|
| [6801] | 587 | }
|
|---|
| [9786] | 588 | // =====================
|
|---|
| 589 | // BROADCAST ORBIT - 8
|
|---|
| 590 | // =====================
|
|---|
| [10577] | 591 | else if (iLine == 8) {
|
|---|
| [10587] | 592 | if (type() == t_eph::CNAV) {
|
|---|
| [10577] | 593 | if ( readDbl(line, pos[0], fieldLen, _TOT)
|
|---|
| [10587] | 594 | || readDbl(line, pos[1], fieldLen, _wnop)) {
|
|---|
| [9786] | 595 | _checkState = bad;
|
|---|
| 596 | return;
|
|---|
| 597 | }
|
|---|
| [10587] | 598 | if (readDbl(line, pos[2], fieldLen, statusflags)) {
|
|---|
| 599 | _flags_unknown = true;
|
|---|
| 600 | }
|
|---|
| 601 | else {
|
|---|
| 602 | _flags_unknown = false;
|
|---|
| [10577] | 603 | // Bit 0:
|
|---|
| [10599] | 604 | _intSF = double(bitExtracted(unsigned(statusflags), 1, 0));
|
|---|
| [10577] | 605 | // Bit 1:
|
|---|
| [10599] | 606 | _L2Cphasing = double(bitExtracted(unsigned(statusflags), 1, 1));
|
|---|
| [10577] | 607 | // Bit 2:
|
|---|
| [10599] | 608 | _alert = double(bitExtracted(unsigned(statusflags), 1, 2));
|
|---|
| [10577] | 609 | }
|
|---|
| [9786] | 610 | }
|
|---|
| [10587] | 611 | else if (type() == t_eph::CNV2) {
|
|---|
| [10577] | 612 | if ( readDbl(line, pos[0], fieldLen, _ISC_L1Cd)
|
|---|
| 613 | || readDbl(line, pos[1], fieldLen, _ISC_L1Cp)) {
|
|---|
| [9786] | 614 | _checkState = bad;
|
|---|
| 615 | return;
|
|---|
| 616 | }
|
|---|
| 617 | }
|
|---|
| [10587] | 618 | else if (type() == t_eph::L1NV) {
|
|---|
| [10577] | 619 | if ( readDbl(line, pos[0], fieldLen, _TOT)) {
|
|---|
| 620 | _checkState = bad;
|
|---|
| 621 | return;
|
|---|
| 622 | }
|
|---|
| 623 | }
|
|---|
| [9786] | 624 | }
|
|---|
| 625 | // =====================
|
|---|
| 626 | // BROADCAST ORBIT - 9
|
|---|
| 627 | // =====================
|
|---|
| [10577] | 628 | else if (iLine == 9) {
|
|---|
| [10587] | 629 | if (type() == t_eph::CNV2) {
|
|---|
| [10577] | 630 | if ( readDbl(line, pos[0], fieldLen, _TOT)
|
|---|
| [10587] | 631 | || readDbl(line, pos[1], fieldLen, _wnop)) {
|
|---|
| [9786] | 632 | _checkState = bad;
|
|---|
| 633 | return;
|
|---|
| 634 | }
|
|---|
| [10587] | 635 | if (readDbl(line, pos[2], fieldLen, statusflags)) {
|
|---|
| 636 | _flags_unknown = true;
|
|---|
| 637 | }
|
|---|
| 638 | else {
|
|---|
| 639 | _flags_unknown = false;
|
|---|
| [10577] | 640 | // Bit 0:
|
|---|
| [10688] | 641 | _intSF = double(bitExtracted(unsigned(statusflags), 1, 0));
|
|---|
| [10587] | 642 | if (system() == t_eph::QZSS) {
|
|---|
| [10577] | 643 | // Bit 1:
|
|---|
| [10688] | 644 | _ephSF = double(bitExtracted(unsigned(statusflags), 1, 1));
|
|---|
| [10577] | 645 | }
|
|---|
| 646 | }
|
|---|
| [9786] | 647 | }
|
|---|
| 648 | }
|
|---|
| [6801] | 649 | }
|
|---|
| 650 | }
|
|---|
| 651 |
|
|---|
| [2222] | 652 | // Compute GPS Satellite Position (virtual)
|
|---|
| [1025] | 653 | ////////////////////////////////////////////////////////////////////////////
|
|---|
| [10577] | 654 | t_irc t_ephGPS::position(int GPSweek, double GPSweeks, double *xc,
|
|---|
| 655 | double *vv) const {
|
|---|
| [1025] | 656 |
|
|---|
| [1098] | 657 | static const double omegaEarth = 7292115.1467e-11;
|
|---|
| [10577] | 658 | static const double gmGRS = 398.6005e12;
|
|---|
| [1025] | 659 |
|
|---|
| [10577] | 660 | memset(xc, 0, 6 * sizeof(double));
|
|---|
| 661 | memset(vv, 0, 3 * sizeof(double));
|
|---|
| [1025] | 662 |
|
|---|
| 663 | double a0 = _sqrt_A * _sqrt_A;
|
|---|
| 664 | if (a0 == 0) {
|
|---|
| [6213] | 665 | return failure;
|
|---|
| [1025] | 666 | }
|
|---|
| 667 |
|
|---|
| [10577] | 668 | double n0 = sqrt(gmGRS / (a0 * a0 * a0));
|
|---|
| [4018] | 669 |
|
|---|
| 670 | bncTime tt(GPSweek, GPSweeks);
|
|---|
| [4543] | 671 | double tk = tt - bncTime(int(_TOEweek), _TOEsec);
|
|---|
| [4018] | 672 |
|
|---|
| [10577] | 673 | double n = n0 + _Delta_n;
|
|---|
| 674 | double M = _M0 + n * tk;
|
|---|
| 675 | double E = M;
|
|---|
| [1025] | 676 | double E_last;
|
|---|
| [10577] | 677 | int nLoop = 0;
|
|---|
| [1025] | 678 | do {
|
|---|
| 679 | E_last = E;
|
|---|
| [10577] | 680 | E = M + _e * sin(E);
|
|---|
| [8368] | 681 |
|
|---|
| 682 | if (++nLoop == 100) {
|
|---|
| 683 | return failure;
|
|---|
| 684 | }
|
|---|
| [10577] | 685 | } while (fabs(E - E_last) * a0 > 0.001);
|
|---|
| 686 | double v = 2.0 * atan(sqrt((1.0 + _e) / (1.0 - _e)) * tan(E / 2));
|
|---|
| 687 | double u0 = v + _omega;
|
|---|
| 688 | double sin2u0 = sin(2 * u0);
|
|---|
| 689 | double cos2u0 = cos(2 * u0);
|
|---|
| 690 | double r = a0 * (1 - _e * cos(E)) + _Crc * cos2u0 + _Crs * sin2u0;
|
|---|
| 691 | double i = _i0 + _IDOT * tk + _Cic * cos2u0 + _Cis * sin2u0;
|
|---|
| 692 | double u = u0 + _Cuc * cos2u0 + _Cus * sin2u0;
|
|---|
| 693 | double xp = r * cos(u);
|
|---|
| 694 | double yp = r * sin(u);
|
|---|
| 695 | double OM = _OMEGA0 + (_OMEGADOT - omegaEarth) * tk - omegaEarth * _TOEsec;
|
|---|
| [7278] | 696 |
|
|---|
| [1025] | 697 | double sinom = sin(OM);
|
|---|
| 698 | double cosom = cos(OM);
|
|---|
| [10577] | 699 | double sini = sin(i);
|
|---|
| 700 | double cosi = cos(i);
|
|---|
| 701 | xc[0] = xp * cosom - yp * cosi * sinom;
|
|---|
| 702 | xc[1] = xp * sinom + yp * cosi * cosom;
|
|---|
| 703 | xc[2] = yp * sini;
|
|---|
| [7481] | 704 |
|
|---|
| [4018] | 705 | double tc = tt - _TOC;
|
|---|
| [10577] | 706 | xc[3] = _clock_bias + _clock_drift * tc + _clock_driftrate * tc * tc;
|
|---|
| [1025] | 707 |
|
|---|
| 708 | // Velocity
|
|---|
| 709 | // --------
|
|---|
| [10577] | 710 | double tanv2 = tan(v / 2);
|
|---|
| 711 | double dEdM = 1 / (1 - _e * cos(E));
|
|---|
| 712 | double dotv = sqrt((1.0 + _e) / (1.0 - _e)) / cos(E / 2) / cos(E / 2)
|
|---|
| 713 | / (1 + tanv2 * tanv2) * dEdM * n;
|
|---|
| 714 | double dotu = dotv + (-_Cuc * sin2u0 + _Cus * cos2u0) * 2 * dotv;
|
|---|
| [1025] | 715 | double dotom = _OMEGADOT - omegaEarth;
|
|---|
| [10577] | 716 | double doti = _IDOT + (-_Cic * sin2u0 + _Cis * cos2u0) * 2 * dotv;
|
|---|
| 717 | double dotr = a0 * _e * sin(E) * dEdM * n
|
|---|
| 718 | + (-_Crc * sin2u0 + _Crs * cos2u0) * 2 * dotv;
|
|---|
| 719 | double dotx = dotr * cos(u) - r * sin(u) * dotu;
|
|---|
| 720 | double doty = dotr * sin(u) + r * cos(u) * dotu;
|
|---|
| [1025] | 721 |
|
|---|
| [10577] | 722 | vv[0] = cosom * dotx - cosi * sinom * doty // dX / dr
|
|---|
| 723 | - xp * sinom * dotom - yp * cosi * cosom * dotom // dX / dOMEGA
|
|---|
| 724 | + yp * sini * sinom * doti; // dX / di
|
|---|
| [1025] | 725 |
|
|---|
| [10577] | 726 | vv[1] = sinom * dotx + cosi * cosom * doty + xp * cosom * dotom
|
|---|
| 727 | - yp * cosi * sinom * dotom - yp * sini * cosom * doti;
|
|---|
| [1025] | 728 |
|
|---|
| [10577] | 729 | vv[2] = sini * doty + yp * cosi * doti;
|
|---|
| [2429] | 730 |
|
|---|
| 731 | // Relativistic Correction
|
|---|
| 732 | // -----------------------
|
|---|
| [10993] | 733 | // Both forms are equivalent per the ICD for an unperturbed broadcast orbit,
|
|---|
| 734 | // but differ numerically once harmonic (Crc/Crs/Cuc/Cus/Cic/Cis) terms are
|
|---|
| 735 | // included in xc/vv. The velocity-based form (IS-GPS-200D 20.3.3.3.3.1) is
|
|---|
| 736 | // the one recommended together with RTCM-SSR corrections; the classic
|
|---|
| 737 | // eccentricity-based form is used otherwise (broadcast-only or IGS-SSR).
|
|---|
| 738 | if (_orbCorr && _orbCorr->_rtcmSsr) {
|
|---|
| 739 | xc[3] -= 2.0 * (xc[0]*vv[0] + xc[1]*vv[1] + xc[2]*vv[2]) / t_CST::c / t_CST::c;
|
|---|
| 740 | }
|
|---|
| 741 | else {
|
|---|
| 742 | xc[3] -= 4.442807633e-10 * _e * sqrt(a0) * sin(E);
|
|---|
| 743 | }
|
|---|
| [9132] | 744 |
|
|---|
| [10577] | 745 | xc[4] = _clock_drift + _clock_driftrate * tc;
|
|---|
| [8542] | 746 | xc[5] = _clock_driftrate;
|
|---|
| [8581] | 747 |
|
|---|
| [6213] | 748 | return success;
|
|---|
| [1025] | 749 | }
|
|---|
| 750 |
|
|---|
| [6801] | 751 | // RINEX Format String
|
|---|
| 752 | //////////////////////////////////////////////////////////////////////////////
|
|---|
| 753 | QString t_ephGPS::toString(double version) const {
|
|---|
| [2221] | 754 |
|
|---|
| [10587] | 755 | if (version < 4.0 &&
|
|---|
| 756 | (type() == t_eph::CNAV ||
|
|---|
| 757 | type() == t_eph::CNV2 ||
|
|---|
| 758 | type() == t_eph::L1NV )) {
|
|---|
| 759 | return "";
|
|---|
| 760 | }
|
|---|
| 761 |
|
|---|
| 762 | QString ephStr = typeStr(_type, _prn, version);
|
|---|
| [10577] | 763 | QString rnxStr = ephStr + rinexDateStr(_TOC, _prn, version);
|
|---|
| [2221] | 764 |
|
|---|
| [6801] | 765 | QTextStream out(&rnxStr);
|
|---|
| [2221] | 766 |
|
|---|
| [10577] | 767 | out
|
|---|
| 768 | << QString("%1%2%3\n")
|
|---|
| 769 | .arg(_clock_bias, 19, 'e', 12)
|
|---|
| 770 | .arg(_clock_drift, 19, 'e', 12)
|
|---|
| 771 | .arg(_clock_driftrate, 19, 'e', 12);
|
|---|
| [2221] | 772 |
|
|---|
| [6801] | 773 | QString fmt = version < 3.0 ? " %1%2%3%4\n" : " %1%2%3%4\n";
|
|---|
| [2221] | 774 |
|
|---|
| [9786] | 775 | // =====================
|
|---|
| 776 | // BROADCAST ORBIT - 1
|
|---|
| 777 | // =====================
|
|---|
| [10587] | 778 | if (type() == t_eph::CNAV ||
|
|---|
| 779 | type() == t_eph::CNV2 ||
|
|---|
| 780 | type() == t_eph::L1NV) {
|
|---|
| [10577] | 781 | out
|
|---|
| 782 | << QString(fmt)
|
|---|
| 783 | .arg(_ADOT, 19, 'e', 12)
|
|---|
| 784 | .arg(_Crs, 19, 'e', 12)
|
|---|
| 785 | .arg(_Delta_n, 19, 'e', 12)
|
|---|
| 786 | .arg(_M0, 19, 'e', 12);
|
|---|
| 787 | } else { // LNAV, undefined
|
|---|
| 788 | out
|
|---|
| 789 | << QString(fmt)
|
|---|
| 790 | .arg(_IODE, 19, 'e', 12)
|
|---|
| 791 | .arg(_Crs, 19, 'e', 12)
|
|---|
| 792 | .arg(_Delta_n, 19, 'e', 12)
|
|---|
| 793 | .arg(_M0, 19, 'e', 12);
|
|---|
| [9786] | 794 | }
|
|---|
| 795 | // =====================
|
|---|
| 796 | // BROADCAST ORBIT - 2
|
|---|
| 797 | // =====================
|
|---|
| [10577] | 798 | out
|
|---|
| 799 | << QString(fmt)
|
|---|
| 800 | .arg(_Cuc, 19, 'e', 12)
|
|---|
| 801 | .arg(_e, 19, 'e', 12)
|
|---|
| 802 | .arg(_Cus, 19, 'e', 12)
|
|---|
| 803 | .arg(_sqrt_A, 19, 'e', 12);
|
|---|
| [9786] | 804 | // =====================
|
|---|
| 805 | // BROADCAST ORBIT - 3
|
|---|
| 806 | // =====================
|
|---|
| [10587] | 807 | if (type() == t_eph::CNAV ||
|
|---|
| 808 | type() == t_eph::CNV2) {
|
|---|
| [10577] | 809 | out
|
|---|
| 810 | << QString(fmt)
|
|---|
| [9786] | 811 | .arg(_top, 19, 'e', 12)
|
|---|
| 812 | .arg(_Cic, 19, 'e', 12)
|
|---|
| 813 | .arg(_OMEGA0, 19, 'e', 12)
|
|---|
| 814 | .arg(_Cis, 19, 'e', 12);
|
|---|
| 815 | }
|
|---|
| [10587] | 816 | else if (type() == t_eph::L1NV) {
|
|---|
| [10577] | 817 | out
|
|---|
| 818 | << QString(fmt)
|
|---|
| 819 | .arg(_IODE, 19, 'e', 12)
|
|---|
| 820 | .arg(_Cic, 19, 'e', 12)
|
|---|
| 821 | .arg(_OMEGA0, 19, 'e', 12)
|
|---|
| 822 | .arg(_Cis, 19, 'e', 12);
|
|---|
| 823 | }
|
|---|
| 824 | else { // LNAV, undefined
|
|---|
| 825 | out
|
|---|
| 826 | << QString(fmt)
|
|---|
| [9786] | 827 | .arg(_TOEsec, 19, 'e', 12)
|
|---|
| 828 | .arg(_Cic, 19, 'e', 12)
|
|---|
| 829 | .arg(_OMEGA0, 19, 'e', 12)
|
|---|
| 830 | .arg(_Cis, 19, 'e', 12);
|
|---|
| 831 | }
|
|---|
| 832 | // =====================
|
|---|
| 833 | // BROADCAST ORBIT - 4
|
|---|
| 834 | // =====================
|
|---|
| [10577] | 835 | out
|
|---|
| 836 | << QString(fmt)
|
|---|
| 837 | .arg(_i0, 19, 'e', 12)
|
|---|
| 838 | .arg(_Crc, 19, 'e', 12)
|
|---|
| 839 | .arg(_omega, 19, 'e', 12)
|
|---|
| 840 | .arg(_OMEGADOT, 19, 'e', 12);
|
|---|
| [9786] | 841 | // =====================
|
|---|
| 842 | // BROADCAST ORBIT - 5
|
|---|
| 843 | // =====================
|
|---|
| [10619] | 844 | if (system() != t_eph::NavIC) {
|
|---|
| [10587] | 845 | if (type() == t_eph::CNAV ||
|
|---|
| 846 | type() == t_eph::CNV2) {
|
|---|
| [10577] | 847 | out
|
|---|
| 848 | << QString(fmt)
|
|---|
| 849 | .arg(_IDOT, 19, 'e', 12)
|
|---|
| 850 | .arg(_Delta_n_dot, 19, 'e', 12)
|
|---|
| 851 | .arg(_URAI_NED0, 19, 'e', 12)
|
|---|
| 852 | .arg(_URAI_NED1, 19, 'e', 12);
|
|---|
| 853 | }
|
|---|
| 854 | else { // LNAV, undefined
|
|---|
| 855 | out
|
|---|
| 856 | << QString(fmt)
|
|---|
| 857 | .arg(_IDOT, 19, 'e', 12)
|
|---|
| 858 | .arg(_L2Codes, 19, 'e', 12)
|
|---|
| 859 | .arg(_TOEweek, 19, 'e', 12)
|
|---|
| 860 | .arg(_L2PFlag, 19, 'e', 12);
|
|---|
| 861 | }
|
|---|
| 862 | }
|
|---|
| 863 | else {
|
|---|
| [10587] | 864 | if (type() == t_eph::LNAV ||
|
|---|
| 865 | type() == t_eph::undefined) {
|
|---|
| [10577] | 866 | out
|
|---|
| 867 | << QString(fmt)
|
|---|
| [8168] | 868 | .arg(_IDOT, 19, 'e', 12)
|
|---|
| [10577] | 869 | .arg("", 19, QChar(' '))
|
|---|
| [8800] | 870 | .arg(_TOEweek, 19, 'e', 12)
|
|---|
| [10577] | 871 | .arg("", 19, QChar(' '));
|
|---|
| [9786] | 872 | }
|
|---|
| [10587] | 873 | else if (type() == t_eph::L1NV) {
|
|---|
| [10577] | 874 | out
|
|---|
| 875 | << QString(fmt)
|
|---|
| 876 | .arg(_IDOT, 19, 'e', 12)
|
|---|
| 877 | .arg(_Delta_n_dot, 19, 'e', 12)
|
|---|
| 878 | .arg("", 19, QChar(' '))
|
|---|
| 879 | .arg(_RSF, 19, 'e', 12);
|
|---|
| [9786] | 880 | }
|
|---|
| [8800] | 881 | }
|
|---|
| [9786] | 882 | // =====================
|
|---|
| 883 | // BROADCAST ORBIT - 6
|
|---|
| 884 | // =====================
|
|---|
| [10619] | 885 | if (system() != t_eph::NavIC) {
|
|---|
| [10587] | 886 | if (type() == t_eph::CNAV ||
|
|---|
| 887 | type() == t_eph::CNV2) {
|
|---|
| [10577] | 888 | out
|
|---|
| 889 | << QString(fmt)
|
|---|
| 890 | .arg(_URAI_ED, 19, 'e', 12)
|
|---|
| 891 | .arg(_health, 19, 'e', 12)
|
|---|
| 892 | .arg(_TGD, 19, 'e', 12)
|
|---|
| 893 | .arg(_URAI_NED2, 19, 'e', 12);
|
|---|
| 894 | }
|
|---|
| 895 | else { // LNAV, undefined
|
|---|
| 896 | out
|
|---|
| 897 | << QString(fmt)
|
|---|
| 898 | .arg(_ura, 19, 'e', 12)
|
|---|
| 899 | .arg(_health, 19, 'e', 12)
|
|---|
| 900 | .arg(_TGD, 19, 'e', 12)
|
|---|
| 901 | .arg(_IODC, 19, 'e', 12);
|
|---|
| 902 | }
|
|---|
| [8168] | 903 | }
|
|---|
| 904 | else {
|
|---|
| [10587] | 905 | if (type() == t_eph::LNAV ||
|
|---|
| 906 | type() == t_eph::undefined) {
|
|---|
| [10577] | 907 | out
|
|---|
| 908 | << QString(fmt)
|
|---|
| 909 | .arg(_ura, 19, 'e', 12)
|
|---|
| 910 | .arg(_health, 19, 'e', 12)
|
|---|
| [10898] | 911 | .arg(_TGD, 19, 'e', 12)
|
|---|
| 912 | .arg("", 19, QChar(' '));
|
|---|
| [9786] | 913 | }
|
|---|
| [10587] | 914 | else if (type() == t_eph::L1NV) {
|
|---|
| [10577] | 915 | int i = 0; (!_RSF) ? i = 2 : i = 3;
|
|---|
| 916 | if (i == 2) {
|
|---|
| 917 | out
|
|---|
| 918 | << QString(fmt)
|
|---|
| 919 | .arg(_URAI, 19, 'e', 12)
|
|---|
| 920 | .arg(_health, 19, 'e', 12)
|
|---|
| 921 | .arg(_TGD, 19, 'e', 12)
|
|---|
| 922 | .arg("", 19, QChar(' '));
|
|---|
| 923 | }
|
|---|
| 924 | else {
|
|---|
| 925 | out
|
|---|
| 926 | << QString(fmt)
|
|---|
| 927 | .arg(_URAI, 19, 'e', 12)
|
|---|
| 928 | .arg(_health, 19, 'e', 12)
|
|---|
| 929 | .arg("", 19, QChar(' '))
|
|---|
| 930 | .arg(_TGD, 19, 'e', 12);
|
|---|
| 931 | }
|
|---|
| [9786] | 932 | }
|
|---|
| [8168] | 933 | }
|
|---|
| [9786] | 934 | // =====================
|
|---|
| 935 | // BROADCAST ORBIT - 7
|
|---|
| 936 | // =====================
|
|---|
| [10587] | 937 | if (type() == t_eph::LNAV ||
|
|---|
| 938 | type() == t_eph::undefined) {
|
|---|
| [6801] | 939 |
|
|---|
| [9786] | 940 | double tot = _TOT;
|
|---|
| 941 | if (tot == 0.9999e9 && version < 3.0) {
|
|---|
| 942 | tot = 0.0;
|
|---|
| 943 | }
|
|---|
| 944 | // fitInterval
|
|---|
| [10619] | 945 | if (system() == t_eph::NavIC) {
|
|---|
| [10577] | 946 | out
|
|---|
| 947 | << QString(fmt)
|
|---|
| 948 | .arg(tot, 19, 'e', 12)
|
|---|
| 949 | .arg("", 19, QChar(' '))
|
|---|
| 950 | .arg("", 19, QChar(' '))
|
|---|
| 951 | .arg("", 19, QChar(' '));
|
|---|
| [9786] | 952 | }
|
|---|
| 953 | else {
|
|---|
| [10587] | 954 | if (_flags_unknown) {
|
|---|
| 955 | out
|
|---|
| 956 | << QString(fmt)
|
|---|
| 957 | .arg(tot, 19, 'e', 12)
|
|---|
| 958 | .arg("", 19, QChar(' '))
|
|---|
| 959 | .arg("", 19, QChar(' '))
|
|---|
| 960 | .arg("", 19, QChar(' '));
|
|---|
| [9786] | 961 | }
|
|---|
| [10587] | 962 | else {
|
|---|
| 963 | // for GPS and QZSS in version 3.02 specified in hours
|
|---|
| 964 | double fitIntervalRnx = _fitInterval;
|
|---|
| 965 | // otherwise specified as flag
|
|---|
| 966 | if (system() == t_eph::QZSS && version != 3.02) {
|
|---|
| 967 | (_fitInterval == 2.0) ? fitIntervalRnx = 0.0 : fitIntervalRnx = 1.0;
|
|---|
| 968 | }
|
|---|
| 969 | out
|
|---|
| 970 | << QString(fmt)
|
|---|
| 971 | .arg(tot, 19, 'e', 12)
|
|---|
| 972 | .arg(fitIntervalRnx, 19, 'e', 12)
|
|---|
| 973 | .arg("", 19, QChar(' '))
|
|---|
| 974 | .arg("", 19, QChar(' '));
|
|---|
| 975 | }
|
|---|
| [9786] | 976 | }
|
|---|
| [7922] | 977 | }
|
|---|
| [10587] | 978 | else if (type() == t_eph::CNAV ||
|
|---|
| 979 | type() == t_eph::CNV2) {
|
|---|
| [10577] | 980 | out
|
|---|
| 981 | << QString(fmt)
|
|---|
| 982 | .arg(_ISC_L1CA, 19, 'e', 12)
|
|---|
| 983 | .arg(_ISC_L2C, 19, 'e', 12)
|
|---|
| 984 | .arg(_ISC_L5I5, 19, 'e', 12)
|
|---|
| 985 | .arg(_ISC_L5Q5, 19, 'e', 12);
|
|---|
| [8800] | 986 | }
|
|---|
| [10587] | 987 | else if (type() == t_eph::L1NV) {
|
|---|
| [10577] | 988 | if (_RSF) {
|
|---|
| 989 | out
|
|---|
| 990 | << QString(fmt)
|
|---|
| 991 | .arg(_ISC_S, 19, 'e', 12)
|
|---|
| 992 | .arg(_ISC_L1D, 19, 'e', 12)
|
|---|
| 993 | .arg("", 19, QChar(' '))
|
|---|
| 994 | .arg("", 19, QChar(' '));
|
|---|
| 995 | }
|
|---|
| 996 | else {
|
|---|
| 997 | out
|
|---|
| 998 | << QString(fmt)
|
|---|
| 999 | .arg("", 19, QChar(' '))
|
|---|
| 1000 | .arg("", 19, QChar(' '))
|
|---|
| 1001 | .arg(_ISC_L1P, 19, 'e', 12)
|
|---|
| 1002 | .arg(_ISC_L1D, 19, 'e', 12);
|
|---|
| 1003 | }
|
|---|
| 1004 | }
|
|---|
| [9786] | 1005 | // =====================
|
|---|
| 1006 | // BROADCAST ORBIT - 8
|
|---|
| 1007 | // =====================
|
|---|
| [10587] | 1008 | if (type() == t_eph::CNAV) {
|
|---|
| 1009 | int intFlags = 0;
|
|---|
| 1010 | if (!_flags_unknown) {
|
|---|
| 1011 | // Bit 0:
|
|---|
| 1012 | if (_intSF) {intFlags |= (1 << 0);}
|
|---|
| 1013 | // Bit 1:
|
|---|
| 1014 | if (_L2Cphasing) {intFlags |= (1 << 1);}
|
|---|
| 1015 | // Bit 2:
|
|---|
| 1016 | if (_alert) {intFlags |= (1 << 2);}
|
|---|
| [10577] | 1017 | out
|
|---|
| 1018 | << QString(fmt)
|
|---|
| [10587] | 1019 | .arg(_TOT, 19, 'e', 12)
|
|---|
| 1020 | .arg(_wnop, 19, 'e', 12)
|
|---|
| 1021 | .arg(double(intFlags), 19, 'e', 12)
|
|---|
| 1022 | .arg("", 19, QChar(' '));
|
|---|
| [10577] | 1023 | }
|
|---|
| 1024 | else {
|
|---|
| 1025 | out
|
|---|
| 1026 | << QString(fmt)
|
|---|
| 1027 | .arg(_TOT, 19, 'e', 12)
|
|---|
| 1028 | .arg(_wnop, 19, 'e', 12)
|
|---|
| 1029 | .arg("", 19, QChar(' '))
|
|---|
| 1030 | .arg("", 19, QChar(' '));
|
|---|
| 1031 | }
|
|---|
| [8800] | 1032 | }
|
|---|
| [10587] | 1033 | else if (type() == t_eph::CNV2) {
|
|---|
| [10577] | 1034 | out
|
|---|
| 1035 | << QString(fmt)
|
|---|
| 1036 | .arg(_ISC_L1Cd, 19, 'e', 12)
|
|---|
| 1037 | .arg(_ISC_L1Cp, 19, 'e', 12)
|
|---|
| 1038 | .arg("", 19, QChar(' '))
|
|---|
| 1039 | .arg("", 19, QChar(' '));
|
|---|
| [9786] | 1040 | }
|
|---|
| [10587] | 1041 | else if (type() == t_eph::L1NV) {
|
|---|
| [10577] | 1042 | out
|
|---|
| 1043 | << QString(fmt)
|
|---|
| 1044 | .arg(_TOT, 19, 'e', 12)
|
|---|
| 1045 | .arg("", 19, QChar(' '))
|
|---|
| 1046 | .arg("", 19, QChar(' '))
|
|---|
| 1047 | .arg("", 19, QChar(' '));
|
|---|
| 1048 | }
|
|---|
| [9786] | 1049 | // =====================
|
|---|
| 1050 | // BROADCAST ORBIT - 9
|
|---|
| 1051 | // =====================
|
|---|
| [10587] | 1052 | if (type() == t_eph::CNV2) {
|
|---|
| 1053 | int intFlags = 0;
|
|---|
| 1054 | if (!_flags_unknown) {
|
|---|
| 1055 | // Bit 0:
|
|---|
| 1056 | if (_intSF) {intFlags |= (1 << 0);}
|
|---|
| 1057 | if (system() == t_eph::QZSS) {
|
|---|
| 1058 | // Bit 1:
|
|---|
| 1059 | if (_ephSF) {intFlags |= (1 << 1);}
|
|---|
| 1060 | }
|
|---|
| [10577] | 1061 | out
|
|---|
| 1062 | << QString(fmt)
|
|---|
| [10587] | 1063 | .arg(_TOT, 19, 'e', 12)
|
|---|
| 1064 | .arg(_wnop, 19, 'e', 12)
|
|---|
| 1065 | .arg(double(intFlags), 19, 'e', 12)
|
|---|
| 1066 | .arg("", 19, QChar(' '));
|
|---|
| [10577] | 1067 | }
|
|---|
| 1068 | else {
|
|---|
| 1069 | out
|
|---|
| 1070 | << QString(fmt)
|
|---|
| 1071 | .arg(_TOT, 19, 'e', 12)
|
|---|
| 1072 | .arg(_wnop, 19, 'e', 12)
|
|---|
| 1073 | .arg("", 19, QChar(' '))
|
|---|
| 1074 | .arg("", 19, QChar(' '));
|
|---|
| 1075 | }
|
|---|
| [9786] | 1076 | }
|
|---|
| [6801] | 1077 | return rnxStr;
|
|---|
| [2221] | 1078 | }
|
|---|
| 1079 |
|
|---|
| [10628] | 1080 | // Health status of GPS Ephemeris (virtual)
|
|---|
| 1081 | ////////////////////////////////////////////////////////////////////////////
|
|---|
| 1082 | unsigned int t_ephGPS::isUnhealthy() const {
|
|---|
| 1083 |
|
|---|
| 1084 | switch (system()) {
|
|---|
| 1085 | case t_eph::GPS:
|
|---|
| 1086 | case t_eph::QZSS:
|
|---|
| 1087 | switch (type()) {
|
|---|
| 1088 | case t_eph::LNAV:
|
|---|
| 1089 | case t_eph::CNAV:
|
|---|
| 1090 | case t_eph::CNV2:
|
|---|
| 1091 | if (_health == 0.0) {
|
|---|
| 1092 | return 0;
|
|---|
| 1093 | }
|
|---|
| 1094 | else {
|
|---|
| 1095 | return 1;
|
|---|
| 1096 | }
|
|---|
| 1097 | break;
|
|---|
| 1098 | }
|
|---|
| 1099 | break;
|
|---|
| 1100 | case t_eph::NavIC:
|
|---|
| 1101 | switch (type()) {
|
|---|
| 1102 | case t_eph::LNAV:
|
|---|
| 1103 | if (_health == 0.0) { // L1 & S healthy
|
|---|
| 1104 | return 0;
|
|---|
| 1105 | }
|
|---|
| 1106 | if (_health == 1.0 || // L5 healthy and S unhealthy,
|
|---|
| 1107 | _health == 2.0 || // L5 unhealthy and S healthy
|
|---|
| 1108 | _health == 3.0) { // both L5 and S unhealthy
|
|---|
| 1109 | return 1;
|
|---|
| 1110 | }
|
|---|
| 1111 | break;
|
|---|
| 1112 | case t_eph::L1NV:
|
|---|
| 1113 | if (_health == 0.0) { // All navigation data on L1-SPS signal OK
|
|---|
| 1114 | return 0;
|
|---|
| 1115 | }
|
|---|
| 1116 | if (_health == 1.0) { // Some or all navigation data on L1-SPS signal bad
|
|---|
| 1117 | return 1;
|
|---|
| 1118 | }
|
|---|
| 1119 | break;
|
|---|
| 1120 | }
|
|---|
| 1121 | break;
|
|---|
| 1122 | }
|
|---|
| 1123 | return 0;
|
|---|
| 1124 | }
|
|---|
| 1125 |
|
|---|
| [6801] | 1126 | // Constructor
|
|---|
| 1127 | //////////////////////////////////////////////////////////////////////////////
|
|---|
| [10603] | 1128 | t_ephGlo::t_ephGlo(double rnxVersion, const QStringList &lines, const QString typeStr) {
|
|---|
| [2221] | 1129 |
|
|---|
| [10603] | 1130 | setType(typeStr);
|
|---|
| 1131 |
|
|---|
| [9367] | 1132 | int nLines = 4;
|
|---|
| [10587] | 1133 |
|
|---|
| 1134 | // Source RINEX version < 4
|
|---|
| 1135 | if (type() == t_eph::undefined) {
|
|---|
| [10628] | 1136 | // cannot be determined from input data
|
|---|
| [10614] | 1137 | // but is set to be able to work with old RINEX files in BNC applications
|
|---|
| 1138 | _type = t_eph::FDMA_M;
|
|---|
| [10587] | 1139 | }
|
|---|
| 1140 |
|
|---|
| [9367] | 1141 | if (rnxVersion >= 3.05) {
|
|---|
| 1142 | nLines += 1;
|
|---|
| [10577] | 1143 | } else {
|
|---|
| [9367] | 1144 | _M_delta_tau = 0.9999e9; // unknown
|
|---|
| [10587] | 1145 | _M_FT = 1.5e1; // unknown
|
|---|
| [10614] | 1146 | _statusflags_unknown = true;
|
|---|
| 1147 | _healthflags_unknown = true;
|
|---|
| [9367] | 1148 | }
|
|---|
| [6801] | 1149 |
|
|---|
| 1150 | if (lines.size() != nLines) {
|
|---|
| 1151 | _checkState = bad;
|
|---|
| 1152 | return;
|
|---|
| [6518] | 1153 | }
|
|---|
| 1154 |
|
|---|
| [6801] | 1155 | // RINEX Format
|
|---|
| 1156 | // ------------
|
|---|
| 1157 | int fieldLen = 19;
|
|---|
| [9367] | 1158 | double statusflags = 0.0;
|
|---|
| 1159 | double healthflags = 0.0;
|
|---|
| [10587] | 1160 | double sourceflags = 0.0;
|
|---|
| 1161 | _tauC = 0.0;
|
|---|
| 1162 | _tau1 = 0.0;
|
|---|
| 1163 | _tau2 = 0.0;
|
|---|
| 1164 | _additional_data_availability = 0.0;
|
|---|
| [2221] | 1165 |
|
|---|
| [6801] | 1166 | int pos[4];
|
|---|
| [10577] | 1167 | pos[0] = (rnxVersion <= 2.12) ? 3 : 4;
|
|---|
| [6801] | 1168 | pos[1] = pos[0] + fieldLen;
|
|---|
| 1169 | pos[2] = pos[1] + fieldLen;
|
|---|
| 1170 | pos[3] = pos[2] + fieldLen;
|
|---|
| [2221] | 1171 |
|
|---|
| [6801] | 1172 | // Read four lines
|
|---|
| 1173 | // ---------------
|
|---|
| 1174 | for (int iLine = 0; iLine < nLines; iLine++) {
|
|---|
| 1175 | QString line = lines[iLine];
|
|---|
| [2221] | 1176 |
|
|---|
| [10577] | 1177 | if (iLine == 0) {
|
|---|
| [8204] | 1178 | QTextStream in(line.left(pos[1]).toLatin1());
|
|---|
| [6213] | 1179 |
|
|---|
| [10577] | 1180 | int year, month, day, hour, min;
|
|---|
| [6801] | 1181 | double sec;
|
|---|
| [2221] | 1182 |
|
|---|
| [7139] | 1183 | QString prnStr, n;
|
|---|
| [6880] | 1184 | in >> prnStr;
|
|---|
| [7639] | 1185 | if (prnStr.size() == 1 && prnStr[0] == 'R') {
|
|---|
| [7139] | 1186 | in >> n;
|
|---|
| 1187 | prnStr.append(n);
|
|---|
| [6880] | 1188 | }
|
|---|
| [10599] | 1189 |
|
|---|
| [6801] | 1190 | if (prnStr.at(0) == 'R') {
|
|---|
| 1191 | _prn.set('R', prnStr.mid(1).toInt());
|
|---|
| [10577] | 1192 | } else {
|
|---|
| [6801] | 1193 | _prn.set('R', prnStr.toInt());
|
|---|
| 1194 | }
|
|---|
| [2221] | 1195 |
|
|---|
| [10599] | 1196 | in >> year >> month >> day >> hour >> min >> sec;
|
|---|
| [10577] | 1197 | if (year < 80) {
|
|---|
| [6801] | 1198 | year += 2000;
|
|---|
| [10577] | 1199 | } else if (year < 100) {
|
|---|
| [6801] | 1200 | year += 1900;
|
|---|
| 1201 | }
|
|---|
| [2221] | 1202 |
|
|---|
| [6801] | 1203 | _gps_utc = gnumleap(year, month, day);
|
|---|
| [2221] | 1204 |
|
|---|
| [6801] | 1205 | _TOC.set(year, month, day, hour, min, sec);
|
|---|
| [10577] | 1206 | _TOC = _TOC + _gps_utc;
|
|---|
| 1207 | int nd = int((_TOC.gpssec())) / (24.0 * 60.0 * 60.0);
|
|---|
| [10587] | 1208 | if ( readDbl(line, pos[1], fieldLen, _tau)
|
|---|
| [10577] | 1209 | || readDbl(line, pos[2], fieldLen, _gamma)
|
|---|
| 1210 | || readDbl(line, pos[3], fieldLen, _tki)) {
|
|---|
| [6801] | 1211 | _checkState = bad;
|
|---|
| 1212 | return;
|
|---|
| 1213 | }
|
|---|
| [8800] | 1214 | _tki -= nd * 86400.0;
|
|---|
| [10577] | 1215 | _tau = -_tau;
|
|---|
| [6801] | 1216 | }
|
|---|
| [9788] | 1217 | // =====================
|
|---|
| 1218 | // BROADCAST ORBIT - 1
|
|---|
| 1219 | // =====================
|
|---|
| [10577] | 1220 | else if (iLine == 1) {
|
|---|
| [10587] | 1221 | if ( readDbl(line, pos[0], fieldLen, _x_pos)
|
|---|
| 1222 | || readDbl(line, pos[1], fieldLen, _x_vel)
|
|---|
| 1223 | || readDbl(line, pos[2], fieldLen, _x_acc)
|
|---|
| [10577] | 1224 | || readDbl(line, pos[3], fieldLen, _health)) {
|
|---|
| [6801] | 1225 | _checkState = bad;
|
|---|
| 1226 | return;
|
|---|
| 1227 | }
|
|---|
| 1228 | }
|
|---|
| [9788] | 1229 | // =====================
|
|---|
| 1230 | // BROADCAST ORBIT - 2
|
|---|
| 1231 | // =====================
|
|---|
| [10577] | 1232 | else if (iLine == 2) {
|
|---|
| [10614] | 1233 | if (type() == t_eph::FDMA ||
|
|---|
| 1234 | type() == t_eph::FDMA_M) {
|
|---|
| [10587] | 1235 | if ( readDbl(line, pos[0], fieldLen, _y_pos)
|
|---|
| 1236 | || readDbl(line, pos[1], fieldLen, _y_vel)
|
|---|
| 1237 | || readDbl(line, pos[2], fieldLen, _y_acc)
|
|---|
| 1238 | || readDbl(line, pos[3], fieldLen, _frq_num)) {
|
|---|
| 1239 | _checkState = bad;
|
|---|
| 1240 | return;
|
|---|
| 1241 | }
|
|---|
| [6801] | 1242 | }
|
|---|
| [10587] | 1243 | else { //L1OC, L3OC
|
|---|
| 1244 | if ( readDbl(line, pos[0], fieldLen, _y_pos)
|
|---|
| 1245 | || readDbl(line, pos[1], fieldLen, _y_vel)
|
|---|
| 1246 | || readDbl(line, pos[2], fieldLen, _y_acc)
|
|---|
| 1247 | || readDbl(line, pos[3], fieldLen, statusflags)) {
|
|---|
| 1248 | _checkState = bad;
|
|---|
| 1249 | return;
|
|---|
| 1250 | }
|
|---|
| 1251 | _data_validity = int(statusflags);
|
|---|
| 1252 | }
|
|---|
| [6801] | 1253 | }
|
|---|
| [9788] | 1254 | // =====================
|
|---|
| 1255 | // BROADCAST ORBIT - 3
|
|---|
| 1256 | // =====================
|
|---|
| [10577] | 1257 | else if (iLine == 3) {
|
|---|
| [10614] | 1258 | if (type() == t_eph::FDMA ||
|
|---|
| 1259 | type() == t_eph::FDMA_M) {
|
|---|
| [10587] | 1260 | if ( readDbl(line, pos[0], fieldLen, _z_pos)
|
|---|
| 1261 | || readDbl(line, pos[1], fieldLen, _z_vel)
|
|---|
| 1262 | || readDbl(line, pos[2], fieldLen, _z_acc)
|
|---|
| 1263 | || readDbl(line, pos[3], fieldLen, _E)) {
|
|---|
| 1264 | _checkState = bad;
|
|---|
| 1265 | return;
|
|---|
| 1266 | }
|
|---|
| [6801] | 1267 | }
|
|---|
| [10587] | 1268 | else if (type() == t_eph::L1OC) {
|
|---|
| 1269 | if ( readDbl(line, pos[0], fieldLen, _z_pos)
|
|---|
| 1270 | || readDbl(line, pos[1], fieldLen, _z_vel)
|
|---|
| 1271 | || readDbl(line, pos[2], fieldLen, _z_acc)
|
|---|
| 1272 | || readDbl(line, pos[3], fieldLen, _TGD_L2OCp)) {
|
|---|
| 1273 | _checkState = bad;
|
|---|
| 1274 | return;
|
|---|
| 1275 | }
|
|---|
| 1276 | }
|
|---|
| 1277 | else if (type() == t_eph::L3OC) {
|
|---|
| 1278 | if ( readDbl(line, pos[0], fieldLen, _z_pos)
|
|---|
| 1279 | || readDbl(line, pos[1], fieldLen, _z_vel)
|
|---|
| 1280 | || readDbl(line, pos[2], fieldLen, _z_acc)
|
|---|
| 1281 | || readDbl(line, pos[3], fieldLen, _TGD_L3OCp)) {
|
|---|
| 1282 | _checkState = bad;
|
|---|
| 1283 | return;
|
|---|
| 1284 | }
|
|---|
| 1285 | }
|
|---|
| [6801] | 1286 | }
|
|---|
| [9788] | 1287 | // =====================
|
|---|
| 1288 | // BROADCAST ORBIT - 4
|
|---|
| 1289 | // =====================
|
|---|
| [10577] | 1290 | else if (iLine == 4) {
|
|---|
| [10614] | 1291 | if (type() == t_eph::FDMA ||
|
|---|
| 1292 | type() == t_eph::FDMA_M) {
|
|---|
| [10587] | 1293 | if (readDbl(line, pos[0], fieldLen, statusflags)) {
|
|---|
| 1294 | //status flags BLK, do nothing
|
|---|
| 1295 | _statusflags_unknown = true;
|
|---|
| 1296 | } else {
|
|---|
| 1297 | _statusflags_unknown = false;
|
|---|
| 1298 | // status flags
|
|---|
| 1299 | // ============
|
|---|
| 1300 | // bit 0-1
|
|---|
| [10688] | 1301 | _M_P = double(bitExtracted(unsigned(statusflags), 2, 0));
|
|---|
| [10587] | 1302 | // bit 2-3
|
|---|
| [10688] | 1303 | _P1 = double(bitExtracted(unsigned(statusflags), 2, 2));
|
|---|
| [10587] | 1304 | // bit 4
|
|---|
| [10688] | 1305 | _P2 = double(bitExtracted(unsigned(statusflags), 1, 4));
|
|---|
| [10587] | 1306 | // bit 5
|
|---|
| [10688] | 1307 | _P3 = double(bitExtracted(unsigned(statusflags), 1, 5));
|
|---|
| [10587] | 1308 | // bit 6
|
|---|
| [10688] | 1309 | _M_P4 = double(bitExtracted(unsigned(statusflags), 1, 6));
|
|---|
| [10587] | 1310 | // bit 7-8
|
|---|
| [10688] | 1311 | _M_M = double(bitExtracted(unsigned(statusflags), 2, 7));
|
|---|
| [10587] | 1312 | /// GLO M/K exclusive flags/values only valid if flag M is set to '01'
|
|---|
| 1313 | if (!_M_M) {
|
|---|
| 1314 | _M_P = 0.0;
|
|---|
| 1315 | _M_l3 = 0.0;
|
|---|
| 1316 | _M_P4 = 0.0;
|
|---|
| 1317 | _M_FE = 0.0;
|
|---|
| 1318 | _M_FT = 0.0;
|
|---|
| 1319 | _M_NA = 0.0;
|
|---|
| 1320 | _M_NT = 0.0;
|
|---|
| 1321 | _M_N4 = 0.0;
|
|---|
| 1322 | _M_l5 = 0.0;
|
|---|
| 1323 | _M_tau_GPS = 0.0;
|
|---|
| 1324 | _M_delta_tau = 0.0;
|
|---|
| [10614] | 1325 | _type = t_eph::FDMA;
|
|---|
| [10587] | 1326 | }
|
|---|
| [10599] | 1327 | else {
|
|---|
| 1328 | _type = t_eph::FDMA_M;
|
|---|
| 1329 | }
|
|---|
| [10587] | 1330 | }
|
|---|
| 1331 | if ( readDbl(line, pos[1], fieldLen, _M_delta_tau)
|
|---|
| 1332 | || readDbl(line, pos[2], fieldLen, _M_FT)) {
|
|---|
| 1333 | _checkState = bad;
|
|---|
| 1334 | return;
|
|---|
| 1335 | }
|
|---|
| 1336 | if (readDbl(line, pos[3], fieldLen, healthflags)) {
|
|---|
| 1337 | // health flags BLK
|
|---|
| 1338 | _healthflags_unknown = true;
|
|---|
| 1339 | } else {
|
|---|
| 1340 | _healthflags_unknown = false;
|
|---|
| 1341 | // health flags
|
|---|
| 1342 | // ============
|
|---|
| 1343 | // bit 0 (is to be ignored, if bit 1 is zero)
|
|---|
| [10688] | 1344 | _almanac_health = double(bitExtracted(unsigned(healthflags), 1, 0));
|
|---|
| [10587] | 1345 | // bit 1
|
|---|
| 1346 | _almanac_health_availablility_indicator =
|
|---|
| [10688] | 1347 | double(bitExtracted(unsigned(healthflags), 1, 1));
|
|---|
| [10587] | 1348 | // bit 2; GLO-M/K only, health bit of string 3
|
|---|
| [10688] | 1349 | _M_l3 = double(bitExtracted(unsigned(healthflags), 1, 2));
|
|---|
| [10587] | 1350 | }
|
|---|
| 1351 | }
|
|---|
| 1352 | else if (type() == t_eph::L1OC ||
|
|---|
| 1353 | type() == t_eph::L3OC) {
|
|---|
| 1354 | if ( readDbl(line, pos[0], fieldLen, _sat_type)
|
|---|
| 1355 | || readDbl(line, pos[1], fieldLen, sourceflags)
|
|---|
| 1356 | || readDbl(line, pos[2], fieldLen, _EE)
|
|---|
| 1357 | || readDbl(line, pos[3], fieldLen, _ET)) {
|
|---|
| 1358 | _checkState = bad;
|
|---|
| 1359 | return;
|
|---|
| 1360 | }
|
|---|
| 1361 | // sourceflags:
|
|---|
| [9367] | 1362 | // ============
|
|---|
| 1363 | // bit 0-1
|
|---|
| [10688] | 1364 | _RT = double(bitExtracted(unsigned(sourceflags), 2, 0));
|
|---|
| [10587] | 1365 | // bit 2-3:
|
|---|
| [10688] | 1366 | _RE = double(bitExtracted(unsigned(sourceflags), 2, 2));
|
|---|
| [10587] | 1367 | }
|
|---|
| 1368 | }
|
|---|
| 1369 | // =====================
|
|---|
| 1370 | // BROADCAST ORBIT - 5
|
|---|
| 1371 | // =====================
|
|---|
| 1372 | else if (iLine == 5) {
|
|---|
| 1373 | if (type() == t_eph::L1OC ||
|
|---|
| 1374 | type() == t_eph::L3OC) {
|
|---|
| 1375 | if ( readDbl(line, pos[0], fieldLen, _attitude_P2)
|
|---|
| 1376 | || readDbl(line, pos[1], fieldLen, _Tin)
|
|---|
| 1377 | || readDbl(line, pos[2], fieldLen, _tau1)
|
|---|
| 1378 | || readDbl(line, pos[3], fieldLen, _tau2)) {
|
|---|
| 1379 | _checkState = bad;
|
|---|
| 1380 | return;
|
|---|
| [9367] | 1381 | }
|
|---|
| [9892] | 1382 | }
|
|---|
| [10587] | 1383 | }
|
|---|
| 1384 | // =====================
|
|---|
| 1385 | // BROADCAST ORBIT - 6
|
|---|
| 1386 | // =====================
|
|---|
| 1387 | else if (iLine == 6) {
|
|---|
| 1388 | if (type() == t_eph::L1OC ||
|
|---|
| 1389 | type() == t_eph::L3OC) {
|
|---|
| 1390 | if ( readDbl(line, pos[0], fieldLen, _yaw)
|
|---|
| 1391 | || readDbl(line, pos[1], fieldLen, _sn)
|
|---|
| 1392 | || readDbl(line, pos[2], fieldLen, _angular_rate)
|
|---|
| 1393 | || readDbl(line, pos[3], fieldLen, _angular_acc)) {
|
|---|
| 1394 | _checkState = bad;
|
|---|
| 1395 | return;
|
|---|
| 1396 | }
|
|---|
| [9892] | 1397 | }
|
|---|
| [10587] | 1398 | }
|
|---|
| 1399 | // =====================
|
|---|
| 1400 | // BROADCAST ORBIT - 7
|
|---|
| 1401 | // =====================
|
|---|
| 1402 | else if (iLine == 7) {
|
|---|
| 1403 | if (type() == t_eph::L1OC ||
|
|---|
| 1404 | type() == t_eph::L3OC) {
|
|---|
| 1405 | if ( readDbl(line, pos[0], fieldLen, _angular_rate_max)
|
|---|
| 1406 | || readDbl(line, pos[1], fieldLen, _X_PC)
|
|---|
| 1407 | || readDbl(line, pos[2], fieldLen, _Y_PC)
|
|---|
| 1408 | || readDbl(line, pos[3], fieldLen, _Z_PC)) {
|
|---|
| 1409 | _checkState = bad;
|
|---|
| 1410 | return;
|
|---|
| 1411 | }
|
|---|
| [9367] | 1412 | }
|
|---|
| 1413 | }
|
|---|
| [10587] | 1414 | // =====================
|
|---|
| 1415 | // BROADCAST ORBIT - 8
|
|---|
| 1416 | // =====================
|
|---|
| 1417 | else if (iLine == 8) {
|
|---|
| 1418 | if (type() == t_eph::L1OC ||
|
|---|
| 1419 | type() == t_eph::L3OC) {
|
|---|
| 1420 | if ( readDbl(line, pos[0], fieldLen, _M_FE)
|
|---|
| 1421 | || readDbl(line, pos[1], fieldLen, _M_FT)
|
|---|
| 1422 | || readDbl(line, pos[3], fieldLen, _TOT)) {
|
|---|
| 1423 | _checkState = bad;
|
|---|
| 1424 | return;
|
|---|
| 1425 | }
|
|---|
| 1426 | }
|
|---|
| 1427 | }
|
|---|
| [6801] | 1428 | }
|
|---|
| 1429 |
|
|---|
| [10599] | 1430 | _prn.setFlag(type());
|
|---|
| 1431 |
|
|---|
| [6801] | 1432 | // Initialize status vector
|
|---|
| 1433 | // ------------------------
|
|---|
| 1434 | _tt = _TOC;
|
|---|
| [10577] | 1435 | _xv.ReSize(6);
|
|---|
| 1436 | _xv = 0.0;
|
|---|
| [6801] | 1437 | _xv(1) = _x_pos * 1.e3;
|
|---|
| 1438 | _xv(2) = _y_pos * 1.e3;
|
|---|
| 1439 | _xv(3) = _z_pos * 1.e3;
|
|---|
| [10587] | 1440 | _xv(4) = _x_vel * 1.e3;
|
|---|
| 1441 | _xv(5) = _y_vel * 1.e3;
|
|---|
| 1442 | _xv(6) = _z_vel * 1.e3;
|
|---|
| [2221] | 1443 | }
|
|---|
| 1444 |
|
|---|
| [6801] | 1445 | // Compute Glonass Satellite Position (virtual)
|
|---|
| [2771] | 1446 | ////////////////////////////////////////////////////////////////////////////
|
|---|
| [10577] | 1447 | t_irc t_ephGlo::position(int GPSweek, double GPSweeks, double *xc,
|
|---|
| 1448 | double *vv) const {
|
|---|
| [2771] | 1449 |
|
|---|
| [6801] | 1450 | static const double nominalStep = 10.0;
|
|---|
| [2771] | 1451 |
|
|---|
| [10577] | 1452 | memset(xc, 0, 6 * sizeof(double));
|
|---|
| 1453 | memset(vv, 0, 3 * sizeof(double));
|
|---|
| [2771] | 1454 |
|
|---|
| [10954] | 1455 | bncTime tt(GPSweek, GPSweeks);
|
|---|
| 1456 | double dtPos = tt - _TOC;
|
|---|
| [6801] | 1457 |
|
|---|
| [8698] | 1458 | if (fabs(dtPos) > 24 * 3600.0) {
|
|---|
| [6213] | 1459 | return failure;
|
|---|
| [2771] | 1460 | }
|
|---|
| 1461 |
|
|---|
| [10577] | 1462 | int nSteps = int(fabs(dtPos) / nominalStep) + 1;
|
|---|
| [6801] | 1463 | double step = dtPos / nSteps;
|
|---|
| [4018] | 1464 |
|
|---|
| [6801] | 1465 | double acc[3];
|
|---|
| [10587] | 1466 | acc[0] = _x_acc * 1.e3;
|
|---|
| 1467 | acc[1] = _y_acc * 1.e3;
|
|---|
| 1468 | acc[2] = _z_acc * 1.e3;
|
|---|
| [9132] | 1469 |
|
|---|
| [10954] | 1470 | // Always integrate fresh from the pristine, decoded TOC state rather
|
|---|
| 1471 | // than rolling _tt/_xv forward across repeated calls. position() can be
|
|---|
| 1472 | // called very frequently (multiple times per epoch, from multiple call
|
|---|
| 1473 | // sites) - chaining many short integration steps across those calls,
|
|---|
| 1474 | // instead of one direct integration to the requested time, lets small
|
|---|
| 1475 | // per-call numerical error accumulate over wall-clock time independent
|
|---|
| 1476 | // of how far the request actually is from TOC, producing a slow but
|
|---|
| 1477 | // steady drift (observed: ~0.5-0.7 mm/s along-track for a GLONASS
|
|---|
| 1478 | // satellite whose broadcast message was barely a few minutes old).
|
|---|
| 1479 | // ----------------------------------------------------------------
|
|---|
| 1480 | ColumnVector xv(6);
|
|---|
| 1481 | xv(1) = _x_pos * 1.e3;
|
|---|
| 1482 | xv(2) = _y_pos * 1.e3;
|
|---|
| 1483 | xv(3) = _z_pos * 1.e3;
|
|---|
| 1484 | xv(4) = _x_vel * 1.e3;
|
|---|
| 1485 | xv(5) = _y_vel * 1.e3;
|
|---|
| 1486 | xv(6) = _z_vel * 1.e3;
|
|---|
| 1487 |
|
|---|
| 1488 | bncTime ttLocal = _TOC;
|
|---|
| [6801] | 1489 | for (int ii = 1; ii <= nSteps; ii++) {
|
|---|
| [10954] | 1490 | xv = rungeKutta4(ttLocal.gpssec(), xv, step, acc, glo_deriv);
|
|---|
| 1491 | ttLocal = ttLocal + step;
|
|---|
| [6801] | 1492 | }
|
|---|
| [4018] | 1493 |
|
|---|
| [6801] | 1494 | // Position and Velocity
|
|---|
| 1495 | // ---------------------
|
|---|
| [10954] | 1496 | xc[0] = xv(1);
|
|---|
| 1497 | xc[1] = xv(2);
|
|---|
| 1498 | xc[2] = xv(3);
|
|---|
| [2771] | 1499 |
|
|---|
| [10954] | 1500 | vv[0] = xv(4);
|
|---|
| 1501 | vv[1] = xv(5);
|
|---|
| 1502 | vv[2] = xv(6);
|
|---|
| [2771] | 1503 |
|
|---|
| [6801] | 1504 | // Clock Correction
|
|---|
| 1505 | // ----------------
|
|---|
| [10954] | 1506 | double dtClk = tt - _TOC;
|
|---|
| [6801] | 1507 | xc[3] = -_tau + _gamma * dtClk;
|
|---|
| [2771] | 1508 |
|
|---|
| [8542] | 1509 | xc[4] = _gamma;
|
|---|
| 1510 | xc[5] = 0.0;
|
|---|
| [8483] | 1511 |
|
|---|
| [6213] | 1512 | return success;
|
|---|
| [2771] | 1513 | }
|
|---|
| 1514 |
|
|---|
| [6801] | 1515 | // RINEX Format String
|
|---|
| [3659] | 1516 | //////////////////////////////////////////////////////////////////////////////
|
|---|
| [6801] | 1517 | QString t_ephGlo::toString(double version) const {
|
|---|
| [3664] | 1518 |
|
|---|
| [10587] | 1519 | if (version < 4.0 &&
|
|---|
| 1520 | (type() == t_eph::L1OC ||
|
|---|
| 1521 | type() == t_eph::L3OC )) {
|
|---|
| 1522 | return "";
|
|---|
| 1523 | }
|
|---|
| 1524 |
|
|---|
| 1525 | QString ephStr = typeStr(_type, _prn, version);
|
|---|
| [10577] | 1526 | QString rnxStr = ephStr + rinexDateStr(_TOC - _gps_utc, _prn, version);
|
|---|
| 1527 | int nd = int((_TOC - _gps_utc).gpssec()) / (24.0 * 60.0 * 60.0);
|
|---|
| [6801] | 1528 | QTextStream out(&rnxStr);
|
|---|
| [3664] | 1529 |
|
|---|
| [10577] | 1530 | out
|
|---|
| [10587] | 1531 | << QString("%1%2%3\n")
|
|---|
| 1532 | .arg(-_tau, 19, 'e', 12)
|
|---|
| 1533 | .arg(_gamma, 19, 'e', 12)
|
|---|
| 1534 | .arg(_tki + nd * 86400.0, 19, 'e', 12);
|
|---|
| [3668] | 1535 |
|
|---|
| [6801] | 1536 | QString fmt = version < 3.0 ? " %1%2%3%4\n" : " %1%2%3%4\n";
|
|---|
| [9788] | 1537 | // =====================
|
|---|
| 1538 | // BROADCAST ORBIT - 1
|
|---|
| 1539 | // =====================
|
|---|
| [10577] | 1540 | out
|
|---|
| [10587] | 1541 | << QString(fmt)
|
|---|
| 1542 | .arg(_x_pos, 19, 'e', 12)
|
|---|
| 1543 | .arg(_x_vel, 19, 'e', 12)
|
|---|
| 1544 | .arg(_x_acc, 19, 'e', 12)
|
|---|
| 1545 | .arg(_health, 19, 'e', 12);
|
|---|
| 1546 |
|
|---|
| [9788] | 1547 | // =====================
|
|---|
| 1548 | // BROADCAST ORBIT - 2
|
|---|
| 1549 | // =====================
|
|---|
| [10599] | 1550 | if (type() == t_eph::FDMA ||
|
|---|
| 1551 | type() == t_eph::FDMA_M) {
|
|---|
| [10587] | 1552 | out
|
|---|
| 1553 | << QString(fmt)
|
|---|
| 1554 | .arg(_y_pos, 19, 'e', 12)
|
|---|
| 1555 | .arg(_y_vel, 19, 'e', 12)
|
|---|
| 1556 | .arg(_y_acc, 19, 'e', 12)
|
|---|
| 1557 | .arg(_frq_num, 19, 'e', 12);
|
|---|
| 1558 | }
|
|---|
| 1559 | else { //L1OC, L3OC
|
|---|
| 1560 | out
|
|---|
| 1561 | << QString(fmt)
|
|---|
| 1562 | .arg(_y_pos, 19, 'e', 12)
|
|---|
| 1563 | .arg(_y_vel, 19, 'e', 12)
|
|---|
| 1564 | .arg(_y_acc, 19, 'e', 12)
|
|---|
| 1565 | .arg(double(_data_validity), 19, 'e', 12);
|
|---|
| 1566 | }
|
|---|
| [9788] | 1567 | // =====================
|
|---|
| 1568 | // BROADCAST ORBIT - 3
|
|---|
| 1569 | // =====================
|
|---|
| [10599] | 1570 | if (type() == t_eph::FDMA ||
|
|---|
| 1571 | type() == t_eph::FDMA_M) {
|
|---|
| [10587] | 1572 | out
|
|---|
| 1573 | << QString(fmt)
|
|---|
| 1574 | .arg(_z_pos, 19, 'e', 12)
|
|---|
| 1575 | .arg(_z_vel, 19, 'e', 12)
|
|---|
| 1576 | .arg(_z_acc, 19, 'e', 12)
|
|---|
| 1577 | .arg(_E, 19, 'e', 12);
|
|---|
| 1578 | }
|
|---|
| 1579 | else if (type() == t_eph::L1OC) {
|
|---|
| 1580 | out
|
|---|
| 1581 | << QString(fmt)
|
|---|
| 1582 | .arg(_z_pos, 19, 'e', 12)
|
|---|
| 1583 | .arg(_z_vel, 19, 'e', 12)
|
|---|
| 1584 | .arg(_z_acc, 19, 'e', 12)
|
|---|
| 1585 | .arg(_TGD_L2OCp, 19, 'e', 12);
|
|---|
| 1586 | }
|
|---|
| 1587 | else if (type() == t_eph::L3OC) {
|
|---|
| 1588 | out
|
|---|
| 1589 | << QString(fmt)
|
|---|
| 1590 | .arg(_z_pos, 19, 'e', 12)
|
|---|
| 1591 | .arg(_z_vel, 19, 'e', 12)
|
|---|
| 1592 | .arg(_z_acc, 19, 'e', 12)
|
|---|
| 1593 | .arg(_TGD_L3OCp, 19, 'e', 12);
|
|---|
| 1594 | }
|
|---|
| [9367] | 1595 | if (version >= 3.05) {
|
|---|
| [10587] | 1596 | // =====================
|
|---|
| 1597 | // BROADCAST ORBIT - 4
|
|---|
| 1598 | // =====================
|
|---|
| [10599] | 1599 | if (type() == t_eph::FDMA ||
|
|---|
| 1600 | type() == t_eph::FDMA_M){
|
|---|
| [9367] | 1601 | int statusflags = 0;
|
|---|
| [10587] | 1602 | int healthflags = 0;
|
|---|
| 1603 | if (!_statusflags_unknown ) {
|
|---|
| 1604 | // bit 0-1
|
|---|
| 1605 | if (_M_P == 1.0) {statusflags |= (1 << 0);}
|
|---|
| 1606 | else if (_M_P == 2.0) {statusflags |= (1 << 1);}
|
|---|
| 1607 | else if (_M_P == 3.0) {statusflags |= (1 << 0); statusflags |= (1 << 1);}
|
|---|
| 1608 | // bit 2-3
|
|---|
| 1609 | if (_P1 == 1.0) {statusflags |= (1 << 2);}
|
|---|
| 1610 | else if (_P1 == 2.0) {statusflags |= (1 << 3);}
|
|---|
| 1611 | else if (_P1 == 3.0) {statusflags |= (1 << 2); statusflags |= (1 << 3);}
|
|---|
| 1612 | // bit 4
|
|---|
| 1613 | if (_P2) {statusflags |= (1 << 4);}
|
|---|
| 1614 | // bit 5
|
|---|
| 1615 | if (_P3) {statusflags |= (1 << 5);}
|
|---|
| 1616 | // bit 6
|
|---|
| 1617 | if (_M_P4) {statusflags |= (1 << 6);}
|
|---|
| 1618 | // bit 7-8
|
|---|
| 1619 | if (_M_M == 1.0) {statusflags |= (1 << 7);}
|
|---|
| [9367] | 1620 | }
|
|---|
| [10587] | 1621 | if (!_healthflags_unknown) {
|
|---|
| 1622 | // bit 0 (is to be ignored, if bit 1 is zero)
|
|---|
| 1623 | if (_almanac_health) {healthflags |= (1 << 0);}
|
|---|
| 1624 | // bit 1
|
|---|
| 1625 | if (_almanac_health_availablility_indicator) {healthflags |= (1 << 1);}
|
|---|
| 1626 | // bit 2
|
|---|
| 1627 | if (_M_l3) {healthflags |= (1 << 2);}
|
|---|
| [9367] | 1628 | }
|
|---|
| [10587] | 1629 |
|
|---|
| 1630 | if (_statusflags_unknown && _healthflags_unknown) {
|
|---|
| 1631 | out
|
|---|
| 1632 | << QString(fmt)
|
|---|
| 1633 | .arg("", 19, QChar(' ')) // status-flags BNK (unknown)
|
|---|
| 1634 | .arg(_M_delta_tau, 19, 'e', 12)
|
|---|
| 1635 | .arg(_M_FT, 19, 'e', 12)
|
|---|
| 1636 | .arg("", 19, QChar(' '));// health-flags BNK (unknown)
|
|---|
| [9367] | 1637 | }
|
|---|
| [10587] | 1638 | else if (!_statusflags_unknown && _healthflags_unknown) {
|
|---|
| 1639 | out
|
|---|
| 1640 | << QString(fmt)
|
|---|
| 1641 | .arg(double(statusflags), 19, 'e', 12)
|
|---|
| 1642 | .arg(_M_delta_tau, 19, 'e', 12)
|
|---|
| 1643 | .arg(_M_FT, 19, 'e', 12)
|
|---|
| 1644 | .arg("", 19, QChar(' '));// health-flags BNK (unknown)
|
|---|
| [9367] | 1645 | }
|
|---|
| [10587] | 1646 | else if (_statusflags_unknown && !_healthflags_unknown) {
|
|---|
| 1647 | out
|
|---|
| 1648 | << QString(fmt)
|
|---|
| 1649 | .arg("", 19, QChar(' ')) // status-flags BNK (unknown)
|
|---|
| 1650 | .arg(_M_delta_tau, 19, 'e', 12)
|
|---|
| 1651 | .arg(_M_FT, 19, 'e', 12)
|
|---|
| 1652 | .arg(double(healthflags), 19, 'e', 12);
|
|---|
| [9367] | 1653 | }
|
|---|
| [10587] | 1654 | else if (!_statusflags_unknown && !_healthflags_unknown) {
|
|---|
| 1655 | out
|
|---|
| 1656 | << QString(fmt)
|
|---|
| 1657 | .arg(double(statusflags), 19, 'e', 12)
|
|---|
| 1658 | .arg(_M_delta_tau, 19, 'e', 12)
|
|---|
| 1659 | .arg(_M_FT, 19, 'e', 12)
|
|---|
| 1660 | .arg(double(healthflags), 19, 'e', 12);
|
|---|
| 1661 | }
|
|---|
| 1662 | }
|
|---|
| 1663 | else if (type() == t_eph::L1OC ||
|
|---|
| 1664 | type() == t_eph::L3OC) {
|
|---|
| 1665 | int sourceflags = 0;
|
|---|
| [9367] | 1666 | // bit 0-1
|
|---|
| [10587] | 1667 | if (_RT == 1.0) {sourceflags |= (1 << 0);}
|
|---|
| 1668 | else if (_RT == 2.0) {sourceflags |= (1 << 1);}
|
|---|
| 1669 | else if (_RT == 3.0) {sourceflags |= (1 << 0); sourceflags |= (1 << 1);}
|
|---|
| 1670 | // bit 2-3
|
|---|
| 1671 | if (_RE == 1.0) {sourceflags |= (1 << 2);}
|
|---|
| 1672 | else if (_RE == 2.0) {sourceflags |= (1 << 3);}
|
|---|
| 1673 | else if (_RE == 3.0) {sourceflags |= (1 << 2); sourceflags |= (1 << 3);}
|
|---|
| [10577] | 1674 | out
|
|---|
| [10587] | 1675 | << QString(fmt)
|
|---|
| 1676 | .arg(_sat_type , 19, 'e', 12)
|
|---|
| 1677 | .arg(double(sourceflags), 19, 'e', 12)
|
|---|
| 1678 | .arg(_ET, 19, 'e', 12)
|
|---|
| 1679 | .arg(_EE, 19, 'e', 12);
|
|---|
| [9367] | 1680 | }
|
|---|
| [10587] | 1681 | // =====================
|
|---|
| 1682 | // BROADCAST ORBIT - 5
|
|---|
| 1683 | // =====================
|
|---|
| 1684 | if (type() == t_eph::L1OC ||
|
|---|
| 1685 | type() == t_eph::L3OC) {
|
|---|
| 1686 | out
|
|---|
| 1687 | << QString(fmt)
|
|---|
| 1688 | .arg(_attitude_P2, 19, 'e', 12)
|
|---|
| 1689 | .arg(_Tin, 19, 'e', 12)
|
|---|
| 1690 | .arg(_tau1, 19, 'e', 12)
|
|---|
| 1691 | .arg(_tau2, 19, 'e', 12);
|
|---|
| 1692 | }
|
|---|
| 1693 | // =====================
|
|---|
| 1694 | // BROADCAST ORBIT - 6
|
|---|
| 1695 | // =====================
|
|---|
| 1696 | if (type() == t_eph::L1OC ||
|
|---|
| 1697 | type() == t_eph::L3OC) {
|
|---|
| 1698 | out
|
|---|
| 1699 | << QString(fmt)
|
|---|
| 1700 | .arg(_yaw, 19, 'e', 12)
|
|---|
| 1701 | .arg(_sn, 19, 'e', 12)
|
|---|
| 1702 | .arg(_angular_rate, 19, 'e', 12)
|
|---|
| 1703 | .arg(_angular_acc, 19, 'e', 12);
|
|---|
| 1704 | }
|
|---|
| 1705 | // =====================
|
|---|
| 1706 | // BROADCAST ORBIT - 7
|
|---|
| 1707 | // =====================
|
|---|
| 1708 | if (type() == t_eph::L1OC ||
|
|---|
| 1709 | type() == t_eph::L3OC) {
|
|---|
| 1710 | out
|
|---|
| 1711 | << QString(fmt)
|
|---|
| 1712 | .arg(_angular_rate_max, 19, 'e', 12)
|
|---|
| 1713 | .arg(_X_PC, 19, 'e', 12)
|
|---|
| 1714 | .arg(_Y_PC, 19, 'e', 12)
|
|---|
| 1715 | .arg(_Z_PC, 19, 'e', 12);
|
|---|
| 1716 | }
|
|---|
| 1717 | // =====================
|
|---|
| 1718 | // BROADCAST ORBIT - 8
|
|---|
| 1719 | // =====================
|
|---|
| 1720 | if (type() == t_eph::L1OC ||
|
|---|
| 1721 | type() == t_eph::L3OC) {
|
|---|
| 1722 | out
|
|---|
| 1723 | << QString(fmt)
|
|---|
| 1724 | .arg(_M_FE, 19, 'e', 12)
|
|---|
| 1725 | .arg(_M_FT, 19, 'e', 12)
|
|---|
| 1726 | .arg("", 19, QChar(' '))
|
|---|
| 1727 | .arg(_TOT, 19, 'e', 12);
|
|---|
| 1728 | }
|
|---|
| [9367] | 1729 | }
|
|---|
| [6801] | 1730 | return rnxStr;
|
|---|
| [3659] | 1731 | }
|
|---|
| 1732 |
|
|---|
| [6801] | 1733 | // Derivative of the state vector using a simple force model (static)
|
|---|
| 1734 | ////////////////////////////////////////////////////////////////////////////
|
|---|
| [10577] | 1735 | ColumnVector t_ephGlo::glo_deriv(double /* tt */, const ColumnVector &xv,
|
|---|
| 1736 | double *acc) {
|
|---|
| [3659] | 1737 |
|
|---|
| [6801] | 1738 | // State vector components
|
|---|
| 1739 | // -----------------------
|
|---|
| [10577] | 1740 | ColumnVector rr = xv.rows(1, 3);
|
|---|
| 1741 | ColumnVector vv = xv.rows(4, 6);
|
|---|
| [3699] | 1742 |
|
|---|
| [6801] | 1743 | // Acceleration
|
|---|
| [3699] | 1744 | // ------------
|
|---|
| [6801] | 1745 | static const double gmWGS = 398.60044e12;
|
|---|
| [10577] | 1746 | static const double AE = 6378136.0;
|
|---|
| [6801] | 1747 | static const double OMEGA = 7292115.e-11;
|
|---|
| [10577] | 1748 | static const double C20 = -1082.6257e-6;
|
|---|
| [3699] | 1749 |
|
|---|
| [8903] | 1750 | double rho = rr.NormFrobenius();
|
|---|
| [10577] | 1751 | double t1 = -gmWGS / (rho * rho * rho);
|
|---|
| 1752 | double t2 = 3.0 / 2.0 * C20 * (gmWGS * AE * AE)
|
|---|
| 1753 | / (rho * rho * rho * rho * rho);
|
|---|
| 1754 | double t3 = OMEGA * OMEGA;
|
|---|
| 1755 | double t4 = 2.0 * OMEGA;
|
|---|
| 1756 | double z2 = rr(3) * rr(3);
|
|---|
| [3699] | 1757 |
|
|---|
| [6801] | 1758 | // Vector of derivatives
|
|---|
| 1759 | // ---------------------
|
|---|
| 1760 | ColumnVector va(6);
|
|---|
| 1761 | va(1) = vv(1);
|
|---|
| 1762 | va(2) = vv(2);
|
|---|
| 1763 | va(3) = vv(3);
|
|---|
| [10577] | 1764 | va(4) = (t1 + t2 * (1.0 - 5.0 * z2 / (rho * rho)) + t3) * rr(1) + t4 * vv(2)
|
|---|
| 1765 | + acc[0];
|
|---|
| 1766 | va(5) = (t1 + t2 * (1.0 - 5.0 * z2 / (rho * rho)) + t3) * rr(2) - t4 * vv(1)
|
|---|
| 1767 | + acc[1];
|
|---|
| 1768 | va(6) = (t1 + t2 * (3.0 - 5.0 * z2 / (rho * rho))) * rr(3) + acc[2];
|
|---|
| [3699] | 1769 |
|
|---|
| [6801] | 1770 | return va;
|
|---|
| 1771 | }
|
|---|
| [3699] | 1772 |
|
|---|
| [6801] | 1773 | // IOD of Glonass Ephemeris (virtual)
|
|---|
| 1774 | ////////////////////////////////////////////////////////////////////////////
|
|---|
| [7169] | 1775 | unsigned int t_ephGlo::IOD() const {
|
|---|
| [6801] | 1776 | bncTime tMoscow = _TOC - _gps_utc + 3 * 3600.0;
|
|---|
| [10577] | 1777 | return (unsigned long) tMoscow.daysec() / 900;
|
|---|
| [3659] | 1778 | }
|
|---|
| 1779 |
|
|---|
| [8187] | 1780 | // Health status of Glonass Ephemeris (virtual)
|
|---|
| 1781 | ////////////////////////////////////////////////////////////////////////////
|
|---|
| 1782 | unsigned int t_ephGlo::isUnhealthy() const {
|
|---|
| [8215] | 1783 |
|
|---|
| [8217] | 1784 | if (_almanac_health_availablility_indicator) {
|
|---|
| [10577] | 1785 | if ((_health == 0 && _almanac_health == 0)
|
|---|
| 1786 | || (_health == 1 && _almanac_health == 0)
|
|---|
| 1787 | || (_health == 1 && _almanac_health == 1)) {
|
|---|
| 1788 | return 1;
|
|---|
| 1789 | }
|
|---|
| 1790 | } else if (!_almanac_health_availablility_indicator) {
|
|---|
| [8217] | 1791 | if (_health) {
|
|---|
| 1792 | return 1;
|
|---|
| 1793 | }
|
|---|
| 1794 | }
|
|---|
| [8215] | 1795 | return 0; /* (_health == 0 && _almanac_health == 1) or (_health == 0) */
|
|---|
| [8187] | 1796 | }
|
|---|
| 1797 |
|
|---|
| [3659] | 1798 | // Constructor
|
|---|
| 1799 | //////////////////////////////////////////////////////////////////////////////
|
|---|
| [10603] | 1800 | t_ephGal::t_ephGal(double rnxVersion, const QStringList &lines, const QString typeStr) {
|
|---|
| [10599] | 1801 |
|
|---|
| [10603] | 1802 | setType(typeStr);
|
|---|
| 1803 |
|
|---|
| [4891] | 1804 | const int nLines = 8;
|
|---|
| [10599] | 1805 |
|
|---|
| [4891] | 1806 | if (lines.size() != nLines) {
|
|---|
| [6518] | 1807 | _checkState = bad;
|
|---|
| [4891] | 1808 | return;
|
|---|
| 1809 | }
|
|---|
| 1810 |
|
|---|
| 1811 | // RINEX Format
|
|---|
| 1812 | // ------------
|
|---|
| 1813 | int fieldLen = 19;
|
|---|
| [6792] | 1814 | double SVhealth = 0.0;
|
|---|
| 1815 | double datasource = 0.0;
|
|---|
| [6798] | 1816 |
|
|---|
| [4891] | 1817 | int pos[4];
|
|---|
| [10577] | 1818 | pos[0] = (rnxVersion <= 2.12) ? 3 : 4;
|
|---|
| [4891] | 1819 | pos[1] = pos[0] + fieldLen;
|
|---|
| 1820 | pos[2] = pos[1] + fieldLen;
|
|---|
| 1821 | pos[3] = pos[2] + fieldLen;
|
|---|
| 1822 |
|
|---|
| 1823 | // Read eight lines
|
|---|
| 1824 | // ----------------
|
|---|
| 1825 | for (int iLine = 0; iLine < nLines; iLine++) {
|
|---|
| 1826 | QString line = lines[iLine];
|
|---|
| 1827 |
|
|---|
| [10577] | 1828 | if (iLine == 0) {
|
|---|
| [8204] | 1829 | QTextStream in(line.left(pos[1]).toLatin1());
|
|---|
| [10599] | 1830 |
|
|---|
| 1831 | int year, month, day, hour, min;
|
|---|
| 1832 | double sec;
|
|---|
| 1833 |
|
|---|
| 1834 | QString prnStr, n;
|
|---|
| [6880] | 1835 | in >> prnStr;
|
|---|
| [7639] | 1836 | if (prnStr.size() == 1 && prnStr[0] == 'E') {
|
|---|
| [7139] | 1837 | in >> n;
|
|---|
| 1838 | prnStr.append(n);
|
|---|
| [6880] | 1839 | }
|
|---|
| [10599] | 1840 | if (prnStr.at(0) == 'E') {
|
|---|
| 1841 | _prn.set('E', prnStr.mid(1).toInt());
|
|---|
| 1842 | } else {
|
|---|
| 1843 | _prn.set('E', prnStr.toInt());
|
|---|
| 1844 | }
|
|---|
| 1845 |
|
|---|
| [6880] | 1846 | in >> year >> month >> day >> hour >> min >> sec;
|
|---|
| [10577] | 1847 | if (year < 80) {
|
|---|
| [4891] | 1848 | year += 2000;
|
|---|
| [10577] | 1849 | } else if (year < 100) {
|
|---|
| [4891] | 1850 | year += 1900;
|
|---|
| 1851 | }
|
|---|
| 1852 |
|
|---|
| 1853 | _TOC.set(year, month, day, hour, min, sec);
|
|---|
| 1854 |
|
|---|
| [10587] | 1855 | if ( readDbl(line, pos[1], fieldLen, _clock_bias)
|
|---|
| [10577] | 1856 | || readDbl(line, pos[2], fieldLen, _clock_drift)
|
|---|
| 1857 | || readDbl(line, pos[3], fieldLen, _clock_driftrate)) {
|
|---|
| [6518] | 1858 | _checkState = bad;
|
|---|
| [4891] | 1859 | return;
|
|---|
| 1860 | }
|
|---|
| 1861 | }
|
|---|
| [9788] | 1862 | // =====================
|
|---|
| 1863 | // BROADCAST ORBIT - 1
|
|---|
| 1864 | // =====================
|
|---|
| [10577] | 1865 | else if (iLine == 1) {
|
|---|
| [10587] | 1866 | if ( readDbl(line, pos[0], fieldLen, _IODnav)
|
|---|
| [10577] | 1867 | || readDbl(line, pos[1], fieldLen, _Crs)
|
|---|
| 1868 | || readDbl(line, pos[2], fieldLen, _Delta_n)
|
|---|
| 1869 | || readDbl(line, pos[3], fieldLen, _M0)) {
|
|---|
| [6518] | 1870 | _checkState = bad;
|
|---|
| [4891] | 1871 | return;
|
|---|
| 1872 | }
|
|---|
| 1873 | }
|
|---|
| [9788] | 1874 | // =====================
|
|---|
| 1875 | // BROADCAST ORBIT - 2
|
|---|
| 1876 | // =====================
|
|---|
| [10577] | 1877 | else if (iLine == 2) {
|
|---|
| [10587] | 1878 | if ( readDbl(line, pos[0], fieldLen, _Cuc)
|
|---|
| [10577] | 1879 | || readDbl(line, pos[1], fieldLen, _e)
|
|---|
| 1880 | || readDbl(line, pos[2], fieldLen, _Cus)
|
|---|
| 1881 | || readDbl(line, pos[3], fieldLen, _sqrt_A)) {
|
|---|
| [6518] | 1882 | _checkState = bad;
|
|---|
| [4891] | 1883 | return;
|
|---|
| 1884 | }
|
|---|
| 1885 | }
|
|---|
| [9788] | 1886 | // =====================
|
|---|
| 1887 | // BROADCAST ORBIT - 3
|
|---|
| 1888 | // =====================
|
|---|
| [10577] | 1889 | else if (iLine == 3) {
|
|---|
| [10587] | 1890 | if ( readDbl(line, pos[0], fieldLen, _TOEsec)
|
|---|
| [10577] | 1891 | || readDbl(line, pos[1], fieldLen, _Cic)
|
|---|
| 1892 | || readDbl(line, pos[2], fieldLen, _OMEGA0)
|
|---|
| 1893 | || readDbl(line, pos[3], fieldLen, _Cis)) {
|
|---|
| [6518] | 1894 | _checkState = bad;
|
|---|
| [4891] | 1895 | return;
|
|---|
| 1896 | }
|
|---|
| 1897 | }
|
|---|
| [9788] | 1898 | // =====================
|
|---|
| 1899 | // BROADCAST ORBIT - 4
|
|---|
| 1900 | // =====================
|
|---|
| [10577] | 1901 | else if (iLine == 4) {
|
|---|
| [10587] | 1902 | if ( readDbl(line, pos[0], fieldLen, _i0)
|
|---|
| [10577] | 1903 | || readDbl(line, pos[1], fieldLen, _Crc)
|
|---|
| 1904 | || readDbl(line, pos[2], fieldLen, _omega)
|
|---|
| 1905 | || readDbl(line, pos[3], fieldLen, _OMEGADOT)) {
|
|---|
| [6518] | 1906 | _checkState = bad;
|
|---|
| [4891] | 1907 | return;
|
|---|
| 1908 | }
|
|---|
| 1909 | }
|
|---|
| [9788] | 1910 | // =====================
|
|---|
| 1911 | // BROADCAST ORBIT - 5
|
|---|
| 1912 | // =====================
|
|---|
| [10577] | 1913 | else if (iLine == 5) {
|
|---|
| [10587] | 1914 | if ( readDbl(line, pos[0], fieldLen, _IDOT)
|
|---|
| [10577] | 1915 | || readDbl(line, pos[1], fieldLen, datasource)
|
|---|
| 1916 | || readDbl(line, pos[2], fieldLen, _TOEweek)) {
|
|---|
| [6518] | 1917 | _checkState = bad;
|
|---|
| [4891] | 1918 | return;
|
|---|
| [10587] | 1919 | }
|
|---|
| 1920 | else {
|
|---|
| [10599] | 1921 | if (bitExtracted(unsigned(datasource), 1, 8)) {
|
|---|
| [6812] | 1922 | _fnav = true;
|
|---|
| [10599] | 1923 | _type = t_eph::FNAV;
|
|---|
| [6812] | 1924 | _inav = false;
|
|---|
| [10587] | 1925 | /* set unused I/NAV values */
|
|---|
| 1926 | _E5b_HS = 0.0;
|
|---|
| 1927 | _E1B_HS = 0.0;
|
|---|
| 1928 | _E1B_DataInvalid = false;
|
|---|
| 1929 | _E5b_DataInvalid = false;
|
|---|
| 1930 | }
|
|---|
| [10599] | 1931 | if (bitExtracted(unsigned(datasource), 1, 9)) {
|
|---|
| [6812] | 1932 | _fnav = false;
|
|---|
| 1933 | _inav = true;
|
|---|
| [10599] | 1934 | _type = t_eph::INAV;
|
|---|
| [10587] | 1935 | /* set unused F/NAV values */
|
|---|
| 1936 | _E5a_HS = 0.0;
|
|---|
| 1937 | _E5a_DataInvalid = false;
|
|---|
| [6792] | 1938 | }
|
|---|
| [10587] | 1939 | // GAL week # in RINEX is aligned/identical to continuous GPS week # used in RINEX
|
|---|
| 1940 | // but GST week # started at the first GPS roll-over (continuous GPS week 1024)
|
|---|
| [6892] | 1941 | _TOEweek -= 1024.0;
|
|---|
| [4891] | 1942 | }
|
|---|
| 1943 | }
|
|---|
| [9788] | 1944 | // =====================
|
|---|
| 1945 | // BROADCAST ORBIT - 6
|
|---|
| 1946 | // =====================
|
|---|
| [10577] | 1947 | else if (iLine == 6) {
|
|---|
| [10587] | 1948 | if ( readDbl(line, pos[0], fieldLen, _SISA)
|
|---|
| [10577] | 1949 | || readDbl(line, pos[1], fieldLen, SVhealth)
|
|---|
| 1950 | || readDbl(line, pos[2], fieldLen, _BGD_1_5A)
|
|---|
| 1951 | || readDbl(line, pos[3], fieldLen, _BGD_1_5B)) {
|
|---|
| [6518] | 1952 | _checkState = bad;
|
|---|
| [4891] | 1953 | return;
|
|---|
| [6792] | 1954 | } else {
|
|---|
| 1955 | // Bit 0
|
|---|
| [10688] | 1956 | _E1B_DataInvalid = bitExtracted(unsigned(SVhealth), 1, 0);
|
|---|
| [6792] | 1957 | // Bit 1-2
|
|---|
| [10688] | 1958 | _E1B_HS = double(bitExtracted(unsigned(SVhealth), 2, 1));
|
|---|
| [6792] | 1959 | // Bit 3
|
|---|
| [10688] | 1960 | _E5a_DataInvalid = bitExtracted(unsigned(SVhealth), 1, 3);
|
|---|
| [6792] | 1961 | // Bit 4-5
|
|---|
| [10688] | 1962 | _E5a_HS = double(bitExtracted(unsigned(SVhealth), 2, 4));
|
|---|
| [6792] | 1963 | // Bit 6
|
|---|
| [10688] | 1964 | _E5b_DataInvalid = bitExtracted(unsigned(SVhealth), 1, 6);
|
|---|
| [6792] | 1965 | // Bit 7-8
|
|---|
| [10688] | 1966 | _E5b_HS = double(bitExtracted(unsigned(SVhealth), 2, 7));
|
|---|
| [10587] | 1967 | if (_fnav) {
|
|---|
| 1968 | _BGD_1_5B = 0.0;
|
|---|
| 1969 | }
|
|---|
| [4891] | 1970 | }
|
|---|
| 1971 | }
|
|---|
| [9788] | 1972 | // =====================
|
|---|
| 1973 | // BROADCAST ORBIT - 7
|
|---|
| 1974 | // =====================
|
|---|
| [10577] | 1975 | else if (iLine == 7) {
|
|---|
| 1976 | if (readDbl(line, pos[0], fieldLen, _TOT)) {
|
|---|
| [6518] | 1977 | _checkState = bad;
|
|---|
| [4891] | 1978 | return;
|
|---|
| 1979 | }
|
|---|
| 1980 | }
|
|---|
| 1981 | }
|
|---|
| [10599] | 1982 | _prn.setFlag(type());
|
|---|
| [3659] | 1983 | }
|
|---|
| [4013] | 1984 |
|
|---|
| [6801] | 1985 | // Compute Galileo Satellite Position (virtual)
|
|---|
| 1986 | ////////////////////////////////////////////////////////////////////////////
|
|---|
| [10577] | 1987 | t_irc t_ephGal::position(int GPSweek, double GPSweeks, double *xc,
|
|---|
| 1988 | double *vv) const {
|
|---|
| [4013] | 1989 |
|
|---|
| [6801] | 1990 | static const double omegaEarth = 7292115.1467e-11;
|
|---|
| [8212] | 1991 | static const double gmWGS = 398.6004418e12;
|
|---|
| [4023] | 1992 |
|
|---|
| [10577] | 1993 | memset(xc, 0, 6 * sizeof(double));
|
|---|
| 1994 | memset(vv, 0, 3 * sizeof(double));
|
|---|
| [4023] | 1995 |
|
|---|
| [6801] | 1996 | double a0 = _sqrt_A * _sqrt_A;
|
|---|
| 1997 | if (a0 == 0) {
|
|---|
| 1998 | return failure;
|
|---|
| 1999 | }
|
|---|
| [4023] | 2000 |
|
|---|
| [10577] | 2001 | double n0 = sqrt(gmWGS / (a0 * a0 * a0));
|
|---|
| [4023] | 2002 |
|
|---|
| [6801] | 2003 | bncTime tt(GPSweek, GPSweeks);
|
|---|
| 2004 | double tk = tt - bncTime(_TOC.gpsw(), _TOEsec);
|
|---|
| [4023] | 2005 |
|
|---|
| [10577] | 2006 | double n = n0 + _Delta_n;
|
|---|
| 2007 | double M = _M0 + n * tk;
|
|---|
| 2008 | double E = M;
|
|---|
| [6801] | 2009 | double E_last;
|
|---|
| [10577] | 2010 | int nLoop = 0;
|
|---|
| [6801] | 2011 | do {
|
|---|
| 2012 | E_last = E;
|
|---|
| [10577] | 2013 | E = M + _e * sin(E);
|
|---|
| [8368] | 2014 |
|
|---|
| 2015 | if (++nLoop == 100) {
|
|---|
| 2016 | return failure;
|
|---|
| 2017 | }
|
|---|
| [10577] | 2018 | } while (fabs(E - E_last) * a0 > 0.001);
|
|---|
| 2019 | double v = 2.0 * atan(sqrt((1.0 + _e) / (1.0 - _e)) * tan(E / 2));
|
|---|
| 2020 | double u0 = v + _omega;
|
|---|
| 2021 | double sin2u0 = sin(2 * u0);
|
|---|
| 2022 | double cos2u0 = cos(2 * u0);
|
|---|
| 2023 | double r = a0 * (1 - _e * cos(E)) + _Crc * cos2u0 + _Crs * sin2u0;
|
|---|
| 2024 | double i = _i0 + _IDOT * tk + _Cic * cos2u0 + _Cis * sin2u0;
|
|---|
| 2025 | double u = u0 + _Cuc * cos2u0 + _Cus * sin2u0;
|
|---|
| 2026 | double xp = r * cos(u);
|
|---|
| 2027 | double yp = r * sin(u);
|
|---|
| 2028 | double OM = _OMEGA0 + (_OMEGADOT - omegaEarth) * tk - omegaEarth * _TOEsec;
|
|---|
| [4023] | 2029 |
|
|---|
| [6801] | 2030 | double sinom = sin(OM);
|
|---|
| 2031 | double cosom = cos(OM);
|
|---|
| [10577] | 2032 | double sini = sin(i);
|
|---|
| 2033 | double cosi = cos(i);
|
|---|
| 2034 | xc[0] = xp * cosom - yp * cosi * sinom;
|
|---|
| 2035 | xc[1] = xp * sinom + yp * cosi * cosom;
|
|---|
| 2036 | xc[2] = yp * sini;
|
|---|
| [4023] | 2037 |
|
|---|
| [6801] | 2038 | double tc = tt - _TOC;
|
|---|
| [10577] | 2039 | xc[3] = _clock_bias + _clock_drift * tc + _clock_driftrate * tc * tc;
|
|---|
| [4023] | 2040 |
|
|---|
| [6801] | 2041 | // Velocity
|
|---|
| 2042 | // --------
|
|---|
| [10577] | 2043 | double tanv2 = tan(v / 2);
|
|---|
| 2044 | double dEdM = 1 / (1 - _e * cos(E));
|
|---|
| 2045 | double dotv = sqrt((1.0 + _e) / (1.0 - _e)) / cos(E / 2) / cos(E / 2)
|
|---|
| 2046 | / (1 + tanv2 * tanv2) * dEdM * n;
|
|---|
| 2047 | double dotu = dotv + (-_Cuc * sin2u0 + _Cus * cos2u0) * 2 * dotv;
|
|---|
| [6801] | 2048 | double dotom = _OMEGADOT - omegaEarth;
|
|---|
| [10577] | 2049 | double doti = _IDOT + (-_Cic * sin2u0 + _Cis * cos2u0) * 2 * dotv;
|
|---|
| 2050 | double dotr = a0 * _e * sin(E) * dEdM * n
|
|---|
| 2051 | + (-_Crc * sin2u0 + _Crs * cos2u0) * 2 * dotv;
|
|---|
| 2052 | double dotx = dotr * cos(u) - r * sin(u) * dotu;
|
|---|
| 2053 | double doty = dotr * sin(u) + r * cos(u) * dotu;
|
|---|
| [4023] | 2054 |
|
|---|
| [10577] | 2055 | vv[0] = cosom * dotx - cosi * sinom * doty // dX / dr
|
|---|
| 2056 | - xp * sinom * dotom - yp * cosi * cosom * dotom // dX / dOMEGA
|
|---|
| 2057 | + yp * sini * sinom * doti; // dX / di
|
|---|
| [6801] | 2058 |
|
|---|
| [10577] | 2059 | vv[1] = sinom * dotx + cosi * cosom * doty + xp * cosom * dotom
|
|---|
| 2060 | - yp * cosi * sinom * dotom - yp * sini * cosom * doti;
|
|---|
| [6801] | 2061 |
|
|---|
| [10577] | 2062 | vv[2] = sini * doty + yp * cosi * doti;
|
|---|
| [6801] | 2063 |
|
|---|
| 2064 | // Relativistic Correction
|
|---|
| 2065 | // -----------------------
|
|---|
| [10993] | 2066 | // See t_ephGPS::position() for the rationale behind selecting between the
|
|---|
| 2067 | // eccentricity-based and velocity-based forms.
|
|---|
| 2068 | if (_orbCorr && _orbCorr->_rtcmSsr) {
|
|---|
| 2069 | xc[3] -= 2.0 * (xc[0]*vv[0] + xc[1]*vv[1] + xc[2]*vv[2]) / t_CST::c / t_CST::c;
|
|---|
| 2070 | }
|
|---|
| 2071 | else {
|
|---|
| 2072 | xc[3] -= 4.442807309e-10 * _e * sqrt(a0) * sin(E);
|
|---|
| 2073 | }
|
|---|
| [6801] | 2074 |
|
|---|
| [10577] | 2075 | xc[4] = _clock_drift + _clock_driftrate * tc;
|
|---|
| [8542] | 2076 | xc[5] = _clock_driftrate;
|
|---|
| [8581] | 2077 |
|
|---|
| [6801] | 2078 | return success;
|
|---|
| [4023] | 2079 | }
|
|---|
| 2080 |
|
|---|
| [8187] | 2081 | // Health status of Galileo Ephemeris (virtual)
|
|---|
| 2082 | ////////////////////////////////////////////////////////////////////////////
|
|---|
| 2083 | unsigned int t_ephGal::isUnhealthy() const {
|
|---|
| [10587] | 2084 | // SHS; 1 = Out of Service, 3 = In Test, 0 = Signal Ok, 2 = Extended Operations Mode
|
|---|
| 2085 | if (_E5a_HS == 1 || _E5a_HS == 3 ||
|
|---|
| 2086 | _E5b_HS == 1 || _E5b_HS == 3 ||
|
|---|
| 2087 | _E1B_HS == 1 || _E1B_HS == 3) {
|
|---|
| [8187] | 2088 | return 1;
|
|---|
| 2089 | }
|
|---|
| [10587] | 2090 | if (_E5a_DataInvalid ||
|
|---|
| 2091 | _E5b_DataInvalid ||
|
|---|
| 2092 | _E1B_DataInvalid) {
|
|---|
| [10562] | 2093 | return 1;
|
|---|
| 2094 | }
|
|---|
| [10587] | 2095 | if (_SISA == 255.0) { // NAPA: No Accuracy Prediction Available
|
|---|
| [10315] | 2096 | return 1;
|
|---|
| 2097 | }
|
|---|
| [10562] | 2098 | /*
|
|---|
| 2099 | * SDD v1.3: SHS=2 leads to a newly-defined "EOM" status.
|
|---|
| 2100 | * It also means that the satellite signal may be used for PNT.
|
|---|
| [10577] | 2101 | if (_E5aHS == 2 ||
|
|---|
| [10587] | 2102 | _E5bHS == 2 ||
|
|---|
| 2103 | _E1_bHS == 2 ) {
|
|---|
| 2104 | return 1;
|
|---|
| [10577] | 2105 | }
|
|---|
| 2106 | */
|
|---|
| [8187] | 2107 | return 0;
|
|---|
| [10587] | 2108 |
|
|---|
| [8187] | 2109 | }
|
|---|
| 2110 |
|
|---|
| [4023] | 2111 | // RINEX Format String
|
|---|
| 2112 | //////////////////////////////////////////////////////////////////////////////
|
|---|
| 2113 | QString t_ephGal::toString(double version) const {
|
|---|
| 2114 |
|
|---|
| [10587] | 2115 | QString ephStr = typeStr(_type, _prn, version);
|
|---|
| [10577] | 2116 | QString rnxStr = ephStr + rinexDateStr(_TOC, _prn, version);
|
|---|
| [4023] | 2117 |
|
|---|
| 2118 | QTextStream out(&rnxStr);
|
|---|
| 2119 |
|
|---|
| [10577] | 2120 | out
|
|---|
| 2121 | << QString("%1%2%3\n").arg(_clock_bias, 19, 'e', 12).arg(_clock_drift, 19,
|
|---|
| 2122 | 'e', 12).arg(_clock_driftrate, 19, 'e', 12);
|
|---|
| [4023] | 2123 |
|
|---|
| 2124 | QString fmt = version < 3.0 ? " %1%2%3%4\n" : " %1%2%3%4\n";
|
|---|
| [9788] | 2125 | // =====================
|
|---|
| 2126 | // BROADCAST ORBIT - 1
|
|---|
| 2127 | // =====================
|
|---|
| [10577] | 2128 | out
|
|---|
| [10587] | 2129 | << QString(fmt)
|
|---|
| 2130 | .arg(_IODnav, 19, 'e', 12)
|
|---|
| 2131 | .arg(_Crs, 19, 'e', 12)
|
|---|
| 2132 | .arg(_Delta_n, 19, 'e', 12)
|
|---|
| 2133 | .arg(_M0, 19, 'e', 12);
|
|---|
| [9788] | 2134 | // =====================
|
|---|
| 2135 | // BROADCAST ORBIT - 2
|
|---|
| 2136 | // =====================
|
|---|
| [10577] | 2137 | out
|
|---|
| [10587] | 2138 | << QString(fmt)
|
|---|
| 2139 | .arg(_Cuc, 19, 'e', 12).
|
|---|
| 2140 | arg(_e, 19, 'e', 12)
|
|---|
| 2141 | .arg(_Cus, 19, 'e', 12)
|
|---|
| 2142 | .arg(_sqrt_A, 19, 'e', 12);
|
|---|
| [9788] | 2143 | // =====================
|
|---|
| 2144 | // BROADCAST ORBIT - 3
|
|---|
| 2145 | // =====================
|
|---|
| [10577] | 2146 | out
|
|---|
| [10587] | 2147 | << QString(fmt).
|
|---|
| 2148 | arg(_TOEsec, 19, 'e', 12)
|
|---|
| 2149 | .arg(_Cic, 19, 'e', 12)
|
|---|
| 2150 | .arg(_OMEGA0, 19, 'e', 12)
|
|---|
| 2151 | .arg(_Cis, 19, 'e', 12);
|
|---|
| [9788] | 2152 | // =====================
|
|---|
| 2153 | // BROADCAST ORBIT - 4
|
|---|
| 2154 | // =====================
|
|---|
| [10577] | 2155 | out
|
|---|
| [10587] | 2156 | << QString(fmt)
|
|---|
| 2157 | .arg(_i0, 19, 'e', 12)
|
|---|
| 2158 | .arg(_Crc, 19, 'e', 12)
|
|---|
| 2159 | .arg(_omega, 19, 'e', 12)
|
|---|
| 2160 | .arg(_OMEGADOT, 19, 'e', 12);
|
|---|
| [9788] | 2161 | // =====================
|
|---|
| [10587] | 2162 | // BROADCAST ORBIT - 5/6
|
|---|
| [9788] | 2163 | // =====================
|
|---|
| [10577] | 2164 | int dataSource = 0;
|
|---|
| 2165 | int SVhealth = 0;
|
|---|
| 2166 | double BGD_1_5A = _BGD_1_5A;
|
|---|
| 2167 | double BGD_1_5B = _BGD_1_5B;
|
|---|
| [6812] | 2168 | if (_fnav) {
|
|---|
| [10577] | 2169 | dataSource |= (1 << 1);
|
|---|
| 2170 | dataSource |= (1 << 8);
|
|---|
| [6792] | 2171 | BGD_1_5B = 0.0;
|
|---|
| 2172 | // SVhealth
|
|---|
| 2173 | // Bit 3 : E5a DVS
|
|---|
| [10587] | 2174 | if (_E5a_DataInvalid) {
|
|---|
| [10577] | 2175 | SVhealth |= (1 << 3);
|
|---|
| [6792] | 2176 | }
|
|---|
| 2177 | // Bit 4-5: E5a HS
|
|---|
| [10587] | 2178 | if (_E5a_HS == 1.0) {
|
|---|
| [10577] | 2179 | SVhealth |= (1 << 4);
|
|---|
| [10587] | 2180 | }
|
|---|
| 2181 | else if (_E5a_HS == 2.0) {
|
|---|
| [10577] | 2182 | SVhealth |= (1 << 5);
|
|---|
| [10587] | 2183 | }
|
|---|
| 2184 | else if (_E5a_HS == 3.0) {
|
|---|
| [10577] | 2185 | SVhealth |= (1 << 4);
|
|---|
| 2186 | SVhealth |= (1 << 5);
|
|---|
| [6792] | 2187 | }
|
|---|
| [10577] | 2188 | } else if (_inav) {
|
|---|
| [6803] | 2189 | // Bit 2 and 0 are set because from MT1046 the data source cannot be determined
|
|---|
| 2190 | // and RNXv3.03 says both can be set if the navigation messages were merged
|
|---|
| [10577] | 2191 | dataSource |= (1 << 0);
|
|---|
| 2192 | dataSource |= (1 << 2);
|
|---|
| 2193 | dataSource |= (1 << 9);
|
|---|
| [6792] | 2194 | // SVhealth
|
|---|
| 2195 | // Bit 0 : E1-B DVS
|
|---|
| [10587] | 2196 | if (_E1B_DataInvalid) {
|
|---|
| [10577] | 2197 | SVhealth |= (1 << 0);
|
|---|
| [6792] | 2198 | }
|
|---|
| 2199 | // Bit 1-2: E1-B HS
|
|---|
| [10587] | 2200 | if (_E1B_HS == 1.0) {
|
|---|
| [10577] | 2201 | SVhealth |= (1 << 1);
|
|---|
| [10587] | 2202 | }
|
|---|
| 2203 | else if (_E1B_HS == 2.0) {
|
|---|
| [10577] | 2204 | SVhealth |= (1 << 2);
|
|---|
| [10587] | 2205 | }
|
|---|
| 2206 | else if (_E1B_HS == 3.0) {
|
|---|
| [10577] | 2207 | SVhealth |= (1 << 1);
|
|---|
| 2208 | SVhealth |= (1 << 2);
|
|---|
| [6792] | 2209 | }
|
|---|
| 2210 | // Bit 6 : E5b DVS
|
|---|
| [10587] | 2211 | if (_E5b_DataInvalid) {
|
|---|
| [10577] | 2212 | SVhealth |= (1 << 6);
|
|---|
| [6792] | 2213 | }
|
|---|
| 2214 | // Bit 7-8: E5b HS
|
|---|
| [10587] | 2215 | if (_E5b_HS == 1.0) {
|
|---|
| [10577] | 2216 | SVhealth |= (1 << 7);
|
|---|
| [10587] | 2217 | }
|
|---|
| 2218 | else if (_E5b_HS == 2.0) {
|
|---|
| [10577] | 2219 | SVhealth |= (1 << 8);
|
|---|
| [10587] | 2220 | }
|
|---|
| 2221 | else if (_E5b_HS == 3.0) {
|
|---|
| [10577] | 2222 | SVhealth |= (1 << 7);
|
|---|
| 2223 | SVhealth |= (1 << 8);
|
|---|
| [6792] | 2224 | }
|
|---|
| [5539] | 2225 | }
|
|---|
| [10587] | 2226 | // =====================
|
|---|
| 2227 | // BROADCAST ORBIT - 5
|
|---|
| 2228 | // =====================
|
|---|
| [10577] | 2229 | out
|
|---|
| [10587] | 2230 | << QString(fmt)
|
|---|
| 2231 | .arg(_IDOT, 19, 'e', 12)
|
|---|
| 2232 | .arg(double(dataSource), 19, 'e', 12)
|
|---|
| 2233 | .arg(_TOEweek + 1024.0, 19, 'e', 12)
|
|---|
| 2234 | .arg(0.0, 19, 'e', 12);
|
|---|
| [9788] | 2235 | // =====================
|
|---|
| 2236 | // BROADCAST ORBIT - 6
|
|---|
| 2237 | // =====================
|
|---|
| [10577] | 2238 | out
|
|---|
| [10587] | 2239 | << QString(fmt)
|
|---|
| 2240 | .arg(_SISA, 19, 'e', 12)
|
|---|
| 2241 | .arg(double(SVhealth), 19, 'e', 12)
|
|---|
| 2242 | .arg(BGD_1_5A, 19, 'e', 12)
|
|---|
| 2243 | .arg(BGD_1_5B, 19, 'e', 12);
|
|---|
| [9788] | 2244 | // =====================
|
|---|
| 2245 | // BROADCAST ORBIT - 7
|
|---|
| 2246 | // =====================
|
|---|
| [7922] | 2247 | double tot = _TOT;
|
|---|
| 2248 | if (tot == 0.9999e9 && version < 3.0) {
|
|---|
| 2249 | tot = 0.0;
|
|---|
| 2250 | }
|
|---|
| [10577] | 2251 | out
|
|---|
| [10587] | 2252 | << QString(fmt)
|
|---|
| 2253 | .arg(tot, 19, 'e', 12)
|
|---|
| 2254 | .arg("", 19, QChar(' '))
|
|---|
| 2255 | .arg("", 19, QChar(' '))
|
|---|
| 2256 | .arg("", 19, QChar(' '));
|
|---|
| [4023] | 2257 |
|
|---|
| 2258 | return rnxStr;
|
|---|
| 2259 | }
|
|---|
| 2260 |
|
|---|
| [6385] | 2261 | // Constructor
|
|---|
| 2262 | //////////////////////////////////////////////////////////////////////////////
|
|---|
| [10603] | 2263 | t_ephSBAS::t_ephSBAS(double rnxVersion, const QStringList &lines, const QString typeStr) {
|
|---|
| [6390] | 2264 |
|
|---|
| [10603] | 2265 | setType(typeStr);
|
|---|
| 2266 |
|
|---|
| [6390] | 2267 | const int nLines = 4;
|
|---|
| 2268 |
|
|---|
| [10587] | 2269 | // Source RINEX version < 4
|
|---|
| 2270 | if (type() == t_eph::undefined) {
|
|---|
| 2271 | _type = t_eph::SBASL1;
|
|---|
| 2272 | }
|
|---|
| 2273 |
|
|---|
| [6390] | 2274 | if (lines.size() != nLines) {
|
|---|
| [6518] | 2275 | _checkState = bad;
|
|---|
| [6390] | 2276 | return;
|
|---|
| 2277 | }
|
|---|
| 2278 |
|
|---|
| 2279 | // RINEX Format
|
|---|
| 2280 | // ------------
|
|---|
| 2281 | int fieldLen = 19;
|
|---|
| 2282 |
|
|---|
| 2283 | int pos[4];
|
|---|
| [10577] | 2284 | pos[0] = (rnxVersion <= 2.12) ? 3 : 4;
|
|---|
| [6390] | 2285 | pos[1] = pos[0] + fieldLen;
|
|---|
| 2286 | pos[2] = pos[1] + fieldLen;
|
|---|
| 2287 | pos[3] = pos[2] + fieldLen;
|
|---|
| 2288 |
|
|---|
| 2289 | // Read four lines
|
|---|
| 2290 | // ---------------
|
|---|
| 2291 | for (int iLine = 0; iLine < nLines; iLine++) {
|
|---|
| 2292 | QString line = lines[iLine];
|
|---|
| 2293 |
|
|---|
| [10577] | 2294 | if (iLine == 0) {
|
|---|
| [8204] | 2295 | QTextStream in(line.left(pos[1]).toLatin1());
|
|---|
| [6390] | 2296 |
|
|---|
| [10577] | 2297 | int year, month, day, hour, min;
|
|---|
| [6390] | 2298 | double sec;
|
|---|
| [6880] | 2299 |
|
|---|
| [7139] | 2300 | QString prnStr, n;
|
|---|
| [6880] | 2301 | in >> prnStr;
|
|---|
| [7639] | 2302 | if (prnStr.size() == 1 && prnStr[0] == 'S') {
|
|---|
| [7139] | 2303 | in >> n;
|
|---|
| 2304 | prnStr.append(n);
|
|---|
| [6880] | 2305 | }
|
|---|
| [6390] | 2306 | if (prnStr.at(0) == 'S') {
|
|---|
| 2307 | _prn.set('S', prnStr.mid(1).toInt());
|
|---|
| [10577] | 2308 | } else {
|
|---|
| [6390] | 2309 | _prn.set('S', prnStr.toInt());
|
|---|
| 2310 | }
|
|---|
| [10599] | 2311 | _prn.setFlag(type());
|
|---|
| [6390] | 2312 |
|
|---|
| [10599] | 2313 | in >> year >> month >> day >> hour >> min >> sec;
|
|---|
| 2314 |
|
|---|
| [10577] | 2315 | if (year < 80) {
|
|---|
| [6390] | 2316 | year += 2000;
|
|---|
| [10577] | 2317 | } else if (year < 100) {
|
|---|
| [6390] | 2318 | year += 1900;
|
|---|
| 2319 | }
|
|---|
| 2320 |
|
|---|
| 2321 | _TOC.set(year, month, day, hour, min, sec);
|
|---|
| 2322 |
|
|---|
| [10587] | 2323 | if ( readDbl(line, pos[1], fieldLen, _agf0)
|
|---|
| [10577] | 2324 | || readDbl(line, pos[2], fieldLen, _agf1)
|
|---|
| 2325 | || readDbl(line, pos[3], fieldLen, _TOT)) {
|
|---|
| [6518] | 2326 | _checkState = bad;
|
|---|
| [6390] | 2327 | return;
|
|---|
| 2328 | }
|
|---|
| 2329 | }
|
|---|
| [9788] | 2330 | // =====================
|
|---|
| 2331 | // BROADCAST ORBIT - 1
|
|---|
| 2332 | // =====================
|
|---|
| [10577] | 2333 | else if (iLine == 1) {
|
|---|
| [10587] | 2334 | if ( readDbl(line, pos[0], fieldLen, _x_pos)
|
|---|
| 2335 | || readDbl(line, pos[1], fieldLen, _x_vel)
|
|---|
| 2336 | || readDbl(line, pos[2], fieldLen, _x_acc)
|
|---|
| [10577] | 2337 | || readDbl(line, pos[3], fieldLen, _health)) {
|
|---|
| [6518] | 2338 | _checkState = bad;
|
|---|
| [6390] | 2339 | return;
|
|---|
| 2340 | }
|
|---|
| 2341 | }
|
|---|
| [9788] | 2342 | // =====================
|
|---|
| 2343 | // BROADCAST ORBIT - 2
|
|---|
| 2344 | // =====================
|
|---|
| [10577] | 2345 | else if (iLine == 2) {
|
|---|
| [10587] | 2346 | if ( readDbl(line, pos[0], fieldLen, _y_pos)
|
|---|
| 2347 | || readDbl(line, pos[1], fieldLen, _y_vel)
|
|---|
| 2348 | || readDbl(line, pos[2], fieldLen, _y_acc)
|
|---|
| [10577] | 2349 | || readDbl(line, pos[3], fieldLen, _ura)) {
|
|---|
| [6518] | 2350 | _checkState = bad;
|
|---|
| [6390] | 2351 | return;
|
|---|
| 2352 | }
|
|---|
| 2353 | }
|
|---|
| [9788] | 2354 | // =====================
|
|---|
| 2355 | // BROADCAST ORBIT - 3
|
|---|
| 2356 | // =====================
|
|---|
| [10577] | 2357 | else if (iLine == 3) {
|
|---|
| [6536] | 2358 | double iodn;
|
|---|
| [10587] | 2359 | if ( readDbl(line, pos[0], fieldLen, _z_pos)
|
|---|
| 2360 | || readDbl(line, pos[1], fieldLen, _z_vel)
|
|---|
| 2361 | || readDbl(line, pos[2], fieldLen, _z_acc)
|
|---|
| [10577] | 2362 | || readDbl(line, pos[3], fieldLen, iodn)) {
|
|---|
| [6518] | 2363 | _checkState = bad;
|
|---|
| [6390] | 2364 | return;
|
|---|
| [6891] | 2365 | } else {
|
|---|
| [6536] | 2366 | _IODN = int(iodn);
|
|---|
| [6390] | 2367 | }
|
|---|
| 2368 | }
|
|---|
| 2369 | }
|
|---|
| [10577] | 2370 | _x_pos *= 1.e3;
|
|---|
| 2371 | _y_pos *= 1.e3;
|
|---|
| 2372 | _z_pos *= 1.e3;
|
|---|
| [10587] | 2373 | _x_vel *= 1.e3;
|
|---|
| 2374 | _y_vel *= 1.e3;
|
|---|
| 2375 | _z_vel *= 1.e3;
|
|---|
| 2376 | _x_acc *= 1.e3;
|
|---|
| 2377 | _y_acc *= 1.e3;
|
|---|
| 2378 | _z_acc *= 1.e3;
|
|---|
| [6385] | 2379 | }
|
|---|
| 2380 |
|
|---|
| [7054] | 2381 | // IOD of SBAS Ephemeris (virtual)
|
|---|
| 2382 | ////////////////////////////////////////////////////////////////////////////
|
|---|
| 2383 |
|
|---|
| [7169] | 2384 | unsigned int t_ephSBAS::IOD() const {
|
|---|
| [7054] | 2385 | unsigned char buffer[80];
|
|---|
| 2386 | int size = 0;
|
|---|
| 2387 | int numbits = 0;
|
|---|
| 2388 | long long bitbuffer = 0;
|
|---|
| 2389 | unsigned char *startbuffer = buffer;
|
|---|
| 2390 |
|
|---|
| 2391 | SBASADDBITSFLOAT(30, this->_x_pos, 0.08)
|
|---|
| 2392 | SBASADDBITSFLOAT(30, this->_y_pos, 0.08)
|
|---|
| 2393 | SBASADDBITSFLOAT(25, this->_z_pos, 0.4)
|
|---|
| [10587] | 2394 | SBASADDBITSFLOAT(17, this->_x_vel, 0.000625)
|
|---|
| 2395 | SBASADDBITSFLOAT(17, this->_y_vel, 0.000625)
|
|---|
| 2396 | SBASADDBITSFLOAT(18, this->_z_vel, 0.004)
|
|---|
| 2397 | SBASADDBITSFLOAT(10, this->_x_acc, 0.0000125)
|
|---|
| 2398 | SBASADDBITSFLOAT(10, this->_y_acc, 0.0000125)
|
|---|
| 2399 | SBASADDBITSFLOAT(10, this->_z_acc, 0.0000625)
|
|---|
| [10577] | 2400 | SBASADDBITSFLOAT(12, this->_agf0,
|
|---|
| 2401 | 1.0 / static_cast<double>(1 << 30) / static_cast<double>(1 << 1))
|
|---|
| 2402 | SBASADDBITSFLOAT(8, this->_agf1,
|
|---|
| 2403 | 1.0 / static_cast<double>(1 << 30) / static_cast<double>(1 << 10))
|
|---|
| 2404 | SBASADDBITS(5, 0); // the last byte is filled by 0-bits to obtain a length of an integer multiple of 8
|
|---|
| [7054] | 2405 |
|
|---|
| 2406 | return CRC24(size, startbuffer);
|
|---|
| 2407 | }
|
|---|
| 2408 |
|
|---|
| [6385] | 2409 | // Compute SBAS Satellite Position (virtual)
|
|---|
| 2410 | ////////////////////////////////////////////////////////////////////////////
|
|---|
| [10577] | 2411 | t_irc t_ephSBAS::position(int GPSweek, double GPSweeks, double *xc,
|
|---|
| 2412 | double *vv) const {
|
|---|
| [6386] | 2413 |
|
|---|
| 2414 | bncTime tt(GPSweek, GPSweeks);
|
|---|
| [10577] | 2415 | double dt = tt - _TOC;
|
|---|
| [6386] | 2416 |
|
|---|
| [10587] | 2417 | xc[0] = _x_pos + _x_vel * dt + _x_acc * dt * dt / 2.0;
|
|---|
| 2418 | xc[1] = _y_pos + _y_vel * dt + _y_acc * dt * dt / 2.0;
|
|---|
| 2419 | xc[2] = _z_pos + _z_vel * dt + _z_acc * dt * dt / 2.0;
|
|---|
| [6386] | 2420 |
|
|---|
| [10587] | 2421 | vv[0] = _x_vel + _x_acc * dt;
|
|---|
| 2422 | vv[1] = _y_vel + _y_acc * dt;
|
|---|
| 2423 | vv[2] = _z_vel + _z_acc * dt;
|
|---|
| [6386] | 2424 |
|
|---|
| 2425 | xc[3] = _agf0 + _agf1 * dt;
|
|---|
| 2426 |
|
|---|
| [8542] | 2427 | xc[4] = _agf1;
|
|---|
| 2428 | xc[5] = 0.0;
|
|---|
| [8483] | 2429 |
|
|---|
| [6386] | 2430 | return success;
|
|---|
| [6385] | 2431 | }
|
|---|
| 2432 |
|
|---|
| [9774] | 2433 | // Health status of SBAS Ephemeris (virtual)
|
|---|
| 2434 | ////////////////////////////////////////////////////////////////////////////
|
|---|
| 2435 | unsigned int t_ephSBAS::isUnhealthy() const {
|
|---|
| 2436 |
|
|---|
| [10628] | 2437 | // Bit 5
|
|---|
| [10688] | 2438 | bool URAindexIs15 = bitExtracted(unsigned(_health), 1, 5);
|
|---|
| [9774] | 2439 | if (URAindexIs15) {
|
|---|
| 2440 | // in this case it is recommended
|
|---|
| 2441 | // to set the bits 0,1,2,3 to 1 (MT17health = 15)
|
|---|
| 2442 | return 1;
|
|---|
| 2443 | }
|
|---|
| 2444 |
|
|---|
| [10628] | 2445 | // Bit 4
|
|---|
| [10688] | 2446 | bool MT17HealthIsUnavailable = bitExtracted(unsigned(_health), 1, 4);
|
|---|
| [10628] | 2447 | if (MT17HealthIsUnavailable) {
|
|---|
| 2448 | return 0;
|
|---|
| 2449 | }
|
|---|
| 2450 |
|
|---|
| [9774] | 2451 | // Bit 0-3
|
|---|
| [10688] | 2452 | int MT17health = bitExtracted(unsigned(_health), 4, 0);
|
|---|
| [9774] | 2453 | if (MT17health) {
|
|---|
| 2454 | return 1;
|
|---|
| 2455 | }
|
|---|
| 2456 |
|
|---|
| 2457 | return 0;
|
|---|
| 2458 | }
|
|---|
| 2459 |
|
|---|
| [6385] | 2460 | // RINEX Format String
|
|---|
| 2461 | //////////////////////////////////////////////////////////////////////////////
|
|---|
| [6388] | 2462 | QString t_ephSBAS::toString(double version) const {
|
|---|
| 2463 |
|
|---|
| [10587] | 2464 | QString ephStr = typeStr(_type, _prn, version);
|
|---|
| [10577] | 2465 | QString rnxStr = ephStr + rinexDateStr(_TOC, _prn, version);
|
|---|
| [6388] | 2466 |
|
|---|
| 2467 | QTextStream out(&rnxStr);
|
|---|
| 2468 |
|
|---|
| [10577] | 2469 | out
|
|---|
| [10587] | 2470 | << QString("%1%2%3\n")
|
|---|
| 2471 | .arg(_agf0, 19, 'e', 12)
|
|---|
| 2472 | .arg(_agf1, 19, 'e', 12)
|
|---|
| 2473 | .arg(_TOT, 19, 'e', 12);
|
|---|
| [6388] | 2474 |
|
|---|
| 2475 | QString fmt = version < 3.0 ? " %1%2%3%4\n" : " %1%2%3%4\n";
|
|---|
| [9788] | 2476 | // =====================
|
|---|
| 2477 | // BROADCAST ORBIT - 1
|
|---|
| 2478 | // =====================
|
|---|
| [10577] | 2479 | out
|
|---|
| [10587] | 2480 | << QString(fmt)
|
|---|
| 2481 | .arg(1.e-3 * _x_pos, 19, 'e', 12)
|
|---|
| 2482 | .arg(1.e-3 * _x_vel, 19, 'e', 12)
|
|---|
| 2483 | .arg(1.e-3 * _x_acc, 19, 'e', 12)
|
|---|
| 2484 | .arg(_health, 19, 'e', 12);
|
|---|
| [9788] | 2485 | // =====================
|
|---|
| 2486 | // BROADCAST ORBIT - 2
|
|---|
| 2487 | // =====================
|
|---|
| [10577] | 2488 | out
|
|---|
| [10587] | 2489 | << QString(fmt)
|
|---|
| 2490 | .arg(1.e-3 * _y_pos, 19, 'e', 12)
|
|---|
| 2491 | .arg(1.e-3 * _y_vel, 19, 'e', 12)
|
|---|
| 2492 | .arg(1.e-3 * _y_acc, 19, 'e', 12)
|
|---|
| 2493 | .arg(_ura, 19, 'e', 12);
|
|---|
| [9788] | 2494 | // =====================
|
|---|
| 2495 | // BROADCAST ORBIT - 3
|
|---|
| 2496 | // =====================
|
|---|
| [10577] | 2497 | out
|
|---|
| [10587] | 2498 | << QString(fmt)
|
|---|
| 2499 | .arg(1.e-3 * _z_pos, 19, 'e', 12)
|
|---|
| 2500 | .arg(1.e-3 * _z_vel, 19, 'e', 12)
|
|---|
| 2501 | .arg(1.e-3 * _z_acc, 19, 'e', 12)
|
|---|
| 2502 | .arg(double(_IODN), 19, 'e', 12);
|
|---|
| [6388] | 2503 |
|
|---|
| 2504 | return rnxStr;
|
|---|
| [6385] | 2505 | }
|
|---|
| [6400] | 2506 |
|
|---|
| 2507 | // Constructor
|
|---|
| 2508 | //////////////////////////////////////////////////////////////////////////////
|
|---|
| [10603] | 2509 | t_ephBDS::t_ephBDS(double rnxVersion, const QStringList &lines, const QString typeStr) {
|
|---|
| [6400] | 2510 |
|
|---|
| [10603] | 2511 | setType(typeStr);
|
|---|
| 2512 |
|
|---|
| [9788] | 2513 | int nLines = 8;
|
|---|
| [6400] | 2514 |
|
|---|
| [10587] | 2515 | if (type() == t_eph::CNV1 ||
|
|---|
| 2516 | type() == t_eph::CNV2) {
|
|---|
| [9788] | 2517 | nLines += 2;
|
|---|
| 2518 | }
|
|---|
| [10587] | 2519 | if (type() == t_eph::CNV3) {
|
|---|
| [9788] | 2520 | nLines += 1;
|
|---|
| 2521 | }
|
|---|
| 2522 |
|
|---|
| [6400] | 2523 | if (lines.size() != nLines) {
|
|---|
| [6518] | 2524 | _checkState = bad;
|
|---|
| [6400] | 2525 | return;
|
|---|
| 2526 | }
|
|---|
| 2527 |
|
|---|
| 2528 | // RINEX Format
|
|---|
| 2529 | // ------------
|
|---|
| 2530 | int fieldLen = 19;
|
|---|
| 2531 |
|
|---|
| 2532 | int pos[4];
|
|---|
| [10577] | 2533 | pos[0] = (rnxVersion <= 2.12) ? 3 : 4;
|
|---|
| [6400] | 2534 | pos[1] = pos[0] + fieldLen;
|
|---|
| 2535 | pos[2] = pos[1] + fieldLen;
|
|---|
| 2536 | pos[3] = pos[2] + fieldLen;
|
|---|
| 2537 |
|
|---|
| 2538 | // Read eight lines
|
|---|
| 2539 | // ----------------
|
|---|
| 2540 | for (int iLine = 0; iLine < nLines; iLine++) {
|
|---|
| 2541 | QString line = lines[iLine];
|
|---|
| 2542 |
|
|---|
| [10577] | 2543 | if (iLine == 0) {
|
|---|
| [8204] | 2544 | QTextStream in(line.left(pos[1]).toLatin1());
|
|---|
| [6400] | 2545 |
|
|---|
| [10577] | 2546 | int year, month, day, hour, min;
|
|---|
| [6400] | 2547 | double sec;
|
|---|
| [6880] | 2548 |
|
|---|
| [7139] | 2549 | QString prnStr, n;
|
|---|
| [6880] | 2550 | in >> prnStr;
|
|---|
| [7639] | 2551 | if (prnStr.size() == 1 && prnStr[0] == 'C') {
|
|---|
| [7139] | 2552 | in >> n;
|
|---|
| 2553 | prnStr.append(n);
|
|---|
| [6880] | 2554 | }
|
|---|
| [6400] | 2555 | if (prnStr.at(0) == 'C') {
|
|---|
| 2556 | _prn.set('C', prnStr.mid(1).toInt());
|
|---|
| [10577] | 2557 | } else {
|
|---|
| [6400] | 2558 | _prn.set('C', prnStr.toInt());
|
|---|
| 2559 | }
|
|---|
| 2560 |
|
|---|
| [10599] | 2561 | in >> year >> month >> day >> hour >> min >> sec;
|
|---|
| [10577] | 2562 | if (year < 80) {
|
|---|
| [6400] | 2563 | year += 2000;
|
|---|
| [10577] | 2564 | } else if (year < 100) {
|
|---|
| [6400] | 2565 | year += 1900;
|
|---|
| 2566 | }
|
|---|
| 2567 |
|
|---|
| [6812] | 2568 | _TOC.setBDS(year, month, day, hour, min, sec);
|
|---|
| [6400] | 2569 |
|
|---|
| [10587] | 2570 | if ( readDbl(line, pos[1], fieldLen, _clock_bias)
|
|---|
| [10577] | 2571 | || readDbl(line, pos[2], fieldLen, _clock_drift)
|
|---|
| 2572 | || readDbl(line, pos[3], fieldLen, _clock_driftrate)) {
|
|---|
| [6518] | 2573 | _checkState = bad;
|
|---|
| [6400] | 2574 | return;
|
|---|
| 2575 | }
|
|---|
| 2576 | }
|
|---|
| [9788] | 2577 | // =====================
|
|---|
| 2578 | // BROADCAST ORBIT - 1
|
|---|
| 2579 | // =====================
|
|---|
| [10577] | 2580 | else if (iLine == 1) {
|
|---|
| [10587] | 2581 | if (type() == t_eph::D1 ||
|
|---|
| 2582 | type() == t_eph::D2 ||
|
|---|
| 2583 | type() == t_eph::undefined) {
|
|---|
| 2584 | double aode;
|
|---|
| 2585 | if ( readDbl(line, pos[0], fieldLen, aode)
|
|---|
| 2586 | || readDbl(line, pos[1], fieldLen, _Crs)
|
|---|
| 2587 | || readDbl(line, pos[2], fieldLen, _Delta_n)
|
|---|
| 2588 | || readDbl(line, pos[3], fieldLen, _M0)) {
|
|---|
| 2589 | _checkState = bad;
|
|---|
| 2590 | return;
|
|---|
| 2591 | }
|
|---|
| 2592 | _AODE = int(aode);
|
|---|
| [6400] | 2593 | }
|
|---|
| [10587] | 2594 | else { //CNV1, CNV2, CNV3
|
|---|
| 2595 | if ( readDbl(line, pos[0], fieldLen, _ADOT)
|
|---|
| 2596 | || readDbl(line, pos[1], fieldLen, _Crs)
|
|---|
| 2597 | || readDbl(line, pos[2], fieldLen, _Delta_n)
|
|---|
| 2598 | || readDbl(line, pos[3], fieldLen, _M0)) {
|
|---|
| 2599 | _checkState = bad;
|
|---|
| 2600 | return;
|
|---|
| 2601 | }
|
|---|
| 2602 | }
|
|---|
| [6400] | 2603 | }
|
|---|
| [9788] | 2604 | // =====================
|
|---|
| 2605 | // BROADCAST ORBIT - 2
|
|---|
| 2606 | // =====================
|
|---|
| [10577] | 2607 | else if (iLine == 2) {
|
|---|
| [10587] | 2608 | if ( readDbl(line, pos[0], fieldLen, _Cuc)
|
|---|
| [10577] | 2609 | || readDbl(line, pos[1], fieldLen, _e)
|
|---|
| 2610 | || readDbl(line, pos[2], fieldLen, _Cus)
|
|---|
| 2611 | || readDbl(line, pos[3], fieldLen, _sqrt_A)) {
|
|---|
| [6518] | 2612 | _checkState = bad;
|
|---|
| [6400] | 2613 | return;
|
|---|
| 2614 | }
|
|---|
| 2615 | }
|
|---|
| [9788] | 2616 | // =====================
|
|---|
| 2617 | // BROADCAST ORBIT - 3
|
|---|
| 2618 | // =====================
|
|---|
| [10577] | 2619 | else if (iLine == 3) {
|
|---|
| [10587] | 2620 | if ( readDbl(line, pos[0], fieldLen, _TOEsec)
|
|---|
| [10577] | 2621 | || readDbl(line, pos[1], fieldLen, _Cic)
|
|---|
| 2622 | || readDbl(line, pos[2], fieldLen, _OMEGA0)
|
|---|
| 2623 | || readDbl(line, pos[3], fieldLen, _Cis)) {
|
|---|
| [6518] | 2624 | _checkState = bad;
|
|---|
| [6400] | 2625 | return;
|
|---|
| 2626 | }
|
|---|
| 2627 | }
|
|---|
| [9788] | 2628 | // =====================
|
|---|
| 2629 | // BROADCAST ORBIT - 4
|
|---|
| 2630 | // =====================
|
|---|
| [10577] | 2631 | else if (iLine == 4) {
|
|---|
| [10587] | 2632 | if ( readDbl(line, pos[0], fieldLen, _i0)
|
|---|
| [10577] | 2633 | || readDbl(line, pos[1], fieldLen, _Crc)
|
|---|
| 2634 | || readDbl(line, pos[2], fieldLen, _omega)
|
|---|
| 2635 | || readDbl(line, pos[3], fieldLen, _OMEGADOT)) {
|
|---|
| [6518] | 2636 | _checkState = bad;
|
|---|
| [6400] | 2637 | return;
|
|---|
| 2638 | }
|
|---|
| [10587] | 2639 | else {
|
|---|
| 2640 | // Source RINEX version < 4
|
|---|
| 2641 | if (type() == t_eph::undefined) {
|
|---|
| 2642 | const double iMaxGEO = 10.0 / 180.0 * M_PI;
|
|---|
| 2643 | if (_i0 > iMaxGEO) {
|
|---|
| 2644 | _type = t_eph::D1;
|
|---|
| 2645 | }
|
|---|
| 2646 | else {
|
|---|
| 2647 | _type = t_eph::D2;
|
|---|
| 2648 | }
|
|---|
| 2649 | }
|
|---|
| 2650 | }
|
|---|
| [6400] | 2651 | }
|
|---|
| [9788] | 2652 | // =====================
|
|---|
| 2653 | // BROADCAST ORBIT - 5
|
|---|
| 2654 | // =====================
|
|---|
| [10577] | 2655 | else if (iLine == 5) {
|
|---|
| [10587] | 2656 | if (type() == t_eph::CNV1 ||
|
|---|
| 2657 | type() == t_eph::CNV2 ||
|
|---|
| 2658 | type() == t_eph::CNV3) {
|
|---|
| 2659 | if ( readDbl(line, pos[0], fieldLen, _IDOT)
|
|---|
| [10577] | 2660 | || readDbl(line, pos[1], fieldLen, _Delta_n_dot)
|
|---|
| 2661 | || readDbl(line, pos[2], fieldLen, _satType)
|
|---|
| 2662 | || readDbl(line, pos[3], fieldLen, _top)) {
|
|---|
| [9788] | 2663 | _checkState = bad;
|
|---|
| 2664 | return;
|
|---|
| 2665 | }
|
|---|
| [10587] | 2666 | }
|
|---|
| 2667 | else { // D1, D2
|
|---|
| 2668 | if ( readDbl(line, pos[0], fieldLen, _IDOT)
|
|---|
| [10577] | 2669 | || readDbl(line, pos[2], fieldLen, _BDTweek)) {
|
|---|
| [9788] | 2670 | _checkState = bad;
|
|---|
| 2671 | return;
|
|---|
| 2672 | }
|
|---|
| 2673 | }
|
|---|
| [6400] | 2674 | }
|
|---|
| [9788] | 2675 | // =====================
|
|---|
| 2676 | // BROADCAST ORBIT - 6
|
|---|
| 2677 | // =====================
|
|---|
| [10577] | 2678 | else if (iLine == 6) {
|
|---|
| [10587] | 2679 | if (type() == t_eph::CNV1 ||
|
|---|
| 2680 | type() == t_eph::CNV2 ||
|
|---|
| 2681 | type() == t_eph::CNV3) {
|
|---|
| 2682 | if ( readDbl(line, pos[0], fieldLen, _SISAI_oe)
|
|---|
| [10577] | 2683 | || readDbl(line, pos[1], fieldLen, _SISAI_ocb)
|
|---|
| 2684 | || readDbl(line, pos[2], fieldLen, _SISAI_oc1)
|
|---|
| 2685 | || readDbl(line, pos[3], fieldLen, _SISAI_oc2)) {
|
|---|
| [9788] | 2686 | _checkState = bad;
|
|---|
| 2687 | return;
|
|---|
| 2688 | }
|
|---|
| [10587] | 2689 | }
|
|---|
| 2690 | else { // D1, D2
|
|---|
| [9788] | 2691 | double SatH1;
|
|---|
| [10587] | 2692 | if ( readDbl(line, pos[0], fieldLen, _ura)
|
|---|
| [10577] | 2693 | || readDbl(line, pos[1], fieldLen, SatH1)
|
|---|
| 2694 | || readDbl(line, pos[2], fieldLen, _TGD1)
|
|---|
| 2695 | || readDbl(line, pos[3], fieldLen, _TGD2)) {
|
|---|
| [9788] | 2696 | _checkState = bad;
|
|---|
| 2697 | return;
|
|---|
| 2698 | }
|
|---|
| 2699 | _SatH1 = int(SatH1);
|
|---|
| 2700 | }
|
|---|
| [6400] | 2701 | }
|
|---|
| [9788] | 2702 | // =====================
|
|---|
| 2703 | // BROADCAST ORBIT - 7
|
|---|
| 2704 | // =====================
|
|---|
| [10577] | 2705 | else if (iLine == 7) {
|
|---|
| [10587] | 2706 | if (type() == t_eph::CNV1) {
|
|---|
| 2707 | if ( readDbl(line, pos[0], fieldLen, _ISC_B1Cd)
|
|---|
| [10577] | 2708 | || readDbl(line, pos[2], fieldLen, _TGD_B1Cp)
|
|---|
| 2709 | || readDbl(line, pos[3], fieldLen, _TGD_B2ap)) {
|
|---|
| [9788] | 2710 | _checkState = bad;
|
|---|
| 2711 | return;
|
|---|
| 2712 | }
|
|---|
| [10587] | 2713 | }
|
|---|
| 2714 | else if (type() == t_eph::CNV2) {
|
|---|
| 2715 | if ( readDbl(line, pos[1], fieldLen, _ISC_B2ad)
|
|---|
| [10577] | 2716 | || readDbl(line, pos[2], fieldLen, _TGD_B1Cp)
|
|---|
| 2717 | || readDbl(line, pos[3], fieldLen, _TGD_B2ap)) {
|
|---|
| [9788] | 2718 | _checkState = bad;
|
|---|
| 2719 | return;
|
|---|
| 2720 | }
|
|---|
| [10587] | 2721 | }
|
|---|
| 2722 | else if (type() == t_eph::CNV3) {
|
|---|
| [9789] | 2723 | double health;
|
|---|
| [10587] | 2724 | if ( readDbl(line, pos[0], fieldLen, _SISMAI)
|
|---|
| [10577] | 2725 | || readDbl(line, pos[1], fieldLen, health)
|
|---|
| 2726 | || readDbl(line, pos[2], fieldLen, _INTEGRITYF_B2b)
|
|---|
| 2727 | || readDbl(line, pos[3], fieldLen, _TGD_B2bI)) {
|
|---|
| [9788] | 2728 | _checkState = bad;
|
|---|
| 2729 | return;
|
|---|
| 2730 | }
|
|---|
| [9789] | 2731 | _health = int(health);
|
|---|
| [10587] | 2732 | }
|
|---|
| 2733 | else { // D1, D2
|
|---|
| [9788] | 2734 | double aodc;
|
|---|
| [10587] | 2735 | if ( readDbl(line, pos[0], fieldLen, _TOT)
|
|---|
| [10577] | 2736 | || readDbl(line, pos[1], fieldLen, aodc)) {
|
|---|
| [9788] | 2737 | _checkState = bad;
|
|---|
| 2738 | return;
|
|---|
| 2739 | }
|
|---|
| 2740 | if (_TOT == 0.9999e9) { // 0.9999e9 means not known (RINEX standard)
|
|---|
| 2741 | _TOT = _TOEsec;
|
|---|
| 2742 | }
|
|---|
| 2743 | _AODC = int(aodc);
|
|---|
| 2744 | }
|
|---|
| [6400] | 2745 | }
|
|---|
| [9788] | 2746 | // =====================
|
|---|
| 2747 | // BROADCAST ORBIT - 8
|
|---|
| 2748 | // =====================
|
|---|
| [10577] | 2749 | else if (iLine == 8) {
|
|---|
| [9789] | 2750 | double health;
|
|---|
| [10587] | 2751 | if (type() == t_eph::CNV1) {
|
|---|
| 2752 | if ( readDbl(line, pos[0], fieldLen, _SISMAI)
|
|---|
| [10577] | 2753 | || readDbl(line, pos[1], fieldLen, health)
|
|---|
| 2754 | || readDbl(line, pos[2], fieldLen, _INTEGRITYF_B1C)
|
|---|
| 2755 | || readDbl(line, pos[3], fieldLen, _IODC)) {
|
|---|
| [9788] | 2756 | _checkState = bad;
|
|---|
| 2757 | return;
|
|---|
| 2758 | }
|
|---|
| [9789] | 2759 | _health = int(health);
|
|---|
| [10587] | 2760 | }
|
|---|
| 2761 | else if (type() == t_eph::CNV2) {
|
|---|
| 2762 | if ( readDbl(line, pos[0], fieldLen, _SISMAI)
|
|---|
| [10577] | 2763 | || readDbl(line, pos[1], fieldLen, health)
|
|---|
| 2764 | || readDbl(line, pos[2], fieldLen, _INTEGRITYF_B2aB1C)
|
|---|
| 2765 | || readDbl(line, pos[3], fieldLen, _IODC)) {
|
|---|
| [9788] | 2766 | _checkState = bad;
|
|---|
| 2767 | return;
|
|---|
| 2768 | }
|
|---|
| [9789] | 2769 | _health = int(health);
|
|---|
| [10587] | 2770 | }
|
|---|
| 2771 | else if (type() == t_eph::CNV3) {
|
|---|
| [10577] | 2772 | if (readDbl(line, pos[0], fieldLen, _TOT)) {
|
|---|
| [9788] | 2773 | _checkState = bad;
|
|---|
| 2774 | return;
|
|---|
| 2775 | }
|
|---|
| 2776 | }
|
|---|
| 2777 | }
|
|---|
| 2778 | // =====================
|
|---|
| 2779 | // BROADCAST ORBIT - 9
|
|---|
| 2780 | // =====================
|
|---|
| [10577] | 2781 | else if (iLine == 9) {
|
|---|
| [10587] | 2782 | if (type() == t_eph::CNV1 ||
|
|---|
| 2783 | type() == t_eph::CNV2) {
|
|---|
| 2784 | if ( readDbl(line, pos[0], fieldLen, _TOT)
|
|---|
| [10577] | 2785 | || readDbl(line, pos[3], fieldLen, _IODE)) {
|
|---|
| [9788] | 2786 | _checkState = bad;
|
|---|
| 2787 | return;
|
|---|
| 2788 | }
|
|---|
| 2789 | }
|
|---|
| 2790 | }
|
|---|
| [6400] | 2791 | }
|
|---|
| [10599] | 2792 | _prn.setFlag(type());
|
|---|
| [6400] | 2793 |
|
|---|
| [10577] | 2794 | _TOE.setBDS(int(_BDTweek), _TOEsec);
|
|---|
| [6400] | 2795 | // remark: actually should be computed from second_tot
|
|---|
| 2796 | // but it seems to be unreliable in RINEX files
|
|---|
| [6843] | 2797 | //_TOT = _TOC.bdssec();
|
|---|
| [6400] | 2798 | }
|
|---|
| 2799 |
|
|---|
| [7054] | 2800 | // IOD of BDS Ephemeris (virtual)
|
|---|
| 2801 | ////////////////////////////////////////////////////////////////////////////
|
|---|
| [7169] | 2802 | unsigned int t_ephBDS::IOD() const {
|
|---|
| [10769] | 2803 | if (type() == t_eph::D1 ||
|
|---|
| 2804 | type() == t_eph::D2) {
|
|---|
| 2805 | return (int(_TOC.gpssec()) / 720) % 240;
|
|---|
| 2806 | }
|
|---|
| 2807 | else {
|
|---|
| 2808 | return _IODE;
|
|---|
| 2809 | }
|
|---|
| [7054] | 2810 | }
|
|---|
| 2811 |
|
|---|
| [6601] | 2812 | // Compute BDS Satellite Position (virtual)
|
|---|
| [6400] | 2813 | //////////////////////////////////////////////////////////////////////////////
|
|---|
| [10577] | 2814 | t_irc t_ephBDS::position(int GPSweek, double GPSweeks, double *xc,
|
|---|
| 2815 | double *vv) const {
|
|---|
| [6400] | 2816 |
|
|---|
| [10577] | 2817 | static const double gmBDS = 398.6004418e12;
|
|---|
| [6602] | 2818 | static const double omegaBDS = 7292115.0000e-11;
|
|---|
| [6400] | 2819 |
|
|---|
| 2820 | xc[0] = xc[1] = xc[2] = xc[3] = 0.0;
|
|---|
| 2821 | vv[0] = vv[1] = vv[2] = 0.0;
|
|---|
| 2822 |
|
|---|
| 2823 | bncTime tt(GPSweek, GPSweeks);
|
|---|
| 2824 |
|
|---|
| 2825 | if (_sqrt_A == 0) {
|
|---|
| 2826 | return failure;
|
|---|
| 2827 | }
|
|---|
| 2828 | double a0 = _sqrt_A * _sqrt_A;
|
|---|
| 2829 |
|
|---|
| [10577] | 2830 | double n0 = sqrt(gmBDS / (a0 * a0 * a0));
|
|---|
| [6400] | 2831 | double tk = tt - _TOE;
|
|---|
| [10577] | 2832 | double n = n0 + _Delta_n;
|
|---|
| 2833 | double M = _M0 + n * tk;
|
|---|
| 2834 | double E = M;
|
|---|
| [6400] | 2835 | double E_last;
|
|---|
| [10577] | 2836 | int nLoop = 0;
|
|---|
| [6400] | 2837 | do {
|
|---|
| 2838 | E_last = E;
|
|---|
| [10577] | 2839 | E = M + _e * sin(E);
|
|---|
| [6400] | 2840 |
|
|---|
| 2841 | if (++nLoop == 100) {
|
|---|
| 2842 | return failure;
|
|---|
| 2843 | }
|
|---|
| [10577] | 2844 | } while (fabs(E - E_last) * a0 > 0.001);
|
|---|
| [6400] | 2845 |
|
|---|
| [10577] | 2846 | double v = atan2(sqrt(1 - _e * _e) * sin(E), cos(E) - _e);
|
|---|
| 2847 | double u0 = v + _omega;
|
|---|
| 2848 | double sin2u0 = sin(2 * u0);
|
|---|
| 2849 | double cos2u0 = cos(2 * u0);
|
|---|
| 2850 | double r = a0 * (1 - _e * cos(E)) + _Crc * cos2u0 + _Crs * sin2u0;
|
|---|
| 2851 | double i = _i0 + _IDOT * tk + _Cic * cos2u0 + _Cis * sin2u0;
|
|---|
| 2852 | double u = u0 + _Cuc * cos2u0 + _Cus * sin2u0;
|
|---|
| 2853 | double xp = r * cos(u);
|
|---|
| 2854 | double yp = r * sin(u);
|
|---|
| [6400] | 2855 | double toesec = (_TOE.gpssec() - 14.0);
|
|---|
| 2856 | double sinom = 0;
|
|---|
| 2857 | double cosom = 0;
|
|---|
| [10577] | 2858 | double sini = 0;
|
|---|
| 2859 | double cosi = 0;
|
|---|
| [7278] | 2860 |
|
|---|
| [7481] | 2861 | // Velocity
|
|---|
| 2862 | // --------
|
|---|
| [10577] | 2863 | double tanv2 = tan(v / 2);
|
|---|
| 2864 | double dEdM = 1 / (1 - _e * cos(E));
|
|---|
| 2865 | double dotv = sqrt((1.0 + _e) / (1.0 - _e)) / cos(E / 2) / cos(E / 2)
|
|---|
| 2866 | / (1 + tanv2 * tanv2) * dEdM * n;
|
|---|
| 2867 | double dotu = dotv + (-_Cuc * sin2u0 + _Cus * cos2u0) * 2 * dotv;
|
|---|
| 2868 | double doti = _IDOT + (-_Cic * sin2u0 + _Cis * cos2u0) * 2 * dotv;
|
|---|
| 2869 | double dotr = a0 * _e * sin(E) * dEdM * n
|
|---|
| 2870 | + (-_Crc * sin2u0 + _Crs * cos2u0) * 2 * dotv;
|
|---|
| [7481] | 2871 |
|
|---|
| [10577] | 2872 | double dotx = dotr * cos(u) - r * sin(u) * dotu;
|
|---|
| 2873 | double doty = dotr * sin(u) + r * cos(u) * dotu;
|
|---|
| [7481] | 2874 |
|
|---|
| [6400] | 2875 | const double iMaxGEO = 10.0 / 180.0 * M_PI;
|
|---|
| 2876 |
|
|---|
| 2877 | // MEO/IGSO satellite
|
|---|
| 2878 | // ------------------
|
|---|
| 2879 | if (_i0 > iMaxGEO) {
|
|---|
| [10577] | 2880 | double OM = _OMEGA0 + (_OMEGADOT - omegaBDS) * tk - omegaBDS * toesec;
|
|---|
| [6400] | 2881 |
|
|---|
| 2882 | sinom = sin(OM);
|
|---|
| 2883 | cosom = cos(OM);
|
|---|
| [10577] | 2884 | sini = sin(i);
|
|---|
| 2885 | cosi = cos(i);
|
|---|
| [6400] | 2886 |
|
|---|
| [10577] | 2887 | xc[0] = xp * cosom - yp * cosi * sinom;
|
|---|
| 2888 | xc[1] = xp * sinom + yp * cosi * cosom;
|
|---|
| 2889 | xc[2] = yp * sini;
|
|---|
| [7481] | 2890 |
|
|---|
| 2891 | // Velocity
|
|---|
| 2892 | // --------
|
|---|
| 2893 |
|
|---|
| 2894 | double dotom = _OMEGADOT - t_CST::omega;
|
|---|
| 2895 |
|
|---|
| [10577] | 2896 | vv[0] = cosom * dotx - cosi * sinom * doty // dX / dr
|
|---|
| 2897 | - xp * sinom * dotom - yp * cosi * cosom * dotom // dX / dOMEGA
|
|---|
| 2898 | + yp * sini * sinom * doti; // dX / di
|
|---|
| [7481] | 2899 |
|
|---|
| [10577] | 2900 | vv[1] = sinom * dotx + cosi * cosom * doty + xp * cosom * dotom
|
|---|
| 2901 | - yp * cosi * sinom * dotom - yp * sini * cosom * doti;
|
|---|
| [7481] | 2902 |
|
|---|
| [10577] | 2903 | vv[2] = sini * doty + yp * cosi * doti;
|
|---|
| [7481] | 2904 |
|
|---|
| [6400] | 2905 | }
|
|---|
| 2906 |
|
|---|
| 2907 | // GEO satellite
|
|---|
| 2908 | // -------------
|
|---|
| 2909 | else {
|
|---|
| [10577] | 2910 | double OM = _OMEGA0 + _OMEGADOT * tk - omegaBDS * toesec;
|
|---|
| 2911 | double ll = omegaBDS * tk;
|
|---|
| [6400] | 2912 |
|
|---|
| 2913 | sinom = sin(OM);
|
|---|
| 2914 | cosom = cos(OM);
|
|---|
| [10577] | 2915 | sini = sin(i);
|
|---|
| 2916 | cosi = cos(i);
|
|---|
| [6400] | 2917 |
|
|---|
| [10577] | 2918 | double xx = xp * cosom - yp * cosi * sinom;
|
|---|
| 2919 | double yy = xp * sinom + yp * cosi * cosom;
|
|---|
| 2920 | double zz = yp * sini;
|
|---|
| [6400] | 2921 |
|
|---|
| [7487] | 2922 | Matrix RX = BNC_PPP::t_astro::rotX(-5.0 / 180.0 * M_PI);
|
|---|
| 2923 | Matrix RZ = BNC_PPP::t_astro::rotZ(ll);
|
|---|
| [6400] | 2924 |
|
|---|
| [10577] | 2925 | ColumnVector X1(3);
|
|---|
| 2926 | X1 << xx << yy << zz;
|
|---|
| 2927 | ColumnVector X2 = RZ * RX * X1;
|
|---|
| [6400] | 2928 |
|
|---|
| 2929 | xc[0] = X2(1);
|
|---|
| 2930 | xc[1] = X2(2);
|
|---|
| 2931 | xc[2] = X2(3);
|
|---|
| [7278] | 2932 |
|
|---|
| [7481] | 2933 | double dotom = _OMEGADOT;
|
|---|
| [6400] | 2934 |
|
|---|
| [10577] | 2935 | double vx = cosom * dotx - cosi * sinom * doty - xp * sinom * dotom
|
|---|
| 2936 | - yp * cosi * cosom * dotom + yp * sini * sinom * doti;
|
|---|
| [6400] | 2937 |
|
|---|
| [10577] | 2938 | double vy = sinom * dotx + cosi * cosom * doty + xp * cosom * dotom
|
|---|
| 2939 | - yp * cosi * sinom * dotom - yp * sini * cosom * doti;
|
|---|
| [7278] | 2940 |
|
|---|
| [10577] | 2941 | double vz = sini * doty + yp * cosi * doti;
|
|---|
| [6400] | 2942 |
|
|---|
| [10577] | 2943 | ColumnVector V(3);
|
|---|
| 2944 | V << vx << vy << vz;
|
|---|
| [7481] | 2945 |
|
|---|
| [10577] | 2946 | Matrix RdotZ(3, 3);
|
|---|
| [7481] | 2947 | double C = cos(ll);
|
|---|
| 2948 | double S = sin(ll);
|
|---|
| [10577] | 2949 | Matrix UU(3, 3);
|
|---|
| 2950 | UU[0][0] = -S;
|
|---|
| 2951 | UU[0][1] = +C;
|
|---|
| 2952 | UU[0][2] = 0.0;
|
|---|
| 2953 | UU[1][0] = -C;
|
|---|
| 2954 | UU[1][1] = -S;
|
|---|
| 2955 | UU[1][2] = 0.0;
|
|---|
| 2956 | UU[2][0] = 0.0;
|
|---|
| 2957 | UU[2][1] = 0.0;
|
|---|
| 2958 | UU[2][2] = 0.0;
|
|---|
| [7487] | 2959 | RdotZ = omegaBDS * UU;
|
|---|
| [7481] | 2960 |
|
|---|
| 2961 | ColumnVector VV(3);
|
|---|
| [10577] | 2962 | VV = RZ * RX * V + RdotZ * RX * X1;
|
|---|
| [7481] | 2963 |
|
|---|
| 2964 | vv[0] = VV(1);
|
|---|
| 2965 | vv[1] = VV(2);
|
|---|
| 2966 | vv[2] = VV(3);
|
|---|
| 2967 | }
|
|---|
| 2968 |
|
|---|
| 2969 | double tc = tt - _TOC;
|
|---|
| [10577] | 2970 | xc[3] = _clock_bias + _clock_drift * tc + _clock_driftrate * tc * tc;
|
|---|
| [7481] | 2971 |
|
|---|
| [9132] | 2972 | // dotC = _clock_drift + _clock_driftrate*tc
|
|---|
| [9290] | 2973 | // - 4.442807309e-10*_e * sqrt(a0) * cos(E) * dEdM * n;
|
|---|
| [6400] | 2974 |
|
|---|
| [7481] | 2975 | // Relativistic Correction
|
|---|
| 2976 | // -----------------------
|
|---|
| [10993] | 2977 | // See t_ephGPS::position() for the rationale behind selecting between the
|
|---|
| 2978 | // eccentricity-based and velocity-based forms.
|
|---|
| 2979 | if (_orbCorr && _orbCorr->_rtcmSsr) {
|
|---|
| 2980 | xc[3] -= 2.0 * (xc[0]*vv[0] + xc[1]*vv[1] + xc[2]*vv[2]) / t_CST::c / t_CST::c;
|
|---|
| 2981 | }
|
|---|
| 2982 | else {
|
|---|
| 2983 | xc[3] -= 4.442807309e-10 * _e * sqrt(a0) * sin(E);
|
|---|
| 2984 | }
|
|---|
| [7481] | 2985 |
|
|---|
| [10577] | 2986 | xc[4] = _clock_drift + _clock_driftrate * tc;
|
|---|
| [8542] | 2987 | xc[5] = _clock_driftrate;
|
|---|
| [9126] | 2988 |
|
|---|
| [6400] | 2989 | return success;
|
|---|
| 2990 | }
|
|---|
| 2991 |
|
|---|
| [10990] | 2992 | // Health status of BDS Ephemeris (virtual)
|
|---|
| [9789] | 2993 | ////////////////////////////////////////////////////////////////////////////
|
|---|
| 2994 | unsigned int t_ephBDS::isUnhealthy() const {
|
|---|
| 2995 |
|
|---|
| [10628] | 2996 | if (type() == t_eph::CNV1 ||
|
|---|
| 2997 | type() == t_eph::CNV2 ||
|
|---|
| 2998 | type() == t_eph::CNV3) {
|
|---|
| [9789] | 2999 | return static_cast<unsigned int>(_health);
|
|---|
| 3000 | }
|
|---|
| 3001 |
|
|---|
| 3002 | return static_cast<unsigned int>(_SatH1);
|
|---|
| 3003 |
|
|---|
| 3004 | }
|
|---|
| 3005 |
|
|---|
| [6400] | 3006 | // RINEX Format String
|
|---|
| 3007 | //////////////////////////////////////////////////////////////////////////////
|
|---|
| [6600] | 3008 | QString t_ephBDS::toString(double version) const {
|
|---|
| [8419] | 3009 |
|
|---|
| [10587] | 3010 | if (version < 4.0 &&
|
|---|
| 3011 | (type() == t_eph::CNV1 ||
|
|---|
| 3012 | type() == t_eph::CNV2 ||
|
|---|
| 3013 | type() == t_eph::CNV3 )) {
|
|---|
| 3014 | return "";
|
|---|
| 3015 | }
|
|---|
| 3016 |
|
|---|
| 3017 | QString ephStr = typeStr(_type, _prn, version);
|
|---|
| [10577] | 3018 | QString rnxStr = ephStr + rinexDateStr(_TOC - 14.0, _prn, version);
|
|---|
| [6400] | 3019 |
|
|---|
| 3020 | QTextStream out(&rnxStr);
|
|---|
| 3021 |
|
|---|
| [10577] | 3022 | out
|
|---|
| [10587] | 3023 | << QString("%1%2%3\n")
|
|---|
| 3024 | .arg(_clock_bias, 19, 'e', 12)
|
|---|
| 3025 | .arg(_clock_drift, 19, 'e', 12)
|
|---|
| 3026 | .arg(_clock_driftrate, 19, 'e', 12);
|
|---|
| [6400] | 3027 |
|
|---|
| 3028 | QString fmt = version < 3.0 ? " %1%2%3%4\n" : " %1%2%3%4\n";
|
|---|
| [9788] | 3029 | // =====================
|
|---|
| 3030 | // BROADCAST ORBIT - 1
|
|---|
| 3031 | // =====================
|
|---|
| [10587] | 3032 | if (type() == t_eph::D1 ||
|
|---|
| 3033 | type() == t_eph::D2 ||
|
|---|
| 3034 | type() == t_eph::undefined) {
|
|---|
| 3035 | out
|
|---|
| 3036 | << QString(fmt)
|
|---|
| 3037 | .arg(double(_AODE), 19, 'e', 12)
|
|---|
| 3038 | .arg(_Crs, 19, 'e', 12)
|
|---|
| 3039 | .arg(_Delta_n, 19, 'e', 12)
|
|---|
| 3040 | .arg(_M0, 19, 'e', 12);
|
|---|
| 3041 | }
|
|---|
| 3042 | else { //CNV1, CNV2, CNV3
|
|---|
| 3043 | out
|
|---|
| 3044 | << QString(fmt)
|
|---|
| 3045 | .arg(_ADOT, 19, 'e', 12)
|
|---|
| 3046 | .arg(_Crs, 19, 'e', 12)
|
|---|
| 3047 | .arg(_Delta_n, 19, 'e', 12)
|
|---|
| 3048 | .arg(_M0, 19, 'e', 12);
|
|---|
| 3049 | }
|
|---|
| 3050 |
|
|---|
| [9788] | 3051 | // =====================
|
|---|
| 3052 | // BROADCAST ORBIT - 2
|
|---|
| 3053 | // =====================
|
|---|
| [10577] | 3054 | out
|
|---|
| [10587] | 3055 | << QString(fmt)
|
|---|
| 3056 | .arg(_Cuc, 19, 'e', 12)
|
|---|
| 3057 | .arg(_e, 19, 'e', 12)
|
|---|
| 3058 | .arg(_Cus, 19, 'e', 12)
|
|---|
| 3059 | .arg(_sqrt_A, 19, 'e', 12);
|
|---|
| 3060 |
|
|---|
| [9788] | 3061 | // =====================
|
|---|
| 3062 | // BROADCAST ORBIT - 3
|
|---|
| 3063 | // =====================
|
|---|
| [10577] | 3064 | out
|
|---|
| [10587] | 3065 | << QString(fmt)
|
|---|
| 3066 | .arg(_TOEsec, 19, 'e', 12)
|
|---|
| 3067 | .arg(_Cic, 19, 'e', 12)
|
|---|
| 3068 | .arg(_OMEGA0, 19, 'e', 12)
|
|---|
| 3069 | .arg(_Cis, 19, 'e', 12);
|
|---|
| [9788] | 3070 | // =====================
|
|---|
| 3071 | // BROADCAST ORBIT - 4
|
|---|
| 3072 | // =====================
|
|---|
| [10577] | 3073 | out
|
|---|
| [10587] | 3074 | << QString(fmt)
|
|---|
| 3075 | .arg(_i0, 19, 'e', 12)
|
|---|
| 3076 | .arg(_Crc, 19, 'e', 12)
|
|---|
| 3077 | .arg(_omega, 19, 'e', 12)
|
|---|
| 3078 | .arg(_OMEGADOT, 19, 'e', 12);
|
|---|
| [9788] | 3079 | // =====================
|
|---|
| 3080 | // BROADCAST ORBIT - 5
|
|---|
| 3081 | // =====================
|
|---|
| [10587] | 3082 | if (type() == t_eph::CNV1 ||
|
|---|
| 3083 | type() == t_eph::CNV2 ||
|
|---|
| 3084 | type() == t_eph::CNV3) {
|
|---|
| [10577] | 3085 | out
|
|---|
| [10587] | 3086 | << QString(fmt)
|
|---|
| 3087 | .arg(_IDOT, 19, 'e', 12)
|
|---|
| 3088 | .arg(_Delta_n_dot, 19, 'e', 12)
|
|---|
| 3089 | .arg(_satType, 19, 'e', 12)
|
|---|
| 3090 | .arg(_top, 19, 'e', 12);
|
|---|
| 3091 | }
|
|---|
| 3092 | else { // D1, D2,
|
|---|
| [10577] | 3093 | out
|
|---|
| [10587] | 3094 | << QString(fmt)
|
|---|
| 3095 | .arg(_IDOT, 19, 'e', 12)
|
|---|
| 3096 | .arg("", 19, QChar(' '))
|
|---|
| 3097 | .arg(_BDTweek, 19, 'e', 12)
|
|---|
| 3098 | .arg("", 19, QChar(' '));
|
|---|
| [9788] | 3099 | }
|
|---|
| 3100 | // =====================
|
|---|
| 3101 | // BROADCAST ORBIT - 6
|
|---|
| 3102 | // =====================
|
|---|
| [10587] | 3103 | if (type() == t_eph::CNV1 ||
|
|---|
| 3104 | type() == t_eph::CNV2 ||
|
|---|
| 3105 | type() == t_eph::CNV3) {
|
|---|
| [10577] | 3106 | out
|
|---|
| [10587] | 3107 | << QString(fmt)
|
|---|
| 3108 | .arg(_SISAI_oe, 19, 'e', 12)
|
|---|
| 3109 | .arg(_SISAI_ocb, 19, 'e', 12)
|
|---|
| 3110 | .arg(_SISAI_oc1, 19, 'e', 12)
|
|---|
| 3111 | .arg(_SISAI_oc2, 19, 'e', 12);
|
|---|
| 3112 | }
|
|---|
| 3113 | else { // D1, D2, undefined
|
|---|
| [10577] | 3114 | out
|
|---|
| [10587] | 3115 | << QString(fmt)
|
|---|
| 3116 | .arg(_ura, 19, 'e', 12)
|
|---|
| 3117 | .arg(double(_SatH1), 19, 'e', 12)
|
|---|
| 3118 | .arg(_TGD1, 19, 'e', 12)
|
|---|
| 3119 | .arg(_TGD2, 19, 'e', 12);
|
|---|
| [9788] | 3120 | }
|
|---|
| 3121 | // =====================
|
|---|
| 3122 | // BROADCAST ORBIT - 7
|
|---|
| 3123 | // =====================
|
|---|
| [10587] | 3124 | if (type() == t_eph::CNV1) {
|
|---|
| [10577] | 3125 | out
|
|---|
| [10587] | 3126 | << QString(fmt)
|
|---|
| 3127 | .arg(_ISC_B1Cd, 19, 'e', 12)
|
|---|
| 3128 | .arg("", 19, QChar(' '))
|
|---|
| 3129 | .arg(_TGD_B1Cp, 19, 'e', 12)
|
|---|
| 3130 | .arg(_TGD_B2ap, 19, 'e', 12);
|
|---|
| 3131 | }
|
|---|
| 3132 | else if (type() == t_eph::CNV2) {
|
|---|
| [10577] | 3133 | out
|
|---|
| [10587] | 3134 | << QString(fmt)
|
|---|
| 3135 | .arg("", 19, QChar(' '))
|
|---|
| 3136 | .arg(_ISC_B2ad, 19, 'e', 12)
|
|---|
| 3137 | .arg(_TGD_B1Cp, 19, 'e', 12)
|
|---|
| 3138 | .arg(_TGD_B2ap, 19, 'e', 12);
|
|---|
| 3139 | }
|
|---|
| 3140 | else if (type() == t_eph::CNV3) {
|
|---|
| [10577] | 3141 | out
|
|---|
| [10587] | 3142 | << QString(fmt)
|
|---|
| 3143 | .arg(_SISMAI, 19, 'e', 12)
|
|---|
| 3144 | .arg(double(_health), 19, 'e', 12)
|
|---|
| 3145 | .arg(_INTEGRITYF_B2b, 19, 'e', 12)
|
|---|
| 3146 | .arg(_TGD_B2bI, 19, 'e', 12);
|
|---|
| 3147 | }
|
|---|
| 3148 | else { // D1, D2, undefined
|
|---|
| [9788] | 3149 | double tots = 0.0;
|
|---|
| [10577] | 3150 | if (_receptDateTime.isValid()) { // RTCM stream input
|
|---|
| [9788] | 3151 | tots = _TOE.bdssec();
|
|---|
| [10577] | 3152 | } else { // RINEX input
|
|---|
| [9788] | 3153 | tots = _TOT;
|
|---|
| 3154 | }
|
|---|
| [10577] | 3155 | out
|
|---|
| [10587] | 3156 | << QString(fmt)
|
|---|
| 3157 | .arg(tots, 19, 'e', 12)
|
|---|
| 3158 | .arg(double(_AODC), 19, 'e', 12)
|
|---|
| 3159 | .arg("", 19, QChar(' '))
|
|---|
| 3160 | .arg("", 19, QChar(' '));
|
|---|
| [9788] | 3161 | }
|
|---|
| [6400] | 3162 |
|
|---|
| [9788] | 3163 | // =====================
|
|---|
| 3164 | // BROADCAST ORBIT - 8
|
|---|
| 3165 | // =====================
|
|---|
| [10587] | 3166 | if (type() == t_eph::CNV1) {
|
|---|
| [10577] | 3167 | out
|
|---|
| [10587] | 3168 | << QString(fmt)
|
|---|
| 3169 | .arg(_SISMAI, 19, 'e', 12)
|
|---|
| 3170 | .arg(double(_health), 19, 'e', 12)
|
|---|
| 3171 | .arg(_INTEGRITYF_B1C, 19, 'e', 12)
|
|---|
| 3172 | .arg(_IODC, 19, 'e', 12);
|
|---|
| 3173 | }
|
|---|
| 3174 | else if (type() == t_eph::CNV2) {
|
|---|
| [10577] | 3175 | out
|
|---|
| [10587] | 3176 | << QString(fmt)
|
|---|
| 3177 | .arg(_SISMAI, 19, 'e', 12)
|
|---|
| 3178 | .arg(double(_health), 19, 'e', 12)
|
|---|
| 3179 | .arg(_INTEGRITYF_B2aB1C, 19, 'e', 12)
|
|---|
| 3180 | .arg(_IODC, 19, 'e', 12);
|
|---|
| 3181 | }
|
|---|
| 3182 | else if (type() == t_eph::CNV3) {
|
|---|
| [10577] | 3183 | out
|
|---|
| [10587] | 3184 | << QString(fmt)
|
|---|
| 3185 | .arg(_TOT, 19, 'e', 12)
|
|---|
| 3186 | .arg("", 19, QChar(' '))
|
|---|
| 3187 | .arg("", 19, QChar(' '))
|
|---|
| 3188 | .arg("", 19, QChar(' '));
|
|---|
| [9788] | 3189 | }
|
|---|
| [6400] | 3190 |
|
|---|
| [9788] | 3191 | // =====================
|
|---|
| 3192 | // BROADCAST ORBIT - 9
|
|---|
| 3193 | // =====================
|
|---|
| [10587] | 3194 | if (type() == t_eph::CNV1 ||
|
|---|
| 3195 | type() == t_eph::CNV2) {
|
|---|
| [10577] | 3196 | out
|
|---|
| [10587] | 3197 | << QString(fmt)
|
|---|
| 3198 | .arg(_TOT, 19, 'e', 12)
|
|---|
| 3199 | .arg("", 19, QChar(' '))
|
|---|
| 3200 | .arg("", 19, QChar(' '))
|
|---|
| 3201 | .arg(_IODE, 19, 'e', 12);
|
|---|
| [9788] | 3202 | }
|
|---|
| [6400] | 3203 |
|
|---|
| 3204 | return rnxStr;
|
|---|
| 3205 | }
|
|---|