GPSd를 이용한 GNSS 프로그래밍
- 프로그래밍/리눅스 프로그래밍
- 2020. 12. 24.
GPSd는 다양한 GNSS 모듈로부터 입력되는 각종 정보를 처리하는 오픈소스 데몬으로써, 처리된 GNSS 정보를 다수의 다른 어플리케이션들이 사용할 수 있도록 제공하는 기능을 지원한다.
본 글에서는 GPSd가 제공하는 GNSS 정보들을 획득하여 처리하는 어플리케이션 프로그램을 작성하는 방법에 대해 소개한다.
GPSd 데몬을 빌드하고 사용하는 방법에 대해서는 아래 글에서 확인할 수 있다.
장치 상에 GNSS 모듈이 내장되어 있고, GPSd 데몬이 GNSS 모듈로부터 입력되는 정보를 정상적으로 처리하는 상태가 되면, 동일한 장치에서 동작하는 다른 어플리케이션들에서는 GPSd 데몬이 제공하는 GNSS 정보들을 사용할 수 있다.
GPSd 데몬이 타 어플리케이션들에게 GNSS 정보를 제공하는 방식은 JSON 방식이나 공유 메모리 방식이 있는데(그 외 다른 방식도 있을 수 있다), 본 글에서는 공유 메모리 방식을 사용하는 방법을 소개한다.
공유 메모리 방식을 사용할 경우, GPSd 데몬은 입력되는 GNSS 정보를 시스템의 공유 메모리 상에 저장하며, 타 어플리케이션들은 해당 공유 메모리로부터 정보를 읽어 처리하게 된다.
다음은 공유 메모리로부터 GNSS 정보를 읽어 처리하는 어플리케이션의 개발 방법이다.
준비 사항
어플리케이션은 GPSd에 포함된 라이브러리인 libgps의 기능을 사용하기 위해, libgps 라이브러리 파일을 링크하고 gps.h 파일을 인클루드 해야 한다. 이 두 파일은 GPSd 빌드 시에 함께 생성되며, 개발하고자 하는 어플리케이션 프로젝트의 링크 디렉토리와 인클루드 디렉토리에 복사하여 사용한다.
아래 글에서 호출되는 각 API 함수들은 모두 libgps에서 제공하는 API 함수들이다.
GNSS 데이터 수신 인터페이스 초기화
어플리케이션은 (보통) 초기화 루틴에서 gps_open() API 함수를 호출하여 GNSS 데이터 수신 인터페이스를 초기화한다.
// libgps 라이브러리 기능을 사용하기 위해 인클루드
#include "gps.h"
/**
* @brief GNSS 관련 기능을 초기화한다.
* @retval 0: 성공
* @retval -1: 실패
*/
int InitGNSSFunction(void)
{
struct gps_data_t gps;
int ret = gps_open(GPSD_SHARED_MEMORY, NULL, &gps); // 공유메모리 방식으로 인터페이스 초기화
if (ret) {
printf("Fail to gps_open(): %s\n", gps_errstr(ret));
return -1;
}
...
return 0;
}
GNSS 데이터 획득
어플리케이션은 필요 시 또는 주기적으로 gps_read() API 함수를 호출하여 GNSS 데이터를 획득한다. 참고로 gps_read() 함수는 논블로킹 함수이며, 저장되어 있는 최신 GNSS 정보가 즉시 반환된다.
/**
* @brief GNSS 데이터를 처리한다.
* @param[in] gps GNSS 데이터 구조체
*/
void ProcessGNSSData(struct gps_data_t *gps)
{
if (gps->fix.mode >= MODE_2D) {
printf("latitude: %.7f\n", gps->fix.latitude);
printf("longitude: %.7f\n", gps->fix.longitude);
printf("speed: %.2f\n", gps->fix.speed);
printf("heading: %.2f\n", gps->fix.track);
if (gps->fix.mode >= MODE_3D) {
printf("altitude: %.1f\n", gps->fix.altitude);
}
}
}
/**
* @brief GNSS 데이터를 읽어 처리한다.
* @param[in] gps GNSS 데이터 구조체
*/
void ReadAndProcessGNSSData(struct gps_data_t *gps)
{
if (gps_read(gps) != -1) {
ProcessGNSSData(gps);
}
}
gps_read() 함수의 인자로 전달되는 struct gps_data_t 구조체에 최신 GNSS 데이터가 저장되어 반환된다.
struct gps_data_t 구조체는 gps.h 파일에 정의되어 있다.
본 글에서는 가장 기본적인 정보인 위도, 경도, 속도, 헤딩, 고도 정보를 획득하여 처리하는 방법을 다루고 있다.
-
gps->fix.latitude: 장치의 1도 단위 위도값이 저장된다.
-
gps->fix.longitude: 장치의 1도 단위 경도값이 저장된다.
-
gps->fix.speed: 장치의 1m/s 단위 속도값이 저장된다.
-
gps->fix.track: 장치의 1도 단위 헤딩값이 저장된다. 0도는 true north를 가리킨다.
-
gps->fix.altitude: 장치의 1미터 단위 고도값이 저장된다.
GNSS 데이터 수신 인터페이스 종료
(일반적을) 프로그램 종료 시에 gps_close() API 함수를 호출하여 GNSS 데이터 수신 인터페이스를 닫는다.
/**
* @brief GNSS 관련 기능을 종료한다.
* @param[in] gps GNSS 데이터 구조체
*/
void CloseGNSSFunction(struct gps_data_t *gps)
{
gps_close(gps);
}
어플리케이션 빌드
어플리케이션 빌드 시 libgps 라이브러리를 링크하여 빌드해야 하므로, 컴파일 명령줄에 -lgps 옵션을 지정한다. CMake를 사용할 경우 target_link_libraries(${TARGET_APP} PRIVATE gps) 명령줄을 사용할 수 있다.
ads-partners.coupang.com/g.js"></script>
파트너스 활동을 통해 일정액의 수수료를 제공받을 수 있음
'프로그래밍 > 리눅스 프로그래밍' 카테고리의 다른 글
Kernel PPS 신호 사용하기 (C source code) (0) | 2022.03.26 |
---|---|
CURL 라이브러리 사용법 - 임베디드 플랫폼용으로 빌드하기(arm-cross-sysroot 활용) (0) | 2021.03.09 |
리눅스 TUN/TAP 디바이스 프로그래밍 (1) | 2021.01.28 |
프로세스 간 통신(IPC) 프로그래밍 - 메시지큐 (0) | 2021.01.19 |
리눅스 프로그래밍 - 프로세스 종료 신호(SIGINT, SIGTERM) 후킹하기 (0) | 2020.08.21 |
리눅스 타이머 프로그래밍 (0) | 2020.07.31 |
리눅스 네트워크 프로그래밍 - CAN(Controller Area Network) 통신 (2) | 2020.04.27 |
리눅스 네트워크 프로그래밍 - UDP6(UDP over IPv6) 송수신 (0) | 2020.03.04 |