satel.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. #include "astro.h"
  2. char* satlst[] =
  3. {
  4. 0,
  5. };
  6. struct
  7. {
  8. double time;
  9. double tilt;
  10. double pnni;
  11. double psi;
  12. double ppi;
  13. double d1pp;
  14. double peri;
  15. double d1per;
  16. double e0;
  17. double deo;
  18. double rdp;
  19. double st;
  20. double ct;
  21. double rot;
  22. double semi;
  23. } satl;
  24. void
  25. satels(void)
  26. {
  27. double ifa[10], t, t1, t2, tinc;
  28. char **satp;
  29. int flag, f, i, n;
  30. satp = satlst;
  31. loop:
  32. if(*satp == 0)
  33. return;
  34. f = open(*satp, 0);
  35. if(f < 0) {
  36. fprint(2, "cannot open %s\n", *satp);
  37. satp += 2;
  38. goto loop;
  39. }
  40. satp++;
  41. rline(f);
  42. tinc = atof(skip(6));
  43. rline(f);
  44. rline(f);
  45. for(i=0; i<9; i++)
  46. ifa[i] = atof(skip(i));
  47. n = ifa[0];
  48. i = ifa[1];
  49. t = dmo[i-1] + ifa[2] - 1.;
  50. if(n%4 == 0 && i > 2)
  51. t += 1.;
  52. for(i=1970; i<n; i++) {
  53. t += 365.;
  54. if(i%4 == 0)
  55. t += 1.;
  56. }
  57. t = (t * 24. + ifa[3]) * 60. + ifa[4];
  58. satl.time = t * 60.;
  59. satl.tilt = ifa[5] * radian;
  60. satl.pnni = ifa[6] * radian;
  61. satl.psi = ifa[7];
  62. satl.ppi = ifa[8] * radian;
  63. rline(f);
  64. for(i=0; i<5; i++)
  65. ifa[i] = atof(skip(i));
  66. satl.d1pp = ifa[0] * radian;
  67. satl.peri = ifa[1];
  68. satl.d1per = ifa[2];
  69. satl.e0 = ifa[3];
  70. satl.deo = 0;
  71. satl.rdp = ifa[4];
  72. satl.st = sin(satl.tilt);
  73. satl.ct = cos(satl.tilt);
  74. satl.rot = pipi / (1440. + satl.psi);
  75. satl.semi = satl.rdp * (1. + satl.e0);
  76. n = PER*288.; /* 5 min steps */
  77. t = day;
  78. for(i=0; i<n; i++) {
  79. if(sunel((t-day)/deld) > 0.)
  80. goto out;
  81. satel(t);
  82. if(el > 0) {
  83. t1 = t;
  84. flag = 0;
  85. do {
  86. if(el > 30.)
  87. flag++;
  88. t -= tinc/(24.*3600.);
  89. satel(t);
  90. } while(el > 0.);
  91. t2 = (t - day)/deld;
  92. t = t1;
  93. do {
  94. t += tinc/(24.*3600.);
  95. satel(t);
  96. if(el > 30.)
  97. flag++;
  98. } while(el > 0.);
  99. if(flag)
  100. if((*satp)[0] == '-')
  101. event("%s pass at ", (*satp)+1, "",
  102. t2, SIGNIF+PTIME+DARK); else
  103. event("%s pass at ", *satp, "",
  104. t2, PTIME+DARK);
  105. }
  106. out:
  107. t += 5./(24.*60.);
  108. }
  109. close(f);
  110. satp++;
  111. goto loop;
  112. }
  113. void
  114. satel(double time)
  115. {
  116. int i;
  117. double amean, an, coc, csl, d, de, enom, eo;
  118. double pp, q, rdp, slong, ssl, t, tp;
  119. i = 500;
  120. el = -1;
  121. time = (time-25567.5) * 86400;
  122. t = (time - satl.time)/60;
  123. if(t < 0)
  124. return; /* too early for satelites */
  125. an = floor(t/satl.peri);
  126. while(an*satl.peri + an*an*satl.d1per/2. <= t) {
  127. an += 1;
  128. if(--i == 0)
  129. return;
  130. }
  131. while((tp = an*satl.peri + an*an*satl.d1per/2.) > t) {
  132. an -= 1;
  133. if(--i == 0)
  134. return;
  135. }
  136. amean = (t-tp)/(satl.peri+(an+.5)*satl.d1per);
  137. pp = satl.ppi+(an+amean)*satl.d1pp;
  138. amean *= pipi;
  139. eo = satl.e0+satl.deo*an;
  140. rdp = satl.semi/(1+eo);
  141. enom = amean+eo*sin(amean);
  142. do {
  143. de = (amean-enom+eo*sin(enom))/(1.0-eo*cos(enom));
  144. enom += de;
  145. if(--i == 0)
  146. return;
  147. } while(fabs(de) >= 1.0e-6);
  148. q = 3963.35*erad/(rdp*(1-eo*cos(enom))/(1-eo));
  149. d = pp + 2*atan2(sqrt((1+eo)/(1-eo))*sin(enom/2),cos(enom/2));
  150. slong = satl.pnni + t*satl.rot -
  151. atan2(satl.ct*sin(d), cos(d));
  152. ssl = satl.st*sin(d);
  153. csl = pyth(ssl);
  154. if(vis(time, atan2(ssl,csl), slong, q)) {
  155. coc = ssl*sin(glat) + csl*cos(glat)*cos(wlong-slong);
  156. el = atan2(coc-q, pyth(coc));
  157. el /= radian;
  158. }
  159. }
  160. int
  161. vis(double t, double slat, double slong, double q)
  162. {
  163. double t0, t1, t2, d;
  164. d = t/86400 - .005375 + 3653;
  165. t0 = 6.238030674 + .01720196977*d;
  166. t2 = t0 + .0167253303*sin(t0);
  167. do {
  168. t1 = (t0 - t2 + .0167259152*sin(t2)) /
  169. (1 - .0167259152*cos(t2));
  170. t2 = t2 + t1;
  171. } while(fabs(t1) >= 1.e-4);
  172. t0 = 2*atan2(1.01686816*sin(t2/2), cos(t2/2));
  173. t0 = 4.926234925 + 8.214985538e-7*d + t0;
  174. t1 = 0.91744599 * sin(t0);
  175. t0 = atan2(t1, cos(t0));
  176. if(t0 < -pi/2)
  177. t0 = t0 + pipi;
  178. d = 4.88097876 + 6.30038809*d - t0;
  179. t0 = 0.43366079 * t1;
  180. t1 = pyth(t0);
  181. t2 = t1*cos(slat)*cos(d-slong) - t0*sin(slat);
  182. if(t2 > 0.46949322e-2) {
  183. if(0.46949322e-2*t2 + 0.999988979*pyth(t2) < q)
  184. return 0;
  185. }
  186. t2 = t1*cos(glat)*cos(d-wlong) - t0*sin(glat);
  187. if(t2 < .1)
  188. return 0;
  189. return 1;
  190. }