Как я могу реализовать клиент gpsd (на C), чтобы получить широту, долготу и высоту?

Я пишу программу C для регистрации данных для моего Raspberry Pi с поддержкой GPS. Я взял gpsd, и его пример приложения cgps правильно отображает информацию GPS. Я хотел использовать libgps для взаимодействия с демоном, чтобы иметь всю эту полезную информацию в своем приложении. , но меня быстро ошеломила сложность его API.

Документация на его странице HOWTO указывает мне посмотреть на cgps и gpxlogger, например, код, но там так много связей, что я не могу разобраться во всем этом. На противоположном конце спектра пример кода C на странице libgps настолько урезан, что кажется непригодный для использования.

Может ли кто-нибудь указать мне на образец одного класса, который мог бы демистифицировать это? Возможно, что-то, что содержит функцию getCoordinates()?


person Nathan Vance    schedule 13.08.2015    source источник


Ответы (2)


Я говорил слишком рано. После просмотра других вопросов SO я столкнулся с этим совершенно не связанным вопрос. Вот моя немного измененная версия:

#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;
}

Я скомпилирую его, запустив gcc -o gps filename.c -lm -lgps

person Nathan Vance    schedule 14.08.2015
comment
Вы случайно не знаете, как получить время GPS? Я не слишком знаком с C, но tv.tv_sec похоже на системное время? - person bakalolo; 02.11.2016
comment
Вероятно, потому что вместо этого я должен был использовать gps_data.fix.time. Спасибо, что поймали это! - person Nathan Vance; 02.11.2016
comment
Это немного поздно, но может оказаться полезным для кого-то еще: вы должны напечатать метку времени как %lf. В gps.h gps_data.fix.time определяется как timestamp_t, что является просто псевдонимом для двойника. В противном случае идеальный ответ! - person Cyril C.; 18.10.2017
comment
gps_data.fix.time теперь определяется как timespec_t, который является спецификацией времени структуры с tv_sec и tv_nsec. - person solsTiCe; 12.03.2020
comment
Чтобы получить удобочитаемое время: struct tm ts; time_t time = gps_data->fix.time; char buf[80]; ts = *localtime(&time); strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", &ts); - person Joel Ravazzolo; 24.03.2020

Для полноты картины я хотел бы предложить следующую отредактированную версию программы Натана, которая демонстрирует подход с использованием интерфейса с общей памятью. Мне потребовался целый день поисков, чтобы найти недостающий ключ, чтобы заставить это работать.

РЕДАКТИРОВАТЬ: я исправил способ правильной обработки ошибок из gps_open и gps_read с помощью 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;
}
person joel reindel    schedule 31.12.2019