35#define PI 3.1415926535897932
36#define D2R (PI / 180.0)
37#define R2D (180.0 / PI)
38#define CLIGHT 299792458.0
39#define SC2RAD 3.1415926535898
58#define FREQ1 1.57542E9
59#define FREQ2 1.22760E9
60#define FREQ5 1.17645E9
61#define FREQ6 1.27875E9
62#define FREQ7 1.20714E9
63#define FREQ8 1.191795E9
64#define FREQ9 2.492028E9
65#define FREQ1_GLO 1.60200E9
66#define DFRQ1_GLO 0.56250E6
67#define FREQ2_GLO 1.24600E9
68#define DFRQ2_GLO 0.43750E6
69#define FREQ3_GLO 1.202025E9
70#define FREQ1a_GLO 1.600995E9
71#define FREQ2a_GLO 1.248060E9
72#define FREQ1_CMP 1.561098E9
82#define P2_11 4.882812500000000E-04
83#define P2_15 3.051757812500000E-05
84#define P2_17 7.629394531250000E-06
85#define P2_19 1.907348632812500E-06
86#define P2_20 9.536743164062500E-07
87#define P2_21 4.768371582031250E-07
88#define P2_23 1.192092895507810E-07
89#define P2_24 5.960464477539063E-08
90#define P2_27 7.450580596923828E-09
91#define P2_29 1.862645149230957E-09
92#define P2_30 9.313225746154785E-10
93#define P2_31 4.656612873077393E-10
94#define P2_32 2.328306436538696E-10
95#define P2_33 1.164153218269348E-10
96#define P2_34 5.820766091346740E-11
97#define P2_35 2.910383045673370E-11
98#define P2_38 3.637978807091710E-12
99#define P2_40 9.094947017729280E-13
100#define P2_43 1.136868377216160E-13
101#define P2_46 1.421085471520200E-14
102#define P2_50 8.881784197001252E-16
103#define P2_55 2.775557561562891E-17
104#define P2_59 1.734723475976810E-18
109#define NVSENDMSG 0x03
112#define ID_XF5RAW 0xf5
113#define ID_X4AIONO 0x4a
114#define ID_X4BTIME 0x4b
115#define ID_XF7EPH 0xf7
116#define ID_XE5BIT 0xe5
118#define ID_XD7ADVANCED 0xd7
119#define ID_X02RATEPVT 0x02
120#define ID_XF4RATERAW 0xf4
121#define ID_XD7SMOOTH 0xd7
122#define ID_XD5BIT 0xd5
125#define U1(p) (*((uint8_t*)(p)))
126#define I1(p) (*((int8_t*)(p)))
127static uint16_t
U2(uint8_t* p) {
132static uint32_t
U4(uint8_t* p) {
137static int16_t
I2(uint8_t* p) {
142static int32_t
I4(uint8_t* p) {
147static float R4(uint8_t* p) {
152static double R8(uint8_t* p) {
159static const double ura_eph[] = {2.4, 3.4, 4.85, 6.85, 9.65, 13.65, 24.0, 48.0,
160 96.0, 192.0, 384.0, 768.0, 1536.0, 3072.0, 6144.0, 0.0};
164 for (i = 0; i < 15; i++) {
174 double tadj = 0.0, toff = 0.0, tn;
176 double dTowUTC, dTowGPS, dTowFrac, L1, P1, D1;
177 double gpsutcTimescale;
178 uint8_t rcvTimeScaleCorr, sys, carrNo;
179 int i, j, prn, sat, n = 0, nsat, week;
180 uint8_t* p = raw->
buff + 2;
181 char *q, tstr[32], flag;
183 trace(NULL, 4,
"decode_xf5raw: len=%d\n", raw->
len);
186 if ((q = strstr(raw->
opt,
"-tadj"))) {
187 sscanf(q,
"-TADJ=%lf", &tadj);
191 gpsutcTimescale =
R8(p + 10);
193 rcvTimeScaleCorr =
I1(p + 26);
197 trace(NULL, 2,
"nvs xf5raw obs week error: week=%d\n", week);
202 if ((raw->
len - 31) % 30) {
204 trace(NULL, 2,
"nvs xf5raw len=%d seems not be correct\n", raw->
len);
207 nsat = (raw->
len - 31) / 30;
209 dTowGPS = dTowUTC + gpsutcTimescale;
212 dTowInt = 10.0 * floor((dTowGPS / 10.0) + 0.5);
213 dTowFrac = dTowGPS - (double)dTowInt;
219 toff = (tn - floor(tn + 0.5)) * tadj;
225 trace(NULL, 2,
"nvs xf5raw time tag jump warning: time=%s\n", tstr);
229 trace(NULL, 2,
"nvs xf5raw time tag duplicated: time=%s\n", tstr);
232 for (i = 0, p += 27; (i < nsat) && (n <
MAXOBS); i++, p += 30) {
236 }
else if (
U1(p) == 2) {
238 }
else if (
U1(p) == 4) {
247 if (!(sat =
satno(sys, prn))) {
248 trace(NULL, 2,
"nvs xf5raw satellite number error: sys=%d prn=%d\n", sys, prn);
257 if (L1 < -1E10 || L1 > 1E10 || P1 < -1E10 || P1 > 1E10 || D1 < -1E5 || D1 > 1E5) {
258 trace(NULL, 2,
"nvs xf5raw obs range error: sat=%2d L1=%12.5e P1=%12.5e D1=%12.5e\n", sat, L1, P1, D1);
272 raw->
obs.
data[n].
LLI[0] = (flag & 0x08) && !(raw->
halfc[sat - 1][0] & 0x08) ? 1 : 0;
273 raw->
halfc[sat - 1][0] = flag;
278 for (j = 1; j < NFREQ + NEXOBS; j++) {
293 uint8_t* puiTmp = (raw->
buff) + 2;
297 trace(NULL, 4,
"decode_ephem: sat=%2d\n", sat);
299 eph.
crs =
R4(&puiTmp[2]);
300 eph.
deln =
R4(&puiTmp[6]) * 1e+3;
301 eph.
M0 =
R8(&puiTmp[10]);
302 eph.
cuc =
R4(&puiTmp[18]);
303 eph.
e =
R8(&puiTmp[22]);
304 eph.
cus =
R4(&puiTmp[30]);
305 eph.
A = pow(
R8(&puiTmp[34]), 2);
306 eph.
toes =
R8(&puiTmp[42]) * 1e-3;
307 eph.
cic =
R4(&puiTmp[50]);
308 eph.
OMG0 =
R8(&puiTmp[54]);
309 eph.
cis =
R4(&puiTmp[62]);
310 eph.
i0 =
R8(&puiTmp[66]);
311 eph.
crc =
R4(&puiTmp[74]);
312 eph.
omg =
R8(&puiTmp[78]);
313 eph.
OMGd =
R8(&puiTmp[86]) * 1e+3;
314 eph.
idot =
R8(&puiTmp[94]) * 1e+3;
315 eph.
tgd[0] =
R4(&puiTmp[102]) * 1e-3;
316 toc =
R8(&puiTmp[106]) * 1e-3;
317 eph.
f2 =
R4(&puiTmp[114]) * 1e+3;
318 eph.
f1 =
R4(&puiTmp[118]);
319 eph.
f0 =
R4(&puiTmp[122]) * 1e-3;
321 eph.
iode =
I2(&puiTmp[128]);
322 eph.
iodc =
I2(&puiTmp[130]);
323 eph.
code =
I2(&puiTmp[132]);
324 eph.
flag =
I2(&puiTmp[134]);
325 week =
I2(&puiTmp[136]);
329 trace(NULL, 2,
"nvs gps ephemeris week error: sat=%2d week=%d\n", sat, week);
337 if (!strstr(raw->
opt,
"-EPHALL")) {
344 raw->
nav.
eph[sat - 1] = eph;
353 tod_p = ep[3] * 3600.0 + ep[4] * 60.0 + ep[5];
354 if (tod < tod_p - 43200.0) {
356 }
else if (tod > tod_p + 43200.0) {
359 ep[3] = ep[4] = ep[5] = 0.0;
365 uint8_t* p = (raw->
buff) + 2;
368 if (raw->
len >= 93) {
370 geph.
frq =
I1(p + 2);
371 geph.
pos[0] =
R8(p + 3);
372 geph.
pos[1] =
R8(p + 11);
373 geph.
pos[2] =
R8(p + 19);
374 geph.
vel[0] =
R8(p + 27) * 1e+3;
375 geph.
vel[1] =
R8(p + 35) * 1e+3;
376 geph.
vel[2] =
R8(p + 43) * 1e+3;
377 geph.
acc[0] =
R8(p + 51) * 1e+6;
378 geph.
acc[1] =
R8(p + 59) * 1e+6;
379 geph.
acc[2] =
R8(p + 67) * 1e+6;
380 tb =
R8(p + 75) * 1e-3;
383 geph.
taun =
R4(p + 87) * 1e-3;
384 geph.
age =
I2(p + 91);
386 trace(NULL, 2,
"nvs NE length error: len=%d\n", raw->
len);
390 trace(NULL, 2,
"nvs NE satellite error: prn=%d\n", prn);
397 geph.
iode = (tb / 900) & 0x7F;
403 if (fabs(tt)>3600.0) {
404 trace(NULL,3,
"nvs NE illegal toe: prn=%2d tt=%6.0f\n",prn,tt);
412 trace(NULL,2,
"nvs NE illegal freq change: prn=%2d frq=%2d->%2d\n",prn,
416 if (!strstr(raw->
opt,
"-EPHALL")) {
430 uint8_t* p = raw->
buff;
432 trace(NULL, 4,
"decode_xf7eph: len=%d\n", raw->
len);
434 if ((raw->
len) < 93) {
435 trace(NULL, 2,
"nvs xf7eph length error: len=%d\n", raw->
len);
441 trace(NULL, 2,
"nvs xf7eph satellite number error: prn=%d\n", prn);
454 int iBlkStartIdx, iExpLen, iIdx;
456 uint8_t uiDataBlocks, uiDataType;
457 uint8_t* p = raw->
buff;
459 trace(NULL, 4,
"decode_xe5bit: len=%d\n", raw->
len);
462 uiDataBlocks =
U1(p);
464 if (uiDataBlocks >= 16) {
465 trace(NULL, 2,
"nvs xf5bit message error: data blocks %u\n", uiDataBlocks);
469 for (iIdx = 0; iIdx < uiDataBlocks; iIdx++) {
470 iExpLen = (iBlkStartIdx + 10);
471 if ((raw->
len) < iExpLen) {
472 trace(NULL, 2,
"nvs xf5bit message too short (expected at least %d)\n", iExpLen);
475 uiDataType =
U1(p + iBlkStartIdx + 1);
477 switch (uiDataType) {
485 prn =
U1(p + (iBlkStartIdx + 2)) + 120;
489 memset(words, 0, 10 *
sizeof(uint32_t));
490 for (iIdx = 0, iBlkStartIdx += 7; iIdx < 10; iIdx++, iBlkStartIdx += 4) {
491 words[iIdx] =
U4(p + iBlkStartIdx);
496 trace(NULL, 2,
"nvs xf5bit SNS type unknown (got %d)\n", uiDataType);
504 uint8_t* p = raw->
buff + 2;
506 trace(NULL, 4,
"decode_x4aiono: len=%d\n", raw->
len);
521 uint8_t* p = raw->
buff + 2;
523 trace(NULL, 4,
"decode_x4btime: len=%d\n", raw->
len);
535 int type =
U1(raw->
buff + 1);
537 trace(NULL, 3,
"decode_nvs: type=%02x len=%d\n", type, raw->
len);
539 sprintf(raw->
msgtype,
"NVS: type=%2d len=%3d", type, raw->
len);
573 trace(NULL, 5,
"input_nvs: data=%02x\n", data);
606 trace(NULL, 2,
"nvs message size error: len=%d\n", raw->
nbyte);
619 int i, data, odd = 0;
621 trace(NULL, 4,
"input_nvsf:\n");
625 if ((data = fgetc(fp)) == EOF) {
633 if ((data = fgetc(fp)) == EOF) {
649 if ((data = fgetc(fp)) == EOF) {
655 if ((data !=
NVSSYNC) || odd) {
669 trace(NULL, 2,
"nvs length error: len=%d\n", raw->
len);
686extern int gen_nvs(
const char* msg, uint8_t* buff) {
688 char mbuff[1024], *args[32], *p;
690 int iRate, n, narg = 0;
693 trace(NULL, 4,
"gen_nvs: msg=%s\n", msg);
696 for (p = strtok(mbuff,
" "); p && narg < 32; p = strtok(NULL,
" ")) {
704 if (!strcmp(args[0],
"CFG-PVTRATE")) {
708 iRate = atoi(args[1]);
709 *q++ = (uint8_t)iRate;
711 }
else if (!strcmp(args[0],
"CFG-RAWRATE")) {
714 iRate = atoi(args[1]);
731 }
else if (!strcmp(args[0],
"CFG-SMOOTH")) {
736 }
else if (!strcmp(args[0],
"CFG-BINR")) {
737 for (n = 1; (n < narg); n++) {
738 if (sscanf(args[n],
"%2x", &
byte)) {
739 *q++ = (uint8_t)
byte;
MRTKLIB Bits Module — Binary bit operations and CRC functions.
MRTKLIB Broadcast Ephemeris Module — Satellite orbit/clock types and Kepler/GLONASS/SBAS orbit comput...
MRTKLIB Matrix Module — Matrix/vector operations and estimation.
int satno(int sys, int prn)
Convert satellite system+prn/slot number to satellite number.
MRTKLIB Navigation Module — Navigation data types and satellite/nav utility functions.
MRTKLIB Observation Module — Observation data types and utility functions.
static int decode_xe5bit(raw_t *raw)
static int uraindex(double value)
static gtime_t adjday(gtime_t time, double tod)
static int decode_gloephem(int sat, raw_t *raw)
int input_nvs(raw_t *raw, uint8_t data)
int gen_nvs(const char *msg, uint8_t *buff)
static int decode_nvs(raw_t *raw)
static int decode_x4aiono(raw_t *raw)
static int decode_xf5raw(raw_t *raw)
int input_nvsf(raw_t *raw, FILE *fp)
static int decode_gpsephem(int sat, raw_t *raw)
static int decode_x4btime(raw_t *raw)
static int decode_xf7eph(raw_t *raw)
MRTKLIB Receiver Raw Data Module — Receiver raw data types and decoder functions for various GNSS rec...
static const double ura_eph[]
MRTKLIB RTCM Module — RTCM message types and functions.
int sbsdecodemsg(gtime_t time, int prn, const uint32_t *words, sbsmsg_t *sbsmsg)
Decode SBAS message frame words.
MRTKLIB SBAS Module — SBAS message decoding and corrections.
MRTKLIB System Module — OS/filesystem utility functions.
gtime_t epoch2time(const double *ep)
Convert calendar day/time to gtime_t struct.
gtime_t gpst2time(int week, double sec)
Convert GPS week/tow to gtime_t.
void time2epoch(gtime_t t, double *ep)
Convert gtime_t struct to calendar day/time.
void time2str(gtime_t t, char *s, int n)
Convert gtime_t struct to string.
double timediff(gtime_t t1, gtime_t t2)
Compute time difference (t1 - t2).
double time2gpst(gtime_t t, int *week)
Convert gtime_t to GPS week/tow.
int adjgpsweek(int week)
Adjust GPS week number using CPU time.
gtime_t timeadd(gtime_t t, double sec)
Add seconds to gtime_t.
gtime_t utc2gpst(gtime_t t)
Convert UTC to GPS time considering leap seconds.
MRTKLIB Time Module — GNSS time types and conversion functions.
void trace(mrtk_ctx_t *ctx, int level, const char *format,...)
Output trace message.
MRTKLIB Trace Module — debug trace and logging functions.
GPS/GAL/QZS/BDS/IRN broadcast ephemeris type.
GLONASS broadcast ephemeris type.
GNSS time representation.
Receiver raw data control type.
uint8_t halfc[MAXSAT][5+5]