1 1.6 christos /* $NetBSD: propdelay.c,v 1.6 2020/05/25 20:47:19 christos Exp $ */ 2 1.1 kardel 3 1.1 kardel /* propdelay.c,v 3.1 1993/07/06 01:05:24 jbj Exp 4 1.1 kardel * propdelay - compute propagation delays 5 1.1 kardel * 6 1.1 kardel * cc -o propdelay propdelay.c -lm 7 1.1 kardel * 8 1.1 kardel * "Time and Frequency Users' Manual", NBS Technical Note 695 (1977). 9 1.1 kardel */ 10 1.1 kardel 11 1.1 kardel /* 12 1.1 kardel * This can be used to get a rough idea of the HF propagation delay 13 1.1 kardel * between two points (usually between you and the radio station). 14 1.1 kardel * The usage is 15 1.1 kardel * 16 1.1 kardel * propdelay latitudeA longitudeA latitudeB longitudeB 17 1.1 kardel * 18 1.1 kardel * where points A and B are the locations in question. You obviously 19 1.1 kardel * need to know the latitude and longitude of each of the places. 20 1.1 kardel * The program expects the latitude to be preceded by an 'n' or 's' 21 1.1 kardel * and the longitude to be preceded by an 'e' or 'w'. It understands 22 1.1 kardel * either decimal degrees or degrees:minutes:seconds. Thus to compute 23 1.1 kardel * the delay between the WWVH (21:59:26N, 159:46:00W) and WWV (40:40:49N, 24 1.1 kardel * 105:02:27W) you could use: 25 1.1 kardel * 26 1.1 kardel * propdelay n21:59:26 w159:46 n40:40:49 w105:02:27 27 1.1 kardel * 28 1.1 kardel * By default it prints out a summer (F2 average virtual height 350 km) and 29 1.1 kardel * winter (F2 average virtual height 250 km) number. The results will be 30 1.1 kardel * quite approximate but are about as good as you can do with HF time anyway. 31 1.1 kardel * You might pick a number between the values to use, or use the summer 32 1.1 kardel * value in the summer and switch to the winter value when the static 33 1.1 kardel * above 10 MHz starts to drop off in the fall. You can also use the 34 1.1 kardel * -h switch if you want to specify your own virtual height. 35 1.1 kardel * 36 1.1 kardel * You can also do a 37 1.1 kardel * 38 1.1 kardel * propdelay -W n45:17:47 w75:45:22 39 1.1 kardel * 40 1.1 kardel * to find the propagation delays to WWV and WWVH (from CHU in this 41 1.1 kardel * case), a 42 1.1 kardel * 43 1.1 kardel * propdelay -C n40:40:49 w105:02:27 44 1.1 kardel * 45 1.1 kardel * to find the delays to CHU, and a 46 1.1 kardel * 47 1.1 kardel * propdelay -G n52:03:17 w98:34:18 48 1.1 kardel * 49 1.1 kardel * to find delays to GOES via each of the three satellites. 50 1.1 kardel */ 51 1.1 kardel 52 1.2 christos #ifdef HAVE_CONFIG_H 53 1.2 christos # include <config.h> 54 1.2 christos #endif 55 1.1 kardel #include <stdio.h> 56 1.1 kardel #include <string.h> 57 1.1 kardel 58 1.1 kardel #include "ntp_stdlib.h" 59 1.1 kardel 60 1.1 kardel extern double sin (double); 61 1.1 kardel extern double cos (double); 62 1.1 kardel extern double acos (double); 63 1.1 kardel extern double tan (double); 64 1.1 kardel extern double atan (double); 65 1.1 kardel extern double sqrt (double); 66 1.1 kardel 67 1.1 kardel #define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0) 68 1.1 kardel 69 1.1 kardel /* 70 1.1 kardel * Program constants 71 1.1 kardel */ 72 1.1 kardel #define EARTHRADIUS (6370.0) /* raduis of earth (km) */ 73 1.1 kardel #define LIGHTSPEED (299800.0) /* speed of light, km/s */ 74 1.1 kardel #define PI (3.1415926536) 75 1.1 kardel #define RADPERDEG (PI/180.0) /* radians per degree */ 76 1.1 kardel #define MILE (1.609344) /* km in a mile */ 77 1.1 kardel 78 1.1 kardel #define SUMMERHEIGHT (350.0) /* summer height in km */ 79 1.1 kardel #define WINTERHEIGHT (250.0) /* winter height in km */ 80 1.1 kardel 81 1.1 kardel #define SATHEIGHT (6.6110 * 6378.0) /* geosync satellite height in km 82 1.1 kardel from centre of earth */ 83 1.1 kardel 84 1.1 kardel #define WWVLAT "n40:40:49" 85 1.1 kardel #define WWVLONG "w105:02:27" 86 1.1 kardel 87 1.1 kardel #define WWVHLAT "n21:59:26" 88 1.1 kardel #define WWVHLONG "w159:46:00" 89 1.1 kardel 90 1.1 kardel #define CHULAT "n45:17:47" 91 1.1 kardel #define CHULONG "w75:45:22" 92 1.1 kardel 93 1.1 kardel #define GOES_UP_LAT "n37:52:00" 94 1.1 kardel #define GOES_UP_LONG "w75:27:00" 95 1.1 kardel #define GOES_EAST_LONG "w75:00:00" 96 1.1 kardel #define GOES_STBY_LONG "w105:00:00" 97 1.1 kardel #define GOES_WEST_LONG "w135:00:00" 98 1.1 kardel #define GOES_SAT_LAT "n00:00:00" 99 1.1 kardel 100 1.1 kardel char *wwvlat = WWVLAT; 101 1.1 kardel char *wwvlong = WWVLONG; 102 1.1 kardel 103 1.1 kardel char *wwvhlat = WWVHLAT; 104 1.1 kardel char *wwvhlong = WWVHLONG; 105 1.1 kardel 106 1.1 kardel char *chulat = CHULAT; 107 1.1 kardel char *chulong = CHULONG; 108 1.1 kardel 109 1.1 kardel char *goes_up_lat = GOES_UP_LAT; 110 1.1 kardel char *goes_up_long = GOES_UP_LONG; 111 1.1 kardel char *goes_east_long = GOES_EAST_LONG; 112 1.1 kardel char *goes_stby_long = GOES_STBY_LONG; 113 1.1 kardel char *goes_west_long = GOES_WEST_LONG; 114 1.1 kardel char *goes_sat_lat = GOES_SAT_LAT; 115 1.1 kardel 116 1.1 kardel int hflag = 0; 117 1.1 kardel int Wflag = 0; 118 1.1 kardel int Cflag = 0; 119 1.1 kardel int Gflag = 0; 120 1.1 kardel int height; 121 1.1 kardel 122 1.4 christos char const *progname; 123 1.1 kardel 124 1.1 kardel static void doit (double, double, double, double, double, char *); 125 1.1 kardel static double latlong (char *, int); 126 1.1 kardel static double greatcircle (double, double, double, double); 127 1.1 kardel static double waveangle (double, double, int); 128 1.1 kardel static double propdelay (double, double, int); 129 1.1 kardel static int finddelay (double, double, double, double, double, double *); 130 1.1 kardel static void satdoit (double, double, double, double, double, double, char *); 131 1.1 kardel static void satfinddelay (double, double, double, double, double *); 132 1.1 kardel static double satpropdelay (double); 133 1.1 kardel 134 1.1 kardel /* 135 1.1 kardel * main - parse arguments and handle options 136 1.1 kardel */ 137 1.1 kardel int 138 1.1 kardel main( 139 1.1 kardel int argc, 140 1.1 kardel char *argv[] 141 1.1 kardel ) 142 1.1 kardel { 143 1.1 kardel int c; 144 1.1 kardel int errflg = 0; 145 1.1 kardel double lat1, long1; 146 1.1 kardel double lat2, long2; 147 1.1 kardel double lat3, long3; 148 1.1 kardel 149 1.2 christos init_lib(); 150 1.2 christos 151 1.1 kardel progname = argv[0]; 152 1.1 kardel while ((c = ntp_getopt(argc, argv, "dh:CWG")) != EOF) 153 1.1 kardel switch (c) { 154 1.1 kardel case 'd': 155 1.1 kardel ++debug; 156 1.1 kardel break; 157 1.1 kardel case 'h': 158 1.1 kardel hflag++; 159 1.1 kardel height = atof(ntp_optarg); 160 1.1 kardel if (height <= 0.0) { 161 1.1 kardel (void) fprintf(stderr, "height %s unlikely\n", 162 1.1 kardel ntp_optarg); 163 1.1 kardel errflg++; 164 1.1 kardel } 165 1.1 kardel break; 166 1.1 kardel case 'C': 167 1.1 kardel Cflag++; 168 1.1 kardel break; 169 1.1 kardel case 'W': 170 1.1 kardel Wflag++; 171 1.1 kardel break; 172 1.1 kardel case 'G': 173 1.1 kardel Gflag++; 174 1.1 kardel break; 175 1.1 kardel default: 176 1.1 kardel errflg++; 177 1.1 kardel break; 178 1.1 kardel } 179 1.1 kardel if (errflg || (!(Cflag || Wflag || Gflag) && ntp_optind+4 != argc) || 180 1.1 kardel ((Cflag || Wflag || Gflag) && ntp_optind+2 != argc)) { 181 1.1 kardel (void) fprintf(stderr, 182 1.1 kardel "usage: %s [-d] [-h height] lat1 long1 lat2 long2\n", 183 1.1 kardel progname); 184 1.1 kardel (void) fprintf(stderr," - or -\n"); 185 1.1 kardel (void) fprintf(stderr, 186 1.1 kardel "usage: %s -CWG [-d] lat long\n", 187 1.1 kardel progname); 188 1.1 kardel exit(2); 189 1.1 kardel } 190 1.1 kardel 191 1.1 kardel 192 1.1 kardel if (!(Cflag || Wflag || Gflag)) { 193 1.1 kardel lat1 = latlong(argv[ntp_optind], 1); 194 1.1 kardel long1 = latlong(argv[ntp_optind + 1], 0); 195 1.1 kardel lat2 = latlong(argv[ntp_optind + 2], 1); 196 1.1 kardel long2 = latlong(argv[ntp_optind + 3], 0); 197 1.1 kardel if (hflag) { 198 1.1 kardel doit(lat1, long1, lat2, long2, height, ""); 199 1.1 kardel } else { 200 1.1 kardel doit(lat1, long1, lat2, long2, (double)SUMMERHEIGHT, 201 1.1 kardel "summer propagation, "); 202 1.1 kardel doit(lat1, long1, lat2, long2, (double)WINTERHEIGHT, 203 1.1 kardel "winter propagation, "); 204 1.1 kardel } 205 1.1 kardel } else if (Wflag) { 206 1.1 kardel /* 207 1.1 kardel * Compute delay from WWV 208 1.1 kardel */ 209 1.1 kardel lat1 = latlong(argv[ntp_optind], 1); 210 1.1 kardel long1 = latlong(argv[ntp_optind + 1], 0); 211 1.1 kardel lat2 = latlong(wwvlat, 1); 212 1.1 kardel long2 = latlong(wwvlong, 0); 213 1.1 kardel if (hflag) { 214 1.1 kardel doit(lat1, long1, lat2, long2, height, "WWV "); 215 1.1 kardel } else { 216 1.1 kardel doit(lat1, long1, lat2, long2, (double)SUMMERHEIGHT, 217 1.1 kardel "WWV summer propagation, "); 218 1.1 kardel doit(lat1, long1, lat2, long2, (double)WINTERHEIGHT, 219 1.1 kardel "WWV winter propagation, "); 220 1.1 kardel } 221 1.1 kardel 222 1.1 kardel /* 223 1.1 kardel * Compute delay from WWVH 224 1.1 kardel */ 225 1.1 kardel lat2 = latlong(wwvhlat, 1); 226 1.1 kardel long2 = latlong(wwvhlong, 0); 227 1.1 kardel if (hflag) { 228 1.1 kardel doit(lat1, long1, lat2, long2, height, "WWVH "); 229 1.1 kardel } else { 230 1.1 kardel doit(lat1, long1, lat2, long2, (double)SUMMERHEIGHT, 231 1.1 kardel "WWVH summer propagation, "); 232 1.1 kardel doit(lat1, long1, lat2, long2, (double)WINTERHEIGHT, 233 1.1 kardel "WWVH winter propagation, "); 234 1.1 kardel } 235 1.1 kardel } else if (Cflag) { 236 1.1 kardel lat1 = latlong(argv[ntp_optind], 1); 237 1.1 kardel long1 = latlong(argv[ntp_optind + 1], 0); 238 1.1 kardel lat2 = latlong(chulat, 1); 239 1.1 kardel long2 = latlong(chulong, 0); 240 1.1 kardel if (hflag) { 241 1.1 kardel doit(lat1, long1, lat2, long2, height, "CHU "); 242 1.1 kardel } else { 243 1.1 kardel doit(lat1, long1, lat2, long2, (double)SUMMERHEIGHT, 244 1.1 kardel "CHU summer propagation, "); 245 1.1 kardel doit(lat1, long1, lat2, long2, (double)WINTERHEIGHT, 246 1.1 kardel "CHU winter propagation, "); 247 1.1 kardel } 248 1.1 kardel } else if (Gflag) { 249 1.1 kardel lat1 = latlong(goes_up_lat, 1); 250 1.1 kardel long1 = latlong(goes_up_long, 0); 251 1.1 kardel lat3 = latlong(argv[ntp_optind], 1); 252 1.1 kardel long3 = latlong(argv[ntp_optind + 1], 0); 253 1.1 kardel 254 1.1 kardel lat2 = latlong(goes_sat_lat, 1); 255 1.1 kardel 256 1.1 kardel long2 = latlong(goes_west_long, 0); 257 1.1 kardel satdoit(lat1, long1, lat2, long2, lat3, long3, 258 1.1 kardel "GOES Delay via WEST"); 259 1.1 kardel 260 1.1 kardel long2 = latlong(goes_stby_long, 0); 261 1.1 kardel satdoit(lat1, long1, lat2, long2, lat3, long3, 262 1.1 kardel "GOES Delay via STBY"); 263 1.1 kardel 264 1.1 kardel long2 = latlong(goes_east_long, 0); 265 1.1 kardel satdoit(lat1, long1, lat2, long2, lat3, long3, 266 1.1 kardel "GOES Delay via EAST"); 267 1.1 kardel 268 1.1 kardel } 269 1.1 kardel exit(0); 270 1.1 kardel } 271 1.1 kardel 272 1.1 kardel 273 1.1 kardel /* 274 1.1 kardel * doit - compute a delay and print it 275 1.1 kardel */ 276 1.1 kardel static void 277 1.1 kardel doit( 278 1.1 kardel double lat1, 279 1.1 kardel double long1, 280 1.1 kardel double lat2, 281 1.1 kardel double long2, 282 1.1 kardel double h, 283 1.1 kardel char *str 284 1.1 kardel ) 285 1.1 kardel { 286 1.1 kardel int hops; 287 1.1 kardel double delay; 288 1.1 kardel 289 1.1 kardel hops = finddelay(lat1, long1, lat2, long2, h, &delay); 290 1.1 kardel printf("%sheight %g km, hops %d, delay %g seconds\n", 291 1.1 kardel str, h, hops, delay); 292 1.1 kardel } 293 1.1 kardel 294 1.1 kardel 295 1.1 kardel /* 296 1.1 kardel * latlong - decode a latitude/longitude value 297 1.1 kardel */ 298 1.1 kardel static double 299 1.1 kardel latlong( 300 1.1 kardel char *str, 301 1.1 kardel int islat 302 1.1 kardel ) 303 1.1 kardel { 304 1.1 kardel register char *cp; 305 1.1 kardel register char *bp; 306 1.1 kardel double arg; 307 1.1 kardel double divby; 308 1.1 kardel int isneg; 309 1.1 kardel char buf[32]; 310 1.1 kardel char *colon; 311 1.1 kardel 312 1.1 kardel if (islat) { 313 1.1 kardel /* 314 1.1 kardel * Must be north or south 315 1.1 kardel */ 316 1.1 kardel if (*str == 'N' || *str == 'n') 317 1.1 kardel isneg = 0; 318 1.1 kardel else if (*str == 'S' || *str == 's') 319 1.1 kardel isneg = 1; 320 1.1 kardel else 321 1.1 kardel isneg = -1; 322 1.1 kardel } else { 323 1.1 kardel /* 324 1.1 kardel * East is positive, west is negative 325 1.1 kardel */ 326 1.1 kardel if (*str == 'E' || *str == 'e') 327 1.1 kardel isneg = 0; 328 1.1 kardel else if (*str == 'W' || *str == 'w') 329 1.1 kardel isneg = 1; 330 1.1 kardel else 331 1.1 kardel isneg = -1; 332 1.1 kardel } 333 1.1 kardel 334 1.1 kardel if (isneg >= 0) 335 1.1 kardel str++; 336 1.1 kardel 337 1.1 kardel colon = strchr(str, ':'); 338 1.1 kardel if (colon != NULL) { 339 1.1 kardel /* 340 1.1 kardel * in hhh:mm:ss form 341 1.1 kardel */ 342 1.1 kardel cp = str; 343 1.1 kardel bp = buf; 344 1.1 kardel while (cp < colon) 345 1.1 kardel *bp++ = *cp++; 346 1.1 kardel *bp = '\0'; 347 1.1 kardel cp++; 348 1.1 kardel arg = atof(buf); 349 1.1 kardel divby = 60.0; 350 1.1 kardel colon = strchr(cp, ':'); 351 1.1 kardel if (colon != NULL) { 352 1.1 kardel bp = buf; 353 1.1 kardel while (cp < colon) 354 1.1 kardel *bp++ = *cp++; 355 1.1 kardel *bp = '\0'; 356 1.1 kardel cp++; 357 1.1 kardel arg += atof(buf) / divby; 358 1.1 kardel divby = 3600.0; 359 1.1 kardel } 360 1.1 kardel if (*cp != '\0') 361 1.1 kardel arg += atof(cp) / divby; 362 1.1 kardel } else { 363 1.1 kardel arg = atof(str); 364 1.1 kardel } 365 1.1 kardel 366 1.1 kardel if (isneg == 1) 367 1.1 kardel arg = -arg; 368 1.1 kardel 369 1.1 kardel if (debug > 2) 370 1.1 kardel (void) printf("latitude/longitude %s = %g\n", str, arg); 371 1.1 kardel 372 1.1 kardel return arg; 373 1.1 kardel } 374 1.1 kardel 375 1.1 kardel 376 1.1 kardel /* 377 1.1 kardel * greatcircle - compute the great circle distance in kilometers 378 1.1 kardel */ 379 1.1 kardel static double 380 1.1 kardel greatcircle( 381 1.1 kardel double lat1, 382 1.1 kardel double long1, 383 1.1 kardel double lat2, 384 1.1 kardel double long2 385 1.1 kardel ) 386 1.1 kardel { 387 1.1 kardel double dg; 388 1.1 kardel double l1r, l2r; 389 1.1 kardel 390 1.1 kardel l1r = lat1 * RADPERDEG; 391 1.1 kardel l2r = lat2 * RADPERDEG; 392 1.1 kardel dg = EARTHRADIUS * acos( 393 1.1 kardel (cos(l1r) * cos(l2r) * cos((long2-long1)*RADPERDEG)) 394 1.1 kardel + (sin(l1r) * sin(l2r))); 395 1.1 kardel if (debug >= 2) 396 1.1 kardel printf( 397 1.1 kardel "greatcircle lat1 %g long1 %g lat2 %g long2 %g dist %g\n", 398 1.1 kardel lat1, long1, lat2, long2, dg); 399 1.1 kardel return dg; 400 1.1 kardel } 401 1.1 kardel 402 1.1 kardel 403 1.1 kardel /* 404 1.1 kardel * waveangle - compute the wave angle for the given distance, virtual 405 1.1 kardel * height and number of hops. 406 1.1 kardel */ 407 1.1 kardel static double 408 1.1 kardel waveangle( 409 1.1 kardel double dg, 410 1.1 kardel double h, 411 1.1 kardel int n 412 1.1 kardel ) 413 1.1 kardel { 414 1.1 kardel double theta; 415 1.1 kardel double delta; 416 1.1 kardel 417 1.1 kardel theta = dg / (EARTHRADIUS * (double)(2 * n)); 418 1.1 kardel delta = atan((h / (EARTHRADIUS * sin(theta))) + tan(theta/2)) - theta; 419 1.1 kardel if (debug >= 2) 420 1.1 kardel printf("waveangle dist %g height %g hops %d angle %g\n", 421 1.1 kardel dg, h, n, delta / RADPERDEG); 422 1.1 kardel return delta; 423 1.1 kardel } 424 1.1 kardel 425 1.1 kardel 426 1.1 kardel /* 427 1.1 kardel * propdelay - compute the propagation delay 428 1.1 kardel */ 429 1.1 kardel static double 430 1.1 kardel propdelay( 431 1.1 kardel double dg, 432 1.1 kardel double h, 433 1.1 kardel int n 434 1.1 kardel ) 435 1.1 kardel { 436 1.1 kardel double phi; 437 1.1 kardel double theta; 438 1.1 kardel double td; 439 1.1 kardel 440 1.1 kardel theta = dg / (EARTHRADIUS * (double)(2 * n)); 441 1.1 kardel phi = (PI/2.0) - atan((h / (EARTHRADIUS * sin(theta))) + tan(theta/2)); 442 1.1 kardel td = dg / (LIGHTSPEED * sin(phi)); 443 1.1 kardel if (debug >= 2) 444 1.1 kardel printf("propdelay dist %g height %g hops %d time %g\n", 445 1.1 kardel dg, h, n, td); 446 1.1 kardel return td; 447 1.1 kardel } 448 1.1 kardel 449 1.1 kardel 450 1.1 kardel /* 451 1.1 kardel * finddelay - find the propagation delay 452 1.1 kardel */ 453 1.1 kardel static int 454 1.1 kardel finddelay( 455 1.1 kardel double lat1, 456 1.1 kardel double long1, 457 1.1 kardel double lat2, 458 1.1 kardel double long2, 459 1.1 kardel double h, 460 1.1 kardel double *delay 461 1.1 kardel ) 462 1.1 kardel { 463 1.1 kardel double dg; /* great circle distance */ 464 1.1 kardel double delta; /* wave angle */ 465 1.1 kardel int n; /* number of hops */ 466 1.1 kardel 467 1.1 kardel dg = greatcircle(lat1, long1, lat2, long2); 468 1.1 kardel if (debug) 469 1.1 kardel printf("great circle distance %g km %g miles\n", dg, dg/MILE); 470 1.1 kardel 471 1.1 kardel n = 1; 472 1.1 kardel while ((delta = waveangle(dg, h, n)) < 0.0) { 473 1.1 kardel if (debug) 474 1.1 kardel printf("tried %d hop%s, no good\n", n, n>1?"s":""); 475 1.1 kardel n++; 476 1.1 kardel } 477 1.1 kardel if (debug) 478 1.1 kardel printf("%d hop%s okay, wave angle is %g\n", n, n>1?"s":"", 479 1.1 kardel delta / RADPERDEG); 480 1.1 kardel 481 1.1 kardel *delay = propdelay(dg, h, n); 482 1.1 kardel return n; 483 1.1 kardel } 484 1.1 kardel 485 1.1 kardel /* 486 1.1 kardel * satdoit - compute a delay and print it 487 1.1 kardel */ 488 1.1 kardel static void 489 1.1 kardel satdoit( 490 1.1 kardel double lat1, 491 1.1 kardel double long1, 492 1.1 kardel double lat2, 493 1.1 kardel double long2, 494 1.1 kardel double lat3, 495 1.1 kardel double long3, 496 1.1 kardel char *str 497 1.1 kardel ) 498 1.1 kardel { 499 1.1 kardel double up_delay,down_delay; 500 1.1 kardel 501 1.1 kardel satfinddelay(lat1, long1, lat2, long2, &up_delay); 502 1.1 kardel satfinddelay(lat3, long3, lat2, long2, &down_delay); 503 1.1 kardel 504 1.1 kardel printf("%s, delay %g seconds\n", str, up_delay + down_delay); 505 1.1 kardel } 506 1.1 kardel 507 1.1 kardel /* 508 1.1 kardel * satfinddelay - calculate the one-way delay time between a ground station 509 1.1 kardel * and a satellite 510 1.1 kardel */ 511 1.1 kardel static void 512 1.1 kardel satfinddelay( 513 1.1 kardel double lat1, 514 1.1 kardel double long1, 515 1.1 kardel double lat2, 516 1.1 kardel double long2, 517 1.1 kardel double *delay 518 1.1 kardel ) 519 1.1 kardel { 520 1.1 kardel double dg; /* great circle distance */ 521 1.1 kardel 522 1.1 kardel dg = greatcircle(lat1, long1, lat2, long2); 523 1.1 kardel 524 1.1 kardel *delay = satpropdelay(dg); 525 1.1 kardel } 526 1.1 kardel 527 1.1 kardel /* 528 1.1 kardel * satpropdelay - calculate the one-way delay time between a ground station 529 1.1 kardel * and a satellite 530 1.1 kardel */ 531 1.1 kardel static double 532 1.1 kardel satpropdelay( 533 1.1 kardel double dg 534 1.1 kardel ) 535 1.1 kardel { 536 1.1 kardel double k1, k2, dist; 537 1.1 kardel double theta; 538 1.1 kardel double td; 539 1.1 kardel 540 1.1 kardel theta = dg / (EARTHRADIUS); 541 1.1 kardel k1 = EARTHRADIUS * sin(theta); 542 1.1 kardel k2 = SATHEIGHT - (EARTHRADIUS * cos(theta)); 543 1.1 kardel if (debug >= 2) 544 1.1 kardel printf("Theta %g k1 %g k2 %g\n", theta, k1, k2); 545 1.1 kardel dist = sqrt(k1*k1 + k2*k2); 546 1.1 kardel td = dist / LIGHTSPEED; 547 1.1 kardel if (debug >= 2) 548 1.1 kardel printf("propdelay dist %g height %g time %g\n", dg, dist, td); 549 1.1 kardel return td; 550 1.1 kardel } 551