void Calculate_Obs(double _time, vector_t *pos, vector_t *vel, geodetic_t *geodetic, obs_set_t *obs_set) { double sin_lat,cos_lat, sin_theta,cos_theta, el,azim, top_s,top_e,top_z; vector_t obs_pos,obs_vel,range,rgvel; Calculate_User_PosVel(_time, geodetic, &obs_pos, &obs_vel); range.x = pos->x - obs_pos.x; range.y = pos->y - obs_pos.y; range.z = pos->z - obs_pos.z; rgvel.x = vel->x - obs_vel.x; rgvel.y = vel->y - obs_vel.y; rgvel.z = vel->z - obs_vel.z; Magnitude(&range); sin_lat = sin(geodetic->lat); cos_lat = cos(geodetic->lat); sin_theta = sin(geodetic->theta); cos_theta = cos(geodetic->theta); top_s = sin_lat * cos_theta * range.x + sin_lat * sin_theta * range.y - cos_lat * range.z; top_e = -sin_theta * range.x + cos_theta * range.y; top_z = cos_lat * cos_theta * range.x + cos_lat * sin_theta * range.y + sin_lat * range.z; azim = atan(-top_e/top_s); /*Azimuth*/ if( top_s > 0 ) azim = azim + pi; if( azim < 0 ) azim = azim + twopi; el = ArcSin(top_z/range.w); obs_set->az = azim; /* Azimuth (radians) */ obs_set->el = el; /* Elevation (radians)*/ obs_set->range = range.w; /* Range (kilometers) */ /* Range Rate (kilometers/second)*/ obs_set->range_rate = Dot(&range, &rgvel)/range.w; /* Corrections for atmospheric refraction */ /* Reference: Astronomical Algorithms by Jean Meeus, pp. 101-104 */ /* Correction is meaningless when apparent elevation is below horizon */ // obs_set->el = obs_set->el + Radians((1.02/tan(Radians(Degrees(el)+ // 10.3/(Degrees(el)+5.11))))/60); if( obs_set->el >= 0 ) SetFlag(VISIBLE_FLAG); else { obs_set->el = el; /*Reset to true elevation*/ ClearFlag(VISIBLE_FLAG); } /*else*/ } /*Procedure Calculate_Obs*/
void Calculate_Obs(double time, const double pos[3], const double vel[3], geodetic_t *geodetic, vector_t *obs_set) { /* The procedures Calculate_Obs and Calculate_RADec calculate */ /* the *topocentric* coordinates of the object with ECI position, */ /* {pos}, and velocity, {vel}, from location {geodetic} at {time}. */ /* The {obs_set} returned for Calculate_Obs consists of azimuth, */ /* elevation, range, and range rate (in that order) with units of */ /* radians, radians, kilometers, and kilometers/second, respectively. */ /* The WGS '72 geoid is used and the effect of atmospheric refraction */ /* (under standard temperature and pressure) is incorporated into the */ /* elevation calculation; the effect of atmospheric refraction on */ /* range and range rate has not yet been quantified. */ /* The {obs_set} for Calculate_RADec consists of right ascension and */ /* declination (in that order) in radians. Again, calculations are */ /* based on *topocentric* position using the WGS '72 geoid and */ /* incorporating atmospheric refraction. */ double sin_lat, cos_lat, sin_theta, cos_theta, el, azim, top_s, top_e, top_z; double obs_pos[3]; double obs_vel[3]; double range[3]; double rgvel[3]; Calculate_User_PosVel(time, geodetic, obs_pos, obs_vel); vec3_sub(pos, obs_pos, range); vec3_sub(vel, obs_vel, rgvel); double range_length = vec3_length(range); sin_lat=sin(geodetic->lat); cos_lat=cos(geodetic->lat); sin_theta=sin(geodetic->theta); cos_theta=cos(geodetic->theta); top_s=sin_lat*cos_theta*range[0]+sin_lat*sin_theta*range[1]-cos_lat*range[2]; top_e=-sin_theta*range[0]+cos_theta*range[1]; top_z=cos_lat*cos_theta*range[0]+cos_lat*sin_theta*range[1]+sin_lat*range[2]; azim=atan(-top_e/top_s); /* Azimuth */ if (top_s>0.0) azim=azim+pi; if (azim<0.0) azim = azim + 2*M_PI; el=ArcSin(top_z/range_length); obs_set->x=azim; /* Azimuth (radians) */ obs_set->y=el; /* Elevation (radians) */ obs_set->z=range_length; /* Range (kilometers) */ /* Range Rate (kilometers/second) */ obs_set->w = vec3_dot(range, rgvel)/vec3_length(range); obs_set->y=el; /**** End bypass ****/ if (obs_set->y<0.0) obs_set->y=el; /* Reset to true elevation */ }