简介
一般 GPS 接收器会遵循美国国家海洋电子协会(National Marine Electronics Association)所指定的标准规格,其中包含传输资料的格式以及传输资料的通讯协议。那我们要在 Ubuntu 下获取 GPS 接收器的数据,一种方法就是使用 libgps 库。
准确来说 libgps(man libgps)是一个与 GPS 守护进程进行通信的 C 库。包含打开、收发、解析数据包等接口。这个库的接口的使用,依赖 GPS 守护进程的运行。而这个守护进程才是真正基于上述协议与 GPS 接收器进行通信的。但是我们作为软件开发人员来说可以不用管守护进程的实现,我们把 libgps 的接口用起来,拿到我们所需要的 GPS 数据就好了。
安装
sudo apt-get install libgps-dev
sudo apt-get install gpsd
启动守护进程
- 接入 GPS 接收器。我手上测试的是探险家V-800,在 Ubuntu 上设备被识别为 /dev/ttyUSB0
- 启动守护进程
sudo gpsd /dev/ttyUSB0
启动客户端程序
- 示例代码:
#include <gps.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <math.h> int main() { int rc; struct timeval tv; struct gps_data_t gps_data; ) { printf("code: %d, reason: %s\n", rc, gps_errstr(rc)); return EXIT_FAILURE; } gps_stream(&gps_data, WATCH_ENABLE | WATCH_JSON, NULL); ) { /* wait for 2 seconds to receive data */ )) { /* read data */ ) { printf("error occured reading gps data. code: %d, reason: %s\n", rc, gps_errstr(rc)); } 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: %ld\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(); } /* 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
- 执行
./gps
然后即可看到打印信息:
当然了,你需要带着电脑和GPS接收器跑到室外去,跑到广场上去,跑到原野上去……才能收到GPS信号。
参考
http://www.cnblogs.com/visoeclipse/archive/2009/10/31/1593522.html
https://*.com/questions/32000328/libgps-c-code-example
2017-6-7 - 廖杰良