29#define D2R (3.1415926535897932 / 180.0)
30#define R2D (180.0 / 3.1415926535897932)
33#define GN(gp) (gp == 1 ? 64 : 16)
39static void vsub(
const double a[3],
const double b[3],
double c[3]) {
42 for (i = 0; i < 3; i++) {
47static int plane(
const double p1[3],
const double p2[3],
const double p3[3],
double peq[4]) {
48 double a2b[3], a2c[3];
56 peq[3] = -1 * (peq[0] * p1[0] + peq[1] * p1[1] + peq[2] * p1[2]);
60static int intpt(
const double p1[3],
const double p2[3],
const double p3[3],
double t[3]) {
62 if (!
plane(p1, p2, p3, peq)) {
65 t[2] = -1 * (t[0] * peq[0] + t[1] * peq[1] + peq[3]) / peq[2];
69static double normvz(
const double a[3],
const double b[3],
const double tgt[3]) {
74 return v1[0] * v2[1] - v1[1] * v2[0];
77static int selpersta(
const stat_t* stat,
const double* llh,
int flag,
double maxdist,
int*
id) {
81 double ecef[3], tllh[2][3];
85 sdist[i] = maxdist * 1E3;
94 if (spos->
ecef[0] == 0.0) {
101 trace(NULL, 4,
"get_site:targetpos llh=%f,%f,%f site pos llh=%f,%f,%f dist=%f\n", tllh[0][0] *
R2D,
102 tllh[0][1] *
R2D, tllh[0][2], tllh[1][0] *
R2D, tllh[1][1] *
R2D, tllh[1][2], d);
103 if (d > maxdist * 1E3) {
111 for (k = n; k > j && k > 0; k--) {
112 sdist[k] = sdist[k - 1];
124static int coldet(
const double p1[3],
const double p2[3],
const double p3[3],
const double tgt[3]) {
127 z[0] =
normvz(p2, p1, tgt);
128 z[1] =
normvz(p3, p2, tgt);
129 z[2] =
normvz(p1, p3, tgt);
131 if ((z[0] > 0 && z[1] > 0 && z[2] > 0) || (z[0] < 0 && z[1] < 0 && z[2] < 0)) {
137static int gettriangledd(
const stat_t* stat,
const double* llh,
int flag,
const double maxdist,
const int extp,
139 int i, j, k, stanum = 0, ret = 0;
141 double sllh[3][3] = {{0.0}};
144 stanum =
selpersta(stat, llh, flag, maxdist,
id);
150 for (i = 0; i < stanum && i <
MAXSITES; i++) {
158 for (j = i + 1; j < stanum && j <
MAXSITES; j++) {
166 for (k = j + 1; k < stanum && k <
MAXSITES; k++) {
174 ret =
coldet(sllh[0], sllh[1], sllh[2], llh);
176 trace(NULL, 3,
"interpolation: %.1f %.1f site=%s %s %s\n", llh[0] *
R2D, llh[1] *
R2D, site[0].name,
177 site[1].name, site[2].name);
185 for (i = 0; i < 3; i++) {
193 trace(NULL, 3,
"extrapolation: %.1f %.1f site=%s %s %s\n", llh[0] *
R2D, llh[1] *
R2D, site[0].name,
194 site[1].name, site[2].name);
203 double zazel[] = {0.0, 90.0 *
D2R}, zhd, trp_s[3][3] = {{0.0}}, std_s[3][3] = {{0.0}};
204 double tri[9] = {0.0}, trit[3];
211 for (i = 0; i < 3; i++) {
215 if (trp_s[i][0] == 0.0) {
219 zhd =
tropmodel(time, &tri[i * 3], zazel, 0.0);
224 memcpy(trit, llh,
sizeof(trit));
227 for (i = 0; i < 3; i++) {
228 for (j = 0; j < 3; j++) {
229 tri[j * 3 + 2] = trp_s[j][i];
231 intpt(&tri[0], &tri[3], &tri[6], &trit[0]);
233 for (j = 0; j < 3; j++) {
234 tri[j * 3 + 2] = std_s[j][i];
236 intpt(&tri[0], &tri[3], &tri[6], &trit[0]);
239 trp[0] +=
tropmodel(time, llh, zazel, 0.0);
244 double* std,
double maxres,
int* nrej,
int* ncnt) {
247 double tri[9] = {0.0}, trit[3], res;
254 for (i = 0; i < 3; i++) {
262 memcpy(trit, llh,
sizeof(trit));
264 for (i = 0; i <
MAXSAT; i++) {
265 for (j = 0; j < 3; j++) {
266 if (ion_s[j][i] == 0.0) {
269 tri[j * 3 + 2] = ion_s[j][i];
274 intpt(&tri[0], &tri[3], &tri[6], &trit[0]);
276 for (j = 0; j < 3; j++) {
277 if (ion_s[j][i] == 0.0) {
280 tri[j * 3 + 2] = std_s[j][i];
282 intpt(&tri[0], &tri[3], &tri[6], &trit[0]);
286 for (i = 0; i < 3; i++) {
287 for (j = 0; j <
MAXSAT; j++) {
288 if (ion_s[i][j] == 0.0) {
291 res = ion[i] - ion_s[i][j];
293 if (fabs(res) > maxres) {
310 char *token, buff[256];
316 if ((sfp = fopen(setfile,
"r")) == NULL) {
317 trace(NULL, 2,
"initgridsta : setting file open error :%s\n", setfile);
320 while (fgets(buff,
sizeof(buff), sfp) != NULL) {
321 if (buff[0] ==
'#') {
325 strcpy(type, strtok(buff,
","));
326 if (strncmp(type,
"I", 1) == 0) {
328 bnum = &lclblk->
inum;
330 }
else if (strncmp(type,
"T", 1) == 0) {
332 bnum = &lclblk->
tnum;
335 trace(NULL, 2,
"initgrid : grid setting file type error :%s\n", type);
341 token = strtok(NULL,
",");
343 trace(NULL, 2,
"initgrid : grid setting file format error : bn\n");
346 bi->
bn = atoi(token);
348 token = strtok(NULL,
",");
350 trace(NULL, 2,
"initgrid : grid setting file format error : gp\n");
356 }
else if (gp == 64) {
359 trace(NULL, 2,
"initgrid : grid setting file grid pitch error :%d\n", gp);
362 token = strtok(NULL,
",");
364 trace(NULL, 2,
"initgrid : grid setting file format error : mask[0]\n");
367 bi->
mask[0] = strtol(token, NULL, 0);
368 token = strtok(NULL,
",");
370 trace(NULL, 2,
"initgrid : grid setting file format error : mask[1]\n");
373 bi->
mask[1] = strtol(token, NULL, 0);
378 trace(NULL, 3,
"initgrid : read grid setting file [%s]\n", buff);
395 for (i = 0; i < lclblk->
tnum; i++) {
399 memset(bi->
gp, 0x00,
sizeof(bi->
gp));
401 for (j = 0, n = 0; j <
GN(bi->
gpitch); j++) {
417 for (j = 0; j < n; j++) {
418 if (bi->
gp[j] < 32) {
419 bi->
mask[0] |= 1 << bi->
gp[j];
421 bi->
mask[1] |= 1 << (bi->
gp[j] - 32);
438 for (i = 0; i < lslblk->
tnum; i++) {
441 for (j = 0; j < stat->
nst; j++) {
443 if (llh[0] >= bi->
bpos[0]) {
446 if (llh[0] < bi->
bpos[0] - bi->
bs *
D2R) {
449 if (llh[1] <= bi->
bpos[1]) {
452 if (llh[1] > bi->
bpos[1] + bi->
bs *
D2R) {
456 strp = &lslblk->
tstat[i][bi->
n];
457 for (k = 0; k < 3; k++) {
458 bi->
grid[bi->
n][k] = llh[k];
482 for (i = 0; i < lclblk->
inum; i++) {
486 memset(bi->
gp, 0x00,
sizeof(bi->
gp));
488 for (j = 0, n = 0; j <
GN(bi->
gpitch); j++) {
499 for (k = 0; k <
MAXSAT; k++) {
506 memset(ionp, 0x00,
sizeof(
ion_t));
513 for (j = 0; j < n; j++) {
514 if (bi->
gp[j] < 32) {
515 bi->
mask[0] |= 1 << bi->
gp[j];
517 bi->
mask[1] |= 1 << (bi->
gp[j] - 32);
535 for (i = 0; i < lslblk->
tnum; i++) {
539 for (j = 0; j < stat->
nsi; j++) {
541 if (llh[0] >= bi->
bpos[0]) {
544 if (llh[0] < bi->
bpos[0] - bi->
bs *
D2R) {
547 if (llh[1] <= bi->
bpos[1]) {
550 if (llh[1] > bi->
bpos[1] + bi->
bs *
D2R) {
554 sion = &lslblk->
istat[i][bi->
n];
555 for (k = 0; k < 3; k++) {
556 bi->
grid[bi->
n][k] = llh[k];
559 for (k = 0; k <
MAXSAT; k++) {
593 for (i = 0; i <
rtcm->lclblk->tnum; i++) {
594 rtcm->lclblk->outtn = i;
599 for (i = 0; i <
rtcm->lclblk->inum; i++) {
600 rtcm->lclblk->outin = i;
601 for (j = basemt + 1; j <= basemt + 5; j++) {
double tropmodel(gtime_t time, const double *pos, const double *azel, double humi)
Compute tropospheric delay by standard atmosphere and Saastamoinen.
MRTKLIB Atmosphere Module — Ionospheric and tropospheric models.
void pos2ecef(const double *pos, double *r)
Transform geodetic position to ECEF position.
void ecef2pos(const double *r, double *pos)
Transform ECEF position to geodetic position.
MRTKLIB Coordinates Module — Coordinate transformations and geometry.
static int plane(const double p1[3], const double p2[3], const double p3[3], double peq[4])
int strwrite(struct stream_tag *stream, uint8_t *buff, int n)
void grid_intp_trop(const gtime_t gt, const stat_t *stat, lclblock_t *lclblk)
Interpolate tropospheric grid data.
static void vsub(const double a[3], const double b[3], double c[3])
int initgridsta(const char *setfile, lclblock_t *lclblk, int btype)
Initialize grid/station settings from a specified file.
static int gettriangledd(const stat_t *stat, const double *llh, int flag, const double maxdist, const int extp, int *staid)
static int corr_iono_plane(const stat_t *stat, gtime_t time, const double *llh, double maxdist, int extp, double *ion, double *std, double maxres, int *nrej, int *ncnt)
static double normvz(const double a[3], const double b[3], const double tgt[3])
static int coldet(const double p1[3], const double p2[3], const double p3[3], const double tgt[3])
void sta_sel_trop(const gtime_t time, const stat_t *stat, lclblock_t *lslblk)
Select and assign tropospheric data blocks based on station positions.
static int selpersta(const stat_t *stat, const double *llh, int flag, double maxdist, int *id)
void grid_intp_iono(const gtime_t gt, const stat_t *stat, lclblock_t *lclblk, double maxres, int *nrej, int *ncnt)
Interpolate ionospheric grid data.
void output_lclcmb(rtcm_t *rtcm, int btype, struct stream_tag *ostr)
Generate and output RTCM3 local combination correction messages.
void sta_sel_iono(const gtime_t gt, const stat_t *stat, lclblock_t *lslblk)
Select and assign ionospheric data blocks based on station positions.
static int corr_trop_plane(const stat_t *stat, gtime_t time, const double *llh, double maxdist, int extp, double *trp, double *std)
static int intpt(const double p1[3], const double p2[3], const double p3[3], double t[3])
MRTKLIB MADOCA Local Combination Module — local correction data combination functions.
double posdist(const double *ecef1, const double *ecef2)
Calculate the Euclidean distance between two ECEF positions.
int corr_trop_distwgt(const stat_t *stat, gtime_t time, const double *llh, double maxdist, double *trp, double *std)
Calculate tropospheric correction using weighted interpolation by distance.
int get_trop_sta(gtime_t time, const trp_t *trpd, double *trp, double *std)
Get tropospheric correction for a point.
int get_iono_sta(gtime_t time, const ion_t *iond, double *ion, double *std, double *el)
Get ionospheric correction for a point.
int corr_iono_distwgt(const stat_t *stat, gtime_t time, const double *llh, const double *el, double maxdist, double *ion, double *std, double maxres, int *nrej, int *ncnt)
Calculate ionospheric correction using weighted interpolation by distance.
void cross3(const double *a, const double *b, double *c)
Cross product of 3D vectors.
int normv3(const double *a, double *b)
Normalize 3D vector.
MRTKLIB Matrix Module — Matrix/vector operations and estimation.
void initblkinf(blkinf_t *b)
Initialize block information struct.
int gen_rtcm3(rtcm_t *rtcm, int type, int subtype, int sync)
Generate RTCM 3 message.
double timediff(gtime_t t1, gtime_t t2)
Compute time difference (t1 - t2).
void trace(mrtk_ctx_t *ctx, int level, const char *format,...)
Output trace message.
MRTKLIB Trace Module — debug trace and logging functions.
double grid[MAXTRPSTA][3]
GNSS time representation.
sitetrp_t tstat[MAXBLK][MAXTRPSTA]
siteion_t istat[MAXBLK][MAXTRPSTA]
RTCM control struct type.