I am writing a number-crunching data-logging C program for my GPS enabled Raspberry Pi. I grabbed gpsd, and its sample app cgps displays gps information correctly. I wanted to use libgps to interface with the daemon so that I could have all that handy information in my app, but I was quickly overwhelmed by the complexity of its API.
The documentation on its HOWTO page points me to look at cgps and gpxlogger for example code, but there's so much coupling that I can't wade through it all. On the opposite end of the spectrum, the C code example on the libgps page is so stripped back that it's unusable.
Can anybody point me to a single class sample that might demystify this? Perhaps something that contains a getCoordinates()
function?
I spoke too soon. After browsing other SO questions, I ran into this completely unrelated question. Here's my very slightly modified version:
#include <gps.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <errno.h>
int main() {
struct timeval tv;
struct gps_data_t gps_data;
if ((gps_open("localhost", "2947", &gps_data)) == -1) {
printf("code: %d, reason: %s\n", errno, gps_errstr(errno));
return EXIT_FAILURE;
}
gps_stream(&gps_data, WATCH_ENABLE | WATCH_JSON, NULL);
while (1) {
/* wait for 2 seconds to receive data */
if (gps_waiting (&gps_data, 2000000)) {
/* read data */
if ((gps_read(&gps_data,NULL,0)) == -1) {
printf("error occured reading gps data. code: %d, reason: %s\n", errno, gps_errstr(errno));
} else {
/* Display data from the GPS receiver. */
if ((gps_data.status == STATUS_FIX) &&
(gps_data.fix.mode == MODE_2D || gps_data.fix.mode == MODE_3D) &&
!isnan(gps_data.fix.latitude) &&
!isnan(gps_data.fix.longitude)) {
//gettimeofday(&tv, NULL); EDIT: tv.tv_sec isn't actually the timestamp!
printf("latitude: %f, longitude: %f, speed: %f, timestamp: %lf\n", gps_data.fix.latitude, gps_data.fix.longitude, gps_data.fix.speed, gps_data.fix.time); //EDIT: Replaced tv.tv_sec with gps_data.fix.time
} else {
printf("no GPS data available\n");
}
}
}
sleep(3);
}
/* When you are done... */
gps_stream(&gps_data, WATCH_DISABLE, NULL);
gps_close (&gps_data);
return EXIT_SUCCESS;
}
I compile it by running gcc -o gps filename.c -lm -lgps
For the sake of completeness I would like to offer the following edited version of Nathan's program which demonstrates the shared memory interface approach. It took me an afternoon of searching to find the missing key to getting this to work.
EDIT: I corrected the way to properly handle errors from gps_open and gps_read using errno.
#include <gps.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <errno.h>
int main() {
int rc;
//struct timeval tv;
struct gps_data_t gps_data;
if ((gps_open(GPSD_SHARED_MEMORY, NULL, &gps_data)) == -1) {
printf("code: %d, reason: %s\n", errno, gps_errstr(errno));
return EXIT_FAILURE;
}
for(int i=0; i<10; i++) {
/* read data */
if ((gps_read(&gps_data,NULL,0)) == -1) {
printf("error occured reading gps data. code: %d, reason: %s\n", errno, gps_errstr(errno));
} else {
/* Display data from the GPS receiver. */
if ((gps_data.status == STATUS_FIX) &&
(gps_data.fix.mode == MODE_2D || gps_data.fix.mode == MODE_3D) &&
!isnan(gps_data.fix.latitude) &&
!isnan(gps_data.fix.longitude)) {
printf("latitude: %f, longitude: %f, speed: %f, timestamp: %lf\n", gps_data.fix.latitude, gps_data.fix.longitude, gps_data.fix.speed, gps_data.fix.time);
} else {
printf("no GPS data available\n");
}
}
sleep(3);
}
/* When you are done... */
gps_close (&gps_data);
return EXIT_SUCCESS;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With