Skip to main content
Siderust

Independent open-source resource

NASA Space Apps Challenge 2026 · November 14–15

Open-source astronomy and orbital mechanics for your next space project.

Siderust — typed ephemerides, coordinates, and mission geometry in Rust and Python.

Siderust is an independent scientific software project. Use it to compute Solar System positions, transform reference frames, and build observation or mission-geometry prototypes during the hackathon — without starting from scratch.

Not an official NASA Space Apps resource, Global Collaborator, NASA product, or NASA endorsement.

Schematic of the Moon with a surface observer and Sun and Earth directions

What is Siderust?

A type-safe astronomy stack: a native Rust crate (siderust) and a Python package (siderust on PyPI) for ephemerides, coordinate centres and frames, astronomical time, and observation geometry. Physical units come from qtty; time scales from tempoch; affine geometry from affn.

How can it help with Space Apps challenges?

Especially for lunar illumination / Earth-visibility tooling and educational orbital mechanics. See the challenge notes and executable examples below.

Relevant 2026 challenges

CLPS Lunar Mission Browser

Comparing lunar landing sites and dates needs Sun and Earth directions relative to a lunar location, illumination geometry, and careful time handling. Siderust provides lunar-surface geometric Alt/Az in Rust and Python, plus selenocentric ephemerides and typed centre/frame transforms.

  • Lunar-surface geometric Alt/Az for the Sun and Earth from a selenographic site
  • Lunar reference centres (Selenocentric) and MoonIauMeanEarth orientation
  • Coordinate and centre transformations with explicit units and frames
  • Observation times via Julian / Modified Julian dates

CLPS Lunar Mission Browser (official listing) ↗

Space Mission Design Game

Educational mission simulators need orbital geometry, ephemerides, and frame conversions more than they need a full flight-dynamics suite. Siderust can supply the astronomical backbone while power, mass, cost, and communications stay in your application layer.

  • Planetary and lunar ephemerides (VSOP87-based)
  • Relative distances and centre shifts (e.g. Earth–Mars)
  • Reference-frame conversions for visualization and scoring
  • Keplerian / mission-geometry helpers in the Rust crate

Space Mission Design Game (official listing) ↗

What you can rely on today

Ephemerides

Planetary and lunar positions with documented models and limitations.

Typed coordinates

Centres, frames, and physical units encoded in the type system (Rust) or runtime metadata (Python).

Lunar & Earth Alt/Az

Geometric horizon angles for Earth observers and lunar surface sites (Sun, Earth, ICRS directions).

Rust + Python

siderust 0.16.0 on crates.io · siderust 0.7.0 on PyPI.

Where is the Sun in the lunar sky?

CLPS-style tools need the apparent direction of the Sun or Earth from a fixed lunar site. Siderust v0.16.0 (Rust) and siderust-py 0.7.0 provide the complete geometric pipeline: define a typed lunar site, transform the target to the Moon-fixed frame, and project it into the local horizontal system.

Three conceptual steps

  1. Step 1

    Define a lunar surface observer

    Selenographic longitude (east-positive), planetocentric latitude, and height on the IAU mean sphere. In Rust use SurfaceSite::<Moon>; in Python use LunarObserver. Poles need a defined azimuth convention.

  2. Step 2

    Obtain the target with an ephemeris

    Place the Sun or Earth in a common centre (typically Selenocentric) at the observation epoch using VSOP87-based models. Python helpers observe_earth / observe_sun do this for you.

  3. Step 3

    Project into the local lunar horizon

    Build a local east–north–up basis at the site and report azimuth and geometric altitude. This is geometric altitude above a reference horizon — not topographic visibility or terrain shadowing.

Executable examples

Beginner-friendly examples for Earth observers, lunar-surface Alt/Az, and mission-style distances. Samples use reproducible fixed epochs.

Sun Alt/Az from Earth

Start with your own longitude, latitude, and height. Change the coordinates to explore the sky above any Earth location.

use siderust::{
    bodies::solar_system::Sun,
    coordinates::{centers::Geodetic as Site, frames::ECEF},
    qtty::{AstronomicalUnit, DEG, M},
};

fn main() {
    // Seville: longitude east-positive, latitude north-positive.
    let site = Site::<ECEF>::new(-5.9845 * DEG, 37.3891 * DEG, 7.0 * M);

    // The result is already topocentric and horizontal.
    let sun = Sun::get_horizontal::<AstronomicalUnit>(siderust::J2000, site);

    println!("Sun horizontal position: {sun:?}");
    // Altitude is geometric (no refraction); azimuth is north through east.
}

Change longitude, latitude, or height to use your own location. Results vary with time and site.

Sun & Earth Alt/Az from the Moon

Geometric altitude and azimuth from a lunar surface site — the CLPS illumination and Earth-visibility primitive. Python LunarObserver wraps the same Rust pipeline.

use siderust::{
    bodies::solar_system::Moon,
    coordinates::{
        cartesian::Position,
        centers::Selenocentric,
        frames::EclipticMeanJ2000 as Ecl,
        surface::SurfaceSite,
        transform::{AstroContext, SurfaceHorizontalExt, TransformCenter},
    },
    ephemeris::{Ephemeris, Vsop87Ephemeris},
    qtty::{AstronomicalUnit, DEG, Kilometer, M},
    time::JulianDate,
};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Lunar site on the IAU mean sphere (lon east, lat planetocentric).
    let site = SurfaceSite::<Moon>::new(20.0 * DEG, (-3.5) * DEG, 0.0 * M)?;
    let jd = JulianDate::new(2_460_000.5); // TT
    let ctx: AstroContext = AstroContext::default();

    // Earth from the Moon centre = −Moon(geocentric), then local Alt/Az.
    let moon_geo = Vsop87Ephemeris::moon_geocentric(jd);
    let earth_sel = Position::<Selenocentric, Ecl, Kilometer>::new(
        -moon_geo.x(), -moon_geo.y(), -moon_geo.z(),
    );
    let earth = site.observe_position(&earth_sel, &jd, &ctx)?;

    let sun_bary = Vsop87Ephemeris::sun_barycentric(jd);
    let sun_sel: Position<Selenocentric, Ecl, AstronomicalUnit> =
        TransformCenter::to_center_with(&sun_bary, (), jd, &ctx);
    let sun = site.observe_position(&sun_sel, &jd, &ctx)?;

    println!("Earth: alt={}, az={}, range={}", earth.alt(), earth.az(), earth.range());
    println!("Sun:   alt={}, az={}, range={}", sun.alt(), sun.az(), sun.range());
    // Geometric only; azimuth north→east. No refraction or terrain.
    Ok(())
}

Change lon/lat for your landing site. Epochs are Julian Date TT. NCP check at J2000: ≈ alt 17.765928422857°, az 12.045094675187°.

Earth–Mars separation

A compact mission-design primitive: relative distance between planets at a fixed epoch.

use siderust::{
    bodies::solar_system::Mars,
    coordinates::{
        cartesian::Position,
        centers::Geocentric,
        frames::EclipticMeanJ2000 as Ecl,
        transform::TransformCenter,
    },
    qtty::AstronomicalUnit,
    time::JulianDate,
};

fn main() {
    type Ecliptic = Position<Geocentric, Ecl, AstronomicalUnit>;

    let jd = JulianDate::new(2_460_001.0);
    let mars_geo: Ecliptic = Mars::vsop87a(jd).to_center(jd);
    println!("Mars geocentric range: {}", mars_geo.distance());
    // Expected ≈ 1.109577 AU
}

Expected output: ≈ 1.109577 AU (JD 2460001)

Getting started

Install either ecosystem and run a minimal example. Links go to crates.io, docs.rs, PyPI, and the GitHub repositories.

Rust

siderust 0.16.0

cargo add siderust@0.16.0

Python

siderust 0.7.0

pip install siderust==0.7.0

Where can I get help?

During the hackathon, maintainers may offer best-effort technical guidance. This is not a staffed mentoring desk and response times are not guaranteed.

License

Siderust is AGPL-3.0-only. Check whether that license fits your team’s distribution and source-sharing plans before integrating it. Cite third-party models and data appropriately. LICENSE ↗

Siderust is an independent open-source project contributing free technical resources to participants. It is not an official NASA Space Apps resource, Global Collaborator, NASA product, or NASA endorsement.

Event name and dates are referenced for outreach only. This page does not use the NASA insignia or claim Space Apps brand affiliation. Visuals are original Siderust artwork.