Exemplo n.º 1
0
/* convert ra to ha, in range 0..2*PI
 * need dec too if not already apparent.
 */
void
radec2ha (Now *np, double ra, double dec, double *hap)
{
	double ha, lst;

	if (epoch != EOD)
	    as_ap (np, epoch, &ra, &dec);
	now_lst (np, &lst);
	ha = hrrad(lst) - ra;
	if (ha < 0)
	    ha += 2*PI;
	*hap = ha;
}
Exemplo n.º 2
0
/* find Greenwich Hour Angle of the given object at the given time, 0..2*PI.
 */
void
gha (Now *np, Obj *op, double *ghap)
{
	Now n = *np;
	Obj o = *op;
	double tmp;

	n.n_epoch = EOD;
	n.n_lng = 0.0;
	n.n_lat = 0.0;
	obj_cir (&n, &o);
	now_lst (&n, &tmp);
	tmp = hrrad(tmp) - o.s_ra;
	if (tmp < 0)
	    tmp += 2*PI;
	*ghap = tmp;
}
Exemplo n.º 3
0
/* find when the given object transits. start the search when LST matches the
 *   object's RA at noon.
 * if ok, return 0 with np and op set to the transit conditions; if can't
 *   converge return -1; if converges ok but not today return -2.
 * N.B. we assume np is passed set to local noon.
 */
static int
find_transit (double dt, Now *np, Obj *op)
{
#define	MAXLOOPS	10
#define	MAXERR		(0.25/60.)		/* hours */
	double mjdn = mjd;
	double lst;
	int i;

	/* insure initial guess is today -- if not, move by 24 hours */
	if (dt < -12.0)
	    dt += 24.0;
	if (dt > 12.0)
	    dt -= 24.0;

	i = 0;
	do {
	    mjd += dt/24.0;
	    if (obj_cir (np, op) < 0)
		return (-1);
	    now_lst (np, &lst);
	    dt = (radhr(op->s_gaera) - lst);
	    if (dt < -12.0)
		dt += 24.0;
	    if (dt > 12.0)
		dt -= 24.0;
	} while (++i < MAXLOOPS && fabs(dt) > MAXERR);

	/* return codes */
	if (i == MAXLOOPS)
	    return (-1);
	return (fabs(mjd - mjdn) < 0.5 ? 0 : -2);

#undef	MAXLOOPS
#undef	MAXERR
}
Exemplo n.º 4
0
/* fill equatoreal and horizontal op-> fields; stern
 *
 *    input:          lam/bet/rho geocentric mean ecliptic and equinox of day
 * 
 * algorithm at EOD:
 *   ecl_eq	--> ra/dec	geocentric mean equatoreal EOD (via mean obliq)
 *   deflect	--> ra/dec	  relativistic deflection
 *   nut_eq	--> ra/dec	geocentric true equatoreal EOD
 *   ab_eq	--> ra/dec	geocentric apparent equatoreal EOD
 *					if (PREF_GEO)  --> output
 *   ta_par	--> ra/dec	topocentric apparent equatoreal EOD
 *					if (!PREF_GEO)  --> output
 *   hadec_aa	--> alt/az	topocentric horizontal
 *   refract	--> alt/az	observed --> output
 *
 * algorithm at fixed equinox:
 *   ecl_eq	--> ra/dec	geocentric mean equatoreal EOD (via mean obliq)
 *   deflect	--> ra/dec	  relativistic deflection [for alt/az only]
 *   nut_eq	--> ra/dec	geocentric true equatoreal EOD [for aa only]
 *   ab_eq	--> ra/dec	geocentric apparent equatoreal EOD [for aa only]
 *   ta_par	--> ra/dec	topocentric apparent equatoreal EOD
 *     precess	--> ra/dec	topocentric equatoreal fixed equinox [eq only]
 *					--> output
 *   hadec_aa	--> alt/az	topocentric horizontal
 *   refract	--> alt/az	observed --> output
 */
static void
cir_pos (
Now *np,
double bet,	/* geo lat (mean ecliptic of date) */
double lam,	/* geo long (mean ecliptic of date) */
double *rho,	/* in: geocentric dist in AU; out: geo- or topocentic dist */
Obj *op)	/* object to set s_ra/dec as per equinox */
{
	double ra, dec;		/* apparent ra/dec, corrected for nut/ab */
	double tra, tdec;	/* astrometric ra/dec, no nut/ab */
	double lsn, rsn;	/* solar geocentric (mean ecliptic of date) */
	double ha_in, ha_out;	/* local hour angle before/after parallax */
	double dec_out;		/* declination after parallax */
	double dra, ddec;	/* parallax correction */
	double alt, az;		/* current alt, az */
	double lst;             /* local sidereal time */
	double rho_topo;        /* topocentric distance in earth radii */

	/* convert to equatoreal [mean equator, with mean obliquity] */
	ecl_eq (mjed, bet, lam, &ra, &dec);
	tra = ra;	/* keep mean coordinates */
	tdec = dec;

	/* precess and save astrometric coordinates */
	if (mjed != epoch)
	    precess (mjed, epoch, &tra, &tdec);
	op->s_astrora = tra;
	op->s_astrodec = tdec;

	/* get sun position */
	sunpos(mjed, &lsn, &rsn, NULL);

	/* allow for relativistic light bending near the sun.
	 * (avoid calling deflect() for the sun itself).
	 */
	if (!is_planet(op,SUN) && !is_planet(op,MOON))
	    deflect (mjed, op->s_hlong, op->s_hlat, lsn, rsn, *rho, &ra, &dec);

	/* correct ra/dec to form geocentric apparent */
	nut_eq (mjed, &ra, &dec);
	if (!is_planet(op,MOON))
	    ab_eq (mjed, lsn, &ra, &dec);
	op->s_gaera = ra;
	op->s_gaedec = dec;

	/* find parallax correction for equatoreal coords */
	now_lst (np, &lst);
	ha_in = hrrad(lst) - ra;
	rho_topo = *rho * MAU/ERAD;             /* convert to earth radii */
	ta_par (ha_in, dec, lat, elev, &rho_topo, &ha_out, &dec_out);

	/* transform into alt/az and apply refraction */
	hadec_aa (lat, ha_out, dec_out, &alt, &az);
	refract (pressure, temp, alt, &alt);
	op->s_alt = alt;
	op->s_az = az;

	/* Get parallax differences and apply to apparent or astrometric place
	 * as needed.  For the astrometric place, rotating the CORRECTIONS
	 * back from the nutated equator to the mean equator will be
	 * neglected.  This is an effect of about 0.1" at moon distance.
	 * We currently don't have an inverse nutation rotation.
	 */
	if (pref_get(PREF_EQUATORIAL) == PREF_GEO) {
	    /* no topo corrections to eq. coords */
	    dra = ddec = 0.0;
	} else {
	    dra = ha_in - ha_out;	/* ra sign is opposite of ha */
	    ddec = dec_out - dec;
	    *rho = rho_topo * ERAD/MAU; /* return topocentric distance in AU */

	    ra = ra + dra;
	    dec = dec + ddec;
	}
	range(&ra, 2*PI);
	op->s_ra = ra;
	op->s_dec = dec;
}
Exemplo n.º 5
0
static int
obj_fixed (Now *np, Obj *op)
{
	double lsn, rsn;	/* true geoc lng of sun, dist from sn to earth*/
	double lam, bet;	/* geocentric ecliptic long and lat */
	double ha;		/* local hour angle */
	double el;		/* elongation */
	double alt, az;		/* current alt, az */
	double ra, dec;		/* ra and dec at equinox of date */
	double rpm, dpm; 	/* astrometric ra and dec with PM to now */
	double lst;

	/* on the assumption that the user will stick with their chosen display
	 * epoch for a while, we move the defining values to match and avoid
	 * precession for every call until it is changed again.
	 * N.B. only compare and store jd's to lowest precission (f_epoch).
	 * N.B. maintaining J2k ref (which is arbitrary) helps avoid accum err
	 */
	if (0 /* disabled in PyEphem */
            && epoch != EOD && epoch != op->f_epoch) {
	    double pr = op->f_RA, pd = op->f_dec, fe = epoch;
	    /* first bring back to 2k */
	    precess (op->f_epoch, J2000, &pr, &pd);
	    pr += op->f_pmRA*(J2000-op->f_epoch);
	    pd += op->f_pmdec*(J2000-op->f_epoch);
	    /* then to epoch */
	    pr += op->f_pmRA*(fe-J2000);
	    pd += op->f_pmdec*(fe-J2000);
	    precess (J2000, fe, &pr, &pd);
	    op->f_RA = pr;
	    op->f_dec = pd;
	    op->f_epoch = fe;
	}

	/* apply proper motion .. assume pm epoch reference equals equinox */
	rpm = op->f_RA + op->f_pmRA*(mjd-op->f_epoch);
	dpm = op->f_dec + op->f_pmdec*(mjd-op->f_epoch);

	/* set ra/dec to astrometric @ equinox of date */
	ra = rpm;
	dec = dpm;
	if (op->f_epoch != mjed)
	    precess (op->f_epoch, mjed, &ra, &dec);

	/* compute astrometric @ requested equinox */
	op->s_astrora = rpm;
	op->s_astrodec = dpm;
	if (op->f_epoch != epoch)
	    precess (op->f_epoch, epoch, &op->s_astrora, &op->s_astrodec);

	/* convert equatoreal ra/dec to mean geocentric ecliptic lat/long */
	eq_ecl (mjed, ra, dec, &bet, &lam);

	/* find solar ecliptical long.(mean equinox) and distance from earth */
	sunpos (mjed, &lsn, &rsn, NULL);

	/* allow for relativistic light bending near the sun */
	deflect (mjed, lam, bet, lsn, rsn, 1e10, &ra, &dec);

	/* TODO: correction for annual parallax would go here */

	/* correct EOD equatoreal for nutation/aberation to form apparent 
	 * geocentric
	 */
	nut_eq(mjed, &ra, &dec);
	ab_eq(mjed, lsn, &ra, &dec);
	op->s_gaera = ra;
	op->s_gaedec = dec;

	/* set s_ra/dec -- apparent */
	op->s_ra = ra;
	op->s_dec = dec;

	/* compute elongation from ecliptic long/lat and sun geocentric long */
	elongation (lam, bet, lsn, &el);
	el = raddeg(el);
	op->s_elong = (float)el;

	/* these are really the same fields ...
	op->s_mag = op->f_mag;
	op->s_size = op->f_size;
	*/

	/* alt, az: correct for refraction; use eod ra/dec. */
	now_lst (np, &lst);
	ha = hrrad(lst) - ra;
	hadec_aa (lat, ha, dec, &alt, &az);
	refract (pressure, temp, alt, &alt);
	op->s_alt = alt;
	op->s_az = az;

	return (0);
}
Exemplo n.º 6
0
/* find where and when an object, op, will rise and set and
 *   it's transit circumstances. all times are utc mjd, angles rads e of n.
 * dis is the angle down from an ideal horizon, in rads (see riset()).
 * N.B. dis should NOT include refraction, we do that here.
 */
void
riset_cir (Now *np, Obj *op, double dis, RiseSet *rp)
{
	double mjdn;	/* mjd of local noon */
	double lstn;	/* lst at local noon */
	double lr, ls;	/* lst rise/set times */
	double ar, as;	/* az of rise/set */
	double ran;	/* RA at noon */
	Now n;		/* copy to move time around */
	Obj o;		/* copy to get circumstances at n */
	int rss;	/* temp status */

	/* work with local copies so we can move the time around */
	(void) memcpy ((void *)&n, (void *)np, sizeof(n));
	(void) memcpy ((void *)&o, (void *)op, sizeof(o));

	/* fast Earth satellites need a different approach.
	 * "fast" here is pretty arbitrary -- just too fast to work with the
	 * iterative approach based on refining the times for a "fixed" object.
	 */
	if (op->o_type == EARTHSAT && op->es_n > FAST_SAT_RPD) {
	    e_riset_cir (&n, &o, dis, rp);
	    return;
	}

	/* assume no problems initially */
	rp->rs_flags = 0;

	/* start the iteration at local noon */
	mjdn = mjd_day(mjd - tz/24.0) + tz/24.0 + 0.5;
	n.n_mjd = mjdn;
	now_lst (&n, &lstn);

	/* first approximation is to find rise/set times of a fixed object
	 * at the current epoch in its position at local noon.
	 * N.B. add typical refraction if dis is above horizon for initial
	 *   go/no-go test. if it passes, real code does refraction rigorously.
	 */
	n.n_mjd = mjdn;
	if (obj_cir (&n, &o) < 0) {
	    rp->rs_flags = RS_ERROR;
	    return;
	}
	ran = o.s_gaera;
	riset (o.s_gaera, o.s_gaedec, lat, dis+(dis>.01 ? 0 : .01), &lr, &ls,
								&ar, &as, &rss);
	switch (rss) {
	case  0:  break;
	case  1: rp->rs_flags = RS_NEVERUP; return;
	case -1: rp->rs_flags = RS_CIRCUMPOLAR; goto dotransit;
	default: rp->rs_flags = RS_ERROR; return;
	}

	/* iterate to find better rise time */
	n.n_mjd = mjdn;
	switch (find_0alt ((lr - lstn)/SIDRATE, dis, &n, &o)) {
	case 0: /* ok */
	    rp->rs_risetm = n.n_mjd;
	    rp->rs_riseaz = o.s_az;
	    break;
	case -1: /* obj_cir error */
	    rp->rs_flags |= RS_RISERR;
	    break;
	case -2: /* converged but not today, err but give times anyway */
	    rp->rs_risetm = n.n_mjd;
	    rp->rs_riseaz = o.s_az;
	    rp->rs_flags |= RS_NORISE;
	    break;
	case -3: /* probably never up */
	    rp->rs_flags |= RS_NEVERUP;
	    break;
	}

	/* iterate to find better set time */
	n.n_mjd = mjdn;
	switch (find_0alt ((ls - lstn)/SIDRATE, dis, &n, &o)) {
	case 0: /* ok */
	    rp->rs_settm = n.n_mjd;
	    rp->rs_setaz = o.s_az;
	    break;
	case -1: /* obj_cir error */
	    rp->rs_flags |= RS_SETERR;
	    break;
	case -2: /* converged but not today, err but give times anyway */
	    rp->rs_settm = n.n_mjd;
	    rp->rs_setaz = o.s_az;
	    rp->rs_flags |= RS_NOSET;
	    break;
	case -3: /* probably circumpolar */
	    rp->rs_flags |= RS_CIRCUMPOLAR;
	    break;
	}

	/* can try transit even if rise or set failed */
    dotransit:
	n.n_mjd = mjdn;
	switch (find_transit ((radhr(ran) - lstn)/SIDRATE, &n, &o)) {
	case 0: /* ok */
	    rp->rs_trantm = n.n_mjd;
	    rp->rs_tranalt = o.s_alt;
	    break;
	case -1: /* did not converge */
	    rp->rs_flags |= RS_TRANSERR;
	    break;
	case -2: /* converged but not today */
	    rp->rs_flags |= RS_NOTRANS;
	    break;
	}
}