关注+星号公众号,不容错过精彩
作者: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
# restart
sudo systemctl restart gpsd
# 停止
sudo systemctl stop gpsd
# 查询状态
sudo systemctl satus gpsd
# 停止
sudo systemctl stop gpsd
sudo systemctl stop gpsd.socket
2.1 确定串口设备
确定哪个串口,查看数据:
sudo stty -F /dev/ttyUSB0 9600 cs8 -cstopb -parenb
sudo 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 gpsd
GPSD_OPTIONS="-F /var/run/gpsd.sock"
# Automatically hot add/remove USB GPS devices via gpsdctl
USBAUTO="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 数据,但是对于嵌入式设备,还需要涉及一个交叉编译的过程,对于交叉编译将后续进行展开。
往期推荐