Disclaimer - I'm practically not familiar with astronomy, only I went into orbit in Kerbal and somehow I managed to make a couple of orbital maneuvers. But the topic is interesting, so that even if I do not express myself correctly somewhere, Iām dirty.
All links are at the end of the article.
To be on the safe side, visibility is not just about seeing with the eye.
. , - . , . , . LEMUR-2 JOEL, 640 --, .
O3B FM8 8,000, Tierra del Fuego. . ( ) , ( , ).
?
( , )
, ( 2,000), ( Kerbal, , , - ), . . 20-30 . . 90 .
, Medium Earth Orbit ā , (GSO) (LEO). 10,000 30,000. 2000 8000 - Van Allen Belt ( ).
GPS . , ( ). 12 .
1 . 36,000. , . . . .
?
FPV , - . , , , .
, " ".
:
( , )
, :
ā "" "feed antenna". -. .
:
( ), . , , . .
, Skyfield . , . , .
, , . 90 , . 8 . ā 10 ā 2- , - . , , .
, , 45 . ā . , . 0 , 180 .
Skyfield Python, Python (3). , , .
:
pip3 install skyfield
:
index.py
import datetime
import time
from skyfield.api import load, Topos, EarthSatellite
:
TLE_FILE = "https://celestrak.com/NORAD/elements/active.txt" # DB file to download
ISS_NAME = "ISS (ZARYA)"
# Coordinats
# 57Ā°00'13.7"N 37Ā°02'53.7"E
# Kimrsky District, Tver Oblast, Russia
LONGITUDE = 57.003810
LATITUDE = 37.048262
:
class SatelliteObserver:
def __init__(self, where: Topos, what: EarthSatellite):
self.where = where
self.sat = what
self.sat_name = what.name
self.ts = load.timescale(builtin=True)
# ...
"" , (, ), EarthSatellite .
# ...
@classmethod
def from_strings(cls, longitude: str or float, latitude: str or float, sat_name: str, tle_file: str) -> 'SatelliteObserver':
place = Topos(latitude, longitude)
satellites = load.tle(tle_file)
print("loaded {} sats from {}".format(len(satellites), tle_file))
_sats_by_name = {sat.name: sat for sat in satellites.values()}
satellite = _sats_by_name[sat_name]
return cls(place, satellite)
# ...
Topos ( ).
, _sats_by_name[sat_name].
def altAzDist_at(self, at: float) -> (float, float, float):
"""
:param at: Unix time GMT (timestamp)
:return: (altitude, azimuth, distance)
"""
current_gmt = datetime.datetime.utcfromtimestamp(at)
current_ts = self.ts.utc(current_gmt.year, current_gmt.month, current_gmt.day, current_gmt.hour,
current_gmt.minute, current_gmt.second + current_gmt.microsecond / 1000000.0)
difference = self.sat - self.where
observer_to_sat = difference.at(current_ts)
altitude, azimuth, distance = observer_to_sat.altaz()
return (altitude.degrees, azimuth.degrees, distance.km)
, at .
def current_altAzDist(self) -> (float, float, float):
return self.altAzDist_at(time.mktime(time.gmtime()))
def above_horizon(self, at: float) -> bool:
"""
:param at: Unix time GMT
:return:
"""
(alt, az, dist) = self.altAzDist_at(at)
return alt > 0
current_altAzDist(self) ā , .
main :
def main():
iss = SatelliteObserver.from_strings(LONGITUDE, LATITUDE, ISS_NAME, TLE_FILE)
elevation, azimuth, distance = iss.current_altAzDist()
visible = "visible!" if elevation > 0 else "not visible =/"
print("ISS from latitude {}, longitude {}: azimuth {}, elevation {} ({})".format(LATITUDE, LONGITUDE, azimuth, elevation, visible))
if __name__ == "__main__":
main()
import datetime
import time
from skyfield.api import load, Topos, EarthSatellite
TLE_FILE = "https://celestrak.com/NORAD/elements/active.txt" # DB file to download
ISS_NAME = "ISS (ZARYA)"
# Coordinats
# 57Ā°00'13.7"N 37Ā°02'53.7"E
# Kimrsky District, Tver Oblast, Russia
LONGITUDE = 57.003810
LATITUDE = 37.048262
class SatelliteObserver:
def __init__(self, where: Topos, what: EarthSatellite):
self.where = where
self.sat = what
self.sat_name = what.name
self.ts = load.timescale(builtin=True)
@classmethod
def from_strings(cls, longitude: str or float, latitude: str or float, sat_name: str, tle_file: str) -> 'SatelliteObserver':
place = Topos(latitude, longitude)
satellites = load.tle(tle_file)
print("loaded {} sats from {}".format(len(satellites), tle_file))
_sats_by_name = {sat.name: sat for sat in satellites.values()}
satellite = _sats_by_name[sat_name]
return cls(place, satellite)
def altAzDist_at(self, at: float) -> (float, float, float):
"""
:param at: Unix time GMT (timestamp)
:return: (altitude, azimuth, distance)
"""
current_gmt = datetime.datetime.utcfromtimestamp(at)
current_ts = self.ts.utc(current_gmt.year, current_gmt.month, current_gmt.day, current_gmt.hour,
current_gmt.minute, current_gmt.second + current_gmt.microsecond / 1000000.0)
difference = self.sat - self.where
observer_to_sat = difference.at(current_ts)
altitude, azimuth, distance = observer_to_sat.altaz()
return (altitude.degrees, azimuth.degrees, distance.km)
def current_altAzDist(self) -> (float, float, float):
return self.altAzDist_at(time.mktime(time.gmtime()))
def above_horizon(self, at: float) -> bool:
"""
:param at: Unix time GMT
:return:
"""
(alt, az, dist) = self.altAzDist_at(at)
return alt > 0
def main():
iss = SatelliteObserver.from_strings(LONGITUDE, LATITUDE, ISS_NAME, TLE_FILE)
elevation, azimuth, distance = iss.current_altAzDist()
visible = "visible!" if elevation > 0 else "not visible =/"
print("ISS from latitude {}, longitude {}: azimuth {}, elevation {} ({})".format(LATITUDE, LONGITUDE, azimuth, elevation, visible))
if __name__ == "__main__":
main()
python3:
python3 index.py
ā
[#################################] 100% active.txt
loaded 6351 sats from https://celestrak.com/NORAD/elements/active.txt
ISS from latitude 37.048262, longitude 57.00381: azimuth 55.695482310974974, elevation 6.232187065056109 (visible!)
( ) (elevation), .
(visible!) ā !.. 6 . , 45.
. .
(https://celestrak.com/NORAD/elements/active.txt) , , .
.
UPD
, :
import datetime
import time
from skyfield.api import load, Topos, EarthSatellite
#
TLE_FILE = "https://celestrak.com/NORAD/elements/active.txt" # DB file to download
SAT_NAME = "ISS (ZARYA)"
#
satellites = load.tle(TLE_FILE)
#
print("loaded {} sats from {}".format(len(satellites), TLE_FILE))
_sats_by_name = {sat.name: sat for sat in satellites.values()}
satellite = _sats_by_name[SAT_NAME]
ts = load.timescale()
t = ts.now()
#
location = Topos('52.173141 N', '44.108612 E')
#
difference = satellite - location
topocentric = difference.at(t)
alt, az, distance = topocentric.altaz()
if alt.degrees > 0:
print('The ISS is above the horizon')
print(alt)
print(az)
print(int(distance.km), 'km')
.
:
import datetime
import time
from skyfield.api import load, Topos, EarthSatellite
TLE_FILE = "https://celestrak.com/NORAD/elements/active.txt" # DB file to download
MIN_DEGREE = 45
MIN_AZ = 50
MAX_AZ = 140
satellites = load.tle(TLE_FILE)
ts = load.timescale()
t = ts.now()
location = Topos('52.173141 N', '44.108612 E')
for sat in satellites.values():
difference = sat - location
topocentric = difference.at(t)
alt, az, distance = topocentric.altaz()
azValue = int(str(az).replace('deg', '').split(" ")[0])
if alt.degrees >= MIN_DEGREE and azValue >= MIN_AZ and azValue <= MAX_AZ:
print(sat.name, alt, az)
upd: tvr
upd: Fenja
upd: sandroDan
upd: dpytaylo
upd: extempl