This shows you the differences between two versions of the page.
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_ip, server_port) < 0) { | + | if (connect(gpsd, local_ip, local_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> | + | |