2024年4月8日 星期一

GPSD to get GNSS infomation

Install
$ sudo apt install gpsd libgps-dev gpsd-clients

Usage manually
$ sudo systemctl stop gpsd
$ sudo systemctl stop gpsd.socket

$ sudo gpsd -N -D5 -F /var/run/gpsd.sock -n /dev/ttyUSB1

Systemd
$ cat /etc/default/gpsd
# Devices gpsd should collect to at boot time.
# They need to be read/writeable, either by user gpsd or the group dialout.
#DEVICES=""
DEVICES="/dev/ttyUSB2"

# Other options you want to pass to gpsd
#GPSD_OPTIONS=""
#MV32, Baud rate 57600 for getting NMEA
GPSD_OPTIONS="-b -s 57600 -F /var/run/gpsd.sock"



$ cat /lib/systemd/system/gpsd.service
[Unit]
Description=GPS (Global Positioning System) Daemon
Requires=gpsd.socket
# Needed with chrony SOCK refclock
After=chronyd.service
After=ModemManager.service
After=network.target

[Service]
Type=forking
EnvironmentFile=-/etc/default/gpsd
#ExecStartPre=/bin/stty speed 57600 -F $DEVICES #手動試試,會失敗
ExecStart=/usr/sbin/gpsd $GPSD_OPTIONS $DEVICES

[Install]
WantedBy=multi-user.target
Also=gpsd.socket

Based on GPSD to get NMEA

#include <stdio.h>
#include <unistd.h>
#include <gps.h>
#include <math.h>

#define SERVER_NAME "localhost"
#define SERVER_PORT "2947"

int main(void)
{
    struct gps_data_t g_gpsdata;
    int ret;
    int exit_cont=1;

    // 1) Open connection to gpsd
    ret = gps_open(SERVER_NAME, SERVER_PORT, &g_gpsdata);
    if (ret != 0) {
        fprintf(stderr, "[GPS] Can't open gpsd connection: %s\n", gps_errstr(ret));
        return -1;
    }

    // 2) Enable streaming of GPS data
    gps_stream(&g_gpsdata, WATCH_ENABLE | WATCH_JSON, NULL);

    printf("Waiting for GPS fix...\n");

    // 3) Loop to read GPS data
    while (gps_waiting(&g_gpsdata, 15000000)) { // wait up to 5 seconds
        if (gps_read(&g_gpsdata, NULL, 0) == -1) {
            fprintf(stderr, "Read error! Exiting...\n");
            break;
        }

        if (g_gpsdata.status == STATUS_FIX &&
            (g_gpsdata.fix.mode == MODE_2D || g_gpsdata.fix.mode == MODE_3D) &&
            isfinite(g_gpsdata.fix.latitude) && isfinite(g_gpsdata.fix.longitude)) {

            // Determine latitude direction
            char lat_dir = (g_gpsdata.fix.latitude >= 0) ? 'N' : 'S';
            // Determine longitude direction
            char lon_dir = (g_gpsdata.fix.longitude >= 0) ? 'E' : 'W';

            printf("[GPS DATA] Time: %ld.%06ld, Latitude: %.6f° %c, Longitude: %.6f° %c, Satellites used: %d, Mode: %d\n",
                   (long)g_gpsdata.fix.time.tv_sec,
                   (long)(g_gpsdata.fix.time.tv_nsec / 1000),  // nanoseconds to microseconds
                   fabs(g_gpsdata.fix.latitude), lat_dir,
                   fabs(g_gpsdata.fix.longitude), lon_dir,
                   g_gpsdata.satellites_used,
                   g_gpsdata.fix.mode);
            exit_cont--;
            if (!exit_cont)
                break;
        } else {
            printf("Waiting for fix...\n");
        }

        sleep(1);
    }

    // 4) Disable streaming and close connection
    gps_stream(&g_gpsdata, WATCH_DISABLE, NULL);
    gps_close(&g_gpsdata);

    return 0;
}

Compile
$ gcc gps.c -o gps -Wall -Wextra -lm -lgps


refer to the following link to get more information:
1. Linux 使用 gpsd 获取 GPS 数据
2. Raw GNSS Measurements(Google APP,好像可在Linxu/Win/Mac執行)

沒有留言:

張貼留言