[네트워크/C reference] inet_pton 함수

by Blogger 하얀쿠아
2017.11.12 01:07 소프트웨어 Note/C

기능 요약 (Summary)

inet_pton( ) 함수는 사람이 알아보기 쉬운 텍스트(human-readable text)형태의 IPv4 와 IPv6 주소를 binary 형태로 변환 하는 기능을 한다.



헤더 (Header files)

이 함수를 사용하려면 다음 헤더파일을 포함시킨다.


#include <arpa/inet.h>


API 원형 (API Prototype)

3개의 파라미터를 가지는 함수이다.

int inet_pton(int af, const char *src, void *dst);

af [input] -  address family를 지정한다. src의 문자열이 IPv4 주소를 나타내는지, IPv6 주소를 나타내는지를 함수에 알린다.

src [input] - 문자열 형태의 IP주소를 넣는다.

dst : [output] - src를 binary형태로 변환 후 복사된 메모리의 포인터이다.


설명 (Description)

이 함수는 af의 address family가 가리키는 네트워크 주소 구조체에 src의 문자열 값을 변환 한 후, 이 네트워크 주소 구조체를 dst에 복사한다.

af는 반드시 AF_INET 혹은 AF_INET6 둘 중 하나여야 한다.

dst는 network byte order로 작성된다.


언급했듯이 현재는 IPv4 및 IPv6를 의미하는 아래 2개의 address family들만 지원된다.


AF_INET

src이 가리키는 문자열은 IPv4 네트워크 주소이고, 점으로 자리를 구분하는 10진수 주소 형태이다.

"ddd.ddd.ddd.ddd" 와 같은 형태이고, ddd 자리에 0~255 범위의 10진수가 온다.

그 주소는 in_addr 구조체로 변환 된 후, 4byte크기를 가지는 dst로 복사된다. 

참고로 in_addr 구조체는 크기가 4byte 이다.



AF_INET6

src이 가리키는 문자열은 IPv6 네트워크 주소이다.

그 주소는 in6_addr 구조체로 변환된 후 16byte크기를 가지는 dst로 복사된다.

src에 넣을 수 있는 IPv6 주소 표현방식은 IPv4 주소 표현 방식에 비해 다양한데, 아래와 같은 규칙을 따른다.


IPv6 주소 표현 규칙

1. 우선시 되는 형태는 x:x:x:x:x:x:x:x 이다. 

각각의 x 는 16진수 문자이며 16bit 값을 표현하므로, 최대 4자리가 될 수 있다.

또한 x와 x 는 콜론으로 구분되며, 전체 8개로 구성된다.


2. 연속되는 0 값들은 :: 로 축약해서 표현하는 방법이 사용된다. 

단, 하나의 주소표현에서 :: 는 단 한번만 등장할 수 있다.

예를 들면, IPv6의 loopback 주소는 0:0:0:0:0:0:0:1 인데, 이걸 간단히 ::1 로 축약해서 표현 할 수 있다.

또한, wildcard 주소인 모든 값이 0으로 구성된 주소는, :: 라고 쓸 수 있다.


3. 대체 유형은  IPv4-mapped IPv6주소를 표현하는데 유용하다. 이 형태는 x:x:x:x:x:x:d.d.d.d 와 같이 쓰인다.

처음 앞의 6개 x 들은 주소의 최상위 비트 6개를 정의한다. (96 bit)

그리고 나머지 d들은 최하위 32bit에 점으로 구분하는 10진수 표기법을 정의한다.

예를 들면 ::FFFF:204.152.189.116 이러한 주소다.



더 자세한 IPv6 주소 표현방법을 알고 싶다면, RFC 2373 을 참고하기 바란다.


반환값 (Return value)

inet_pton( )은 성공시 1을 반환한다.

즉, 1이 return되면 네트워크 주소가 성공적으로 변환되었음을 의미한다.


0 이 반환되는 경우는 src의 문자열이 나타내는 네트워크 주소가, af에 명시된 address family의 유효한 값이 아닌 경우이다.

-1 이 반환되는 경우는 af가 적절한 address family값이 아닌 경우이다. 이때는 errno이 EAFNOSUPPORT 값으로 설정된다.


준수사항

POSIX.1-2001, POSIX.1-2008.  



알아둘 내용

inet_aton( ) 및 inet_addr( )와는 달리, inet_pton( )은 IPv6주소를 지원한다. 


반면에, inet_pton( )은 점 3개와 10진수 표현법의 (dotted-decimal notation) IPv4주소만 받아들인다. 

inet_aton( )및 inet_addr( )은 좀더 일반적인 표현법인 'numbers-and-dots notation' 에 대해서도 받아들인다.


'numbers-and-dots notation'는 이와 같다.

hexadecimal and octal number formats, and formats that don't require all four bytes to be explicitly written.  


알려진 버그

AF_INET6은 IPv4주소를 인식하지 못한다. 

대신에 명시적으로 IPv4-mapped IPv6 주소가 반드시 src에 넣어져야 한다.


같이 볼 함수들

getnameinfo( )

getaddrinfo( )

inet_ntop( )


이 댓글을 비밀 댓글로

[네트워크/C reference] inet_ntop 함수

by Blogger 하얀쿠아
2017.11.02 02:16 소프트웨어 Note/C

기능 요약 (Summary)

inet_ntop - IPv4 와 IPv6 주소를 binary 형태에서 사람이 알아보기 쉬운 텍스트(human-readable text)형태로 전환해준다.



헤더 (Header files)

  #include <arpa/inet.h>


API 원형 (API Prototype)

const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);



설명 (Description)

이 함수는 네트워크 주소 구조체인 src를 캐릭터 문자열 dst로 변환해주는 함수이다. 네트워크 주소는 IPv4 혹은 IPv6 가 될 수 있으며, 'address family'를 의미하는 af 를 참고하여 src를 해석하게 된다. 결과가 저장되는 dst는 반드시 NULL 포인터가 아니어야 한다. 즉, 메모리 공간이 할당된 포인터 이어야 한다는 뜻.


이 API를 호출하는 쪽에서는 dst 버퍼의 크기를 size 를 통해 지정한다.


inet_ntop( )는 다양한 address family를 지원하기 위해 inet_ntoa( ) 함수를 확장한다.

그래서 inet_ntoa( )는 현재 deprecated 되도록 고려되고 있다.


af 는 현재 아래의 address family들을 사용 할 수 있도록 지원된다.


AF_INET

src 는 struct in_addr (network byte order임) 구조체를 가리킨다. 

이것은 IPv4 네트워크 주소로 변환 될 것이고, 'dotted-decimal format' 이라고 불리는 형태의 주소, 즉, "ddd.ddd.ddd.ddd" 과 같은 형태가 될 것이다.

버퍼 dst 는 반드시 메모리가 할당되어야 하며, 그 크기는 최소한 INET_ADDRSTRLEN 크기만큼의 바이트 수는 되어야 한다.


AF_INET6

src 는 struct in6_addr (network byte order임) 구조체를 가리킨다.

이것은 IPv6 네트워크 주소로 변환될 것이다. 변환된 문자열의 형태는 해당 IPv6 주소를 나타내기에 가장 적절한 형태가 될 것이다. 

즉, 생략가능한 부분은 연속으로 콜론 2개를 찍은 형태의 단축형 결과를 얻게 된다는 것이다. 

버퍼 dst 는 반드시 메모리가 할당되어야 하며, 그 크기는 최소한 INET6_ADDRSTRLEN 크기만큼의 바이트 수는 되어야 한다.



반환값 (Return value)

성공하면, inet_ntop( ) 는 dst 를 가리키는 포인터를 반환한다.

만약 에러가 있었다면, NULL이 반환되고, errno 에 에러와 관련된 값이 설정된다.




오류 값 (Errors)

EAFNOSUPPORT

af 가 유효한 address family가 아님.


ENOSPC 

변환된 주소 문자열이 size에 의해 주어진 크기를 초과하게 됨.



준수사항

POSIX.1-2001, POSIX.1-2008.  

RFC 2553 에서는 이 함수 원형의 마지막 인자인 size를 size_t로 정의하고 있음을 알아둘 것.

많은 시스템이 RFC2553를 따른다. Glibc 2.0와 2.1 버전은 size_t 이지만, 2.2 및 이후 버전은 socklen_t 이다.



같이 볼 함수들

getnameinfo( )

getaddrinfo( )

inet_pton( )



이 댓글을 비밀 댓글로

TCP Flags: PSH 그리고 URG

by Blogger 하얀쿠아
2017.09.29 00:34 소프트웨어 Note/Network Technology

개요

TCP헤더를 들여다 보면, 1비트 짜리 플래그가 몇개 있다. 1비트로는 0 아니면 1 만을 나타낼 수 있기 때문에, 플래그는 태생적으로 boolean type 이다.
이 플래그들은 TCP연결을 통하는 데이터의 흐름을 조절 및 제어 하기 위해 사용된다고 알려져 있다.

RFC 3168 에 의해 혼잡 통지(Congestion Notification)을 위해 추가된 CWR 그리고 ECE 플래그를 제외하고나면, 총 6개의 TCP 제어 플래그가 남는다.
일단 CWR과 ECE는 논외로 하자.

TCP 기본 헤더 포맷


Data Offset 다음을 보면, 6개의 플래그, URG, ACK, PSH, RST, SYN, FIN 이 보인다.

그 중, 아래 4개는 TCP연결의 설정(establish), 유지 관리(management) 및 분리(tear-down)를 제어하는 용도이다. 아마  패킷 분석좀 해본 경험이 있다면 이미 익숙 한 플래그 일 것이다.


  • SYN - 연결을 시작한다
  • ACK - 수신 된 데이터를 확인한다
  • FIN - 연결을 닫는다
  • RST - 오류에 대한 응답으로 연결을 중단한다


나머지 두개의 플래그 PSH (Push)와 URG (Urgent)가 있는데, 이 둘의 역할이 종종 헷갈린다.

눈치 챘는가? 이 두개 플래그의 역할, 그것이 바로 오늘 쓸 포스팅의 주제다.



PSH 플래그

PSH 플래그의 기능을 이해하려면 우선 TCP가 데이터를 버퍼링하는 방법을 이해해야 한다. 


기본적인 이야기 부터 해보자. TCP는 OSI Layer 4에서 동작한다. 그것은 패킷 기반 통신의 복잡성을 감추고, 들어온 데이터를 읽어내거나, 혹은, 내보낼 데이터를 쓸 수 있는 간단한 소켓 인터페이스를 상위 Layer에 제공한다. 그리고 TCP는 응용 프로그램(OSI Layer 7)이 언제든지 이 소켓으로부터 읽거나 쓸 수 있도록 버퍼를 제공한다. 버퍼는 TCP 연결 양쪽(송신자와 수신자)의 들어오고 나가는 양쪽 방향 모두에서 구현된다. 말이 헷갈린다면 간단히 생각하자. 송신자의 TCP도 read buffer, write buffer 를 가지고, 수신자의 TCP도 read buffer, write buffer를 가진다.


아래 다이어그램은 송신 전에 송신자가 데이터를 버퍼링하는 방법과 수신자가 수신 시 데이터를 버퍼링하는 방법을 보여준다.





MSS (Maximum Segment Size)를 초과하는 데이터 보낼때를 상상해 보라. 예를 들면 큰 파일 전송 같은 것 말이다. 버퍼는 이런 큰 데이터를 보다 효율적으로 전송할 수 있게 해주는 역할을 한다. 그러나 데이터를 가능한 한 빨리 전송해야 하는 실시간 응용 프로그램을 처리 할 때는 큰 버퍼가 좋지 않다. 예를 들어 TCP가 패킷을 보내기 전에 패킷의 버퍼를 데이터가 가득 채울때까지 기다리다가 전송한다면.. 텔넷 세션에 어떤 일이 발생하는지 생각해보라. 첫 번째 패킷이 원격 장치로 전송되게 하려면 그 전에 먼저 문자 타이핑을 1000자 넘게 해야할 것이다. 이럴땐 별로 유용해 보이지 않는다. 


만약 텔넷의 예가 어렵다면, 카카오톡이나 채팅 프로그램 같은걸 상상해 보면 된다. 짧은 메세지 몇글자 보내려 하는데, TCP버퍼가 가득 찰때까지 기다렸다가 전달된다면? 답답할 것이다.


바로 이것이 PSH 플래그가 필요한 경우다.

응용프로그램(Application Layer) 에서는 소켓에  "Push"하는 옵션을 사용하여 데이터를 쓸 수있다. 이 옵션은  추가 데이터가 버퍼에 들어갈 때까지 기다리지 않고 즉시 데이터를 내보낸다. 이 경우 송신 TCP 패킷의 PSH 플래그가 1로 설정된다. 연결의 반대편인 '수신측' 종단에서는 PSH 플래그가 설정된 패킷을 수신하면 TCP세그먼트를 응용프로그램에 즉시 전달하도록 동작한다. PSH 플래그가 없다면 수신측에서도 버퍼에 일정량의 데이터가 모일때까지 기다렸다가 응용프로그램에 전달할 것이다.


설명이 어렵고 이해가 안된다면 아래 요약만 일단 기억하자

TCP의 push 기능은 다음 두 가지를 수행한다.

  • 송신측에서의 PSH 기능: 호스트의 응용프로그램(Application Layer)은 '이 데이터는 버퍼에 쌓지 말고 즉시 보내라' 고 TCP Layer에 알리는 역할을 한다.
  • 수신측에서의 PSH 기능: '이 데이터는 버퍼에 쌓지 말고 즉시 응용프로그램(Application Layer) 에 올려야 되겠군' 하고 수신측 호스트의 TCP Layer가 인식하게 하는 역할을 한다.


아래 패킷 캡쳐 예를 보자.

패킷 #36은 HTTP GET 요청인데, PSH 플래그를 사용하는 예를 볼 수 있다. 이 HTTP 요청에는 PSH 플래그가 설정되어 클라이언트에 추가 할 데이터가 더 이상 없고 요청이 애플리케이션 (이 경우 웹서버 데몬)에 즉시 전송되어야 함을 나타낸다. 다시 말하면, PSH 플래그는 송신기가 더 이상 송신 할 데이터가 없다는 것을 수신기에 알리기 위해 사용된다 (현재로서는).



HTTP.cap





앞서 언급 했듯이, PSH 플래그는 TCP를 통한 실시간 통신을 용이하게하기 위해 사용된다. 관심이 있다면 한가지 실험을 해보면 좋을것 같다. 텔넷의 패킷을 캡쳐해서 wireshark로 살펴보길 바란다. 텔넷 세션의 패킷 캡처는 텔넷 데이터를 전송하는 모든 패킷이 키 누름이 TCP에 의해 버퍼링되는 것을 방지하기 위해 PSH 플래그를 1로 설정되어 있음을 보여줄 것이다.



URG 플래그

URG 플래그는 이름 그대로 긴급(Urgent) 하다는 의미를 표시한다. 이 플래그는 수신측에게 '네가 현재 받은 TCP 세그먼트에 포함된 데이터는 긴급한 데이터야. 우선 처리되도록 우선순위를 높게 주길 바래' 쯤의 의미를 알리는 역할이다. 이때, 수신측 호스트의 TCP stack은 TCP 헤더의 16비트 필드인 'Urgent Pointer'를 측정하게 된다. Urgent Pointer는 '긴급한 정도'를 나타낸다. 얼마나 긴급한지 말이다.





URG 플래그는 현대의 프로토콜에서는 많이 사용되지 않는다. 왜냐하면 이 플래그의 사용이 더이상 추천되지 않기(RFC 6093) 때문이다. 아주 휘귀하다. 그러나 운 좋게도 이전에 언급 했던 텔넷의 패킷 캡처에서 URG 플래그의 예를 볼 수 있다. 


cm4116_telnet.cap





수신측 입장에서 패킷 #86에서 전송 된 0xFF 문자는 패킷 #70 의 텔넷 명령 0xF2 (242)보다 앞서서 전달된다. RFC 854[각주:1]에 따라, 이 명령은 TCP URG 플래그가 설정된 상태로 보내야한다. 패킷 #86의 긴급 포인터는 세그먼트의 첫 번째 바이트 (이 경우 전체 세그먼트)가 긴급 데이터로 간주되어야 함을 나타낸다.


이것은 URG 플래그의 가장 훌륭한 예는 아니겠지만, 현실에서의 여러 캡처를 아무리 살펴봐도 실제 사용되는 다른 예를 거의 찾아볼 수가 없었다.


TCP의 PSH 및 URG 기능에 대한 더욱 자세한 내용은 온라인 TCP/IP 가이드를 참조하길 바란다.


  1. RFC 854는 TELNET PROTOCOL SPECIFICATION 에 대한 내용이다. 다음 주소에서 확인할 수 있다. https://tools.ietf.org/html/rfc854 [본문으로]

'소프트웨어 Note > Network Technology' 카테고리의 다른 글

TCP Flags: PSH 그리고 URG  (0) 2017.09.29
무선 LAN, Wi-Fi 이야기  (0) 2017.02.08
이 댓글을 비밀 댓글로

렉서스 뉴IS250 - 그린텍 콘솔박스 트레이 구매 후기

by Blogger 하얀쿠아
2017.09.28 00:41 자동차/렉서스 3세대 IS250

구매 이유 



요즘 렉서스 뉴IS250을 잘 타고 다니다가, 문득 부족한 게 생각 났다.

동전을 보관할 만한 장소가 마땅치 않다는 것.

시청이나 구청 등 지자체에서 운영하는 주차장등을 사용할 때면, 몇백원 단위 요금이 부과되곤 한다.

카드로 결제하기에는 애매해서, 천원짜리 지폐를 지불하고 잔돈을 받으면 마땅히 둘곳이 없다.


그냥 콘솔박스에 넣거나, 컵 홀더에 넣긴 하는데...

지저분해 보이고, 특히  콘솔박스는 너무 정신없다는 생각이 들었다.


지갑, 세차카드, 주유적립카드, 레모나, 치실 등으로 정신없는 렉서스 IS250 콘솔박스 내부.


그래서 찾아본 것이, 콘솔박스 트레이!


지금은, 콘솔박스안에 RF방식의 하이패스 단말도 놓고, 지갑도 놓고, 세차카드나 주유적립카드 및 핸드크림, 레모나, 치실 등등이 있다. (치실은 왜있는거지....--?)

아무튼 하이패스 단말과 기타 여러가지들이 뒤섞여서 뭔가 필요한것 찾을때마다 좀 스트레스를 받는다.


콘솔 박스 정리 용품, 트레이

제품을 월요일에 주문했고, 화요일에 배송이 되어 퇴근하고 택배상자를 열어 제품을 확인해봤다.




동전놓는 곳에 동전을 채워넣고 싶어서, 물고기 배를갈랐다.

생각보다 가진게 얼마 없다. 가난하다.



이제는 배고픈 물고기 두마리.

동전을 채워놓은 모습

 

동전을 채워놓으니 기분이 좋다.




장착 사진


장착해보니 꼭 맞다. 깔끔하다.

유격없이 딱 맞다. 제품의 형상이나 마감은 완성도가 높다.

단순 플라스틱 성형 제품이긴 하지만, 모서리가 날카롭거나 하지 않고 마감을 꽤 신경쓴 느낌이다.

과격한 주행 중 차가 흔들려도 트레이로 인한 소음은 발생하지 않을 것으로 기대된다. (사실 과격한 주행중엔 아드레날린 분비로 심박수가 빨라져서 귀가 잘 안들린다.)


렉서스 뉴IS250 콘솔박스 트레이 장착 모습



특히, USB포트에서 시작되는 하이패스 단말의 전원 공급 케이블이, 트레이 측면으로 지나갈 수 있게 약간의 공간이 있어서 아주 마음에 드는 모양새다.

다 정리하고 나면, 나름 깔끔해 진다.








단점


렉서스 뉴IS250 용 콘솔박스 트레이의 단점은.. '지갑을 놓기에 너무 작다'.

사실 이 단점은 이 차의 콘솔박스 크기에 dependency(의존성)가 있다.

이 차 콘솔박스가 원체 작아서, 어쩔 수 없이 발생하는 단점이라 생각된다.


내가 사용하는 지갑은, 남성용 반지갑으로, 나의 손바닥 만하다.




그런데 이게 트레이에 놓을 수가 없다... - -

이참에 지갑을 머니클립으로 바꿔?

지갑이 들어있는 콘솔박스를 깔끔하게 정리하려고 트레이를 구매한 나에게는 충격적인 단점이다.




이렇게 놓아도 안된다.

방향을 돌려서 이렇게 놓아도 안된다.



이 사진같은 상황이다.

결국. 지갑은 도어의 물병 칸으로...


지갑은 결국 도어 스피커 옆 물병칸에 구겨넣었다.



가격

11번가에서 배송비 포함 약 27,000~28,000원 에서 구매 가능하다.

더 저렴해 보이는 제품(약 21,000원) 이 있으나 막상 구매하려고 보면 렉서스 차종 선택옵션이 있고, IS용은 34,000원을 요구한다. (ES용도 2만원대 초반인데, 이 판매자는 뭔가 이상하다)


다른 쇼핑몰 찾아보면 더 저렴한 제품도 있을 것 같다.







이 댓글을 비밀 댓글로

런플랫 타이어 (Run Flat Tire) 장점 단점

by Blogger 하얀쿠아
2017.09.21 00:23 자동차/자동차 이야기

자동차 타이어에 대한 관심

최근 타이어에 대한 관심이 생겼다.

얼마전 4만 km를 탄 타이어중 앞쪽 한개가 펑크나면서, 전체 4개를 일시에 교체하게 되면서이다.

어떤 타이어를 끼울까? 참많이 고민했다.


22살부터 현재까지 만 9년간 운전을 하면서 그동안 나는 타이어를 그다지 중요하지 않게 여겼다.

타이어란 단지, 오래오래 사용가능하고 굴러가기만 하면 된다고 생각했다.


그러나 우리나라 전체적인 자동차문화가 발달하고 그 깊이가 깊어지면서, 다양한 매체를 통해서 쉽게 자동차에 대한 정보를 접하게 되었다.

그러면서 자동차의 타이어에 관심을 갖게 되었다. 타이어의 중요성을 깨닫게 된 것이다.


여러 타이어 회사들은 단순히 내구성이 뛰어나다는 것을 떠나서 조금 더 접지력이 좋은 타이어, 특정 계절에 적합한 성능을 발휘하는 타이어, 소음이 적은 타이어,  연비가 좀 더 좋은 타이어를 출시하려고 노력한다. 그러나 이런 특성을 하나의 타이어에 모두 담지는 못한다. 연비가 좋으면 소음이 발생하기도 하고, 접지력이 좋으면 내구성이 떨어지기도 한다. 




아무튼 이런 타이어에 대한 특성들을 이해하고 타이어의 중요성을 인식한다면, 한번 교체할 때 자신의 운전성향 및 선호도에 맞는 타이어를 고를 수 있을 것이다.



런플랫 타이어란 ? (Run Flat Tire?)


런 플랫 타이어(Run Flat Tire)는 쉽게 말해 타이어에 손상이 생기는 경우, 흔히 말하는 '펑크'가 난 경우에도 타이어의 형상이 유지되어 정비소를 방문하기 전까지 일정 거리를 교환 없이 주행할 수 있는 타이어를 말한다. 영어로 펑크난 타이어를 'Flattend Tire' 라고 말하는데, 이런 경우에도 달릴수 있다는 의미로 'Run Flat Tire' 라고 말한다.


보통의 타이어의 경우 거의 틀림없이 내부에 공기나 혹은 질소와 같은 기체를 주입해 타이어를 부풀려서 형상을 유지하는데, 대개는 타이어 어딘가에 손상이 발생해 구멍이 나는 경우 내부에 주입되어 있던 기체가 구멍을 통해 빠져나감으로써 타이어의 형상이 무너지고 결국 타이어가 접지력을 완전히 상실하게 되어 주행불가 상태가 된다.


한국에서는 일반적으로 이런 상황에서 선택할 수 있는 옵션은 몇가지 있다.

1. 수리 가능한 경우 

  - 보험을 불러 지렁이를 박아서 펑크 부위를 막고, 다시 공기를 채워넣어 주행가능한 상태로 '임시' 복구한다.

  - 보험을 불러 정비소로 견인 하고, 펑크난 타이어는 버섯 패치 등,좀더 개선된 방법으로 수리한다. (지렁이 박는것보다 훨씬 비용은 높지만 더 내구도가 높다고 한다)

2. 수리 불가능한 경우 - 스페어 타이어로 교환을 한 후 정비소까지 일정 거리를 주행 한 뒤 타이어를 새것으로 교체한다.


런플랫 타이어의 경우는 내부, 특히 타이어의 형상을 유지하는 측면 부분에 형상을 유지할 수 있는 보강재를 덧붙임으로써 타이어의 형상을 최대한 유지하도록 설계되어있다. 그래서 공기가 빠지더라도 내부의 보강재로 인해 형태가 완전히 무너지지 않으며, 그래서 일정 거리를 공기가 빠진 상태에서도 주행할 수 있다. 즉, 스페어 교체를 하지 않아도 된다.


런플랫 타이어 단면도


런플랫 타이어 장점


'공기가 빠져도 형상이 무너지지 않아 일정 거리를 주행 가능하다' 

이것이 런플랫 타이어가 가진 가장 큰 장점 중 하나이다. 


다른 장점으로는 스페어 타이어를 차에 싣고다니지 않아도 된다. 굳이 스페어로 교체할 필요가 없기 때문이다. 

무거운 스페어 타이어와 스페어 휠을 빼고 다님으로 인한 무게 절감 -> 연비에서 유리한 이득이 있다.


고속도로 등에서 타이어가 펑크나고, 급격한 공기압 감소가 되어도 어느 정도 거리를 그대로 달릴 수 있기 때문에 위험하게 갓길에 차를 세우지 않아도 되며, 교체를 위해 번거로운 과정을 거치지 않아도 된다는 이점도 가지고 있다.


런플랫 타이어의 단면 - 강화 사이드월




런플랫 타이어 단점 

그러나 단점도 존재한다.


첫 번째 단점 '가격'

런 플랫 타이어가 가진 가장 큰 단점 중 하나는 가격이다. 가격이 일반 타이어에 비해 비싸다.

내부 보강재가 추가로 들어가 있기 때문에 그에 따른 단가 상승은 피할 수 없다. 당연한 단점이다.

아직 보편적이지 않아 사람들이 많이 찾지 않는 것도 가격이 떨어지지 않은 것도 이유 중 하나일 것이다.


두 번째 단점 '승차감'

comfort tire에 비해 '비교적' 좋지 않다는 의견이 일반적이다. 

타이어는 노면과의 접지력과 운전자가 느끼는 승차감에 영향을 주는 요소이다. 서스펜션과 함께 말이다.


타이어는 내부에 공기가 주입되어 있기에, 그 자체만으로도 훌륭한 완충 효과를 담당할 수 있다.

특히 주행 상태에 따라 적절하게 형태가 일그러지는 타이어의 측면은 일종의 스프링 역할을 수행함으로써 노면으로부터 전달되는 불필요한 진동을 완충해 주고 탑승자의 엉덩이가 승차감을 좋다고 느끼게하는 역할을 수행한다.


그런데 측면('사이드 월 - side wall'이라 한다)을 보강하여 단단해진 런플랫타이어는, 충격에 대한 완충효과가 줄어든다.

노면의 진동이 비교적 명확하게 운전자의 엉덩이에 전달된다는 의미다. 즉, 승차감에 있어서 일반 comfort tire에 비해 손해를 보게 된다.


세번째 단점 '소음'

같은 관점에서 접근하면, 측면이 단단하여 충격도 많이 전달하지만, 그만큼 노면의 소음도 많이 전달한다.

그래서 런 플랫 타이어는 승차감이나 소음 면에서 다소 불편하다는 의견이 많다.


네번째 단점 '연비'

보강재의 삽입으로 인해 타이어 자체의 무게가 무거워지므로 그에 따른 회전 저항이 커져 연비 면에서도 불리하다는 의견이 있다.



주행중 펑크 실험 비교영상 - 런플랫 타이어  vs 일반 타이어

2005년에 BMW에서 재미있는 실험을 했다.

주행을 하는 도중, 펑크 발생 시 런플랫 타이어와 런플랫이 아닌 타이어에 따른 차이를 비교했다.


영상을 보면, 특수 장치를 운전석 뒷바퀴에 장착한 후, 운전자가 버튼조작으로 공기압을 0으로 만든다.

이렇게 함으로써 펑크상황과 유사한 상황을 만들었다.


일반 타이어의 경우는 차량 한바퀴 회전하는 모습을 볼 수 있다.

운전석 뒤쪽 타이어의 공기압이 급격이 0이 되면서 해당 타이어의 형상이 찌그러지고, 접지력을 상실하며 발생하는 현상이다.


일반타이어의 주행 중 펑크 발생상황. 차량이 급회전 하는 것을 볼 수 있다.



반면에 런플랫 타이어를 끼우고 동일하게 시험한 영상에서는, 차량이 순각적으로 좌우로 흔들리지만 한바퀴를 급회전 하는 현상은 없었다.







전체 영상은 아래 영상을 참고하자.





개선되는 런플랫 타이어


단점이 꽤 많아보인다.

그렇지만 여러 타이어 제조사들은 이런 점들을 지속적으로 개선해 나가고 있는것으로 보인다.

그래서 최근에 출시되는 런플랫 타이어는 반드시 위와 같은 단점을 가진다고 확언할 수는 없다.





런플랫 타이어 만능은 아냐


런플랫 타이어라고 해도 만능은 아니다.


종종 런플랫 타이어를 사용하며 가장 크게 오해하는 부분 중 하나가, 타이어 펑크가 나도 계속 달릴 수 있다고 착각한다는 점이다.

분명한 것은 '일정 거리'를 교환 없이 달릴 수 있다는 것일 뿐, 수리 혹은 교환할 필요 없이 타이어가 완전히 닳을 때까지 사용할 수 있다는 뜻은 결코 아니다.


내부를 고무로 가득채워 형상을 유지하는 솔리드 타이어가 아닌 이상, 런플랫 타이어도 내부에 공기를 주입해야만 올바른 형상이 잡힌다.

만약 공기압이 비정상적으로 낮을 경우 타이어가 받게 되는 압력은 공기가 아닌 순전히 측면 보강재가 담당하게 된다.

이런 압력이 누적되면 측면 보강재도 결국은 손상될 수 있다. 보강재가 손상된 후 타이어 펑크를 수리 한다고 해도 제대로 된 성능을 기대하기는 어려울 것이다. (이미 늦었다.)


그래서 런플랫 타이어의 가장 이상적인 사용 형태는 타이어 손상이 발생함을 인식한 즉시 인근 정비소를 찾아가는 것이다.

이때 주행 속도는 높지 않아야 한다.

고속 주행을 할 경우 타이어에 전달되는 압력은 더욱 커질 수 밖에 없는데, 이 때 런플랫 타이어 내부 보강재 역시 높은 압력을 전달받게 된다. 따라서 타이어의 내구성 보존을 위해서라도 공기압 감소 경고등이 뜰 경우에는 속도를 줄이고 빨리 가까운 정비소로 가는 것이 바람직 하다 하겠다.


보통은 약 80km/h의 속도로 100km이내를 주행할 수 있다고 하는데, 되도록 빨리 정비소로 가서 수리를 받는 것이 옳다. 버팅기지 말고, 정비소를 찾아가자. 골든타임 놓치면 호미로 막을것 가래로 막게된다.


기억하자. 플랫 타이어의 경우 공기압의 손실이 발생하는 손상이 있더라도 교환 없이 어느 정도 주행할 수 있게 만든 타이어이지, 교환이나 수리할 필요조차 없는 만능타이어는 아니라는 것을.



이 댓글을 비밀 댓글로
    • 대청호돌이
    • 2017.10.30 13:31 신고
    좋은 내용 감사합니다
    가격이 40만원대라 부담은 되는 타이어네요 ㅎㅎ
    • 찾아보시면, 보급형으로 나온 20만원대의 저렴한 런플랫 타이어도 있긴 합니다. 저도 브리지스톤에서 나온 보급형 런플랫을 현재 사용해보는중이기도 하고요 ^^

[정비후기] 렉서스 IS250 타이어 교체 및 휠밸런스, 휠얼라이먼트 조정

by Blogger 하얀쿠아
2017.09.18 03:13 자동차/렉서스 3세대 IS250





7월 어느 여름날. 렉서스 뉴 IS250



교체 배경 - 타이어 펑크

한동안 탈없이 잘 타고 다니던 렉서스 뉴 IS250.

8월 초 비가 아주 많이 내리던 날 밤. 안산에 갔다가 다시 집으로 돌아오는 길에 뾰족한 못을 밟은 것 같다.


집에 돌아오면서 운전할 때는 그런걸 밟았는지, 타이어에 문제가 있는지 조차 몰랐다.


다음날 출근하려고 집 주차장에 내려가서 시동을 걸자, 타이어 공기압 경고등이 들어오는게 아닌가.

기온이 떨어져서 그런가 보다 라고 대수롭지 않게 넘기고 그대로 운전하여 출근했다.


그리고 저녁. 퇴근하려고 회사 주차장에서 차를 봤는데. 차가 한쪽으로 기우뚱 한 듯한 기분.


아차 싶었다. 타이어에 펑크가 난 것이었다.

일단, 가장 가까운 세차장에 가서 펑크난 타이어에 다시 공기를 주입 하곤  집으로 복귀했다.


그리고 하루가 더 지난 다음날.

집 주차장에 내려가 보았더니 ... 주행이 불가능한 상태였다.


조수석 앞쪽 타이어가 펑크났다. 공기압이 잔뜩 줄어, 타이어가 찌그러진 모습이다.



펑크 임시 조치 


일단 보험의 펑크 임시 수리 서비스를 요청해 놓은 뒤 고민했다.


어차피 총 주행거리 40,000km 를 넘기면서 타이어 트레드가 많이 달아서 교체할때가 되긴 했다.

사용하던 타이어는 '브리지스톤 Potenza RE092' (https://www.bridgestonetire.com/tire/potenza-re92)

High Performance 성향의 4계절용 타이어 인데, tirerack에서의 평점은 썩 좋지 못하다. 2.5/5 점.

아무래도 Performance 계열의 타이어를 찾고 사용하는 사람들은, 여름용 Performance 타이어와 이 타이어를 비교를 하며 가혹한 평가를 한 게 아닌가.. 하는 조심스러운 추측을 해본다.



기존 타이어 - Bridgestone Potenza RE92 평점

tirerack.com 에서 Potenza RE92 는 썩 좋은 평가를 받지 못하고 있다.



https://www.tirerack.com/tires/tires.jsp?tireMake=Bridgestone&tireModel=Potenza+RE92



아무튼, 나는 개인적으로 이 타이어를 '무난하다' 라고 평가하고 싶다.

별 5개에 3.5 개 정도는 주어도 된다.


기존 타이어 임시 조치


그런데, 이렇게 .. 잔인하게 못이 박혀버렸다.


이런 못대가리가 보인다. 제대로 박혔다.


못을뽑아내고, 지렁이를 박아 넣어 공기가 빠져나오지 못하도록 임시로 조치했다.



일단, 지렁이를 박아넣었다.

임시적으로 공기압이 부족해지는 것을 막아주어 저속주행은 가능해진다.

그런 뒤 어떤 타이어로 교체할지 고민했다.


새 타이어 선택 기준, 런플랫

2일정도 고민 끝에 '런플랫' 타이어를 선택하기로 했다. 

몇일전 친구의 포트홀에 의한 타이어 파손 사고소식을 전해듣고 런플랫 타이어가 상당히 장점이 많은 타이어라고 느꼈는데, 나도 이번기회에 런플랫 타이어[각주:1]를 사용해보기로 했다.


런플랫 타이어와 일반 타이어 비교



내 운전성향을 반영하여 아래처럼 4가지 기준을 잡았다.


1. 4계절 타이어를 선호함. - 도심 운전 위주이다. 내가 주로 운행하는 구간은 적설기간이 짧은 편이며(3개월) 눈이 오더라도, 도로 제설은 빠르게 잘 진행되는 곳이다.

2. 런플랫 타이어일 것. - 주행중 펑크발생시 차량 회전이나 뒤집어짐에 대한 공포를 심리적으로 경감시킬 목적(?).

3. 225/45R17 규격 일 것. - 휠 바꿀돈 없다. 순정이 좋다.

4. 성향은 High Performance 를 선호함. - 도로에 다른 차 없으면 그래도, 달리고는 싶다.


보급형 런플랫 - Bridgestone DriveGuard

자금 사정상 비싸고 좋은 타이어를 선택하진 못할 것 같았다.

그래서 보급형 런플랫을 찾아보게 되었고, Bridgestone의 DriveGuard를 선택했다.


이 타이어는 위 1~3 조건은 모두 만족하지만, 4는 아니다. 

성향은 Grand Touring 이다.


tire rack.com 에서의 평점은 별 4/5 개로 비교적 좋은 편이지만, 댓글은 상당히 호불호가 갈리는 듯하다.

대다수의 사람들은 주행질감이 좋다는 평이 있는 반면, 주행질감이 자갈받을 다니는 것 같다는 어느 스바루 임프레자 오너의 댓글도 있었다.


tire rack.com에서의 평점은 좋은 편이다.




브리지스톤 공식 홈페이지에서는 제품에 대한 정보를 아래와 같이 표시하고 있다.

런플랫 타이어이지만 TPMS만 설치되어있다면, 모든 차량에 장착이 가능한 것이 포인트 인듯하다.







DriveGuard 가격, 장착비, 공임비


타이어 구입 및 장착은 수원에 위치한 센트럴 모터스의 렉서스 서비스센터에서 진행했다.

가격은 생각보다 비싸지 않았다.


 항목

 금액

 DriveGuard 225/45R17

217,400 X 4 = 869,600

 교환 & 휠밸런스

107,200 

 휠얼라이먼트 조정 

140,700 


이와 같이 진행했고, 총 1,117,500 원의 비용이 들었다.



렉서스 New IS250 - DriveGuard 장착 사진



운전석 뒤쪽



앞으로 4~5만 km 정도 버텨주었으면 좋겠다 ^^

  1. 주행 중 손상에 의해 타이어 내의 공기압이 제로가 되어도 80km/h의 속도로 일정거리 이상 주행이 가능한 타이어를 런플랫 타이어라고 한다. [본문으로]
이 댓글을 비밀 댓글로

[C][CURL] CURLOPT_FOLLOWLOCATION 의 버전별 동작 차이

by Blogger 하얀쿠아
2017.08.31 01:49 소프트웨어 Note/C


C언어로 프로그램을 작성하다보면, HTTP 통신을 해야 할 때가 종종있는데, 이때 개인적으로 선호하는 라이브러리가 있다.

바로 CURL[각주:1] 이다. 라이브러리만을 따로 부를땐 libcurl 이라는 이름으로도 부른다.



이 libcurl을 사용해서 HTTP 처리를 하다보면, 서버가 주는 3xx 응답을 만날때가 있다. 이때 클라이언트는 이에 대한 추가적인 처리 - 변경 혹은 이동된 URL을 따라간다던가 하는 - 를 해야 할 경우가 있다.  libcurl은 이때 간단히 사용할 수 있는 옵션을 제공하는데 바로 'CURLOPT_FOLLOWLOCATION' 옵션이다.


우선 HTTP 3xx status에 대해 간단히 살펴보겠다.


300(여러 선택항목): 서버가 요청에 따라 여러 조치를 선택할 수 있다. 서버가 사용자 에이전트에 따라 수행할 작업을 선택하거나, 요청자가 선택할 수 있는 작업 목록을 제공한다.


301(영구 이동): 요청한 페이지를 새 위치로 영구적으로 이동했다. GET 또는 HEAD 요청에 대한 응답으로 이 응답을 표시하면 요청자가 자동으로 새 위치로 전달된다.


302(임시 이동): 현재 서버가 다른 위치의 페이지로 요청에 응답하고 있지만 요청자는 향후 요청 시 원래 위치를 계속 사용해야 한다.


303(기타 위치 보기): 요청자가 다른 위치에 별도의 GET 요청을 하여 응답을 검색할 경우 서버는 이 코드를 표시한다. HEAD 요청 이외의 모든 요청을 다른 위치로 자동으로 전달한다.


304(수정되지 않음): 마지막 요청 이후 요청한 페이지는 수정되지 않았다. 서버가 이 응답을 표시하면 페이지의 콘텐츠를 표시하지 않는다. 요청자가 마지막으로 페이지를 요청한 후 페이지가 변경되지 않으면 이 응답(If-Modified-Since HTTP 헤더라고 함)을 표시하도록 서버를 구성해야 한다.


305(프록시 사용): 요청자는 프록시를 사용하여 요청한 페이지만 액세스할 수 있다. 서버가 이 응답을 표시하면 요청자가 사용할 프록시를 가리키는 것이기도 하다.


307(임시 리다이렉션): 현재 서버가 다른 위치의 페이지로 요청에 응답하고 있지만 요청자는 향후 요청 시 원래 위치를 계속 사용해야 한다.


308(영구 리다이렉션, RFC에서 실험적으로 승인됨)


HTTP의 3xx 상태값은 총 9가지 상태가 IETF RFC 2616에 정의되어 있다.


예를들어 302(임시 이동 - temporarily moved) 를 서버로 부터 응답받았다고 하자. 서버는 보통 HTTP header에 이동된 URL을 함께 전달해야 한다.


HTTP 302 status header




위 사진들처럼 'Location:" 필드에 이동된 URL을 전달한다. 유의해야 할 점은, 서버에 따라  절대URL로 알려주기도 하고, 상대URL로 알려주기도 한다는 점이다.

이것을 자세히 알아보고자 하는건 아니고, libcurl을 사용할 때 이를 어떻게 처리할 지를 알아보고자 한다.



API header 및 prototype

#include <curl/curl.h>


CURLcode curl_easy_setopt(CURL *handle, CURLOPT_FOLLOWLOCATION, long enable);


앞서 언급한 CURLOPT_FOLLOWLOCATION 옵션은 curl_easy_setopt( ) 의 2번째 매개변수로 사용한다.

3번째 매개변수로 '0L' 혹은 '1L'을 줄수 있다. 어떤 값을 주느냐에 따라 동작이 달라진다.


0L : 3xx에 대해 libcurl은 아무런 처리를 하지 않는다.

1L : 3xx에 대해 libcurl의 내장된 로직으로 처리를 한다. 내장된 로직은 HTTP헤더의 Location: 필드의 URL로 HTTP request 다시 시도하는 것이다.


자세한 설명

3번째 'long enable' 매개변수를 1로 설정하면 libcurl 라이브러리가 3xx 응답을 받았을 때, HTTP 헤더의 일부로 서버가 보내는 Location: 필드의 값을 따라가도록 설정하는 것이다. Location: 필드는 따라야 할 상대URL 또는 절대URL가 지정될 수 있다.


libcurl은 새로운 URL에 대한 또 다른 요청을하고 더 이상 그러한 헤더가 반환되지 않을 때까지 새로운 Location: 헤더를 따라간다. CURLOPT_MAXREDIRS를 통해서 libcurl이 따라가는 'redirection'의 회수를 제한할 수 있다.


libcurl은 자동으로 따르는 프로토콜을 제한한다. 허용 된 프로토콜은 CURLOPT_REDIR_PROTOCOLS로 설정된다. 기본적으로 libcurl은 보안상의 이유로 인해 비활성화 된 프로토콜을 제외한 모든 프로토콜을 redirection 할 수 있다. => 7.19.4 버전부터 FILE 및 SCP 프로토콜이 비활성화되며, 7.40.0 버전부터는 SMB 및 SMBS도 비활성화된다.


Location을 따라갈 때, 3xx 응답 코드는 다음 요청에서 사용할 요청 방법을 지시한다. 301, 302 및 303 응답의 경우 CURLOPT_POSTREDIR이 libcurl을 지정하지 않는 한 libcurl은 메소드를 GET으로 전환합니다. 다른 모든 3xx 코드는 libcurl이 동일한 메소드를 다시 전송하도록 한다.


기존 위치 추적이 너무 단순하거나 기능이 부족하다고 생각하는 사용자라면, CURLOPT_FOLLOWLOCATION 대신 curl_easy_getinfo의 CURLINFO_REDIRECT_URL 옵션을 사용하여 redirection 추적 로직을 구현하는 것이 차라리 매우 싸게먹힌다.



겪은 이슈

libcurl 7.40 버전과 libcurl 7.50 버전에서 모든 세팅을 동일하게 했으나 서로 다른 동작을 하는 경우가 있다. 예상치 못한 문제였다.


조건

1. CURLOPT_PROXY로 proxy server를 사용하도록 libcurl을 설정할 것

2. CURLOPT_FOLLOWLOCATION를 사용하도록 libcurl을 설정할 것

3. 위 1에서 설정한 proxy server가 꽤나 저성능(기능도 적고, 단순하고, 스마트하지 못한)일 것


위 조건을 만족한 상태에서, 예를들어, http://x-sub.abcd.com/first.html 을 요청(HTTP GET)했다고 하자. 

그리고 x-sub.abcd.com 서버가 302 상태값과 함께 Location: http://subdomain.abcd.com/second.html 을 주었다고 가정하자. 

main domain은 abcd.com으로 동일하지만 sub domain이 다르며, 각각의 sub domain을 호스팅하는 서버가 물리적으로 다를 수 있다.


libcurl 7.40 동작

프록시 서버와 연결 -> HTTP GET 으로 http://x-sub.abcd.com/first.html 를 요청함.

-> 302  Location: http://subdomain.abcd.com/second.html 를 받음 -> 프록시 서버와 새로운 포트로 새로운 연결 -> http://subdomain.abcd.com/second.html 를 요청함 -> 200 OK 받음 -> 프록시 서버와 연결 끊음 -> 프록시 서버와 새로운 포트로 새롭게 열었던 연결 끊음


libcurl 7.50 동작

프록시 서버와 연결 -> HTTP GET 으로 http://x-sub.abcd.com/first.html 를 요청함.

-> 302  Location: http://subdomain.abcd.com/second.html 를 받음 ->  http://subdomain.abcd.com/second.html 를 요청함 -> 404 Not found 받음 -> 프록시 서버와 연결 끊음


libcurl 7.50에서는 프록시 서버와 새로운 포트로 새롭게 연결하는 동작이 없었다. 이 점은 개선된 점이다. 프록시 서버와 매번 연결하는 부하를 줄였다. 그런데 redirection URL의 서버가 물리적으로 다른 경우, 프록시 서버에서 새로운 서버로 연결을 진행해야 할 것 같은데, 그렇지 않은 경우가 있었다. 첫번째 요청했던 서버한테 그대로 redirection URL의 resource를 HTTP GET 으로 요청하는 것처럼 보였다.


해결방법

이를 해결하기 위해서는 아래와 같이 했다.


1. CURLOPT_FOLLOWLOCATION 를 사용하지 않도록 0L 로 libcurl을 설정한다.

2. 요청하려는 URL로의 curl_easy_perform의 반환값이 CURLE_OK 인 경우

 2-1. curl_easy_getinfo(curl, CURLINFO_REDIRECT_URL, &url) 

 2-2. url 이 존재하는 경우

  2-2-1. redirection url이므로 다시 curl_easy_perform을 수행한다.



기본값

0L (비활성화)


프로토콜

HTTP(S)





예제 코드

CURL *curl = curl_easy_init();
if(curl) {
  curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
 
  /* example.com is redirected, so we tell libcurl to follow redirection */
  curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
 
  curl_easy_perform(curl);
}


사용가능성

HTTP와 사용가능하다.


반환값

HTTP가 지원되면 CURLE_OK를 반환하고 그렇지 않으면 CURLE_UNKNOWN_OPTION을 반환한다.


같이 보기

CURLOPT_REDIR_PROTOCOLS

CURLOPT_PROTOCOLS

CURLOPT_POSTREDIR

CURLINFO_REDIRECT_URL

CURLINFO_REDIRECT_COUNT

  1. cURL(/kɝl/ 또는 /kə:l/)은 다양한 통신 프로토콜을 이용하여 데이터를 전송하기 위한 라이브러리와 명령 줄 도구를 제공하는 컴퓨터 소프트웨어 프로젝트이다. 이 cURL 프로젝트는 libcurl와 cURL이라는 2개의 제품을 만든다. [본문으로]
이 댓글을 비밀 댓글로

[NMEA-0183] Checksum 계산 예제코드 (How to calculate checksum of NMEA-0183)

by Blogger 하얀쿠아
2017.08.26 15:52 하드웨어 Note/GPS 이야기

본 포스팅에서 다뤄볼 내용은 NMEA-0183 문장의 checksum 계산 방법이다.

보통 GPS chip은 해석한 GPS신호를 NMEA라는 특정 형태의 프로토콜로 제공한다.

NMEA 가 무엇인지에 대해서 더 자세히 알고싶다면 아래 포스팅을 참고하도록 하자.


2017/08/10 - [하드웨어 Note/GPS 이야기] - [GPS 이야기] NMEA-0183 형식, NMEA Sentence Format


위 포스팅에 나와있듯이, NMEA sentence는 $ 문자로 시작해서 * 문자로 끝난다.

checksum의 계산은 $, * 의 사이에 있는 각각의 문자 하나하나를 exclusive-or (XOR) 연산 및 누적하면 된다.

어떤 NMEA sentence가 주어졌을 때, "*" 뒤에 있는 16진수 두자리의 checksum도 같이 주어질 텐데, 직접 XOR연산하여 checksum을 계산한 값과 주어진 checksum값이 일치하는지를 검사해야 한다. 일치하지 않는다면, 그 sentence는 통신상의 문제 등의 이유로, 결함이 있는 것으로 간주해야 하며, 사용하면 안된다. 




구체적인 계산 예제 코드를 제시한다.




NMEA 체크섬 계산 함수(JAVA 버전)

char checkSum(String nmeaStr) {
  char check = 0;
  // iterate over the string, XOR each byte with the total sum:
  for (int c = 0; c < theseChars.length(); c++) {
    check = char(check ^ theseChars.charAt(c));
  } 
  // return the result
  return check;
}


인자 'nmeaStr' 은 $와 * 사이의 NMEA문자열을 넣으면 된다. 각 문자 하나하나를 XOR연산하여 'check' 변수에 저장하여 반환한다.

return type은 char 이다. 이것을 2bytes hex string으로 변환해서 사용하면 된다.




NMEA 체크섬 계산 함수 (C 버전 1)

#include <stdint.h>

#define NMEA_END_CHAR_1 '\n'
#define NMEA_MAX_LENGTH 70

uint8_t
nmea_get_checksum(const char *nmea_str)
{
    const char *n = NULL;
    uint8_t chk = 0;
    if (strcmp(nmea_str[0], '$') == 0) {
        n = nmea_str + 1; // skip '$' by plus one
    } else {
        n = nmea_str;
    }

    /* While current char isn't '*' or sentence ending (newline) */
    while ('*' != *n && NMEA_END_CHAR_1 != *n) {
        if ('\0' == *n || n - sentence > NMEA_MAX_LENGTH) {
            /* Sentence too long or short */
            return 0;
        }
        chk ^= (uint8_t) *n;
        n++;
    }

    return chk;
}


인자 nmea_str은 $와 * 사이의 NMEA sentence를 넣으면 된다. 그러나 만약 인자로 들어오는 NMEA sentence가 $ 를 포함하고 있다면 생략하도록 방어코드를 넣어 두었다.

이제, checksum 값은 아래와 같이 계산하면 된다.

GPRMCBuf 가 NMEA sentence이다.


uint8_t chk = nmea_get_checksum(GPRMCBuf);



NMEA 체크섬 계산 함수 (C 버전 2)

또다른 방법으로 NMEA의 checksum 계산을 구현한 C언어 버전이다. 

첫번째 인자 'buf'가 계산하려는 NMEA sentence이다. 위의 버전1과는 달리 $ 부터 * 까지의 NMEA sentence를 인자로 넣어도 된다. 

두번째 인자 'len'는 buf의 길이이다.

int calc_NMEA_Checksum( char *buf, int len )
{
    char Character;
    int Checksum = 0;
    int i;              // loop counter

    // foreach(char Character in sentence)
    for (i=0; i < len; ++i)
    {
        Character = buf[i];
        switch(Character)
        {
            case '$':
                // Ignore the dollar sign
                break;
            case '*':
                // Stop processing before the asterisk
                i = len;
                continue;
            default:
                // Is this the first value for the checksum?
                if (Checksum == 0)
                {
                    // Yes. Set the checksum to the value
                    Checksum = Character;
                }
                else
                {
                    // No. XOR the checksum with this character's value
                    Checksum = Checksum ^ Character;
                }
                break;
        }
    }

    // Return the checksum
    return Checksum;
}



이 함수를 통해 checksum을 계산하면 int 형 결과가 반환된다.

이제, 비교하려는 NMEA sentence에서 2bytes의 char형 checksum 문자를 읽고, 1byte의 hex형으로 변환 한 후, 위 함수의 반환값과 비교하면 된다.

이 댓글을 비밀 댓글로

[GPS 이야기] NMEA-0183 형식, NMEA Sentence Format

by Blogger 하얀쿠아
2017.08.10 00:15 하드웨어 Note/GPS 이야기

만약 당신이 GNSS와 직접적으로 관련된 일을 한다면.

혹은 간접적으로 GPS등과 같은 것을 통해 얻은 위치정보등을 다뤄야 할 일이 있다면.

조만간 'NMEA' 라는 것을 마주하게 될 수도 있다.


위치정보라는것은 어떤 목적으로 활용하느냐에 따라 다뤄야 하는 데이터는 달라진다.  

현재 위치에 기반하여 날씨정보를 보여주는 어플리케이션처럼 간단히 위도, 경도만 알면 되는 경우가 있는가 하면,

목적지까지 경로를 알려주는 내비게이션 어플리케이션처럼 때로는 위도, 경도 뿐만아니라 속도, 위치정확도 오차값, 방향.. 등을 알아야 하는 경우도 존재 한다.

또한 종종 등산 트래커 어플리케이션처럼 고도를 활용하는 경우도 있다. 사실 고가의 GPS가 아닌 이상, 스마트폰과 같은 저렴한 GPS칩이 주는 고도값은 부정확하다고 알려져있다.


그리고 이 와중에, NMEA라는 것이 있다. 자세히는 몰라도 되는 것이지만, 알면 도움이 될 수도 있다. (알면 좀 있어보이기도 한다.) 

이 포스팅에서는 NMEA란 무엇이고, NMEA데이터를 해석하기 위해 알아야 할 내용들을 간략히 다루어 보겠다.

NMEA의 개념정도를 잡아보자는 생각으로 가볍게 읽어보자.


지구에서 보이는 위성의 개수 이해하기



NMEA 개요

NMEA는 'National Marine Electronics Association'의 앞글자를 딴 약자이다.

해양 전자공학 산업의 발달과 교육을 위해 모인 비영리 단체를 지칭한다.

그리고 NMEA 표준은 ”해양 전자 장비 기자재들 간의 통신을 위해 정의된 전기적 인터페이스 및 데이터 프로토콜” 이라고 정의할 수 있다.


해양 전자 장비 기자재들 간의 통신을 위해 정의된 전기적 인터페이스 및 데이터 프로토콜


NMEA에서는 몇가지 프로토콜을 정의 했는데, 현재 GPS통신에서는 'NMEA-0183'을 표준 프로토콜로 사용하고 있다.

표준을 관리하는 NMEA의 웹사이트는 http://www.nmea.org 이니 알아두도록 하자.






NMEA 들여다보기

NMEA Sentence 기본 형태

먼저 어떤 모양인지 보자. NMEA는 아래와 같은 형태로 되어있다.


$GPGGA,141113.999,3730.0308,N,12655.2369,E,1,06,1.7,98.9,M,,,,0000*3E

$GPGSA,A,3,02,07,01,20,04,13,,,,,,,3.7,1.7,3.2*31 

$GPRMC,141113.999,A,3730.0308,N,12655.2369,E,19.77,195.23,101200,,*3C

$GPGGA,141114.999,3730.0264,N,12655.2351,E,1,07,1.2,98.8,M,,,,0000*3C 

$GPGSA,A,3,02,07,01,20,24,04,13,,,,,,2.3,1.2,1.9*3E

$GPRMC,141114.999,A,3730.0264,N,12655.2351,E,15.51,202.12,101200,,*3C 

$GPGGA,141115.999,3730.0231,N,12655.2345,E,1,07,1.2,98.7,M,,,,0000*37

$GPGSA,A,3,02,07,01,20,24,04,13,,,,,,2.3,1.2,1.9*3E

$GPGSV,2,1,07,07,84,025,47,04,51,289,48,20,40,048,47,02,32,203,46*74

$GPGSV,2,2,07,01,23,101,47,13,20,131,32,24,19,268,40*49

$GPRMC,141115.999,A,3730.0231,N,12655.2345,E,12.14,194.75,101200,,*33

$GPGGA,141116.999,3730.0210,N,12655.2330,E,1,07,1.2,98.5,M,,,,0000*37

$GPGSA,A,3,02,07,01,20,24,04,13,,,,,,2.3,1.2,1.9*3E

$GPRMC,141116.999,A,3730.0210,N,12655.2330,E,8.01,194.65,101200,,*0F

$GPGGA,141117.998,3730.0199,N,12655.2320,E,1,06,1.3,98.2,M,,,,0000*33

$GPGSA,A,3,02,07,01,20,24,04,,,,,,,2.4,1.3,2.0*30


GNSS에서는 언제 NMEA-0183을 사용하는가?

위성신호를 해석해낸 GPS수신기가 해석한 정보를 외부에 알리는데 사용하는 방법이다.

GPS측위가 시작되면 GPS위성으로부터의 반송파에 실려오는 데이터를 GPS수신기는 해석을 할텐데, 해석되는 내용을 알려주는 방식이라고 이해하면 쉽다.


GPS수신기는 이와 같은 내용을 1초 ~ 수초마다 Serial 출력의 형태로 내보낸다.

위의 예를 보면 '$' 라는 문자로 시작되는데, 이렇게 $로 시작되는 각각의 한줄을 'NMEA Sentence' 혹은 'NMEA 문장' 이라고 부른다.


이 그림은 GPS수신기가 GPS위성 시스템으로부터 반송파를 받아 해석한 후, NMEA 문장(혹은 NMEA 메세지)으로 내보내는 과정을 보여주고 있다. 

NMEA메세지는 기본적으로 정보나 데이터의 패킷이다. 

GPS수신기는 해석된 각각의 정보를 이 NMEA메세지를 한줄 한줄 내보내는데, 이 NMEA메세지는 여러 타입으로 분류된다. 각 NMEA메세지는 타입에 따라 고유한 프로토콜을 가지고 있다. 따라서, 타입을 먼저 파악 한 후, 그에 맞는 프로토콜로 해석을 해야 한다. 타입은 NMEA메세지의 'Device ID'와 'Sentence ID'라고 불리는 첫 5글자를 읽어서 파악할 수 있다.


보다 더 자세한 내용은 아래에서 설명한다.


NMEA Sentence 구성요소

그럼 NMEA Sentence의 구성요소를 알아보자.


$ - 문장의 시작을 의미함


Linefeed - 문장의 끝을 의미함, 줄바꿈 문자 <CR>/<LF> 를 말한다.


Device ID - 장치를 구분하는 용도다. 현재 이 데이터를 말하는 장치의 ID라는 의미로 'Talker ID'라고도 부른다. '$' 바로 다음에 오는 문자 2개. 예를 들면 'GP' 와 같은 것.


Sentence ID - 문장을 구분하는 용도다. Sentence Name이라고도 한다. Device ID 다음에 오는 문자 3개. 예를 들면 'RMC' 와 같은 것.


콤마 - 각 필드를 구분하는 용도이다.




$GPRMC,141114.999,A,3730.0264,N,12655.2351,E,15.51,202.12,101200,,*3C


이 문장을 다시 보자.

문장의 시작을 의미하는 $ 보이고, GP라는 Device ID(Talker ID)를 가지고 있으며, RMC라는 Sentence ID(Sentence Name)을 가지고 있다.

맨 마지막에 붙는 '3C'는 checksum값이다. 두자리 16진수 이다. 데이터가 올바르게 전달 되었는지 확인하는 용도이다.

checksum 계산 방법은 아래부분에서 다루도록 하겠다.


자, 색상으로 칠해진 부분은 이제 읽을 줄 알게 되었다.

가운데 검은색 부분은 어떻게 읽으면 되는지 알아보자. 어떻게 읽는지는, Sentence ID에 따라 달라진다.


참고로, 통상적인 GPS 수신기에서는 몇가지 Device ID만 제한적으로 출력된다.


GP - Global Positioning System receive

LC - Loran-C receive

OM - Omega Navigation receive



GPGGA

GPGGA는 'Global Positioning System Fix Data'를 의미한다.  아래의 GPGGA 예제 sentence를 살펴보자.

GPGGA는 총 17개의 field를 가진다. 

참고로 예제에서는 12 ~ 15 필드는 비어 있다.

그리고, 17번 필드는 그림에서는 보이지 않는데, 그 이유는 Terminator문자인 CR/LF 이기 때문이다.


NMEA-0183 GPGGA 문장의 예





 Idx

 Field

 Value

 Comments

 1

 Sentence ID

 $GPGGA

 Global Positioning system fixed data

 2

 UTC Time

 141113.999

 시각. hhmmss.sss 형태이다. 

 예제는 14시 11분 13.999초 라는 의미이다. 세계 표준시 이므로 한국에서 사용하려면 +9 를 해야 한다.

 참고로 날짜는 GPGGA로는 확인 할 수 없고, GPRMC에서 처리해야 한다.

 3

 Latitude

 3730.0308

 위도. ddmm.mmmm 형식이다. 앞의 2자가 '도' 이고 이후는 '분' 이다.

 *'도분초' 형식이 아닌 '도분' 인것을 유의할 것. 

 필요하다면 소수점 아래는 60을 곱하여 '초' 형식으로 변환 해야 한다.

 => 0.0308분 x 60 = 1.848 초

 4

 N/S Indicator

 N

 N = North, S = South

 북위 인지 남위 인지를 나타낸다.

 5

 Longitude

 12655.2369

 경도. dddmm.mmmm 형식이다.  앞의 3자가 '도' 이고 이후는 '분' 이다. 

 *'도분초' 형식이 아닌 '도분' 인것을 유의할 것. 

 필요하다면 소수점 아래는 60을 곱하여 '초' 형식으로 변환 해야 한다.

 6

 E/W Indicator

 E

 E = East, W = West, 

 동경인지 서경인지를 나타낸다.

 7

 Position Fix

 1

 0 = Invalid, 1 = Valid SPS, 2 = Valid DGPS, 3 = Valid PPS

 위치가 결정 됐는지를 나타낸다. 이 값이 0이면 위도, 경도 등을 믿을 수 없으므로 사용하면 안된다.

 8

 Satellites Used

 06

 Satellites being used (0-12)

 현재 수신되는 위성의 개수이다.

 9

 HDOP

 1.7

 Horizontal Dilution of Precision

 10

 Altitude

 98.9

 WGS-84 타원체에서  평균해수면(MSL : Mean Sea Level)을 기준으로 한 고도.

 고도값의 단위는 다음에 오는 Altitude Units 필드가 결정한다.

 11

 Altitude Units

 M

 M = Meters

 12

 Geoid Seperation

 (empty) 

 Geoid seperation in meters according to WGS-84 ellipsoid

 MSL과 Geoid의 고도차. 마이너스 값이 나올 수 있다.

 13

 Seperation Units

 (empty)

 M = Meters

 14

 DGPS Age

 (empty)

 Age of DGPS data in seconds

 15

 DPGS Station ID

 0

 

 16

 Checksum

 *3E

 

 17

 Terminator

 CR/LF

 


몇가지 부연설명을 하고자 한다.


10번의 고도값이 있는데, 이는 생각보다 부정확하다. 일반적으로 GPS는 수평오차보다 수직오차가 크다고 알려져있다. 간단하게 말하면 위성이 우리의 발 밑에는 없고 전부 머리 위에 있기 때문으로 이해하면 될 것같다. 즉, 고도 값 자체를 너무 신뢰하지는 말아야 한다.


12번에서 언급하는 Geoid와 WGS-84 타원체는 좌표에 대해 다루면서 좀 더 자세히 알아보겠다. GPS에서 등장하는 경도, 위도 좌표는 모두 WGS-84 타원체를 기준으로 하고 있다고만 알아두자.





GPRMC

문서에 의하면 GPRMC는 'Recommended Minimum Specific GNSS Data'로 정의되어있다. 

NMEA에는 GPS에서 필수적인 PVT(Position, Velocity, Time) 데이터의 고유한 버전이 있다. 

그것을 RMC라고 부른다. 'RMC'에서 RM이 Recommended Minimum의 약자이고, C는 GNSS를 의미한다. RMA, RMB도 있으며 각각 LORAN-C와 Navigation을 의미한다. 상식으로 알아두자.


아래와 같은 형태이다.


NMEA-0183 GPRMC 문장의 예



 idx

 Field

 Value

 Comments

 1

 Sentence ID

 $GPRMC

 Recommended Minimum Specific GNSS Data

 2

 UTC Time

 141113.999

 UTC시각. hhmmss.sss 형태. 예제는 14시 11분 13.999초 이다.

 3

 Status

 A

 A = Active, V = Void

 GPGGA의 7번항목, Position Fix와 유사하다. 차이점은 GPRMC가 더 간단하게 2-상태 라는 점. 

 V이면 신뢰할 수 없는 상태이다.

 4

 Latitude

 3730.0308

 위도. ddmm.mmmm

 37도 30.0308'

 5

 N/S Indicator

 N

 N = North, S = South

 북위 인지 남위 인지를 나타낸다.

 6

 Longitude

 12655.2369

 경도. dddmm.mmmm

 126도 55.2369'

 7

 E/W Indicator

 E

 E = East, W = West, 

 동경인지 서경인지를 나타낸다.

 8

 Speed over ground

 19.77

 Knots 단위의 속도이다. 

 km/h 로 변환하려면 1.852 를 곱하면 된다.

 eg. 19.77 (Knots) x 1.852 = 36.61404 (km/h)

 9

 Course over ground

 195.23

 Degrees. 진행방향을 표현한다.

 진북을 중심으로 시계방향으로 0 보다 같거나 크고, 360 보다 작은 범위의 각도값이 주어진다.

 여기서 말하는 '진북'은 WGS-84 타원체를 중심으로 한 것이다.

 10

 UTC Date

 101200

 UTC날짜. DDMMYY

 eg. 101200은 2000년 12월 10일을 의미한다.

 11

 Magnetic variation

 (empty)

 Degrees. '자북' 과 9번에서 말한 '진북' 과의 차이를 각도로 표시한 것이다.

 통상적인 GPS에서는 대개 NULL로 채워져 있다.

 12

 Checksum

 *3C

 

 13

 Terminator

 CR/LF

 



GPGSA

문서에 의하면 GSA는 "GNSS DOP and Active Satellite"를 의미한다고 되어있다. GSA는 단독으로 쓰이기 보다는 GSV와 조합해서 위성상태를 확인하거나 Graphical하게 천공도를 그리는데 사용될 수 있다.


NMEA-0183 GPGSA 문장의 예




4번부터 15까지는 수신기에 잡힌 GPS위성의 번호가 나와 있다. 일반적으로 12채널 GPS수신기라고 말하면 위성신호를 12개 까지 수신할 수 있다는 의미이다. GPS위성 전용 수신기는 12채널이면 충분하며, 사실 그 이상은 의미가 없다. 왜냐하면, GPS위성은 총 24개가 배열되어 있고, 지표면상에서는 12개 이상의 위성은 보이지 않도록 각 위성의 궤도를 설정하기 때문이다. 물론, 높은 하늘에서라면 이야기가 달라진다. 지표면에서 사용하는게 아닌, 항공기나 전투기 등에서 사용하는 GPS수신기는 12채널 이상이어도 의미가 있다는 얘기. 


그런데 예외가 있다. GPS 뿐만 아니라, GLONASS, Baidu, Galieo 위성 등 위치 측위에 사용할 수 있는 위성들이 여럿 존재한다. 이들 모두을 동시에 수신할 수 있는 수신기의 경우에는 또 이야기가 달라진다. 비글보드, 라즈베리파이 등에 붙여서 자주 사용되는 제품중에 'Adafruit Ultimate GPS breakout' 이란 것이 있는데, 66채널 수신이 가능한 제품이다. 

Link : https://www.adafruit.com/product/746


또한 참고로, NMEA sentence상에서 수신되지 않은 위성의 자리는 NULL처리되어 있다.


16번부터 18까지는 위성의 측위 오차에 관한 항목이다. 

수신기에서 4개이상의 위성이 감지되더라도 수신기는 PDOP이 최소인 위성 4개의 배열을 잡아 위치를 계산해 낸다. 

 PDOP은 수신기 위치를 꼭지점으로 각각의 위성이 이르는 사각뿔의 체적에 반비례한다. 체적이 큰 경우가 측위 오차가 적게 되는데 이는 위성이 널리 퍼져 오차가 상쇄되기 때문으로 이해하면 될 것이다. 수직방향은 그러한 상쇄되는 면이 없기 때문에 (위성은 전부 하늘에 있다.) 수평오차보다 크게 된다.

 VDOP은 수직오차를 HDOP은 수평오차를 말한다. PDOP = Sqrt(HDOP*HDOP + VDOP*VDOP)의 관계가 성립한다. 최적값은 1.0으로 대개 6이하면 쓸만하다고 보면 된다.

사실 전문가가 아니면 크게 필요없는 내용이다. 더 자세한 내용을 알고자 하면 인터넷에서 검색해보기 바란다. 상당히 많은 내용이 나와 있을 것이다.



GPGSV

GSV는 'GNSS Satellite in View' 를 의미한다. 각각 위성의 상태에 대해 나와있는 문장이다.

아래와 같은 모양이다.



NMEA-0183 GPGSV 문장의 예


그런데, GSV를 해석할 때 유의할 점 한가지가 있다.

GSV는 한 문장에 4개의 위성에 대한 정보만을 가진다. 따라서 만약 총 12개의 위성을 수신 중인 상황 에는 GPGSV문장이 3개 연속으로 등장하게 된다. 만약 7개의 위성을 수신 중인 상황에서는 GPGSV문장이 2개 연속으로 등장하게 될 것이다.




NMEA checksum 계산방법 및 예제코드

지금까지 예제로 보여준 NMEA sentence들을 살펴보면 알겠지만, checksum은 * 뒤에 16진수 두자리로 표시한다.

checksum의 계산은 $, * 의 사이에 있는 각 문자를 exclusive-or (XOR) 연산한 값을 표시한다.

어떤 NMEA sentence가 주어지면, "*" 뒤에 있는 16진수 두자리의 checksum과 직접 XOR연산한 값이 일치하는지를 검사해야 한다. 일치하지 않는다면, 그 sentence는 통신상의 문제 등의 이유로, 결함이 있는 것으로 간주해야 하며, 사용하면 안된다. 


예를 들어보자.


$GPRMC,155123.000,A,4043.8432,N,07359.7653,W,0.15,83.25,200407,,*28


이와 같은 NMEA sentence가 주어졌을때, checksum계산을 위한 XOR연산은 아래 각 문자들에 대해서 수행하면 된다.


GPRMC,155123.000,A,4043.8432,N,07359.7653,W,0.15,83.25,200407,,



Checksum 계산 하는 코드는 다음 포스팅을 참고하기 바란다.


2017/08/26 - [하드웨어 Note/GPS 이야기] - [NMEA-0183] Checksum 계산 예제코드 (How to calculate checksum of NMEA-0183)





NMEA Sentence ID (Sentence Name) 목록

아래는 NMEA Sentence의 모든  ID와 그것이 어떤 것을 의미하는지를 나열 한 것이다.

또한, 첨부파일을 참고해도 좋다.


nmea_0183_identifier_list(20130801).pdf

여기까지 읽었으면, GPRMC, GPGGA, GPGSA, GPGSV 이렇게 4개 설명하는데도 상당한 양이라는 것을 알 것이다. 따라서 모든 내용을 다루기엔 무리가 있다.

각 항목 하나하나의 자세한 설명은 본 포스팅에서는 더이상 하지 않기로 한다.

우선 각 코드들의 의미 정도만 파악해 보고, 자세한 내용은 추후에 기회가 된다면 다뤄보겠다.

  • $GPAAM - Waypoint Arrival Alarm
  • $GPALM - GPS Almanac Data
  • $GPAPA - Autopilot format "A"
  • $GPAPB - Autopilot format "B"
  • $GPASD - Autopilot System Data
  • $GPBEC - Bearing & Distance to Waypoint, Dead Reckoning
  • $GPBOD - Bearing, Origin to Destination
  • $GPBWC - Bearing & Distance to Waypoint, Great Circle
  • $GPBWR - Bearing & Distance to Waypoint, Rhumb Line
  • $GPBWW - Bearing, Waypoint to Waypoint
  • $GPDBT - Depth Below Transducer
  • $GPDCN - Decca Position
  • $GPDPT - Depth
  • $GPFSI - Frequency Set Information
  • $GPGGA - Global Positioning System Fix Data
  • $GPGLC - Geographic Position, Loran-C
  • $GPGLL - Geographic Position, Latitude/Longitude
  • $GPGRS - GPS Range Residuals
  • $GPGSA - GPS DOP and Active Satellites
  • $GPGST - GPS Pseudorange Noise Statistics
  • $GPGSV - GPS Satellites in View
  • $GPGXA - TRANSIT Position
  • $GPHDG - Heading, Deviation & Variation
  • $GPHDT - Heading, True
  • $GPHSC - Heading Steering Command
  • $GPLCD - Loran-C Signal Data
  • $GPMSK - Control for a Beacon Receiver
  • $GPMSS - Beacon Receiver Status
  • $GPMTA - Air Temperature (to be phased out)
  • $GPMTW - Water Temperature
  • $GPMWD - Wind Direction
  • $GPMWV - Wind Speed and Angle
  • $GPOLN - Omega Lane Numbers
  • $GPOSD - Own Ship Data
  • $GPR00 - Waypoint active route (not standard)
  • $GPRMA - Recommended Minimum Specific Loran-C Data
  • $GPRMB - Recommended Minimum Navigation Information
  • $GPRMC - Recommended Minimum Specific GPS/TRANSIT Data
  • $GPROT - Rate of Turn
  • $GPRPM - Revolutions
  • $GPRSA - Rudder Sensor Angle
  • $GPRSD - RADAR System Data
  • $GPRTE - Routes
  • $GPSFI - Scanning Frequency Information
  • $GPSTN - Multiple Data ID
  • $GPTRF - TRANSIT Fix Data
  • $GPTTM - Tracked Target Message
  • $GPVBW - Dual Ground/Water Speed
  • $GPVDR - Set and Drift
  • $GPVHW - Water Speed and Heading
  • $GPVLW - Distance Traveled through the Water
  • $GPVPW - Speed, Measured Parallel to Wind
  • $GPVTG - Track Made Good and Ground Speed
  • $GPWCV - Waypoint Closure Velocity
  • $GPWNC - Distance, Waypoint to Waypoint
  • $GPWPL - Waypoint Location
  • $GPXDR - Transducer Measurements
  • $GPXTE - Cross-Track Error, Measured
  • $GPXTR - Cross-Track Error, Dead Reckoning
  • $GPZDA - UTC Date / Time and Local Time Zone Offset
  • $GPZFO - UTC & Time from Origin Waypoint
  • $GPZTG - UTC & Time to Destination Waypoint



참고 [GNSS, NMEA-0183(National Marine Electronics Association) Format 쉽게 설명] : http://joongyup.egloos.com/9173927

참고 [Glenn Baddeley - GPS - NMEA sentence information] : http://home.mira.net/~gnb/gps/nmea.html

참고 : [NMEA data] http://www.gpsinformation.org/dale/nmea.htm






이 글이 도움이 되었다면 아래 '공감' 버튼 콕!

이 댓글을 비밀 댓글로

[제품후기] coms 발 받침대 - 바른 자세로 앉도록 해주는 도구

by Blogger 하얀쿠아
2017.07.27 01:10 NULL ptr/ NULL ptr



발 받침대 구입 동기


나는 직업적인 이유로 인해, 하루의 대부분을 책상에서 보낸다. 즉 의자에 앉아있는 시간이 상당히 길다는 이야기.

일찍 일을 끝내는 날에는 9시간 정도.

일이 많을때는 10시간~11시간.

종종 본인의 능력부족으로 일이 많은건아닌데... 잘 모르는 문제를 맞딱뜨리게 되면 온갖 문서들을 뒤져가며 해결해야 할 경우도 있는데, 이럴땐 12~14시간 정도를 책상앞 의자에 앉아있게 된다.


대부분 알고있을테지만, 의자에 앉을때는 바른 자세가 중요하다.

그런데, 내 다리가 평균신장의 성인보다 짧다보니(ㅜ_ㅜ) 평균신장을 가진 성인남성을 기준으로 만들어진 의자에서는 바른자세 유지가 쉽지 않다.



의자에 앉는 바른 자세


게다가 엉덩이를 깊숙히 의자안쪽에 넣고 앉았을 때 문제가 있다. 

이 그림을 보면 맨 마지막 그림에 발이 살짝 떠 있는데, 내가 그렇다.. 


그렇지만 발을 바닥에 닿게 하기 위해 의자를 낮추게 되면 문제가 있다.

책상에 놓여진 키보드를 타이핑 할 때 어깨근육이 긴장을 하게 된다는 것.


팔꿈치와 책상이 수평을 이루게... 해야 가장 이상적인 자세라고 하는데, 그걸 달성하려면 의자를 높여야 하고, 그러면 발이 뜬다.(악순환ㅋ)



결국, 발받침대를 샀다.


제품 소개

바로 이 제품이다.

http://www.coupang.com/vp/products/13092993?vendorItemId=3085938807



제품을 받아보니, 직접 조립을 해야 한다. 

조립은 간단하다.


아래 사진처럼 박스에 포장되어 배송된다.




상자 한 귀퉁이에는 발받침대를 사용할때의 옆모습 그림이 있고, 그 아래에는 각도 조절, 높이 조절이 쉽게 된다는 문구와 그림이 있다.





제품 구성

제품 부속품은 이와 같이 간단히 구성되어 있다.

발 받침대 상판, 하부 지지대 2개, 각도조절이 가능한 측면 조임부품 2개








하부 지지대의 바닥면에는 쉽게 미끌어지지 않는 고무재질로 처리되어 있다.

실제로 회사 사무실에서 사용해보면, 이것 덕분에 뒤로 밀리거나 하지 않는다.


 

 



측면 조임부분은 이와 같이 육각 너트와 볼트로 조이는 구조이다.

각도 조절은 빨간색 손잡이를 돌려서 너트로부터 볼트를 살짝 풀어 내고 가능하다.

상판을 원하는 각도로 조절 한 뒤 다시 잘 조여주면, 상판은 단단히 고정된다.





조립을 완성한 실제 모습이다.


실제 사용후기 (구입후 사용 2일차)

이걸 사용한 이후로는 퇴근 후 허리가 뻐근하거나 어깨가 뻐근한 느낌이 확실히 덜하다.

발받침대 위에 발을 올려놓게되면, 엉덩이와 허리에 가해지는 하중이 발바닥으로도 약간 분산되는 효과가 있는 것 같다.

또한, 의자를 높이는게 가능해 져서 어깨 위치가 자연히 높아지고, 키보드를 타이핑할때도 어깨 부담이 덜해지는 효과도 있는 것 같다.


몇일간 더 사용해보고 내용을 업데이트 하겠다.

이 댓글을 비밀 댓글로

티스토리 툴바