GNSS篇(四) - 整活定位模块(GPSD 使用)

文摘   2024-09-01 18:50   新加坡  

关注+星号公众号,不容错过精彩

作者:HywelStar

本章节主要介绍GPSD 的使用,简单来说GPSD 是一个开源项目,适用于各种不同的GNSS模块创建的一个中间层服务,应用层可以方便的与GPSD服务进行交互获取相关的数据,更重要的意义来说统一了应用层调用接口,采用网络方式进行通信,采用统一的JSON 数据格式进行交互。当然在你的项目中,GPSD也不是非必须得服务,也可以不用这样,可以直接进行GNSS数据的分析到应用层。

1. 认识GPSD

GPSD 是一个开放源代码的守护进程,用于从 GPS 接收器收集位置信息,并将其标准化为应用程序可以轻松读取的格式。可以将数据标准化并通过 TCP/IP 套接字提供给多个客户端应用程序。它支持多种 GPS 硬件设备,并能够解析各种 NMEA 数据协议。

特点:

  • 支持多种设备:GPSD 支持许多不同的 GPS 接收器和其他 GNSS (全球导航卫星系统) 设备。
  • 标准化数据:GPSD 将来自不同 GPS 设备的原始数据标准化,以便客户端应用程序可以使用一致的 API 来访问位置信息。
  • 多客户端支持:多个客户端可以同时连接到 GPSD,并从同一 GPS 接收器接收位置信息。
  • 数据格式:GPSD 使用 JSON 格式传递数据,使得解析和使用数据变得简单。
  • 时间同步:GPSD 还可以用于高精度的时间同步,从 GPS 接收器获取时间信息来同步系统时钟。

应用场景:

  • 导航系统:GPSD 可以用于汽车导航系统,提供实时的位置信息和导航数据。
  • 地理信息系统 (GIS):在 GIS 应用中,GPSD 可以提供准确的位置信息用于地理数据的收集和分析。
  • 时间同步:一些系统需要高精度的时间同步,GPSD 可以从 GPS 信号中提取时间信息并同步系统时钟。
  • 移动应用:在移动设备或应用程序中使用 GPSD,可以实时获取设备的位置和移动轨迹。

总结来说这个一个开源统一管理各种GPS的工具,广泛应用于各种场景,不过目前是支持在Linux 系统下,如果放在其他系统下需要做一个修改。

2. 安装GPSD

以Ubuntu 为例子:

sudo apt-get install gpsd gpsd-clients

启动服务,服务控制:

# 启动sudo systemctl start gpsd
# restartsudo systemctl restart gpsd
# 停止sudo systemctl stop gpsd
# 查询状态sudo systemctl satus gpsd
# 停止sudo systemctl stop gpsdsudo systemctl stop gpsd.socket

2.1 确定串口设备

确定哪个串口,查看数据:

sudo stty -F /dev/ttyUSB0 9600 cs8 -cstopb -parenbsudo cat /dev/ttyUSB0

2.2 配置GPSD

GPSD 主要配置文件**/etc/default/gpsd** 和 /lib/systemd/system/gpsd.service

$ 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="/dev/ttyUSB0"
# Other options you want to pass to gpsdGPSD_OPTIONS="-F /var/run/gpsd.sock"
# Automatically hot add/remove USB GPS devices via gpsdctlUSBAUTO="true"

配置完毕后GPSD需要重新启动一次服务;

查看GPS数据

cgps

gpsmon

2. 应用程序接入

这里以C语言为demo, 创建gsp_app.c

先安装依赖相关:

sudo apt-get install libgps-dev libjansson-dev

2.1 代码编译运行

gps_app.c 代码demo

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <gps.h>
#define GPSD_HOST "localhost"#define GPSD_PORT "2947"
void print_gps_data(struct gps_data_t *gps_data) { if (gps_data->fix.mode >= MODE_2D) { printf("Latitude: %f\n", gps_data->fix.latitude); printf("Longitude: %f\n", gps_data->fix.longitude); printf("Altitude: %f\n", gps_data->fix.altitude);
// Time is stored as a struct timespec, so we need to check if tv_sec is non-zero if (gps_data->fix.time.tv_sec != 0) { printf("Time: %ld.%09ld\n", gps_data->fix.time.tv_sec, gps_data->fix.time.tv_nsec); } else { printf("Time: N/A\n"); } } else { printf("GPS data not available.\n"); }}
int main(void) { struct gps_data_t gps_data; char buf[256]; int ret;
// Initialize GPSD library if (gps_open(GPSD_HOST, GPSD_PORT, &gps_data) != 0) { fprintf(stderr, "Could not connect to GPSD\n"); return 1; }
// Configure GPSD to provide data gps_stream(&gps_data, WATCH_ENABLE, NULL);
while (1) { // Read GPS data with appropriate arguments ret = gps_read(&gps_data, buf, sizeof(buf)); if (ret == -1) { fprintf(stderr, "Error reading GPS data\n"); break; } print_gps_data(&gps_data); sleep(1); // Update interval }
gps_stream(&gps_data, WATCH_DISABLE, NULL); gps_close(&gps_data);
return 0;}

通过应用程序已经可以获取到经纬度,时间相关的信息。

3. 总结

通过GPSD 获取设备的GNSS 信息来说难度不大,通过GPSD 已经将GNSS 数据包协议已经解析,支持多用户获取实时的相关数据,对于不想去深究其中可以采用添加GPSD 服务的方式进行处理GNSS 数据,但是对于嵌入式设备,还需要涉及一个交叉编译的过程,对于交叉编译将后续进行展开。



往期推荐



GNSS篇(一) - 定位基础知识

GNSS 篇(二) - 卫星导航定位原理

GNSS 篇(三) - 定位模块与协议介绍

嵌入式软件的编译知识

公众号目录指引

USB 接口小科普

认识Type-C 与快充相关知识



码思途远
一位码农的日常分享,探索软件技术知识与新闻的数字十字路口。