Computes the geocentric position of the Moon using a JPL DE440s (or compatible) SPK binary ephemeris kernel.
The SPK file provides positions in ICRF/J2000 Cartesian coordinates (km). This module chains the available segments to produce the Moon's position relative to the Earth's centre, then applies IAU 1980 precession and nutation to yield apparent geocentric RA, Dec, and distance in the true equator and equinox of date.
Segment chaining (DE440s)
de440s.bsp supplies:
- Body 301 (Moon) relative to body 3 (Earth-Moon Barycenter, EMB)
- Body 399 (Earth) relative to body 3 (EMB)
Moon relative to Earth = Moon/EMB − Earth/EMB.
Setup
Load the kernel once at application startup and pass it to all calls:
# This step is performed automatically at application start
{:ok, kernel} = Astro.Ephemeris.Kernel.load("priv/de440s.bsp")
{:ok, {ra, dec, dist}} = Astro.Ephemeris.moon_position(utc_dt)Accuracy
Position accuracy is limited by the ephemeris itself: DE440 achieves sub-centimetre accuracy for the Moon relative to current-epoch laser ranging data. The dominant remaining error sources for rise/set timing are:
- Atmospheric refraction model (~1 arcmin, ~2 s of time near horizon)
- Topocentric correction residuals at high solar-altitude latitudes
This represents a 10–100× improvement over the truncated Chapront series used in Meeus that was the core of the Astro 1.x library.
Summary
Functions
Returns the equatorial horizontal parallax for a given geocentric distance.
Computes the apparent geocentric position of the Moon for the given datetime.
Computes the apparent geocentric position of the Moon for the given dynamical time.
Computes the apparent geocentric position of the Sun for the given datetime.
Computes the apparent geocentric position of the Sun for the given dynamical time.
Functions
Returns the equatorial horizontal parallax for a given geocentric distance.
Computed as asin(R_earth / distance) using the WGS-84
equatorial radius of 6378.137 km.
Arguments
distance_kmis the geocentric distance in kilometers.
Returns
- The equatorial horizontal parallax in degrees.
@spec moon_position(DateTime.t()) :: {:ok, {right_ascension :: Astro.angle(), float(), float()}} | {:error, term()}
Computes the apparent geocentric position of the Moon for the given datetime.
Chains the Moon/EMB and Earth/EMB segments from the loaded JPL ephemeris, then applies IAU 1980 precession and nutation to produce coordinates in the true equator and equinox of date.
Arguments
date_timeis aDateTimein any time zone (converted internally to a moment and then to dynamical time).
Returns
{:ok, {ra_deg, dec_deg, distance_km}}where right ascension is in degrees in the range [0, 360), declination is in degrees in the range [-90, 90], and distance is in kilometers.{:error, reason}if a required ephemeris segment is not found.
Computes the apparent geocentric position of the Moon for the given dynamical time.
Arguments
dynamical_timeis TDB seconds past J2000.0.
Returns
{:ok, {ra_deg, dec_deg, distance_km}}where right ascension is in degrees in the range [0, 360), declination is in degrees in the range [-90, 90], and distance is in kilometers.{:error, reason}if a required ephemeris segment is not found.
@spec sun_position(DateTime.t()) :: {:ok, {float(), float(), float()}} | {:error, term()}
Computes the apparent geocentric position of the Sun for the given datetime.
Chains the Sun/SSB, EMB/SSB and Earth/EMB segments from the loaded JPL ephemeris (Sun/SSB − EMB/SSB + Earth/EMB), then applies IAU 1980 precession and nutation.
Arguments
date_timeis aDateTimein any time zone.
Returns
{:ok, {ra_deg, dec_deg, distance_km}}where right ascension is in degrees in the range [0, 360), declination is in degrees in the range [-90, 90], and distance is in kilometers.{:error, reason}if a required ephemeris segment is not found.
Computes the apparent geocentric position of the Sun for the given dynamical time.
Arguments
dynamical_timeis TDB seconds past J2000.0.
Returns
{:ok, {ra_deg, dec_deg, distance_km}}where right ascension is in degrees in the range [0, 360), declination is in degrees in the range [-90, 90], and distance is in kilometers.{:error, reason}if a required ephemeris segment is not found.