Forum: Mikrocontroller und Digitale Elektronik GPS-Shield-Auswertung über LoraWan und Cayenne


You were forwarded to this site from EmbDev.net. Back to EmbDev.net
von BlaBla (Gast)


Lesenswert?

Hallo,

ich arbeitet mich gerade in Lora und LoraWan ein. Dazu habe ich hier ein 
Dragino Lora IoT Kit V2 zum Einarbeiten. Ich habe es geschafft, die 
etwas ältere Kit-Version ins TTN V3 (TTS) zu überführen. Alles läuft bis 
auf das GPS, das zeigt meinen Standort nicht korrekt auf der Cayenne-Map 
an. Die Anzeige ist ungefähr 1-2 km Richtung Nordost verschoben.

Ich versuch nun die mit gelieferte Software 
(GPS_shield_cayenne_and_ttn-otaaClient.ino) zum Kit zu verstehen, da ich 
hier einen Fehler in der Berechnung vermutet. Die Koordinaten aus dem 
GPS-Modul stimmen mit meinem Standort überein. Das Modul beispielweise 
liefert 5126.1234 N und 01220.1234 E.

Jetzt bin ich über die folgenden Programmzeilen gestolpert, die nicht 
verstehe:
1
void GPSRead()
2
{
3
  unsigned long age;
4
  gps.f_get_position(&flat, &flon, &age);
5
  falt=gps.f_altitude();  //get altitude       
6
  flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6;//save six decimal places 
7
  flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6;
8
  falt == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : falt, 2;//save two decimal places
9
  if((flon < 72.004 || flon > 137.8347)&&(flat < 0.8293 || flat >55.8271))  //out of China
10
  {
11
    longitude=flon;
12
    latitude=flat;
13
  // Serial.println("Out of China");
14
  }
15
  else
16
  {
17
    WGS2GCJTransform(flon,flat,longitude,latitude);
18
   //Serial.println("In China");
19
  }
20
  int32_t lat = latitude * 10000;
21
  int32_t lon = longitude * 10000;
22
  int32_t alt = falt * 100;
23
24
  mydata[2] = lat >> 16;
25
  mydata[3] = lat >> 8;
26
  mydata[4] = lat;
27
  mydata[5] = lon >> 16;
28
  mydata[6] = lon >> 8;
29
  mydata[7] = lon;
30
  mydata[8] = alt >> 16;
31
  mydata[9] = alt >> 8;
32
  mydata[10] = alt;  
33
}

Was machen diese drei Zeilen. Der Bedingungsoperator "?" ist mir 
bekannt. Aber was machen "flon ==" und "flon, 6". Diese Schreibweise ist 
mir unbekannt. "TinyGPS::GPS_INVALID_F_ANGLE" liefert im Fehlerfall 
1000.0 zurück.
1
  flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6;//save six decimal places 
2
  flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6;
3
  falt == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : falt, 2;//save two decimal places

Wäre für Hilfe sehr dankbar!

von Wolfgang (Gast)


Lesenswert?

BlaBla schrieb:
> Das Modul beispielweise liefert 5126.1234 N und 01220.1234 E.

Das sind bestimmt nicht die Koordinaten als float, sondern die Strings 
für Länge und Breite aus dem NMEA-Datensatz des GPS-Moduls.

> WGS2GCJTransform(flon,flat,longitude,latitude);

Das ist der Aufruf einer Umrechnungsfunktion. Bevor du dich über 
Ergebnisse wunderst, solltest du dir anhand der Dokumentation zu der 
Library klar machen, was die tut.

> Aber was machen "flon =="
Das ist Teil der Bedingung, die vom Bedingungsoperator ausgewertet wird.

Die Bedingung lautet
1
flon == TinyGPS::GPS_INVALID_F_ANGLE

von Wolfgang (Gast)


Lesenswert?

BlaBla schrieb:
> Das Modul beispielweise liefert 5126.1234 N und 01220.1234 E.

Hoffentlich bist du passend gekleidet. Auf dem Wasser ist es schon ganz 
schön frisch. Bist du sicher, dass dein Modul das liefert?

> Die Anzeige ist ungefähr 1-2 km Richtung Nordost verschoben.
Dann stell das bitte mal genauer fest. Vielleicht hast du irgendwo das 
Kartendatum falsch konfiguriert.

von Frank K. (frank)


Lesenswert?

1
Serial.println(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6);
2
Serial.println(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6);
3
Serial.println(falt == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : falt, 2);

fällt mir dazu ein. Gibt der Compiler Warnungen zu den betreffenden 
Zeilen aus?

von BlaBla (Gast)


Angehängte Dateien:

Lesenswert?

Frank K. schrieb:
> Serial.println(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6);
> Serial.println(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6);
> Serial.println(falt == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : falt, 2);

> fällt mir dazu ein. Gibt der Compiler Warnungen zu den betreffenden
> Zeilen aus?

In der Tat, im AtmelStudio 7 konnte ich die Warnungen sehen. Da hat der 
Entwickler einfach Serial.println unterschlagen. Jetzt macht das ",6" 
auch Sinn.

Wolfgang schrieb:
>> Das Modul beispielweise liefert 5126.1234 N und 01220.1234 E.
>
> Hoffentlich bist du passend gekleidet. Auf dem Wasser ist es schon ganz
> schön frisch. Bist du sicher, dass dein Modul das liefert?

Das sind natürlich nur fiktive Koordinaten ;-)

Wolfgang schrieb:
>> WGS2GCJTransform(flon,flat,longitude,latitude);

Diese Funktion wird aus Deutschland nicht ausgeführt.
----------------------------------------------------
Danke, da bin ich ein Stück weiter. Jetzt nur noch die falschen 
Koordinaten finden.

von Wolfgang (Gast)


Lesenswert?

BlaBla schrieb:
> Danke, da bin ich ein Stück weiter. Jetzt nur noch die falschen
> Koordinaten finden.

Deshalb die Frage nach dem Kartendatum.

von STK500-Besitzer (Gast)


Lesenswert?

Wolfgang schrieb:
> Deshalb die Frage nach dem Kartendatum.

In NMEA werden die Koordinaten in Grad, -Minuten und -Sekunden 
angegeben.
Das muss man je nach KIartendarstellung in Dezimalgrad umrechnen.
Die WGS-Funktion optimiert die Erde auf eine "richtige" Sphäre.

von Wolfgang (Gast)


Lesenswert?

STK500-Besitzer schrieb:
> In NMEA werden die Koordinaten in Grad, -Minuten und -Sekunden
> angegeben.

Nein, lies dir die Definition der NMEA-Datensätze nochmal genau durch.
NMEA verwendet Grad und Dezimalminuten.

> Das muss man je nach KIartendarstellung in Dezimalgrad umrechnen.

Darum geht es nicht. Je nach Kartendatum ergeben sich auf der 
Erdoberfläche für identische Koordinatenangaben Abweichungen der 
geographischen Position von bis zu 2 km. Das liegt an der Abweichung der 
Form der Erde von einer Kugelform.

von Wolfgang (Gast)


Lesenswert?

p.s.

STK500-Besitzer schrieb:
> Die WGS-Funktion optimiert die Erde auf eine "richtige" Sphäre.

Nein, keine Sphäre (aka Kugel).

WGS-84 ist ein Ellipsoid mit einer großen Halbachse von 6378,137km und 
einer Abplattung von etwa 1:298,257

von BlaBla (Gast)


Lesenswert?

Der Quectel L80 ist default auf WGS84 eingestellt. Die Koordinaten 
werden in der Form Grad×100+Dezimalminuten gesendet. Die empfangenen 
Werte habe ich händisch in die Form Grad,Minuten und Dezimalsekunden 
umgerechnet. Google Earth zeigt mir dann auch den richtigen Standort an. 
Ich verwende die Library TinyGPS und vermute den Fehler in dem 
Arduino-Programm.

von Wolfgang (Gast)


Lesenswert?

BlaBla schrieb:
> Ich verwende die Library TinyGPS und vermute den Fehler in dem
> Arduino-Programm.

TinyGPS ist 8 Jahre alt und du bist sicher nicht der einzige, der das 
verwendet. Ein Fehler wäre vermutlich schon mal aufgefallen.
Verfolge die Umrechnungen und prüfe, wo ein von dir nicht erwartetes 
Zwischenergebnis entsteht.

von BlaBla (Gast)


Lesenswert?

Hallo Wolfgang, der Fehler könnte im Arduino-Programm liegen. Das 
rechnet in Dezimalgrad und so kommt es auch aus TinyGPS. Bis hier 
scheint alles korrekt zu sein. Dann kommt aber die Datenübergabe an 
LoraWan und Cayenne. Und Cayenne scheint die Daten im Format Grad, 
Minuten und Sekunden zu erwarten. Das muss ich aber noch überprüfen.

von Wolfgang (Gast)


Lesenswert?

BlaBla schrieb:
> Und Cayenne scheint die Daten im Format Grad,
> Minuten und Sekunden zu erwarten. Das muss ich aber noch überprüfen.

Gute Idee.

Falls es am Datenformat liegt, kann es aber nicht sein, dass eine fest 
Verschiebung von 1-2 km nach Nordosten entsteht. Bei Problemen mit dem 
Format müsste der Fehler abhängig von der Position sein.

von BlaBla (Gast)


Lesenswert?

Habe jetzt wieder zeitgefunden an dem Projekt weiterzumachen.

Jetzt bin ich über einige Zeilen im originalen Dragino-Quellcode zum 
Projekt gestolpert. Was machen diese u.a. Zeilen? Die Funktionsweise ist 
mir aus C nicht bekannt. TinyGPS::GPS_INVALID_F_ANGLE enthält eine 
Konstante: "1000.0".
Findet hier überhaupt eine formatierte Zuweisung (flat, 6) statt?
Der Compiler läuft fehlerfrei durch. Der Bedingungsoperator "?:" ist mir 
bekannt.
1
float flat, flon;
2
...
3
    flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6;          
4
    flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6;

Ausschnitt aus:
https://github.com/dragino/Lora/blob/master/Lora%20GPS%20Shield/Examples/Lora%20GPS%20Tracker/Client/Client.ino

von BlaBla (Gast)


Lesenswert?

Schade, hat keiner eine Idee?

von BlaBla (Gast)


Lesenswert?

BlaBla schrieb:
1
 float flat, flon;
2
     flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6;
3
     flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6;
Hat denn keiner der C-Profis eine Idee, ob die Syntax der beiden Zeile 
überhaupt funktionieren kann?
Der Inhalt der Variablen und Konstanten ist erstmal egal.

von Stephan (Gast)


Lesenswert?

Ich habe keine Ahnung von dem Arduino-Zeug, aber wage trotzdem eine 
Vermutung:
Kann das „flon, 6“ eine Angabe der maximalen Nachkommastellen bei der 
Zuweisung sein?

Beim Serial.print() gibt es lt Doku einen derartigen optionalen 
Parameter:
Serial.print(1.23456, 2) gives "1.23"

Ob das aber generell ein float ‚Feature‘ ist? k.A.
Im einfachsten Fall denkt sich der Compiler seinen Teil und ignoriert 
das „,6“…
Aber das kannst Du ja selbst im Arduino-Umfeld ausprobieren.

von Stephan (Gast)


Lesenswert?

… aber das steht ja in dem Thread schon alles… sorry, was antworte ich 
eigentlich…
Was genau ist jetzt noch Deine Frage??

von BlaBla (Gast)


Lesenswert?

Vielen Dank Stephan für deine Antwort. Gedacht habe ich mir das auch, 
aber wo ist die Zuweisung zu einer Variablen. Ich sehe nur einen 
Vergleich "==". Der Teil hat nicht direkt etwas mit Arduino zu tun, 
sondern ist "reines" C bzw C++. Jedenfalls marschiert der Compiler 
gnadenlos darüber hinweg. Ist schon merkwürdig, dass da nicht gemerkt 
wird. Leider haben meine Recherchen in diversen Büchern und im Internet 
nichts ergeben. Dein Hinweis zu "Serial.print(x,y)" passt hier leider 
nicht ganz. Die Funktion ist überladen.

Staune, dass darüber noch keiner, in einer so alten Library, gestolpert 
ist.

von BlaBla (Gast)


Lesenswert?

Ist natürliche keine Library sondern ein Sketch (Programm). Trotzdem 
enthält die TinyGPS-Lib auch noch seltsame Dinge. Das ist aber ein 
anderes Thema.

von Stephan (Gast)


Lesenswert?

1.)
>Dein Hinweis zu "Serial.print(x,y)" passt hier leider nicht ganz.
Doch ;) denn nach nochmaliger Beschäftigung mit dem gesamten Thread 
vermnute ich, dass die beiden Zeilen:
1
flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6;
2
flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6;
schlicht Überreste eines alten Codefragments mit ss.printf (siehe Zeilen 
75 & 77 aus dem Origial-Code) ist.

2.)
[ich schrieb]>Ob das aber generell ein float ‚Feature‘ ist? k.A.
Sicher nicht; ein:
1
float baa = 1.123456789;
2
float foo == baa, 6;
ist definitiv in C++ Quatsch - der Arduino-Umgebung hätte ich noch 
zugetraut, sowas zu unterstützen ;)

3.)
Das der Code aus (1) niemand angemeckert hat UND auch Deinen Compiler 
nicht stört, liegt schlicht daran, dass ein C++ Compiler die ganze Zeile
1
foo == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : baa, 6;
als "expression has no effect" erkennt und ignoriert.
Interessanterweise macht aber weder:
1
foo == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : baa, 6;
noch
1
foo == GPS_INVALID_F_ANGLE ? 0.0 : baa, 6, 8, 9, 42;
einen Syntaxfehler. Mein C++ Compiler prüft das offenbar auch nur kurz 
auf "kann klappen" - optimiert die Zeile dann aber eben wg "has no 
effect" sowieso komplett weg.

Fazit:
Die beiden Zeilen kannst Du auch auskommentieren.
Hat im Ergebnis den selben Effekt.
Der Inhalt von flat/flon kommt ja aus:
1
gps.f_get_position(&flat, &flon, &age);
Der Rest ist nur Demo/Debug für die Example-Client Implementierung.

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Stephan schrieb:
> Ich habe keine Ahnung von dem Arduino-Zeug, aber wage trotzdem eine

Kein Problem. Arduino ist nichts magisches. Arduino ist auch nur C++. 
Das ist kein eigener Dialekt. Das was Arduino ausmacht, steckt in den 
vorgefertigten Bibliotheken.
1
float flat, flon;
2
flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6;
3
flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6;
Das ist jedenfalls Quatsch und sollte ein Compiler auch als Quatsch 
abweisen. Vielleicht mal alle Warnungen einschalten.

von BlaBla (Gast)


Lesenswert?

Vielen Dank, für die ausführlichen Antworten und Mühen. Ich werde den 
ganzen Sketch mal überarbeiten und die TinyGPS-Library gleich mit 
entrümpeln. Denn die Positionsdaten von dort sind ungenau. Liegt 
eventuell an den Restriktionen der chinesischen Gesetzgebung, die genaue 
Positionsangaben in China unter Strafe stellen. Die diversen GPS-Module 
liefern jedenfalls korrekte native Daten. In der TinyGPS++ sind meines 
Erachtens ähnliche Verschleierungsalgorithmen eingebaut. Habe ich aber 
bisher nur dem Quelltext entnommen und noch nicht an der Hardware 
überprüft.

von Wolfgang (Gast)


Lesenswert?

BlaBla schrieb:
> Denn die Positionsdaten von dort sind ungenau.
Statt irgendwelche Behauptungen aufzustellen, solltest du ein paar 
Fakten nennen, z.B. Beispieldaten (Raw, TinyGPS-Output). Oft steckt das 
Problem zwischen Stuhl und Monitor ;-)

> Liegt eventuell an den Restriktionen der chinesischen Gesetzgebung, die
> genaue Positionsangaben in China unter Strafe stellen. ...
> In der TinyGPS++ sind meines Erachtens ähnliche Verschleierungsalgorithmen
> eingebaut.

Leidest du an Verfolgungswahn?

von BlaBla (Gast)


Lesenswert?

Wolfgang schrieb:
> BlaBla schrieb:
>> Denn die Positionsdaten von dort sind ungenau.
> Statt irgendwelche Behauptungen aufzustellen, solltest du ein paar
> Fakten nennen, z.B. Beispieldaten (Raw, TinyGPS-Output). Oft steckt das
> Problem zwischen Stuhl und Monitor ;-)
>
>> Liegt eventuell an den Restriktionen der chinesischen Gesetzgebung, die
>> genaue Positionsangaben in China unter Strafe stellen. ...
>> In der TinyGPS++ sind meines Erachtens ähnliche Verschleierungsalgorithmen
>> eingebaut.
>
> Leidest du an Verfolgungswahn?

Warum wirst du unhöflich. Ich bin jetzt etwas durch die obigen Antworten 
weitergekommen. Der Positionsfehler zu Cayenne besteht immer noch und 
das interessiert mich. Und nein, ich leide nicht und Verfolgungswahn 
sondern unter dämlichen Antworten.

von Wolfgang (Gast)


Lesenswert?

BlaBla schrieb:
> Warum wirst du unhöflich.

Du beklagst dich über angebliche Positionsfehler/-verfälschungen und 
lieferst keine Fakten dazu, nur Verschwörungstheorien. Gehe systematisch 
vor:
1. NMEA Rohdaten vom Modul
2. Tiny-GPS Koordinaten (Latitude, Longitude)
3. Transformation WGS84 -> GCJ-02

Ich frage mich allerdings, was du überhaupt mit den Koordinaten im 
chinesiches GCJ-02 vorhast und womit genau du die vergleichst?

von BlaBla (Gast)


Lesenswert?

Wolfgang schrieb:
> Du beklagst dich über angebliche Positionsfehler/-verfälschungen und
> lieferst keine Fakten dazu, nur Verschwörungstheorien. Gehe systematisch
> vor:
> 1. NMEA Rohdaten vom Modul
> 2. Tiny-GPS Koordinaten (Latitude, Longitude)
> 3. Transformation WGS84 -> GCJ-02
>
> Ich frage mich allerdings, was du überhaupt mit den Koordinaten im
> chinesiches GCJ-02 vorhast und womit genau du die vergleichst?

Wolfgang halt dich hier raus. Nur dummes Zeug.

Der Fehler liegt in der (siehe Eingangspost) genannten Datei. Die 
folgende Zeile muss geändert werden:
1
if ((flon < 72.004 || flon > 137.8347) && (flat < 0.8293 || flat > 55.8271))  //out of China?

in
1
if (!((flon < 72.004 || flon > 137.8347) && (flat < 0.8293 || flat > 55.8271)))  //out of China?

Ob die Umrechnung für China von "World Geodetic System" in das "Mars 
Geodetic System" richtig ist, kann ich nicht beurteilen.
Für Deutschland passt es jedenfalls. Die TinyGPS-Library arbeitet meiner 
Einschätzung nach richtig.

von Wolfgang (Gast)


Lesenswert?

BlaBla schrieb:
> Der Fehler liegt in der (siehe Eingangspost) genannten Datei. Die
> folgende Zeile muss geändert werden:
> if ((flon < 72.004 || flon > 137.8347) && (flat < 0.8293 || flat >
> 55.8271))  //out of China?
>
> in
> if (!((flon < 72.004 || flon > 137.8347) && (flat < 0.8293 || flat >
> 55.8271)))  //out of China?

Mit deiner Änderung schaltest du die Transformation auf GCJ-02 für den 
Rest der Welt außerhalb des chinesischen Rechtecks EIN, du Experte.

von BlaBla (Gast)


Lesenswert?

Wolfgang schrieb:
> Mit deiner Änderung schaltest du die Transformation auf GCJ-02 für den
> Rest der Welt außerhalb des chinesischen Rechtecks EIN, du Experte.

Ach ja. Halt dich doch einfach zurück. Du bist doch nur unfreundlich.
Komisch, dass es jetzt geht und der Rest der Welt interessiert mich 
nicht.

von Wolfgang (Gast)


Lesenswert?

BlaBla schrieb:
> Komisch, dass es jetzt geht ...

Dann geh mal von dir aus ein Stück nach Norden, z.B. nach 56°N.
Da geht es dann plötzlich nicht mehr.

Besser muss die Zeile
1
if ((flon < 72.004 || flon > 137.8347) && (flat < 0.8293 || flat > 55.8271))  //out of China?

geändert werden in
1
if (flon < 72.004 || flon > 137.8347 || flat < 0.8293 || flat > 55.8271)  //out of China?
Dann klappt es auch auf 56°N

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.