<- Volver al trabajo

apsis

Publicado

Predicción open source de pases de satélite sobre datos orbitales reales.

apsis es un pequeño backend open source que responde a una pregunta operativa: cuándo es la próxima ventana de contacto entre una estación terrestre y un satélite, y por dónde cruza el cielo. Ingiere elementos orbitales (TLE) de CelesTrak, los propaga con SGP4 a través de skyfield y devuelve cada pase por encima de la máscara de elevación de la estación durante las próximas 48 horas, con su ground track sub-satélite como GeoJSON. Corre sobre FastAPI y PostgreSQL/PostGIS, con jobs programados y un outbox transaccional dentro del propio Postgres. No hay un broker de mensajes en ningún punto del sistema.

Pases de la ISS (NORAD 25544) sobre dos estaciones terrestres de la ESA en España, Cebreros y Maspalomas, calculados por apsis a partir de datos orbitales reales. Las líneas cian son los ground tracks sub-satélite; los anillos marcan la culminación. Pulsa una traza para ver los tiempos (de AOS a LOS, UTC) y la elevación máxima de cada pase.Instantánea estática calculada por apsis a partir de TLE reales; pases sobre una máscara de elevación de 10 grados. Mapa base: Natural Earth (dominio público).

El problema: visibilidad del segmento terreno

Una estación terrestre solo puede comunicarse con un satélite mientras está por encima del horizonte local y, en la práctica, por encima de una máscara de elevación: a elevaciones bajas la señal atraviesa demasiada atmósfera y terreno. Planificar una ventana de contacto es propagar la órbita, encontrar cuándo el satélite supera la máscara (AOS), dónde culmina y cuándo vuelve a bajar (LOS), y proyectar la trayectoria sobre el suelo. Es la misma familia de problema en la que trabajo en Telespazio alrededor de SIBA y Sentinel/Copernicus. apsis la destila en una referencia pública sin nada confidencial.

La tesis: sin broker

apsis tiene dos clases de trabajo en segundo plano: recurrente (refrescar los TLE cada un par de horas) y reactivo (cuando una órbita cambia, recalcular sus pases). En lugar de añadir un broker de mensajes y un framework de workers, apsis ejecuta ambas sobre PostgreSQL: una tabla scheduled_jobs con lease para lo recurrente y un outbox transaccional (LISTEN/NOTIFY más SELECT ... FOR UPDATE SKIP LOCKED) que solo dispara un evento cuando la escritura en base de datos ha hecho commit. El problema de la doble escritura desaparece porque no hay un segundo sistema al que escribir.

La geometría: PostGIS

Las estaciones son puntos y los ground tracks son linestrings, todo en WGS84 (longitud/latitud, SRID 4326). PostGIS almacena e indexa la geometría, y la API serializa cada traza directamente a GeoJSON, que es exactamente lo que pinta el mapa de arriba. Las preguntas espaciales (qué pases cruzan este bounding box, qué estaciones caen dentro de esta zona) se resuelven con un índice GiST en vez de con código de aplicación.

Cuándo NO lo haría

Una cola nativa en Postgres encaja en un servicio que ya es dueño de su base de datos y necesita trabajo en segundo plano fiable y transaccional a escala humana. Deja de encajar con throughput muy alto, con fan-out a muchos consumidores independientes o entre lenguajes y servicios: esos son problemas de broker, y fingir lo contrario es lo que da mala fama a este patrón. El trade-off completo está escrito en una nota.

Arquitectura

Por capas y por contexto: API a casos de uso a servicios y repositorios a modelos. El núcleo de cálculo (propagación orbital, búsqueda de pases, geometría) es puro, síncrono y sin efectos, y un pequeño helper run_blocking lo mantiene fuera del event loop asíncrono. Cada decisión no obvia está registrada como ADR en el repositorio.