Sistema completo per il tracciamento dei satelliti artificiali in orbita terrestre. Calcola quando e dove osservare i satelliti sopra la tua posizione, con dati in tempo reale da Celestrak e calcoli orbitali precisi tramite Orekit e/o SGP4.
- Cos'Γ¨ questo progetto
- Concetti Base
- Tecnologie
- Installazione e Avvio
- API Endpoints
- Come Funzionano i Calcoli
- Interpretare i Risultati
- Esempi Pratici
- Configurazione Avanzata
- Troubleshooting
Questo sistema ti permette di:
β
Tracciare satelliti in tempo reale (ISS, Starlink, Hubble, etc.)
β
Calcolare passaggi visibili sopra qualsiasi posizione sulla Terra
β
Sapere quando guardare - orari precisi di rise, max elevation, set
β
Sapere dove guardare - direzione cardinale e gradi azimuth
β
Valutare la visibilitΓ - elevazione, condizioni di illuminazione, magnitudine stimata
β
Ricevere consigli - suggerimenti testuali per l'osservazione
I dati orbitali vengono aggiornati automaticamente ogni 6 ore da Celestrak, garantendo precisione nei calcoli.
L'azimuth Γ¨ l'angolo orizzontale misurato in gradi (da 0Β° a 360Β°) partendo dal Nord e procedendo in senso orario.
N (0Β°/360Β°)
|
|
W (270Β°)---+---E (90Β°)
|
|
S (180Β°)
Esempi pratici:
- Azimuth 0Β° = Nord puro
- Azimuth 90Β° = Est puro
- Azimuth 180Β° = Sud puro
- Azimuth 270Β° = Ovest puro
- Azimuth 45Β° = Nordest
- Azimuth 225Β° = Sudovest
PerchΓ© Γ¨ importante? Ti indica verso quale direzione guardare sull'orizzonte per vedere il satellite apparire (rise) o scomparire (set).
L'elevazione Γ¨ l'angolo verticale in gradi (da 0Β° a 90Β°) tra l'orizzonte e il satellite.
90Β° (Zenit)
* satellite
/|
/ |
/ | elevazione
/ |
------/--------- 0Β° (Orizzonte)
Esempi pratici:
- Elevazione 0Β° = Satellite esattamente sull'orizzonte
- Elevazione 45Β° = Satellite a metΓ strada tra orizzonte e zenit
- Elevazione 90Β° = Satellite direttamente sopra la testa
PerchΓ© Γ¨ importante? Determina quanto in alto guardare nel cielo. Elevazioni > 30Β° sono ottime per l'osservazione.
- Latitudine: da -90Β° (Polo Sud) a +90Β° (Polo Nord)
- Longitudine: da -180Β° (ovest) a +180Β° (est)
- Altitudine: metri sopra il livello del mare
Misura della luminositΓ apparente del satellite:
- Valori negativi = Molto luminosi (es. ISS a -3 come Venere)
- Valori positivi bassi (0-2) = Ben visibili
- Valori alti (>5) = Visibili solo con telescopio
Un satellite Γ¨ visibile a occhio nudo solo se:
- Γ illuminato dal Sole (isSunlit = true)
- Il cielo Γ¨ scuro per l'osservatore (night o twilight)
Momento migliore: Subito dopo il tramonto o prima dell'alba, quando:
- Per te Γ¨ buio (sole sotto l'orizzonte)
- Ma il satellite, piΓΉ in alto, Γ¨ ancora illuminato dal sole
- Spring Boot 4.0.3 - Framework Java per REST API
- PostgreSQL 15 - Database per satelliti e parametri orbitali
- Orekit 12.1 - Libreria per dinamica orbitale e propagazione SGP4/SDP4
- Hipparchus 3.1 - Libreria matematica per calcoli astronomici
- Spring WebFlux - Client HTTP reattivo per chiamate a Celestrak
- Hibernate/JPA - ORM per persistenza dati
- Lombok - Riduzione boilerplate Java
- Docker & Docker Compose - Containerizzazione
- Maven - Build automation
- SGP4/SDP4 - Simplified General Perturbations per propagazione orbitale
- TLE - Two-Line Element format per parametri orbitali
- ITRF - International Terrestrial Reference Frame
- WGS84 - World Geodetic System per coordinate terrestri
- Docker Desktop installato e avviato
- Git (opzionale, per clonare il repository)
- 8080 porta libera (o modificare in docker-compose.yml)
# 1. Clona il repository (o scarica lo ZIP)
git clone <repository-url>
cd satelliteTracker
# 2. Avvia tutti i servizi con Docker Compose
docker compose up --build
# 3. Attendi che i servizi si avviino (2-3 minuti al primo avvio)
# Vedrai:
# β
Database PostgreSQL avviato
# β
Container dati Orekit creato
# β
Applicazione Spring Boot avviata sulla porta 8080
# β
Scheduler inizia a scaricare dati satelliti (primi 100 da Celestrak)L'applicazione Γ¨ pronta quando vedi:
satellite-app | β
Orekit initialized with local data: /orekit-data
satellite-app | Started SatelliteTrackerApplication in X.XXX seconds
# Controlla satelliti disponibili
curl http://localhost:8080/api/satellites
# Calcola passaggi ISS
curl http://localhost:8080/api/satellites/1/passes?hours=24# Ferma i container mantenendo i dati
docker compose down
# Ferma e rimuovi anche i volumi (dati persi)
docker compose down -vGET /api/satellitesRestituisce tutti i satelliti tracciati con i parametri orbitali piΓΉ recenti.
Risposta:
[
{
"id": 1,
"noradCatId": 25544,
"objectName": "ISS (ZARYA)",
"objectType": "PAYLOAD",
"orbitalParameters": [
{
"epoch": "2026-02-22T12:34:56",
"inclination": 51.6416,
"raan": 13.2515,
"eccentricity": 0.0005678,
"argOfPerigee": 123.4567,
"meanAnomaly": 236.7890,
"meanMotion": 15.501,
"fetchedAt": "2026-02-22T18:00:00"
}
]
}
]GET /api/satellites/{id}/passes?hours=24Parametri:
id(path, obbligatorio) - ID del satellitehours(query, default 24) - Ore nel futuro da analizzare
Esempio:
curl "http://localhost:8080/api/satellites/1/passes?hours=48"Risposta:
[
{
"satelliteId": 1,
"satelliteName": "ISS (ZARYA)",
"riseTime": "2026-02-22T22:45:30",
"maxElevationTime": "2026-02-22T22:50:15",
"setTime": "2026-02-22T22:55:45",
"maxElevation": 68.5,
"riseAzimuth": 238.5,
"setAzimuth": 53.2,
"maxDistance": 398.7,
"isVisible": true,
"isSunlit": true,
"visibility": "excellent",
"observingCondition": "night",
"estimatedMagnitude": -2.5,
"satelliteAltitudeKm": 418.3,
"durationSeconds": 615,
"riseDirection": "SW",
"setDirection": "NE",
"viewingTips": "Cerca il satellite verso SW (azimuth 238.5Β°). PasserΓ quasi sopra la tua testa! Ottima visibilitΓ : satellite illuminato su cielo scuro."
}
]GET /api/satellites/{id}/passes/custom?lat=41.9&lon=12.5&alt=20&hours=24Parametri:
id(path) - ID del satellitelat(query) - Latitudine (-90 a +90)lon(query) - Longitudine (-180 a +180)alt(query, default 0) - Altitudine in metrihours(query, default 24) - Ore da analizzare
Esempio Roma:
curl "http://localhost:8080/api/satellites/1/passes/custom?lat=41.9&lon=12.5&alt=20&hours=12"GET /api/satellites/observer-locationRisposta:
{
"latitude": 41.01,
"longitude": 14.30,
"altitude": 30.0,
"locationName": "San Marcellino, Caserta, Italia"
}GET /api/satellites/{id}GET /api/satellites/{id}/orbital-historyMostra tutti i TLE storici per vedere come l'orbita Γ¨ cambiata nel tempo.
GET /api/satellites/norad/{noradCatId}Esempio ISS:
curl http://localhost:8080/api/satellites/norad/25544Ogni 6 ore, lo scheduler scarica i TLE aggiornati da Celestrak:
https://celestrak.org/NORAD/elements/gp.php?GROUP=stations&FORMAT=json
I dati includono:
- Identificatori (NORAD Catalog ID)
- Parametri orbitali (inclination, RAAN, eccentricity, etc.)
- Epoch (timestamp di validitΓ )
I parametri orbitali vengono convertiti in formato TLE standard (Two-Line Elements):
ISS (ZARYA)
1 25544U 98067A 24054.12345678 .00000000 00000-0 00000-0 0 09
2 25544 51.6416 13.2515 0005678 123.4567 236.7890 15.50103472345678
- Line 1: Satellite ID, epoca, drag, radiazione
- Line 2: Inclinazione, RAAN, eccentricitΓ , argomento perigeo, anomalia media, mean motion
SGP4 (Simplified General Perturbations) Γ¨ un algoritmo che:
-
Parte dai parametri TLE
-
Propaga l'orbita nel tempo considerando:
- Attrazione gravitazionale terrestre (armoniche sferiche J2, J3, J4)
- Resistenza atmosferica (drag)
- Pressione di radiazione solare
- Perturbazioni lunari e solari (per orbite alte)
-
Calcola posizione e velocitΓ del satellite in ogni istante
Precisione: ~1 km per orbite LEO se il TLE Γ¨ recente (<1 settimana)
Per calcolare cosa vede un osservatore sulla Terra:
Posizione Satellite (ITRF)
β
Trasformazione β Frame Topocentrico (osservatore)
β
Estrazione β Azimuth, Elevazione, Distanza
Processo:
- Ogni 60 secondi, calcola posizione satellite
- Trasforma in coordinate relative all'osservatore
- Estrae azimuth (0-360Β°) ed elevazione (-90 a +90Β°)
- Calcola distanza slant-range (km)
Un passaggio Γ¨ identificato quando:
- Rise: Satellite supera l'orizzonte (elevazione passa da <0Β° a >0Β°)
- Max Elevation: Punto di massima elevazione durante il passaggio
- Set: Satellite scende sotto l'orizzonte (elevazione torna <0Β°)
Filtro visibilitΓ minima: Solo passaggi con elevazione massima >10Β° (altrimenti troppo bassi).
Per determinare se il satellite Γ¨ visibile:
- Posizione Sole: Calcolata con effemeridi preciseDatella libreria Orekit
- Angolo Satellite-Sole: Se <90Β°, satellite Γ¨ illuminato
- Elevazione Sole per Osservatore:
- Sole < -18Β° β Notte astronomica
- Sole tra -18Β° e -6Β° β Crepuscolo
- Sole > -6Β° β Giorno
VisibilitΓ ottimale: Satellite illuminato + Osservatore al buio
Formula semplificata basata su:
- Distanza dal satellite (piΓΉ vicino = piΓΉ luminoso)
- Altitudine orbitale (LEO piΓΉ luminose di MEO/GEO)
- Stato di illuminazione
ISS tipicamente varia da -3 (brillantissima) a +2 (ben visibile).
| Campo | Significato | Valori |
|---|---|---|
riseTime |
Quando il satellite appare sull'orizzonte | ISO 8601 timestamp |
maxElevationTime |
Momento di massima altezza | ISO 8601 timestamp |
setTime |
Quando scompare sotto l'orizzonte | ISO 8601 timestamp |
maxElevation |
Altezza massima sopra orizzonte | 0-90Β° |
riseAzimuth |
Direzione dove appare | 0-360Β° |
setAzimuth |
Direzione dove scompare | 0-360Β° |
maxDistance |
Distanza nel punto piΓΉ vicino | km |
isVisible |
Effettivamente visibile a occhio nudo | true/false |
isSunlit |
Satellite illuminato dal sole | true/false |
visibility |
QualitΓ dell'osservazione | excellent/good/fair/poor |
observingCondition |
Condizioni di luce | night/twilight/daylight |
estimatedMagnitude |
LuminositΓ apparente | -4 a +6 |
satelliteAltitudeKm |
Altitudine orbitale | km |
durationSeconds |
Durata totale passaggio | secondi |
riseDirection |
Direzione cardinale rise | N/NE/E/SE/S/SW/W/NW |
setDirection |
Direzione cardinale set | N/NE/E/SE/S/SW/W/NW |
viewingTips |
Suggerimenti testuali | stringa |
Migliori condizioni:
- β
visibility: "excellent"o"good" - β
isVisible: true - β
observingCondition: "night" - β
maxElevation > 40Β° - β
estimatedMagnitude < 3
Condizioni discrete:
β οΈ visibility: "fair"β οΈ observingCondition: "twilight"β οΈ maxElevation 20-40Β°
Da evitare:
- β
visibility: "poor" - β
observingCondition: "daylight" - β
isVisible: false - β
maxElevation < 20Β°
# 1. Trova l'ID della ISS
curl http://localhost:8080/api/satellites | jq '.[] | select(.objectName | contains("ISS"))'
# 2. Calcola passaggi prossime 12 ore
curl "http://localhost:8080/api/satellites/1/passes?hours=12" | jq
# 3. Filtra solo passaggi ottimi (elevazione > 40Β°)
curl "http://localhost:8080/api/satellites/1/passes?hours=12" | jq '.[] | select(.maxElevation > 40)'
# 4. Ordina per magnitudine (piΓΉ luminosi)
curl "http://localhost:8080/api/satellites/1/passes?hours=12" | jq 'sort_by(.estimatedMagnitude)'curl "http://localhost:8080/api/satellites/1/passes?hours=72" | \
jq '[.[] | select(.visibility == "excellent")] | sort_by(.maxElevation) | reverse | .[0]'Risultato: Il passaggio con elevazione piΓΉ alta nei prossimi 3 giorni.
# Per ogni satellite, calcola passaggi e conta quanti sono visibili
for id in $(curl -s http://localhost:8080/api/satellites | jq '.[].id'); do
name=$(curl -s http://localhost:8080/api/satellites/$id | jq -r '.objectName')
visible=$(curl -s "http://localhost:8080/api/satellites/$id/passes?hours=24" | jq '[.[] | select(.isVisible == true)] | length')
echo "$name: $visible passaggi visibili"
donecurl "http://localhost:8080/api/satellites/1/passes/custom?lat=41.9&lon=12.5&alt=20&hours=24" | jq# Trova Starlink disponibili
curl http://localhost:8080/api/satellites | jq '.[] | select(.objectName | contains("STARLINK")) | {id, name: .objectName}'
# Calcola passaggi per uno specifico
curl "http://localhost:8080/api/satellites/42/passes?hours=24" | jq '.[] | select(.isVisible == true)'Modifica ObserverLocation.java:
public static ObserverLocation sanMarcellino() {
return new ObserverLocation(
45.46, // Latitudine Milano
9.19, // Longitudine Milano
120.0, // Altitudine
"Milano, Italia"
);
}In SatelliteScheduler.java:
@Scheduled(fixedRate = 21600000) // 6 ore in millisecondi
// Cambia in 3600000 per 1 ora, 43200000 per 12 ore, etc.In SatellitePassService.java:
if (pd.maxElevation > 10.0) { // Cambia 10.0 in altro valoreIn SatellitePassService.java:
double step = 60.0; // Secondi tra ogni calcolo
// 30.0 = piΓΉ preciso ma piΓΉ lento
// 120.0 = meno preciso ma piΓΉ veloceIn CelestrakService.java:
private static final String[] SATELLITE_GROUPS = {
"stations", // ISS, Tiangong
"starlink", // Tutti i Starlink
"planet", // Planet Labs
"science", // Hubble, JWST
"weather", // NOAA, GOES
"amateur" // Satelliti radioamatoriali
};Causa: Dati astronomici Orekit non scaricati correttamente.
Soluzione:
docker compose down -v
docker compose up --build --force-recreateCausa: Scheduler non Γ¨ partito o Celestrak non raggiungibile.
Soluzione:
# Verifica log
docker logs satellite-app
# Forza il download manualmente
curl -X POST http://localhost:8080/api/satellites/refreshPossibili cause:
- Satellite con inclinazione insufficiente per la tua latitudine
- Periodo di analisi troppo breve
- Parametri orbitali obsoleti
Soluzioni:
# Aumenta periodo
curl "http://localhost:8080/api/satellites/1/passes?hours=72"
# Verifica ultimo aggiornamento parametri
curl http://localhost:8080/api/satellites/1 | jq '.orbitalParameters[0].fetchedAt'
# Prova satellite diverso (ISS quasi sempre visibile)
curl "http://localhost:8080/api/satellites/1/passes?hours=24"Causa: TLE vecchi (perdono precisione dopo giorni/settimane).
Soluzione:
- Assicurati che lo scheduler stia aggiornando (ogni 6 ore)
- Verifica
fetchedAtrecente - Celestrak potrebbe essere temporaneamente down
Modifica docker-compose.yml:
ports:
- "9090:8080" # Usa porta 9090 esternaPoi accedi su http://localhost:9090
Prima build: Normale (scarica Orekit data ~50MB).
Build successivi: Usa cache Docker. Se sempre lento:
# Pulisci cache Maven
docker compose down
docker volume prune
docker compose up --build- Orekit Documentation
- SGP4 Model Explained
- TLE Format Specification
- Celestrak - Fonte dati TLE
- Heavens Above - Tracking satelliti online
- N2YO - Real-time satellite tracking
- ISS Tracker - NASA ISS notifications
- LatLong.net - Trova coordinate di qualsiasi luogo
- Google Maps - Click destro β coordinate
β
Tracciamento satelliti con dati TLE da Celestrak
β
Aggiornamento automatico ogni 6 ore
β
Calcoli orbitali precisi con SGP4 e Orekit
β
Calcolo passaggi visibili per qualsiasi posizione
β
Azimuth, elevazione, distanza, durata
β
Direzioni cardinali (N, NE, E, SE, S, SW, W, NW)
β
Calcolo illuminazione satellite (sunlit)
β
Condizioni di osservazione (night/twilight/daylight)
β
Stima magnitudine apparente
β
QualitΓ visibilitΓ (excellent/good/fair/poor)
β
Suggerimenti testuali per l'osservazione
β
Storico parametri orbitali
β
API REST completa
β
Containerizzazione Docker completa
β
Separazione dati Orekit in container dedicato
β
Nessuna duplicazione satelliti nel database
Progetto educational per tracking satelliti.
Stack:
- Java 21
- Spring Boot 4.0.3
- PostgreSQL 15
- Orekit 12.1
- Docker & Docker Compose
Struttura Progetto:
satelliteTracker/
βββ docker-compose.yml # Orchestrazione container
βββ orekit-data.Dockerfile # Container dati Orekit
βββ satelliteTracking/
β βββ Dockerfile # Container applicazione
β βββ pom.xml # Dipendenze Maven
β βββ src/main/java/com/satelliteTracking/
β βββ config/
β β βββ OrekitConfig.java
β βββ controller/
β β βββ SatelliteController.java
β βββ dto/
β β βββ SatellitePassDTO.java
β β βββ CelestrakSatelliteDTO.java
β βββ model/
β β βββ Satellite.java
β β βββ OrbitalParameters.java
β β βββ ObserverLocation.java
β βββ repository/
β β βββ SatelliteRepository.java
β β βββ OrbitalParametersRepository.java
β βββ scheduler/
β β βββ SatelliteScheduler.java
β βββ service/
β β βββ CelestrakService.java
β β βββ SatellitePassService.java
β βββ util/
β βββ TLEConverter.java
Buon tracking! π°οΈβ¨
Data: 22 Febbraio 2026
Versione: 2.0.0