from skyfield.api import load, EarthSatellite
import numpy as np
import plotly.express as px
import pandas as pd
En esta entrada vamos a ver cómo se puede generar la trayectoria de un satélite artificial y representar gráficamente su paso sobre la superficie terrestre utilizando la librería gráfica Plotly, que nos permite generar mapas geográficos con mucha facilidad.
Para determinar la órbita y posición de un satélite artificial, se puede recurrir a descargar una descripción de sus parámetros en un momento determinado, conocida como TLE (Two Line Element). En este artículo veremos cómo obtener el TLE de un satélite y la manera de procesarlo utilizando la librería Skyfield
Para descargar el TLE de un satélite artificial, podemos acceder a la página de CelesTrak en el enlace "NORAD Two-Line Element Sets". Dirijámonos a la sección "Current Data > Space Stations" y copiemos el TLE de la Estación Espacial Internacional (ISS), el cual pegaremos en la siguiente celda (en realidad son tres líneas ya que la primera contiene simplemente el nombre del satélite):
ISS_TLE = '''ISS (ZARYA)
1 25544U 98067A 21103.84943184 .00000176 00000-0 11381-4 0 9990
2 25544 51.6434 300.9481 0002858 223.8443 263.8789 15.48881793278621
'''
Ahora crearemos un objeto satélite con la función EarthSatellite de la librería Skyfield
L0, L1, L2 = ISS_TLE.splitlines()
ISS = EarthSatellite(L1, L2, L0) # La línea conteniendo el nombre va en último lugar
ISS
<EarthSatellite ISS (ZARYA) catalog #25544 epoch 2021-04-13 20:23:11 UTC>
Un dato importante es el "epoch", o momento al cual se refiere este TLE, ya que los TLE se van actualizando con frecuencia para mantener una razonable exactitud.
print(ISS.epoch.utc_iso()) # Tiempo UTC en formato ISO
2021-04-13T20:23:11Z
Para crear un objeto Time de Skyfield hay que crear primero un objeto "timescale" y luego utilizar el método apropiado. Se puede crear un array de tiempos, como vemos en el ejemplo siguiente. Esto nos permitirá a continuación obtener un array de posiciones.
ts = load.timescale()
tiempos = ts.utc(2021, 4, 13, 0, np.arange(0,1000)) # Array de tiempos en minutos
A partir del array de tiempos, podemos generar un array de posiciones en forma de vectores referidos a las coordenadas geocéntricas, utilizando el método at()
posiciones = ISS.at(tiempos)
display(posiciones)
<Geocentric ICRS position and velocity at date t center=399 target=-125544>
Estas posiciones podemos obtenerlas en Km:
posiciones.position.km.shape
(3, 1000)
posiciones.position.km[:,0]
array([4667.69660275, 163.14840181, 4933.24756383])
Y de forma análoga, aunque no vamos a necesitarlo ahora, podemos obtener el vector velocidad en cada posición:
posiciones.velocity.km_per_s[:,3]
array([-3.6176679 , 6.66698085, 1.07131543])
Pero también podemos obtener las posiciones en coordenadas geográficas (longitud, latitud) bajo el satélite, lo cual nos va a ser útil para representar su trayectoria sobre la superficie terrestre:
sub = posiciones.subpoint()
A partir de dicho array podemos obtener longitudes, latitudes y alturas (estas últimas no las utilizaremos en este ejemplo), por ejemplo en unidades de grados y km.:
long = sub.longitude.degrees
lat = sub.latitude.degrees
altura = sub.elevation.km
Y representar las posiciones sobre la superficie terrestre mediante Plotly:
px.line_geo(lat=lat, lon=long)
px.line_geo(lat=lat, lon=long,projection="orthographic", width=400, height=400)
Obsérvese que los gráficos producidos con Plotly son interactivos, sobre los cuales es posible desplazar el cursor para obtener información de las coordenadas geográficas de los puntos de paso de la Estación Espacial. Puede ser útil que la información proporcionada por la posición del cursor nos indique también el instante de tiempo al que corresponde la posición. Para ello crearemos un dataframe de Pandas con todos los datos: latitud, longitud y tiempo, y en la llamada a la función de Plotly simplemente indicaremos el nombre de las columnas.
datos = {"lat":lat, "lon":long, "t":tiempos.utc_strftime('%Y-%m-%d %H:%M')}
df = pd.DataFrame(datos)
px.line_geo(df, lat='lat', lon='lon', hover_data='t', title='Trayectoria terrestre ISS')
No hay comentarios:
Publicar un comentario