Astronomia i mecànica orbital de codi obert per al teu proper projecte espacial.
Siderust — efemèrides, coordenades i geometria de missions tipades en Rust i Python.
Siderust és un projecte científic independent. Serveix per calcular posicions del Sistema Solar, transformar sistemes de referència i prototipar geometria d’observació o de missió durant la hackató.
No és un recurs oficial de NASA Space Apps, ni Global Collaborator, producte o aval de la NASA.
Què és Siderust?
Una pila d’astronomia tipada: una biblioteca Rust nativa (siderust) i un paquet Python (siderust a PyPI) per a efemèrides, centres i sistemes de coordenades, temps astronòmic i geometria d’observació. Les unitats venen de qtty; el temps, de tempoch; la geometria afí, d’affn.
Com pot ajudar en els reptes de Space Apps?
Especialment per a eines d’il·luminació lunar / visibilitat de la Terra i mecànica orbital educativa. Consulteu les notes dels reptes i els exemples executables.
Reptes rellevants del 2026
CLPS Lunar Mission Browser
Comparar llocs i dates d’aterratge lunar exigeix direccions del Sol i de la Terra, geometria d’il·luminació i un tractament cuós del temps. Siderust ofereix Alt/Az geomètric de superfície lunar en Rust i Python, a més d’efemèrides selenocèntriques i transformacions tipades.
•Alt/Az geomètric de superfície lunar per al Sol i la Terra des d’un lloc selenogràfic
•Centres lunars (Selenocentric) i orientació MoonIauMeanEarth
•Transformacions de centres i sistemes amb unitats explícites
•Temps d’observació amb dates julianes / julianes modificades
Un simulador educatiu de missions necessita geometria orbital, efemèrides i conversions de sistemes. Siderust pot ser l’esquelet astronòmic mentre potència, massa, cost i comunicacions queden a la vostra aplicació.
•Efemèrides planetàries i lunars (basades en VSOP87)
•Distàncies relatives i canvis de centre (p. ex. Terra–Mart)
•Conversions de sistemes de referència per a visualització
•Ajudes keplerianes / de geometria de missió al crate Rust
Posicions planetàries i lunars amb models i limitacions documentades.
Coordenades tipades
Centres, sistemes i unitats físiques al sistema de tipus (Rust) o metadades (Python).
Alt/Az lunar i terrestre
Angles horitzontals geomètrics per a observadors a la Terra i llocs a la superfície lunar (Sol, Terra, direccions ICRS).
Rust + Python
siderust 0.16.0 a crates.io · siderust 0.7.0 a PyPI.
On és el Sol al cel lunar?
Les eines a l’estil CLPS necessiten la direcció aparent del Sol o de la Terra des d’un lloc lunar. Siderust v0.16.0 (Rust) i siderust-py 0.7.0 ofereixen el pipeline geomètric complet: defineix un lloc lunar tipat, transforma l’objectiu al sistema fix de la Lluna i projecta’l al sistema horitzontal local.
Tres passos conceptuals
Pas 1
Defineix un observador a la superfície lunar
Longitud selenogràfica (est-positiva), latitud planetocèntrica i altura sobre l’esfera mitjana IAU. En Rust: SurfaceSite::<Moon>; en Python: LunarObserver. Als pols cal una convenció d’azimut.
Pas 2
Obté l’objectiu amb una efemèride
Situa el Sol o la Terra en un centre comú (típicament Selenocentric) a l’època d’observació amb models VSOP87. Els helpers Python observe_earth / observe_sun ho fan per tu.
Pas 3
Projecta al horitzó lunar local
Construeix una base local est–nord–zenit i reporta azimut i altitud geomètrica. Això no és visibilitat topogràfica ni ombres del terreny.
Exemples executables
Exemples introductoris per a observadors terrestres, Alt/Az de superfície lunar i distàncies d’estil missió. Els exemples utilitzen èpoques fixes reproduïbles.
Alt/Az del Sol des de la Terra
Comença amb la teva longitud, latitud i altura. Canvia les coordenades per explorar el cel des de qualsevol lloc terrestre.
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.
}
from siderust import Body as B, Observer as Site
# Seville: longitude east-positive, latitude north-positive.
site = Site(lon_deg=-5.9845, lat_deg=37.3891, height_m=7.0)
# A fixed epoch makes the output reproducible (MJD, TT).
mjd = 60000.5
print(f"Sun altitude: {B.Sun.altitude_at(site, mjd):.2f}°")
print(f"Sun azimuth: {B.Sun.azimuth_at(site, mjd):.2f}°")
# Altitude is geometric; azimuth is measured north through east.
Canvia la longitud, la latitud o l’altura per fer servir el teu lloc. Els resultats varien segons l’hora i la ubicació.
Alt/Az del Sol i la Terra des de la Lluna
Altitud i azimut geomètrics des d’un lloc a la superfície lunar — la primitiva CLPS d’il·luminació i visibilitat de la Terra. LunarObserver en Python encapsula el mateix pipeline Rust.
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(())
}
from siderust import LunarObserver
from siderust.direction import ICRS
# Lunar site on the IAU mean sphere (R = 1737.4 km).
# Longitude east-positive; latitude planetocentric; height above the sphere.
site = LunarObserver(lon_deg=20.0, lat_deg=-3.5, height_m=0.0)
# Direction-only: north celestial pole at J2000 TT (no invented parallax).
ncp = ICRS(ra_deg=0.0, dec_deg=90.0)
hz = site.observe_direction(ncp, jd_tt=2451545.0)
print(f"NCP: alt={hz.alt_deg:.6f}°, az={hz.az_deg:.6f}°")
# Expected ≈ alt=17.765928°, az=12.045095° (N=0°, E=90°)
# Finite-distance Earth and Sun from the lunar site (ephemeris + transform).
jd = 2460000.5 # Julian Date TT
earth = site.observe_earth(jd)
sun = site.observe_sun(jd)
print(f"Earth: alt={earth.alt_deg:.4f}°, az={earth.az_deg:.4f}°, range={earth.range:.3f} {earth.range_unit}")
print(f"Sun: alt={sun.alt_deg:.4f}°, az={sun.az_deg:.4f}°, range={sun.range:.6f} {sun.range_unit}")
# Geometric only: no refraction, aberration, light-time, or terrain.
Canvia lon/lat per al teu lloc d’aterratge. Les èpoques són data juliana TT. Comprovació NCP a J2000: ≈ alt 17.765928422857°, az 12.045094675187°.
Separació Terra–Mart
Una primitiva compacta de disseny de missions: distància relativa entre planetes en una època fixa.
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
}
from siderust import Body as B
jd = 2460001.0
earth = B.Earth.track(jd)
mars = B.Mars.track(jd)
# Barycentric tracks → mutual separation (≈ geocentric Mars range).
sep_au = earth.position.distance_to(mars.position)
print(f"Earth–Mars separation: {sep_au:.6f} AU")
# Expected ≈ 1.109577 AU
moon = B.Moon.track(jd) # geocentric ecliptic, kilometres
print(f"Geocentric Moon range: {moon.position.distance():.0f} km")
# Expected ≈ 385046 km
Sortida esperada: ≈ 1.109577 AU (JD 2460001)
Comença
Instal·la qualsevol dels dos ecosistemes i executa un exemple mínim. Enllaços a crates.io, docs.rs, PyPI i els repositoris.
Siderust es distribueix sota AGPL-3.0-only. Comproveu si aquesta llicència encaixa amb els plans de distribució del vostre equip abans d’integrar-la. Citeu correctament models i dades de tercers. LICENSE ↗
Siderust és un projecte independent de codi obert que aporta recursos tècnics gratuïts als participants. No és un recurs oficial de NASA Space Apps, ni Global Collaborator, producte o aval de la NASA.
El nom i les dates de l’esdeveniment s’esmenten només amb finalitat divulgativa. Aquesta pàgina no utilitza la insígnia de la NASA ni reclama afiliació a la marca Space Apps. Les il·lustracions són originals de Siderust.