Warum sich die von Android erhaltene PRN von der von TLE berechneten unterscheidet

Ich möchte TLE-Daten verwenden, um den Azimut und die Höhe aller GPS-Satelliten am Standort des Benutzers zu berechnen.
Um die Korrektheit der TLE-Berechnung zu überprüfen, habe ich eine Android-App geschrieben, die über GPS positioniert werden kann und die Daten jedes Satelliten bei der Positionierung über die Android-API erhält.
Gleichzeitig werden Azimut und Elevation des Satelliten anhand von Pyephem und Benutzerposition, Ortungszeit und TLE-Daten berechnet, wenn die App ausgeführt wird.
Seltsamerweise unterscheiden sich die Ergebnisse meiner TLE-Datenberechnung von denen, die per App auf Telefonen erhalten wurden.
Das Folgende ist der spezifische Prozess:

Zuerst schreibe ich ein einfaches Android-Programm, verwende getPrn() , getAzimuth() , getElevation() , um Prn, Azimut und Höhe jedes Satelliten zu erhalten. Und erhalten Sie den GPS-Standort. Der Kerncode lautet wie folgt:

private final GpsStatus.Listener gpsStatusListener = new GpsStatus.Listener() {
    public void onGpsStatusChanged(int event) {
        GpsStatus status = mLocationManager.getGpsStatus(null);
        getGPSStatus(event, status);
    }
};

private void getGPSStatus(int event, GpsStatus status) {
    if (status == null) {
    } else if (event == GpsStatus.GPS_EVENT_SATELLITE_STATUS) {
        String detail = "";
        int maxSatellites = status.getMaxSatellites();
        Iterator<GpsSatellite> it = status.getSatellites().iterator();
        // numSatelliteList.clear();
        int count = 0;
        int goodcount = 0;
        mPrnStr = "";
        while (it.hasNext() && count <= maxSatellites) {
            GpsSatellite gpsSatellite = it.next();
            float elevation = gpsSatellite.getElevation();
            float azimuth = gpsSatellite.getAzimuth();
            int prn = gpsSatellite.getPrn();
            float snr = gpsSatellite.getSnr();
            int hasAlmanac = gpsSatellite.hasAlmanac() ? 1 : 0;
            int hasEphemeris = gpsSatellite.hasEphemeris() ? 1 : 0;
            int usedInFix = gpsSatellite.usedInFix() ? 1 : 0;
            if (usedInFix == 1) {
                goodcount++;
                mPrnStr += (prn + "|");
            }
            count++;
            detail = detail + String.format("%.5f:%.5f:%d:%.5f:%d:%d:%d|", elevation, azimuth, prn, snr, hasAlmanac,
                    hasEphemeris, usedInFix);
        }
        mGpsStar = String.format("%d-%d", goodcount, count);
        mGpsStarDetail = detail;
    }
}

Ich habe die APP auf meinem Handy ausgeführt und folgende Ergebnisse erhalten:

49.00000:185.00000:10:29.20000:1:1:1|33.00000:52.00000:12:42.30000:1:1:1|54.00000:312.00000:14:38.80000:1:0:1

Aus den Daten können wir ersehen, dass der Azimut des Satelliten mit PRN gleich 10 185° und die Elevation 49° beträgt.

Zweitens , wenn ich die App ausführe, ist das Ergebnis der GPS-Positionierung, dass 116.295953,40.050029,42.00(longitude,latitude,altitude)
ich Pyephem und TLE verwende, um Azimut und Höhe jedes Satelliten zu berechnen, wenn meine Position 116.295953,40.050029,42.00und Zeit ist 2018-11-9 18:30:30(dies ist die Zeit, in der ich die Android-App ausgeführt habe).
Der Code lautet wie folgt:

import ephem
me = ephem.Observer()
me.lon, me.lat, me.elevation = 116.295953,40.050029,42.00
line1 = 'GPS BIIF-11  (PRN 10)'
line2 = '1 41019U 15062A   18315.18162228  .00000031  00000-0  00000-0 0  9991'
line3 = '2 41019  55.1130 139.9366 0040562 201.4871 158.3788  2.00564661 22171'
sat = ephem.readtle(line1, line2, line3)
me.date = ephem.date((2018, 11, 9, 18, 30, 30))
sat.compute(me)
print sat.az * 180.0 / 3.1416
print sat.alt * 180.0 / 3.1416

Die Ausgabe dieses Codes ist:

24.5045833546
-19.6957760088

Da ich denselben Ort und dieselbe Zeit eingestellt habe, sollten die von TLE berechneten Ergebnisse den Ergebnissen ähneln, die ich von der Ausführung der Android-App erhalten habe. Aber im App-Ergebnis beträgt der Azimut und die Höhe von prn10: 185° und 49°. Im TLE-Ergebnis betragen der Azimut und die Höhe von prn10: 24,5045833546°, -19,6957760088°. Sie sind sehr unterschiedlich. Es ist komisch.

Bitte sagen Sie mir, wo das Problem liegt. Danke vielmals.

@AndyShan (versucht, Ihre Frage zu retten) - Sie fragen, warum der Azimut und die Höhe von Satelliten unterschiedlich sind, aber das von Ihnen gepostete Code-Snippet berechnet Az / Alt nur einmal, anscheinend mit PyEphem (wie Sie sagten) und zwei Zeilen, die ich schätze, sie kommen von TLE. Wer ist also anders als was? dh wenn Sie sat.az drucken, schätze ich, dass das Ergebnis Sie nicht zufrieden stellt, aber womit vergleichen Sie dieses Ergebnis?
@AndyShan es wäre auch gut, wenn der Code durch einfaches Kopieren/Einfügen lauffähig wäre, ohne etwas hinzufügen zu müssen. Fügen Sie also bitte am Anfang "import ephem" hinzu und auch den Code, woher lon, lat, ele und time kommen.
@BlueCoder Entschuldigung, die vorherige Beschreibung ist zu grob. Ich habe die Details erneuert und meinen Zweck erklärt. Der Python-Code ist lauffähig, aber der Android-Code ist nur ein Kernfragment. Ich habe den Code wiederholt debuggt und hatte das Gefühl, dass es kein Problem mit dem Programm gab. Ich frage mich also, ob sich der von TLE berechnete GPS-Azimut vom tatsächlichen Azimut des vom Benutzer gescannten Satelliten unterscheidet.
@uhoh Entschuldigung, ich habe meine Absichten nicht klar gesagt. Ich möchte keine spezifischen Programmierfragen stellen. Da ich mein Programm wiederholt debuggt habe, denke ich, dass es kein Problem mit dem Programm gibt. Ich frage mich, ob der von TLE berechnete GPS-Azimut vom tatsächlichen Azimut des Satelliten abweicht vom Benutzer gescannt.
@AndyShan Ich habe meine Stimme auf "oben" geändert und dafür gestimmt, Ihre schön bearbeitete Frage erneut zu öffnen. Danke und willkommen im Weltraum!
@AndyShan hier ist ein Lauf mit dem Python-Paket Skyfield , das von derselben Person geschrieben wurde, die PyEphem implementiert hat. pastebin.com/yHFaZuBw Ich habe meine Ergebnisse in den Kommentaren dort unten hinzugefügt. Es scheint anders als jede Ihrer Antworten zu sein, aber ich denke, dass PyEphem dieselbe Python-Implementierung von SGP4 (dem TLE-Propagator) wie Skyfield verwendet. Ich weiß nicht, wo das Problem liegt, aber behalte Dinge wie Längen- und Breitengrad im Auge, die vertauscht werden. Deshalb habe ich Topos()in meinem Skript benannte Argumente verwendet. Ich habe aus Spaß Subsat hinzugefügt. Viel Glück!
Ich ging zu in-the-sky.org/satmap_worldmap.php und gab den 9. November um 21:30 Uhr ein (ich bin Ostzeit) und fand GPS 10, das sich Kapstadt näherte. Nicht sicher, aber vielleicht kann diese Seite helfen.
@AndyShan schöne Bearbeitung! Ich habe dafür gestimmt, die Frage erneut zu öffnen :) Ein paar Fragen, um einige Daten zu überprüfen: 1) Ihr Beobachterstandort ist also sehr nahe an Peking, richtig? 2) Hast du die richtige Zeit eingegeben? Ich sehe hier, dass PyEphem wahrscheinlich die Weltzeit benötigt (und nicht die Zeit in der lokalen Zeitzone) [ rhodesmill.org/pyephem/quick.html#dates]
Meine Antwort: Anscheinend können (oder müssen?) Breiten- und Längengrade PyEphem als Zeichenfolgen bereitgestellt werden, wobei das Gradformat verwendet wird, dh Längengrad in Grad: 116: 17,75718 Breitengrad in Grad: 40: 3,00174, siehe rhodesmill.org/pyephem/ quick.html#observers Ich habe einige Tests durchgeführt und meine Ergebnisse mit PyEphem stimmten nur mit den Ergebnissen auf in-the-sky.org/… überein , als ich dieses Format verwendete. Außerdem habe ich die aktuelle Weltzeit verwendet, nicht meine lokale Zeitzone. Unter Verwendung dieses Formats und 10:30 als Zeit (statt 18:30) erhalte ich Az: 183,2 El: 38,5, was nahe an den Erwartungen liegt.
10:30 macht Sinn, da Peking GMT+8 ist, also würde man erwarten, dass man 8 Stunden abziehen muss, um UTC zu erhalten :) Tatsächlich ist es derzeit 10:32 UTC und in diesem Moment 18:32 in Peking: ) Das Ergebnis weicht immer noch von den erwarteten 185° / 49° ab, aber vielleicht war die Zeit ein paar Minuten früher oder später? (es könnte vielleicht eine Höhe von +11 ausmachen)
In der Tat kann ich 185 Az, 49 Elev erhalten, indem ich 10:08 als Beobachtungszeit angebe. Es folgt modifizierter Code (ich muss ihn in zwei Kommentare aufteilen und er wird hässlich aussehen, bis ich ihn als Antwort erneut posten kann) import ephem me = ephem.Observer() me.lon, me.lat, me.elevation = 116.295953,40.050029 ,42,00 Längengrad = '116:'+str(int(0.295953*60))+str((0.295953*60)%1)[1:] Breitengrad = '40:'+str(int(0.050029*60))+ str((0.050029*60)%1)[1:] print "Längengrad in Grad:", Längengrad, "Breitengrad in Grad:", Breitengrad me.lon = Längengrad me.lat = Breitengrad
line1 = 'GPS BIIF-11 (PRN 10)' line2 = '1 41019U 15062A 18315.18162228 .00000031 00000-0 00000-0 0 9991' line3 = '2 41019 55.1130 139.9366 0040562 201.4871 158.3788 2.00564661 22171' sat = ephem.readtle(line1 , line2, line3) me.date = ephem.date((2018, 11, 9, 10, 30, 30)) sat.compute(me) print sat.az * 180.0 / 3.1416 print sat.alt * 180.0 / 3.1416 me .date = ephem.date((2018, 11, 9, 10, 8, 30)) sat.compute(me) print sat.az * 180.0 / 3.1416 print sat.alt * 180.0 / 3.1416

Antworten (1)

Anscheinend können (oder müssen?) Breiten- und Längengrade PyEphem als Zeichenfolgen bereitgestellt werden, wobei das Grad:Minuten-Format verwendet wird, dh Längengrad: 116:17.75718, Breitengrad: 40:3.00174
Siehe rhodesmill.org/pyephem/quick.html#observers

PyEphem benötigt auch die Weltzeit (und nicht die Zeit in der lokalen Zeitzone)
Siehe rhodesmill.org/pyephem/quick.html#dates

Angesichts der Tatsache, dass 40 N, 116 E in der Nähe von Peking (GMT-8) liegt, vermutete ich, dass die korrekte UTC-Zeit 10:30 sein würde.

Durch die Verwendung des korrekten Längen-/Breitenformats und 10:30 UTC-Zeit erhalte ich Az: 183,2 El: 38,5, das nahe an den Erwartungen liegt.

Das Ergebnis ist immer noch anders als die erwarteten 185° / 49°, aber vielleicht war die Zeit früher oder später ein paar Minuten?

In der Tat kann ich 185 Az, 49 Elev erhalten, indem ich 10:08 als Beobachtungszeit angebe.

Mein Code folgt:

import ephem
me = ephem.Observer()
me.lon, me.lat, me.elevation = 116.295953,40.050029,42.00 
longitude = '116:'+str(int(0.295953*60))+str((0.295953*60)%1)[1:] 
latitude = '40:'+str(int(0.050029*60))+str((0.050029*60)%1)[1:]
print "Longitude in degrees:minutes format:", longitude
print "Latitude in degrees:minutes format:", latitude 
me.lon = longitude 
me.lat = latitude
line1 = 'GPS BIIF-11  (PRN 10)'
line2 = '1 41019U 15062A   18315.18162228  .00000031  00000-0  00000-0 0  9991'
line3 = '2 41019  55.1130 139.9366 0040562 201.4871 158.3788  2.00564661 22171'
sat = ephem.readtle(line1, line2, line3)


me.date = ephem.date((2018, 11, 9, 10, 30, 30)) 
sat.compute(me) 
print sat.az * 180.0 / 3.1416 
print sat.alt * 180.0 / 3.1416 

me.date = ephem.date((2018, 11, 9, 10, 8, 30)) 
sat.compute(me) 
print sat.az * 180.0 / 3.1416 
print sat.alt * 180.0 / 3.1416 

BEARBEITEN: Wenn Sie Lat/Lon als Zahlen anstelle von Zeichenfolgen angeben, werden sie als Bogenmaß interpretiert. Ihr vorhandener Code würde also funktionieren, wenn me.lon und me.lat in Grad konvertiert würden (geteilt durch 180, multipliziert mit 3,1416). Die Uhrzeit muss noch in UTC umgerechnet werden.

Hervorragende Detektivarbeit!
@BlueCoder Dies ist ein sehr wichtiges Projekt für mich. Gestern habe ich deine Antwort gesehen. Ich habe sofort festgestellt, dass Ihre Antwort die richtige Antwort auf diese Frage ist. Ich hatte keine Zeit, Ihnen zu danken, weil ich das Problem gelöst und mein Projekt abgeschlossen habe. Nun möchte ich Ihnen meinen herzlichen Dank für Ihre Geduld und großartige Arbeit aussprechen.
@AndyShan Gern geschehen! Dank dir weiß ich jetzt, wie man TLE und PyEphem benutzt :)