Wir zielen und kommunizieren mit Satelliten: Teil eins - programmgesteuertes Zielen



Haftungsausschluss - Ich bin praktisch nicht mit Astronomie vertraut, nur ich bin in Kerbal in die Umlaufbahn gegangen und habe es irgendwie geschafft, ein paar Umlaufmanöver durchzuführen. Aber das Thema ist interessant, so dass ich schmutzig bin, auch wenn ich mich irgendwo nicht richtig ausdrücke.



Alle Links befinden sich am Ende des Artikels.



Um auf der sicheren Seite zu sein, geht es bei der Sichtbarkeit nicht nur darum, mit dem Auge zu sehen.



, , . , . . — , .





.





. , - . , . , . LEMUR-2 JOEL, 640 --, .

O3B FM8 8,000, Tierra del Fuego. . ( ) , ( , ).





?





( , )



. 3- (LEO), (MEO), (GSO).



, ( 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- , - . , , .



, (altitude) elevation.

.





, , 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





https://nyan-sat.com/chapter0.html








All Articles