51#define PI 3.1415926535897932
52#define D2R (PI / 180.0)
53#define AS2R (D2R / 3600.0)
54#define CLIGHT 299792458.0
55#define OMGE 7.2921151467E-5
57#define SQR(x) ((x) * (x))
71#define FREQ1 1.57542E9
72#define FREQ2 1.22760E9
73#define FREQ5 1.17645E9
74#define FREQ7 1.20714E9
75#define FREQ9 2.492028E9
76#define FREQ1_CMP 1.561098E9
77#define FREQ2_CMP 1.20714E9
82#define EXTERR_CLK 1E-3
83#define EXTERR_EPH 5E-7
105 trace(NULL, 3,
"readerp: file=%s\n", file);
107 if (!(fp = fopen(file,
"r"))) {
108 trace(NULL, 2,
"erp file open error: file=%s\n", file);
111 while (fgets(buff,
sizeof(buff), fp)) {
112 if (sscanf(buff,
"%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf", v, v + 1, v + 2, v + 3, v + 4,
113 v + 5, v + 6, v + 7, v + 8, v + 9, v + 10, v + 11, v + 12, v + 13) < 5) {
116 if (erp->
n >= erp->
nmax) {
122 erp->
n = erp->
nmax = 0;
126 erp->
data = erp_data;
132 erp->
data[erp->
n].
lod = v[4] * 1E-7;
147 const double ep[] = {2000, 1, 1, 12, 0, 0};
151 trace(NULL, 4,
"geterp:\n");
159 if (mjd <= erp->data[0].mjd) {
167 if (mjd >= erp->
data[erp->
n - 1].
mjd) {
168 day = mjd - erp->
data[erp->
n - 1].
mjd;
172 erpv[3] = erp->
data[erp->
n - 1].
lod;
175 for (j = 0, k = erp->
n - 1; j < k - 1;) {
177 if (mjd < erp->data[i].mjd) {
188 erpv[0] = (1.0 - a) * erp->
data[j].
xp + a * erp->
data[j + 1].
xp;
189 erpv[1] = (1.0 - a) * erp->
data[j].
yp + a * erp->
data[j + 1].
yp;
191 erpv[3] = (1.0 - a) * erp->
data[j].
lod + a * erp->
data[j + 1].
lod;
202 if (code ==
'G' || code ==
' ') {
226static int readsp3h(FILE* fp,
gtime_t* time,
char* type,
int* sats,
double* bfact,
char* tsys) {
227 int i, j, k = 0, ns = 0, sys, prn;
230 trace(NULL, 3,
"readsp3h:\n");
233 if (!fgets(buff,
sizeof(buff), fp)) {
242 }
else if (!strncmp(buff,
"+ ", 2)) {
246 for (j = 0; j < 17 && k < ns; j++) {
248 prn = (int)
str2num(buff, 10 + 3 * j, 2);
250 sats[k++] =
satno(sys, prn);
253 }
else if (!strncmp(buff,
"++", 2)) {
255 }
else if (!strncmp(buff,
"%c", 2)) {
256 sprintf(tsys,
"%.3s", buff + 9);
257 }
else if (!strncmp(buff,
"%f", 2) && bfact[0] == 0.0) {
258 bfact[0] =
str2num(buff, 3, 10);
259 bfact[1] =
str2num(buff, 14, 12);
260 }
else if (!strncmp(buff,
"%i", 2)) {
262 }
else if (!strncmp(buff,
"/*", 2)) {
264 }
else if (!strncmp(buff,
"* ", 2)) {
278 trace(NULL, 1,
"readsp3b malloc error n=%d\n", nav->
nemax);
284 nav->
peph = nav_peph;
286 nav->
peph[nav->
ne++] = *peph;
290static void readsp3b(FILE* fp,
char type,
int* sats,
int ns,
double* bfact,
char* tsys,
int index,
int opt,
294 double val, std, base;
295 int i, j, sat, sys, prn, n = ns * (type ==
'P' ? 1 : 2), pred_o, pred_c, v;
298 trace(NULL, 3,
"readsp3b: type=%c ns=%d index=%d opt=%d\n", type, ns, index, opt);
300 while (fgets(buff,
sizeof(buff), fp)) {
301 if (!strncmp(buff,
"EOF", 3)) {
306 if (buff[0] !=
'*' ||
str2time(buff, 3, 28, &time)) {
309 if (!strcmp(tsys,
"UTC")) {
315 for (i = 0; i <
MAXSAT; i++) {
316 for (j = 0; j < 4; j++) {
317 peph.
pos[i][j] = 0.0;
318 peph.
std[i][j] = 0.0f;
319 peph.
vel[i][j] = 0.0;
320 peph.
vst[i][j] = 0.0f;
322 for (j = 0; j < 3; j++) {
323 peph.
cov[i][j] = 0.0f;
324 peph.
vco[i][j] = 0.0f;
327 for (i = pred_o = pred_c = v = 0; i < n && fgets(buff,
sizeof(buff), fp); i++) {
328 if (strlen(buff) < 4 || (buff[0] !=
'P' && buff[0] !=
'V')) {
333 prn = (int)
str2num(buff, 2, 2);
340 if (!(sat =
satno(sys, prn))) {
344 if (buff[0] ==
'P') {
345 pred_c = strlen(buff) >= 76 && buff[75] ==
'P';
346 pred_o = strlen(buff) >= 80 && buff[79] ==
'P';
348 for (j = 0; j < 4; j++) {
350 if (j < 3 && (opt & 1) && pred_o) {
353 if (j < 3 && (opt & 2) && !pred_o) {
356 if (j == 3 && (opt & 1) && pred_c) {
359 if (j == 3 && (opt & 2) && !pred_c) {
363 val =
str2num(buff, 4 + j * 14, 14);
364 std =
str2num(buff, 61 + j * 3, j < 3 ? 2 : 3);
366 if (buff[0] ==
'P') {
367 if (val != 0.0 && fabs(val - 999999.999999) >= 1E-6) {
368 peph.
pos[sat - 1][j] = val * (j < 3 ? 1000.0 : 1E-6);
371 if ((base = bfact[j < 3 ? 0 : 1]) > 0.0 && std > 0.0) {
372 peph.
std[sat - 1][j] = (float)(pow(base, std) * (j < 3 ? 1E-3 : 1E-12));
375 if (val != 0.0 && fabs(val - 999999.999999) >= 1E-6) {
376 peph.
vel[sat - 1][j] = val * (j < 3 ? 0.1 : 1E-10);
378 if ((base = bfact[j < 3 ? 0 : 1]) > 0.0 && std > 0.0) {
379 peph.
vst[sat - 1][j] = (float)(pow(base, std) * (j < 3 ? 1E-7 : 1E-16));
392static int cmppeph(
const void* p1,
const void* p2) {
395 return tt < -1E-9 ? -1 : (tt > 1E-9 ? 1 : q1->
index - q2->index);
401 trace(NULL, 3,
"combpeph: ne=%d\n", nav->
ne);
409 for (i = 0, j = 1; j < nav->
ne; j++) {
411 for (k = 0; k <
MAXSAT; k++) {
415 for (m = 0; m < 4; m++) {
418 for (m = 0; m < 4; m++) {
421 for (m = 0; m < 4; m++) {
424 for (m = 0; m < 4; m++) {
428 }
else if (++i < j) {
434 trace(NULL, 4,
"combpeph: ne=%d\n", nav->
ne);
453 double bfact[2] = {0};
454 int i, j, n, ns, sats[
MAXSAT] = {0};
455 char *efiles[
MAXEXFILE], *ext, type =
' ', tsys[4] =
"";
457 trace(NULL, 3,
"readpephs: file=%s\n", file);
460 if (!(efiles[i] = (
char*)
malloc(1024))) {
461 for (i--; i >= 0; i--) {
470 for (i = j = 0; i < n; i++) {
471 if (!(ext = strrchr(efiles[i],
'.'))) {
475 if (!strstr(ext,
".sp3") && !strstr(ext,
".SP3") && !strstr(ext,
".eph") && !strstr(ext,
".EPH")) {
479 if (!(fp = fopen(efiles[i],
"r"))) {
480 trace(NULL, 2,
"sp3 file open error %s\n", efiles[i]);
484 ns =
readsp3h(fp, &time, &type, sats, bfact, tsys);
487 readsp3b(fp, type, sats, ns, bfact, tsys, j++, opt, nav);
510 pcv_t pcv0 = {0}, *pcv;
513 trace(NULL, 3,
"readsap : file=%s time=%s\n", file,
time_str(time, 0));
519 for (i = 0; i <
MAXSAT; i++) {
521 nav->
pcvs[i] = pcv ? *pcv : pcv0;
530 char buff[256], str1[32], str2[32] =
"";
531 int i, j, sat, type = 0;
533 trace(NULL, 3,
"readdcbf: file=%s\n", file);
535 if (!(fp = fopen(file,
"r"))) {
536 trace(NULL, 2,
"dcb parameters file open error: %s\n", file);
539 while (fgets(buff,
sizeof(buff), fp)) {
540 if (strstr(buff,
"DIFFERENTIAL (P1-P2) CODE BIASES")) {
542 }
else if (strstr(buff,
"DIFFERENTIAL (P1-C1) CODE BIASES")) {
544 }
else if (strstr(buff,
"DIFFERENTIAL (P2-C2) CODE BIASES")) {
548 if (!type || sscanf(buff,
"%s %s", str1, str2) < 1) {
552 if ((cbias =
str2num(buff, 26, 9)) == 0.0) {
556 if (sta && (!strcmp(str1,
"G") || !strcmp(str1,
"R"))) {
557 for (i = 0; i <
MAXRCV; i++) {
558 if (!strcmp(sta[i].name, str2)) {
563 j = !strcmp(str1,
"G") ? 0 : 1;
564 nav->
rbias[i][j][type - 1] = cbias * 1E-9 *
CLIGHT;
566 }
else if ((sat =
satid2no(str1))) {
567 nav->
cbias[sat - 1][type - 1] = cbias * 1E-9 *
CLIGHT;
587 trace(NULL, 3,
"readdcb : file=%s\n", file);
589 for (i = 0; i <
MAXSAT; i++) {
590 for (j = 0; j < 3; j++) {
591 nav->
cbias[i][j] = 0.0;
595 if (!(efiles[i] = (
char*)
malloc(1024))) {
596 for (i--; i >= 0; i--) {
604 for (i = 0; i < n; i++) {
614static double interppol(
const double* x,
double* y,
int n) {
617 for (j = 1; j < n; j++) {
618 for (i = 0; i < n - j; i++) {
619 y[i] = (x[i + j] * y[i] - x[i] * y[i + 1]) / (x[i + j] - x[i]);
625static int pephpos(
gtime_t time,
int sat,
const nav_t* nav,
double* rs,
double* dts,
double* vare,
double* varc) {
626 double t[
NMAX + 1], p[3][
NMAX + 1], c[2], *pos, std = 0.0, s[3], sinl, cosl;
629 trace(NULL, 4,
"pephpos : time=%s sat=%2d\n",
time_str(time, 3), sat);
631 rs[0] = rs[1] = rs[2] = dts[0] = 0.0;
635 trace(NULL, 3,
"no prec ephem %s sat=%2d\n",
time_str(time, 0), sat);
639 for (i = 0, j = nav->
ne - 1; i < j;) {
647 index = i <= 0 ? 0 : i - 1;
650 i = index - (
NMAX + 1) / 2;
653 }
else if (i +
NMAX >= nav->
ne) {
657 for (j = 0; j <=
NMAX; j++) {
659 if (
norm(nav->
peph[i + j].
pos[sat - 1], 3) <= 0.0) {
660 trace(NULL, 3,
"prec ephem outage %s sat=%2d\n",
time_str(time, 0), sat);
664 for (j = 0; j <=
NMAX; j++) {
665 pos = nav->
peph[i + j].
pos[sat - 1];
667 sinl = sin(
OMGE * t[j]);
668 cosl = cos(
OMGE * t[j]);
669 p[0][j] = cosl * pos[0] - sinl * pos[1];
670 p[1][j] = sinl * pos[0] + cosl * pos[1];
673 for (i = 0; i < 3; i++) {
677 for (i = 0; i < 3; i++) {
678 s[i] = nav->
peph[index].
std[sat - 1][i];
685 }
else if (t[
NMAX] < 0.0) {
693 c[0] = nav->
peph[index].
pos[sat - 1][3];
694 c[1] = nav->
peph[index + 1].
pos[sat - 1][3];
697 if ((dts[0] = c[0]) != 0.0) {
700 }
else if (t[1] >= 0.0) {
701 if ((dts[0] = c[1]) != 0.0) {
704 }
else if (c[0] != 0.0 && c[1] != 0.0) {
705 dts[0] = (c[1] * t[0] - c[0] * t[1]) / (t[0] - t[1]);
706 i = t[0] < -t[1] ? 0 : 1;
718 double t[2], c[2], std;
721 trace(NULL, 4,
"pephclk : time=%s sat=%2d\n",
time_str(time, 3), sat);
725 trace(NULL, 3,
"no prec clock %s sat=%2d\n",
time_str(time, 0), sat);
729 for (i = 0, j = nav->
nc - 1; i < j;) {
737 index = i <= 0 ? 0 : i - 1;
742 c[0] = nav->
pclk[index].
clk[sat - 1][0];
743 c[1] = nav->
pclk[index + 1].
clk[sat - 1][0];
746 if ((dts[0] = c[0]) == 0.0) {
750 }
else if (t[1] >= 0.0) {
751 if ((dts[0] = c[1]) == 0.0) {
755 }
else if (c[0] != 0.0 && c[1] != 0.0) {
756 dts[0] = (c[1] * t[0] - c[0] * t[1]) / (t[0] - t[1]);
757 i = t[0] < -t[1] ? 0 : 1;
760 trace(NULL, 3,
"prec clock outage %s sat=%2d\n",
time_str(time, 0), sat);
787 double ex[3], ey[3], ez[3], es[3], r[3], rsun[3], gmst, erpv[5] = {0}, freq[2];
788 double C1, C2, dant1, dant2;
791 trace(NULL, 4,
"satantoff: time=%s sat=%2d\n",
time_str(time, 3), sat);
793 dant[0] = dant[1] = dant[2] = 0.0;
799 for (i = 0; i < 3; i++) {
805 for (i = 0; i < 3; i++) {
806 r[i] = rsun[i] - rs[i];
826 if (freq[0] == 0.0 || freq[1] == 0.0) {
830 C1 =
SQR(freq[0]) / (
SQR(freq[0]) -
SQR(freq[1]));
831 C2 = -
SQR(freq[1]) / (
SQR(freq[0]) -
SQR(freq[1]));
839 for (i = 0; i < 3; i++) {
840 dant1 = pcv->
off[a1][0] * ex[i] + pcv->
off[a1][1] * ey[i] + pcv->
off[a1][2] * ez[i];
841 dant2 = pcv->
off[a2][0] * ex[i] + pcv->
off[a2][1] * ey[i] + pcv->
off[a2][2] * ez[i];
842 dant[i] = C1 * dant1 + C2 * dant2;
866 double rss[3], rst[3], dtss[1], dtst[1], dant[3] = {0}, vare = 0.0, varc = 0.0, tt = 1E-3;
869 trace(NULL, 4,
"peph2pos: time=%s sat=%2d opt=%d\n",
time_str(time, 3), sat, opt);
871 if (sat <= 0 ||
MAXSAT < sat) {
876 if (!
pephpos(time, sat, nav, rss, dtss, &vare, &varc) || !
pephclk(time, sat, nav, dtss, &varc)) {
881 if (!
pephpos(time_tt, sat, nav, rst, dtst, NULL, NULL) || !
pephclk(time_tt, sat, nav, dtst, NULL)) {
889 for (i = 0; i < 3; i++) {
890 rs[i] = rss[i] + dant[i];
891 rs[i + 3] = (rst[i] - rss[i]) / tt;
894 if (dtss[0] != 0.0) {
896 dts[1] = (dtst[0] - dtss[0]) / tt;
898 dts[0] = dts[1] = 0.0;
int readpcv(const char *file, pcvs_t *pcvs)
Read antenna parameters from file (ANTEX or NGS format).
pcv_t * searchpcv(int sat, const char *type, gtime_t time, const pcvs_t *pcvs)
Search antenna parameter by satellite number or antenna type.
MRTKLIB Antenna Module — Antenna phase center model and parameter I/O.
void sunmoonpos(gtime_t tutc, const double *erpv, double *rsun, double *rmoon, double *gmst)
Compute sun and moon position in ECEF.
MRTKLIB Astronomy Module — Sun and moon position computation.
int satid2no(const char *id)
double sat2freq(int sat, uint8_t code, const nav_t *nav)
void cross3(const double *a, const double *b, double *c)
Cross product of 3D vectors.
double norm(const double *a, int n)
Euclidean norm of vector.
int normv3(const double *a, double *b)
Normalize 3D vector.
double dot(const double *a, const double *b, int n)
Inner product of vectors.
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.
void readsp3(const char *file, nav_t *nav, int opt)
Read sp3 precise ephemeris file.
static int code2sys(char code)
int freq_idx2ant_idx(int sys, int freq_idx)
static int pephclk(gtime_t time, int sat, const nav_t *nav, double *dts, double *varc)
int readdcb(const char *file, nav_t *nav, const sta_t *sta)
Read differential code bias (DCB) parameters.
static void readsp3b(FILE *fp, char type, int *sats, int ns, double *bfact, char *tsys, int index, int opt, nav_t *nav)
static int readsp3h(FILE *fp, gtime_t *time, char *type, int *sats, double *bfact, char *tsys)
static double interppol(const double *x, double *y, int n)
static int cmppeph(const void *p1, const void *p2)
static void combpeph(nav_t *nav, int opt)
int satsys_bd2(int sat, int *prn)
int readerp(const char *file, erp_t *erp)
Read earth rotation parameters from IGS ERP file (ver.2).
double freq_num2freq(int sys, int freq_num, int fcn)
static int pephpos(gtime_t time, int sat, const nav_t *nav, double *rs, double *dts, double *vare, double *varc)
int peph2pos(gtime_t time, int sat, const nav_t *nav, int opt, double *rs, double *dts, double *var)
Compute satellite position/clock with precise ephemeris/clock.
static int readdcbf(const char *file, nav_t *nav, const sta_t *sta)
int readsap(const char *file, gtime_t time, nav_t *nav)
Read satellite antenna parameters.
int freq_idx2freq_num(int sys, int freq_idx)
void satantoff(gtime_t time, const double *rs, int sat, const nav_t *nav, double *dant)
Compute satellite antenna phase center offset in ecef.
int geterp(const erp_t *erp, gtime_t time, double *erpv)
Get earth rotation parameter values at specified time.
static int addpeph(nav_t *nav, peph_t *peph)
MRTKLIB Precise Ephemeris Module — Earth rotation parameter types and ERP I/O functions.
int expath(const char *path, char *paths[], int nmax)
Expand file path with wild-card (*) in file.
double str2num(const char *s, int i, int n)
Convert substring in string to number.
MRTKLIB System Module — OS/filesystem utility functions.
gtime_t epoch2time(const double *ep)
Convert calendar day/time to gtime_t struct.
gtime_t gpst2utc(gtime_t t)
Convert GPS time to UTC considering leap seconds.
double timediff(gtime_t t1, gtime_t t2)
Compute time difference (t1 - t2).
gtime_t timeadd(gtime_t t, double sec)
Add seconds to gtime_t.
char * time_str(gtime_t t, int n)
Get time string (not reentrant).
int str2time(const char *s, int i, int n, gtime_t *t)
Convert substring in string to gtime_t struct.
gtime_t utc2gpst(gtime_t t)
Convert UTC to GPS time considering leap seconds.
void trace(mrtk_ctx_t *ctx, int level, const char *format,...)
Output trace message.
MRTKLIB Trace Module — debug trace and logging functions.
ERP (earth rotation parameter) type.
ERP (earth rotation parameter) data type.
GNSS time representation.
double rbias[MAXRCV][2][3]