43static const double PI = 3.1415926535897932;
44static const double D2R = 3.1415926535897932 / 180.0;
45static const double R2D = 180.0 / 3.1415926535897932;
50#define SQR(x) ((x) * (x))
52#define AS2R (D2R / 3600.0)
53#define GME 3.986004415E+14
54#define GMS 1.327124E+20
55#define GMM 4.902801E+12
59extern int dehanttideinel_(
double* xsta,
int* year,
int* mon,
int* day,
double* fhr,
double* xsun,
double* xmon,
65static void tide_pl(
const double* eu,
const double* rp,
double GMp,
const double* pos,
double* dr) {
66 const double H3 = 0.292, L3 = 0.015;
67 double r, ep[3], latp, lonp, p, K2, K3, a, H2, L2, dp, du, cosp, sinl, cosl;
70 trace(NULL, 4,
"tide_pl : pos=%.3f %.3f\n", pos[0] *
R2D, pos[1] *
R2D);
72 if ((r =
norm(rp, 3)) <= 0.0) {
76 for (i = 0; i < 3; i++) {
83 lonp = atan2(ep[1], ep[0]);
89 p = (3.0 * sinl * sinl - 1.0) / 2.0;
90 H2 = 0.6078 - 0.0006 * p;
91 L2 = 0.0847 + 0.0002 * p;
93 dp = K2 * 3.0 * L2 * a;
94 du = K2 * (H2 * (1.5 * a * a - 0.5) - 3.0 * L2 * a * a);
97 dp += K3 * L3 * (7.5 * a * a - 1.5);
98 du += K3 * (H3 * (2.5 * a * a * a - 1.5 * a) - L3 * (7.5 * a * a - 1.5) * a);
101 du += 3.0 / 4.0 * 0.0025 * K2 * sin(2.0 * latp) * sin(2.0 * pos[0]) * sin(pos[1] - lonp);
102 du += 3.0 / 4.0 * 0.0022 * K2 * cosp * cosp * cosl * cosl * sin(2.0 * (pos[1] - lonp));
104 dr[0] = dp * ep[0] + du * eu[0];
105 dr[1] = dp * ep[1] + du * eu[1];
106 dr[2] = dp * ep[2] + du * eu[2];
108 trace(NULL, 5,
"tide_pl : dr=%.3f %.3f %.3f\n", dr[0], dr[1], dr[2]);
111static void tide_solid(
const double* rsun,
const double* rmoon,
const double* pos,
const double* E,
double gmst,
112 int opt,
double* dr) {
113 double dr1[3], dr2[3], eu[3], du, dn, sinl, sin2l;
115 trace(NULL, 3,
"tide_solid: pos=%.3f %.3f opt=%d\n", pos[0] *
R2D, pos[1] *
R2D, opt);
125 sin2l = sin(2.0 * pos[0]);
126 du = -0.012 * sin2l * sin(gmst + pos[1]);
128 dr[0] = dr1[0] + dr2[0] + du * E[2];
129 dr[1] = dr1[1] + dr2[1] + du * E[5];
130 dr[2] = dr1[2] + dr2[2] + du * E[8];
135 du = 0.1196 * (1.5 * sinl * sinl - 0.5);
137 dr[0] += du * E[2] + dn * E[1];
138 dr[1] += du * E[5] + dn * E[4];
139 dr[2] += du * E[8] + dn * E[7];
141 trace(NULL, 5,
"tide_solid: dr=%.3f %.3f %.3f\n", dr[0], dr[1], dr[2]);
147 const double args[][5] = {
148 {1.40519E-4, 2.0, -2.0, 0.0, 0.00},
149 {1.45444E-4, 0.0, 0.0, 0.0, 0.00},
150 {1.37880E-4, 2.0, -3.0, 1.0, 0.00},
151 {1.45842E-4, 2.0, 0.0, 0.0, 0.00},
152 {0.72921E-4, 1.0, 0.0, 0.0, 0.25},
153 {0.67598E-4, 1.0, -2.0, 0.0, -0.25},
154 {0.72523E-4, -1.0, 0.0, 0.0, -0.25},
155 {0.64959E-4, 1.0, -3.0, 1.0, -0.25},
156 {0.53234E-5, 0.0, 2.0, 0.0, 0.00},
157 {0.26392E-5, 0.0, 1.0, -1.0, 0.00},
158 {0.03982E-5, 2.0, 0.0, 0.0, 0.00}
160 const double ep1975[] = {1975, 1, 1, 0, 0, 0};
161 double ep[6], fday, days, t, t2, t3, a[5], ang, dp[3] = {0};
164 trace(NULL, 3,
"tide_oload:\n");
168 fday = ep[3] * 3600.0 + ep[4] * 60.0 + ep[5];
169 ep[3] = ep[4] = ep[5] = 0.0;
171 t = (27392.500528 + 1.000000035 * days) / 36525.0;
176 a[1] = (279.69668 + 36000.768930485 * t + 3.03E-4 * t2) *
D2R;
177 a[2] = (270.434358 + 481267.88314137 * t - 0.001133 * t2 + 1.9E-6 * t3) *
D2R;
178 a[3] = (334.329653 + 4069.0340329577 * t - 0.010325 * t2 - 1.2E-5 * t3) *
D2R;
182 for (i = 0; i < 11; i++) {
184 for (j = 0; j < 5; j++) {
185 ang += a[j] * args[i][j];
187 for (j = 0; j < 3; j++) {
188 dp[j] += odisp[j + i * 6] * cos(ang - odisp[j + 3 + i * 6] *
D2R);
195 trace(NULL, 5,
"tide_oload: denu=%.3f %.3f %.3f\n", denu[0], denu[1], denu[2]);
199 const double ep2000[] = {2000, 1, 1, 0, 0, 0};
204 if (y < 3653.0 / 365.25) {
207 *xp_bar = 55.974 + 1.8243 * y + 0.18413 * y2 + 0.007024 * y3;
208 *yp_bar = 346.346 + 1.7896 * y - 0.10729 * y2 - 0.000908 * y3;
210 *xp_bar = 23.513 + 7.6141 * y;
211 *yp_bar = 358.891 - 0.6287 * y;
216 double xp_bar, yp_bar, m1, m2, cosl, sinl;
218 trace(NULL, 3,
"tide_pole: pos=%.3f %.3f\n", pos[0] *
R2D, pos[1] *
R2D);
224 m1 = erpv[0] /
AS2R - xp_bar * 1E-3;
225 m2 = -erpv[1] /
AS2R + yp_bar * 1E-3;
230 denu[0] = 9E-3 * sin(pos[0]) * (m1 * sinl - m2 * cosl);
231 denu[1] = -9E-3 * cos(2.0 * pos[0]) * (m1 * cosl + m2 * sinl);
232 denu[2] = -33E-3 * sin(2.0 * pos[0]) * (m1 * cosl + m2 * sinl);
234 trace(NULL, 5,
"tide_pole : denu=%.3f %.3f %.3f\n", denu[0], denu[1], denu[2]);
263 double pos[2], E[9], drt[3], denu[3], rs[3], rm[3], gmst, erpv[5] = {0};
277 dr[0] = dr[1] = dr[2] = 0.0;
279 if (
norm(rr, 3) <= 0.0) {
283 pos[0] = asin(rr[2] /
norm(rr, 3));
284 pos[1] = atan2(rr[1], rr[0]);
297 fhr = ep[3] + ep[4] / 60.0 + ep[5] / 3600.0;
300 dehanttideinel_((
double*)rr, &year, &mon, &day, &fhr, rs, rm, drt);
304 for (i = 0; i < 3; i++) {
308 if ((opt & 2) && odisp) {
310 matmul(
"TN", 3, 1, 3, 1.0, E, denu, 0.0, drt);
311 for (i = 0; i < 3; i++) {
315 if ((opt & 4) && erp) {
317 matmul(
"TN", 3, 1, 3, 1.0, E, denu, 0.0, drt);
318 for (i = 0; i < 3; i++) {
322 trace(NULL, 5,
"tidedisp: dr=%.3f %.3f %.3f\n", dr[0], dr[1], dr[2]);
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.
void xyz2enu(const double *pos, double *E)
Compute ECEF to local coordinate transformation matrix.
MRTKLIB Coordinates Module — Coordinate transformations and geometry.
double norm(const double *a, int n)
Euclidean norm of vector.
void matmul(const char *tr, int n, int k, int m, double alpha, const double *A, const double *B, double beta, double *C)
Multiply matrix by matrix (C = alpha*A*B + beta*C).
double dot(const double *a, const double *b, int n)
Inner product of vectors.
MRTKLIB Matrix Module — Matrix/vector operations and estimation.
int geterp(const erp_t *erp, gtime_t time, double *erpv)
Get earth rotation parameter values at specified time.
static void tide_pole(gtime_t tut, const double *pos, const double *erpv, double *denu)
static void iers_mean_pole(gtime_t tut, double *xp_bar, double *yp_bar)
static void tide_solid(const double *rsun, const double *rmoon, const double *pos, const double *E, double gmst, int opt, double *dr)
void tidedisp(gtime_t tutc, const double *rr, int opt, const erp_t *erp, const double *odisp, double *dr)
Compute displacements by earth tides.
static void tide_pl(const double *eu, const double *rp, double GMp, const double *pos, double *dr)
void tide_oload(gtime_t tut, const double *odisp, double *denu)
Compute displacement by ocean tide loading (11 constituents).
MRTKLIB Tides Module — Tidal displacement corrections.
gtime_t epoch2time(const double *ep)
Convert calendar day/time to gtime_t struct.
void time2epoch(gtime_t t, double *ep)
Convert gtime_t struct to calendar day/time.
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).
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.
GNSS time representation.