Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
sdk:gps-udp-client-gnsstogps [2019/07/08 13:41]
fachet created
sdk:gps-udp-client-gnsstogps [2021/10/08 10:22] (current)
dodenhoeft [SDK Script gps-udp-client-GNSStoGPS.are]
Line 1: Line 1:
 +====== Background ======
 +GPS was the first Global Navigation Satellite System (GNSS) and the term GPS is often used as a synonym for GNSS.
 +
 +Older software often only checks for NMEA 0183 sentences starting with <​nowiki>"​$GP"</​nowiki>​ (= GPS only) instead of looking for  all GNSS systems.
 +
 +Newer GNSS receivers often use multiple GNSS systems and therefore <​nowiki>"​$GN"</​nowiki>​ is used (<​nowiki>"​$GNRMC..."</​nowiki>​) if it recives a combination of GPS, Galileo and GLONASS signals.
 +
 +It would be better to us instead of <​nowiki>"​$GPRMC"</​nowiki>​ either <​nowiki>"​$G.RMC"</​nowiki>​ ("​."​ = anychar) for using GPS, Galileo and/or GLONASS (GNSS) or even <​nowiki>"​$..RMC"</​nowiki>​ which means any source.
 +
 +<​code>​
 +NMEA 0183 sentence "​$XXYYY..."​ explanation:​
 +
 +"​$"​ = Start 
 +"​XX"​ = Source device (https://​de.wikipedia.org/​wiki/​NMEA_0183#​Ger%C3%A4te-IDs)
 + BD = Beidu
 + GA = Galileo
 + GL = GLONASS
 + GP = GPS
 + GN = GNSS position fix from more than one constellation (eg. GPS + GLONASS)
 +"​YYY"​ = Record
 + RMC = Recommended Minimum Sentence C (used in most cases)
 + GGA = Global Positioning System Fix Data
 + GNS = GNSS fixed data
 + GLL = Geographic Position - Latitude/​Longitude
 + ...
 +
 +Source: https://​de.wikipedia.org/​wiki/​NMEA_0183
 +</​code>​
 +
 ====== SDK Script gps-udp-client-GNSStoGPS.are ====== ====== SDK Script gps-udp-client-GNSStoGPS.are ======
-<code c gps-udp-client-gnstogps.are>+<code c gps-udp-client-gnsstogps.are>
 /* DESC: This script sends the local GPS NMEA stream to a remote UDP server. /* DESC: This script sends the local GPS NMEA stream to a remote UDP server.
 * DESC: It checks for the correct CR/LF end of line characters and convert messages $GN to $GP  * DESC: It checks for the correct CR/LF end of line characters and convert messages $GN to $GP 
Line 7: Line 36:
  
 /* default values */ /* default values */
-server_ip ​= "​127.0.0.1";​ +local_ip ​= "​127.0.0.1";​ 
-server_port ​= 2947; /* would be better to take it from the configuaration */+local_port ​= 2947; /* would be better to take it from the configuaration */
  
 gpsd = -1; gpsd = -1;
Line 23: Line 52:
  
  nb_config_set("​gpsd.0.status=0"​);​  nb_config_set("​gpsd.0.status=0"​);​
- sleep(3);+                do { 
 +                                ​sleep(3); 
 +                } while ( nb_config_done() != 0) 
 +     
  nb_config_set("​gpsd.0.status=1"​);​  nb_config_set("​gpsd.0.status=1"​);​
- sleep(5); +                do { 
 +                 ​sleep(5); 
 +                } while ( nb_config_done() != 0)
  return 0;  return 0;
 } }
- 
 int gpsd_connect () int gpsd_connect ()
 { {
Line 39: Line 71:
  exit(-1);  exit(-1);
  }  }
- for (attempt = 0; attempt <= 5; attempt++) { + for (attempt = 0; attempt <= 15; attempt++) { 
- sleep(3);+ sleep(15);
  
- if (connect(gpsd, ​server_ipserver_port) < 0) {+ if (connect(gpsd, ​local_iplocal_port) < 0) {
  nb_syslog("​Could not connect to daemon"​);​  nb_syslog("​Could not connect to daemon"​);​
- + if (attempt == 12) {
- if (attempt == 3) {+
  nb_syslog("​Unable to connect, restarting daemon"​);​  nb_syslog("​Unable to connect, restarting daemon"​);​
  gpsd_restart();​  gpsd_restart();​
Line 54: Line 85:
  }  }
  nb_syslog("​Connected to daemon, requesting NMEA"​);​  nb_syslog("​Connected to daemon, requesting NMEA"​);​
- send(gpsd,"​R=1\n"​);​+ send(gpsd, "​R=1\n"​);​
  
  nb_syslog("​Processing NMEA"​);​  nb_syslog("​Processing NMEA"​);​
  
  return gpsd;  return gpsd;
 +}
 +
 +string checksum(string s)
 +{
 + pos = strchr(s, "​*"​);​
 +
 +  if (is_void(pos))
 + return s; /* no checksum to correct */
 +
 + cs = 0;
 + chars = explode(s);
 +        for (i = 1; i < pos; i++) { /* skip $ and *XX */ 
 +     c = ord(chars[i]);​
 +            cs ^= c;
 +        }
 +        r = sprintf("​%s%02X%s",​ substr(s, 0, pos + 1), cs, substr(s, pos + 3));
 + return r;
 } }
  
 /* main() */ /* main() */
  
-if(argc ​> 0) { +if (argc 2) { 
- server_ip = trim((string) argv[1]); +    usage();
-+
-if(argc > 1) { +
- server_port = (int) argv[2]; +
-+
-if(argc > 2) { +
- usage();+
 } }
 +
 +SERVER = trim((string) argv[1]);
 +PORT = (int) argv[2];
  
 /* open UDP server socket */ /* open UDP server socket */
 server = socket(AF_INET,​ SOCK_DGRAM, IPPROTO_UDP);​ server = socket(AF_INET,​ SOCK_DGRAM, IPPROTO_UDP);​
-if(server < 0) {+if (server < 0) {
  nb_syslog("​Unable to open socket"​);​  nb_syslog("​Unable to open socket"​);​
  exit(-1);  exit(-1);
Line 109: Line 154:
  data = recv(gpsd);  data = recv(gpsd);
  len = strlen(data);​  len = strlen(data);​
-  
  /* Check for correct framing: CR+LF */  /* Check for correct framing: CR+LF */
  if(len > 2) {  if(len > 2) {
Line 128: Line 172:
  }  }
  /* Convert message $GN to $GP for backward compatibility */  /* Convert message $GN to $GP for backward compatibility */
- if(strstr(data,"​$GN"​) == 0) {+ if(strstr(data,​ "​$GN"​) == 0) {;
  a_arr = explode(data);​  a_arr = explode(data);​
  a_arr[2] = "​P";​  a_arr[2] = "​P";​
- data = implode(a_arr);​+ data = checksum(implode(a_arr));
  }  }
- 
  /* skip all messages different from GPGGA   /* skip all messages different from GPGGA 
  * if(strstr(data,"​$GPGGA"​)==())  * if(strstr(data,"​$GPGGA"​)==())
Line 150: Line 193:
  close(server);​  close(server);​
 } }
-exit(-1); +exit(-1);</​code>​
- +
-</​code>​+