40extern int satsys(
int sat,
int* prn);
47#define PI 3.1415926535897932
48#define D2R (PI / 180.0)
49#define R2D (180.0 / PI)
56static int decodef(
char* p,
int n,
double* v) {
59 for (i = 0; i < n; i++) {
62 for (i = 0, p = strtok(p,
" "); p && i < n; p = strtok(NULL,
" ")) {
63 v[i++] = atof(p) * 1E-3;
71 if (pcvs->
nmax <= pcvs->
n) {
74 trace(NULL, 1,
"addpcv: memory allocation error\n");
77 pcvs->
n = pcvs->
nmax = 0;
82 pcvs->
pcv[pcvs->
n++] = *pcv;
87 static const pcv_t pcv0 = {0};
93 if (!(fp = fopen(file,
"r"))) {
94 trace(NULL, 2,
"ngs pcv file open error: %s\n", file);
97 while (fgets(buff,
sizeof(buff), fp)) {
98 if (strlen(buff) >= 62 && buff[61] ==
'|') {
102 if (buff[0] !=
' ') {
107 sprintf(pcv.
type,
"%.61s", buff);
109 if (
decodef(buff, 3, neu) < 3) {
112 pcv.
off[0][0] = neu[1];
113 pcv.
off[0][1] = neu[0];
114 pcv.
off[0][2] = neu[2];
120 if (
decodef(buff, 3, neu) < 3) {
123 pcv.
off[1][0] = neu[1];
124 pcv.
off[1][1] = neu[0];
125 pcv.
off[1][2] = neu[2];
140 static const pcv_t pcv0 = {0};
143 int i, f, idx = -1, state = 0, sys;
144 char buff[256], s = 0;
146 trace(NULL, 3,
"readantex: file=%s\n", file);
148 if (!(fp = fopen(file,
"r"))) {
149 trace(NULL, 2,
"antex pcv file open error: %s\n", file);
152 while (fgets(buff,
sizeof(buff), fp)) {
153 if (strlen(buff) < 60 || strstr(buff + 60,
"COMMENT")) {
157 if (strstr(buff + 60,
"START OF ANTENNA")) {
161 if (strstr(buff + 60,
"END OF ANTENNA")) {
169 if (strstr(buff + 60,
"TYPE / SERIAL NO")) {
170 strncpy(pcv.
type, buff, 20);
172 strncpy(pcv.
code, buff + 20, 20);
174 if (!strncmp(pcv.
code + 3,
" ", 8)) {
177 }
else if (strstr(buff + 60,
"VALID FROM")) {
181 }
else if (strstr(buff + 60,
"VALID UNTIL")) {
185 }
else if (strstr(buff + 60,
"START OF FREQUENCY")) {
187 if (sscanf(buff + 4,
"%d", &f) < 1) {
193 if (sscanf(buff + 3,
"%c%d", &s, &f) < 2) {
201 }
else if (strstr(buff + 60,
"END OF FREQUENCY")) {
203 }
else if (strstr(buff + 60,
"NORTH / EAST / UP")) {
204 if (idx < 0 || (
NFREQPCV - 1) <= idx) {
207 if (
decodef(buff, 3, neu) < 3) {
210 pcv.
off[idx][0] = neu[pcv.
sat ? 0 : 1];
211 pcv.
off[idx][1] = neu[pcv.
sat ? 1 : 0];
212 pcv.
off[idx][2] = neu[2];
213 }
else if (strstr(buff,
"NOAZI")) {
217 if ((i =
decodef(buff + 8, 19, pcv.
var[idx])) <= 0) {
220 for (; i < 19; i++) {
221 pcv.
var[idx][i] = pcv.
var[idx][i - 1];
231 double a = ang / 5.0;
235 }
else if (i >= 18) {
238 return var[i] * (1.0 - a + i) + var[i + 1] * (a - i);
260 trace(NULL, 3,
"readpcv: file=%s\n", file);
262 if (!(ext = strrchr(file,
'.'))) {
266 if (!strcmp(ext,
".pcv") || !strcmp(ext,
".PCV")) {
273 for (i = 0; i < pcvs->
n; i++) {
278 if (!strstr(pcv->
type,
"BLOCK IIF")) {
288 for (i = 0; i < pcvs->
n; i++) {
300 for (i = 0; i < pcvs->
n; i++) {
312 for (i = 0; i < pcvs->
n; i++) {
324 for (i = 0; i < pcvs->
n; i++) {
336 for (i = 0; i < pcvs->
n; i++) {
348 for (i = 0; i < pcvs->
n; i++) {
360 for (i = 0; i < pcvs->
n; i++) {
372 for (i = 0; i < pcvs->
n; i++) {
384 for (i = 0; i < pcvs->
n; i++) {
389 if (
norm(pcv->
off[10], 3) > 0.0 ||
norm(pcv->
var[10], 19) > 0.0) {
396 for (i = 0; i < pcvs->
n; i++) {
399 if (
norm(pcv->
off[f], 3) == 0.0) {
402 trace(NULL, 4,
"readpcv: sat=%2d type=%20s code=%s f=%2d off=%8.4f %8.4f %8.4f\n", pcv->
sat, pcv->
type,
403 pcv->
code, f, pcv->
off[f][0], pcv->
off[f][1], pcv->
off[f][2]);
418 char buff[
MAXANT], *types[2], *p;
421 trace(NULL, 3,
"searchpcv: sat=%2d type=%s\n", sat, type);
424 for (i = 0; i < pcvs->
n; i++) {
426 if (pcv->
sat != sat) {
439 for (p = strtok(buff,
" "); p && n < 2; p = strtok(NULL,
" ")) {
447 for (i = 0; i < pcvs->
n; i++) {
449 for (j = 0; j < n; j++) {
450 if (!strstr(pcv->
type, types[j])) {
459 for (i = 0; i < pcvs->
n; i++) {
461 if (strstr(pcv->
type, types[0]) != pcv->
type) {
465 trace(NULL, 2,
"pcv without radome is used type=%s\n", type);
481extern void antmodel(
const pcv_t* pcv,
const double* del,
const double* azel,
int opt,
double* dant) {
482 double e[3], off[3], cosel = cos(azel[1]);
485 trace(NULL, 4,
"antmodel: azel=%6.1f %4.1f opt=%d\n", azel[0] *
R2D, azel[1] *
R2D, opt);
487 e[0] = sin(azel[0]) * cosel;
488 e[1] = cos(azel[0]) * cosel;
492 for (j = 0; j < 3; j++) {
493 off[j] = pcv->
off[i][j] + del[j];
496 dant[i] = -
dot(off, e, 3) + (opt ?
interpvar(90.0 - azel[1] *
R2D, pcv->
var[i]) : 0.0);
498 trace(NULL, 5,
"antmodel: dant=%6.3f %6.3f\n", dant[0], dant[1]);
510 trace(NULL, 4,
"antmodel_s: nadir=%6.1f\n", nadir *
R2D);
515 trace(NULL, 5,
"antmodel_s: dant=%6.3f %6.3f\n", dant[0], dant[1]);
int satsys(int sat, int *prn)
int readpcv(const char *file, pcvs_t *pcvs)
Read antenna parameters from file (ANTEX or NGS format).
static int readngspcv(const char *file, pcvs_t *pcvs)
static void addpcv(const pcv_t *pcv, pcvs_t *pcvs)
void antmodel(const pcv_t *pcv, const double *del, const double *azel, int opt, double *dant)
Compute receiver antenna offset by antenna phase center parameters.
int freq_num2ant_idx(int sys, int freq_num)
int satid2no(const char *id)
static int decodef(char *p, int n, double *v)
static double interpvar(double ang, const double *var)
pcv_t * searchpcv(int sat, const char *type, gtime_t time, const pcvs_t *pcvs)
Search antenna parameter by satellite number or antenna type.
static int readantex(const char *file, pcvs_t *pcvs)
void antmodel_s(const pcv_t *pcv, double nadir, double *dant)
Compute satellite antenna phase center parameters.
MRTKLIB Antenna Module — Antenna phase center model and parameter I/O.
void matcpy(double *A, const double *B, int n, int m)
Copy matrix.
double norm(const double *a, int n)
Euclidean norm of vector.
double dot(const double *a, const double *b, int n)
Inner product of vectors.
MRTKLIB Matrix Module — Matrix/vector operations and estimation.
double timediff(gtime_t t1, gtime_t t2)
Compute time difference (t1 - t2).
int str2time(const char *s, int i, int n, gtime_t *t)
Convert substring in string to gtime_t struct.
void trace(mrtk_ctx_t *ctx, int level, const char *format,...)
Output trace message.
MRTKLIB Trace Module — debug trace and logging functions.
GNSS time representation.