RU:Gpsd

From OpenStreetMap Wiki
Jump to navigation Jump to search
gpsd
Xgps screenshot.png
Автор:
Лицензия: BSD
Платформ: Linux, macOS, OpenBSD, и NetBSD
Версия: 3.25 (2023-01-10)
Язык:
английский
Веб-сайт: https://gpsd.gitlab.io/gpsd/
Исходный код: https://gitlab.com/gpsd/gpsd
Язык
программирования:
C

Соединение с приёмником глобальных навигационных систем, сглаживание результатов измерений

Features
Feature Value
Map Display
Display map нет
Map data
?
Source
?
Rotate map
?
3D view
?
Shows website
?
Shows phone number
?
Shows operation hours
?
Routing
Routing нет
Create route manually
?
Calculate route
?
Create route via Waypoints
?
Routing profiles
?
Turn restrictions
?
Calculate route without Internet (Offline routing)
?
Routing providers
?
Avoid traffic
?
Traffic Provider
?
Navigating
Navigate нет
Find location
?
Find nearby POIs
?
Navigate to point
?
Navigation with voice / Voice guidance
?
Keep on road
?
Lane guidance
?
Works without GPS
?
Navigate along predefined route
?
Tracking
Make track нет
Customizable log interval
?
Track formats
?
Geotagging
?
Fast POI buttons
?
Upload GPX to OSM
?
Monitoring
Monitoring да
Show current track нет
Open existing track нет
Altitude diagram нет
Show POD value нет
Satellite view да
Show live NMEA data нет
Show speed да
Send current position
?
Editing
?
Rendering
?
Accessibility
?

gpsd это служебная резидентная программа (демон) глобальных навигационных систем для Linux, OpenBSD and Mac OS X. Предпринимались попытки выпустить Windows версию. Программа позволяет клиентам через использование выделенного TCP/IP порта подсоединяться к приёмниками глобальных навигационных систем, подключаемых через последовательный порт, USB, Bluetooth, GPIO. КЛиенты могут подвоединяться к другому источнику навигационных данных данных по сети TCP/IP, обращаясь к порту на другой машине. Множество приложений для картографирования и просмотра карт используют gpsd, среди них FoxtrotGPS, Marble, Merkaartor, QLandkarteGT, TangoGPS и Viking. Такие навигационные приложения как GpsDrive, Gosmore, Navit and ShareNav используют gpsd для показа текущего положения при работе на настольных машинах или ноутбуках.

Типовые или тестовые клиенты

К gpsd прилагается (на Linux нередко в других пакетах) комплект программ, которые отображают пространственное положение и показывают статус подключения к устройству-источнику навигационных пространственных данных.

xgps

xgps это простой клиент gpsd для графического интерфейса X. Он показывает текщее пространственное положение, время и смещение а также (для приёмников поддерживающих такого рода данные) положение доступных навигационных спутников на небесном своде в виде азимутальной диаграммы.

xgpsspeed

xgpsspeed графический спидометр, основывающийся на данных, считываемых с подключенных приёмников навигационных данных.

cgps

cgps клиент, работающий в текстовом теримнале. Аналогичен xgps, однако не имеет графичесокго интерфейса и не показывает диаграмму положения спутников.

Пакеты Linux

Debian/Ubuntu/Mint

  • gpsd - основная служба
  • gpsd-utils - типовые и тестовые клиентские прогарммы
  • libgps - функциональаня библиотека
  • libgps-dev - пакет для написания своих клиентов

Пример клиента на языке C

Исходный код

/*
 * Пример gpsd клиента на языке C.
 * Программа записывает в БД PostgreSQL результаты навигационных измерений со сглаживанием,
 * для получения координат без сглаживания см. пример клиента gpsmon из пакета gpsd.
 *		Требует: sudo apt install libgps-dev libpq-dev
 *		компилируется:
 *			rm pg_gps; gcc pggps.c -o pg_pgs -I/usr/include/postgresql -lgps -lm -lpq;
 *		запускается:
 *			./pg_pgs "dbname='Платон' host="172.16.241.4" port=5432 connect_timeout=10 password=abracadabra" "серия измерений №1";
 */
#include <gps.h>		/* gps_*() */
#include <math.h>		/* isfinite() */
#include <stdio.h>
#include <stdlib.h>
#include "libpq-fe.h"	/* PostgreSQL клиентские функции*/

static void
exit_nicely(PGconn *conn)
{
	PQfinish(conn);
	exit(1);
}

#define MODE_STR_NUM 4
static char *mode_str[MODE_STR_NUM] = {
	"?",
	"∅",
	"2D",
	"3D"
};

/*
 * Печать основных данных на текстовый терминал
 */
static void
gps_stdout(struct gps_data_t* gps_data)
{
	/* Показываем время при наличии */
	bool time = TIME_SET == (TIME_SET & gps_data->set);
	if (time) {
		// not 32 bit safe
		printf("t: %ld.%09ld ", gps_data->fix.time.tv_sec,
			   gps_data->fix.time.tv_nsec);
	} else {
		puts("t:  ? ");
	}

	/* Показываем географические координаты */
	if (isfinite(gps_data->fix.latitude) &&
		isfinite(gps_data->fix.longitude)) {
		printf("φ %12.9f λ %13.9f ",
			   gps_data->fix.latitude, gps_data->fix.longitude);
	} else {
		printf("φ  ?  λ  ? ");
	}

	/* Показываем высоту над эллипсоидом */
	if (isfinite(gps_data->fix.altHAE)) {
		printf("над элипсоидом %.6f ", gps_data->fix.altHAE);
	} else {
		printf("над элипсоидом  ? ");
	}

	/* Показываем высоту над условным уровнем моря */
	if (isfinite(gps_data->fix.altMSL)) {
		printf("над морем %.6f ", gps_data->fix.altMSL);
	} else {
		printf("над морем  ? ");
	}
}

int main(int argc, char *argv[])
{
	struct gps_data_t	gps_data;
	char			   *conninfo = NULL;
	char			   *seria = "?";
	PGconn			   *conn;
	PGresult		   *res;
	int					nFields;
	int					i,
						j;
	char stmt[512]; /* максимальная длина запроса */
	const char		   *query1 =
		"INSERT INTO \"Измерения\".\"Факт\" (\"Серия\", φ, λ, \"HAE\", \"MSL\", \"t_GPS\")"
		" VALUES('%s', '%12.9f', '%13.9f', '%8.2f', '%8.2f', '%ld.%09ld') RETURNING *;";

	if (argc > 2)
		seria = argv[2];
	if (argc > 1)
		conninfo = argv[1];

	/* Соединяемся с БД */
	conn = PQconnectdb(conninfo);

	/* Проверка провала соединения с БД */
	if (PQstatus(conn) != CONNECTION_OK)
	{
		fprintf(stderr, "%s", PQerrorMessage(conn));
		exit_nicely(conn);
	}

	/* Соединяемся со службой поставки навигационных данных gpsd */
	if (0 != gps_open("localhost", "2947", &gps_data)) {
		printf("Нет соединения со службой поставки навигационных данных \n");
		exit_nicely(conn);
	}

	(void)gps_stream(&gps_data, WATCH_ENABLE | WATCH_JSON, NULL);

	/* Главный цикл обработки поступающих данных */
	while (gps_waiting(&gps_data, 5000000)) {
		bool time = false;

		if (-1 == gps_read(&gps_data, NULL, 0)) {
			printf("Ошибка чтения\n");
			break;
		}

		/* Вдруг не получены данные о режиме сглаживания в поступающих данных */
		if (MODE_SET != (MODE_SET & gps_data.set)) {
			continue;
		}

		/* Ставим режим без сглаживания */
		if (0 > gps_data.fix.mode ||
			MODE_STR_NUM <= gps_data.fix.mode) {
			gps_data.fix.mode = MODE_NO_FIX ;
		}

		/* Показываем режим сглаживания */
		printf("∮ %s (%d),",
			   mode_str[gps_data.fix.mode],
			   gps_data.fix.mode);

		/* Составляем текст запроса в БД - лучше делать через параметры и не char* */
		time = TIME_SET == (TIME_SET & gps_data.set); /* достуно ли навигационное время ? */
        sprintf(stmt, query1,
        	seria,
        	gps_data.fix.latitude,
        	gps_data.fix.longitude,
        	gps_data.fix.altHAE,
        	gps_data.fix.altMSL,
        	time ? gps_data.fix.time.tv_sec : 0,
        	time ?gps_data.fix.time.tv_nsec : 0
        );

		/* Отправка текста запроса в БД */
		res = PQexec(conn,stmt);
		if(PQresultStatus(res) != PGRES_COMMAND_OK)
			fprintf(stderr, "%s", PQerrorMessage(conn));

		/* Выдача данных на терминал, для отладки и наглядности */
		gps_stdout(&gps_data);
	}

	/* конец делу венец, прибираемся за собой */
	PQfinish(conn);
	(void)gps_stream(&gps_data, WATCH_DISABLE, NULL);
	(void)gps_close(&gps_data);

	exit(0);
}

См. дополнительно