반응형

ardupilot의 로그로 다음의 파일이 생성된다.

  • *.bin (FCC SW 가 생성)
  • *.tlog (Mission Planner 가 생성)

해당 파일들을 사람이 읽을 수 있는 ASCII 문자열이 아닌 바이너리로 저장되어있기 때문에 변환하는 과정이 필요하다.

본 글은 생성된 로그 파일을 쉼표로 구분된 파일인 csv 파일로 생성하는 방법을 다룬다.

 

파이썬 라이브러리 pymavlink 설치하기

MAVLink 란? [1]

오픈소스 비행제어 소프트웨어인 Ardupilot과 PX4는 외부 장치와 통신할 때 메시징 프로토콜로 MAVLink를 사용한다. [1]

이 메시징 프로토콜은 사람이 읽을 수 있는 형태의 포맷인 *.xml 형태의 파일로 표현[2]되며, 예시로 common.xml은 다음 위치에서 설명xml 파일을 볼 수 있다. 또한 사용자가 원한다면 유사하게 *.xml 파일을 만들어서 메시지 프로토콜로 추가할 수 있다. 이러한 임의의, 혹은 다른 목적을 가지고 추가한 것을 Dialect (방언, 사투리)이라 한다.

*.xml으로 정의된 MAVLink 메시지는 해당 메시지를 사용하는 장비에 모두 사용되기 때문에 비행제어 SW의 빌드, 지상통제SW의 빌드 시에 반드시 같이 사용해야한다.

 

Dialect 란? [4]

Dialect 는 사전적 의미로 보면 방언, 사투리이다. MAVLink는 표준 메시지와 시험용 메시지를 정의해놓은 바 있으며, 추가적으로 특정 목적에 따라 필요한 메시지, 열거형, 명령들을 정의할 수 있도록 해두었다.

위와 같은 점을 정리해볼 때, 지방에서만 통용되는 방언, 즉 특정 목적 및 환경에서만 사용하는 메시지들을 정의해놓은 것을 Dialect라 할 수 있다.

Dialect는 다른 MAVLink xml 파일을 포함할 수 있으며, 그 깊이는 mavgen.pyMAXIMUM_INCLUDE_FILE_NESTING으로 정의된 대로 5단계 까지 가능하다고 한다. 일반적인 Dialect의 패턴은 다음과 같이 common.xml 을 포함한다.

cubepilot.xml의 일부

 

PyMavlink 란? [3]

pymavlink는 MAVLink 프로토콜을 다룰 수 있도록 만든 파이썬 패키지이다.

이를 사용하기 위해서 윈도우 환경에서 Native으로 Python을 설치하거나, Anaconda와 같은 가상환경 상에 Python을 설치하도록 한다. 그 다음, 아래의 명령어를 입력하여 pymavlink 패키지를 설치하자.

python -m pip install pymavlink

 

설치가 완료되면 pymavlink 패키지의 설치 위치는 다음과 같다. 굵은 글씨는 달라질 수 있다.

  • Native 환경 : C:\Users\[ACCOUNT_NAME]\AppData\Local\Programs\Python\PythonXX\Lib\site-packages\pymavlink
  • Anaconda 환경 : [ANACONDA_PATH]\envs\[ENV_NAME]\Lib\site-packages\pymavlink

pymavlink 패키지에서 사용하는 Dialect들은 위 경로에서 더하여 MAVLink 의 버전별로 다음 위치에 *.xml*.py 파일으로 존재한다. 해당 방언들을 바탕으로 pymavlink 패키지의 기능들을 사용할 수 있다.

  • [PYMAVLINK_PATH]\dialects\v10
  • [PYMAVLINK_PATH]\dialects\v20

 

pymavlink를 이용하여 로그 파일 추출하기

pymavlink를 이용하여 로그를 추출하는 방법은 패키지의 라이브러리인 mavlogdump를 이용하면 된다. 해당 라이브러리를 사용하는 형태는 일반적으로 다음의 명령어를 입력하여 사용할 수 있다.

python -m mavlogdump --format [FORMAT] --types [TYPES] --dialect [DIALECT] --output [OUTPUT_FILENAME] [INPUT_FILENAME]
python -m mavlogdump --format csv --types DATA1 --output somewhere\output.csv somewhere\input.bin
python -m mavlogdump --format csv --types DATA1 --output somewhere\output.csv somewhere\input.tlog

 

인자에 대해서 설명하면 다음과 같다.

  • FORMAT : 출력 포맷으로 'standard', 'json', 'csv', 'mat'을 선택할 수 있으며, MAT 출력이라면 --mat_file 옵션이 필요하다.
  • TYPES : 메시지 타입이며, 콤마로 구분하여 여러개를 넣어줄 수도 있다고 한다. [--types DATA1,DATA2,DATA3]
  • DIALECT : 특정 방언을 선택할 수 있으며, 생략한다면 ardupilotmega.xml/py을 참조하게 된다.
  • OUTPUT_FILENAME : 출력 파일 이름이다. 확장자까지 써야한다.
  • INPUT_FILE_NAME : 입력 파일 이름이다. 항상 마지막에 나와야한다.

입출력 파일 이름에 띄어쓰기가 있다면 쌍따옴표 " " 으로 감싸준다.

이를 통해서 *.bin, *.tlog 파일에서 csv 파일으로 다음과 같이 데이터를 추출할 수 있다.

GPS 타입을 뽑은 데이터

 

여러 types을 입력하면 다음과 같이 나오면서 안된다.

설명에는 여러 개 된다는데 안되나보다.

Need exactly one type when dumping CSV from bin file

 

 

타입과 메시지 포맷에 맞추어 대량의 데이터를 한꺼번에 추출하는 코드는 다음과 같다.

더보기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import os
import argparse
import sys
 
parser = argparse.ArgumentParser(description="make csv from *.bin/*.tlog (ardupilot log)")
parser.add_argument("-s""--signature")
 
args = parser.parse_args()
print("Input signature : {}".format(args.signature))
 
pymavlink_path  = ""
root_path       = ""
script_path     = "{}\Scripts".format(pymavlink_path)
dialect_name    = "cubepilot"
 
# Message types
bin_msg_types = list()
bin_msg_types.append("DATA1")
tlog_msg_types = dict()
tlog_msg_types["50002"= "HERELINK_VIDEO_STREAM_INFORMATION"
 
print("At {}...".format(root_path))
 
# File Names
signature = args.signature
file_list = os.listdir(root_path + "\\input_{}\\".format(signature))
os.makedirs(root_path + "\\input_{}\\output_{}\\".format(signature, signature), exist_ok=True)
 
print(" - Dump logs")
for file_name in file_list:
    filename = file_name[:-4]
    extension = file_name[-4:]
 
    if(filename[0!= '2'):
        continue
 
    # Extension Check
    if(extension.lower() == ".bin"):
        # filename = "00000019"
        for msg_type in bin_msg_types:
            # msg_type = "TM11"
            input_file = "{}\input_{}\{}".format(root_path, signature, file_name)
            output_file = "{}\input_{}\output_{}\{}_{}.csv".format(root_path, signature, signature, filename, msg_type)
            bash_cmd = 'python {}\mavlogdump.py --format csv --types {:} "{:}" > "{:}"'.format(script_path, msg_type, input_file, output_file)
            # print(bash_cmd)
            os.system(bash_cmd)
 
        print_msg = "\tdump {:} - {:}".format(file_name, bin_msg_types)
        print(print_msg)
    elif(extension.lower() == "tlog"):
        for id in tlog_msg_types.keys():
            # msg_type = "TM11"
            input_file = "{}\input_{}\{}".format(root_path, signature, file_name)
            output_file = "{}\input_{}\output_{}\{}_{}.csv".format(root_path, signature, signature, filename[:-1], id)
            bash_cmd = 'python -m mavlogdump --dialect {:} --format csv --types {:} "{:}" > "{:}"'.format(tlog_msg_types[id], input_file, output_file)
            # print(bash_cmd)
            os.system(bash_cmd)
        print_msg = "\tdump {:}".format(file_name)
        print(print_msg)
        for key, value in tlog_msg_types.items():
            print("\t\t{} - {}".format(key, value))
 
 
cs

 

pymavlink를 이용하여 dialect 만들고 로그 데이터 추출용 코드 생성하기

pymavlink는 사용자가 *.xml 형태의 dialect를 만들면 pymavlink에서 사용할 수 있도록 코드를 자동생성해주는 라이브러리인 mavgen을 제공한다. mavgen의 사용 명령어는 다음과 같다.

python -m mavgen --wire-protocol [MAVLINK_VERSION] -o [OUTPUT_NAME] [XML_FILENAME]
python -m mavgen --wire-protocol 2.0 -o somewhere\common somewhere\common.xml

 

각 인자에 대해서 설명하면 다음과 같다.

  • MAVLINK_VERSION : 특정 MAVLink 버전을 선택해서 처리하며 0.9, 1.0, 2.0을 고를 수 있으며 기본은 1.0 이다.
  • OUTPUT_NAME : 출력 파일의 이름을 기입한다.이름에는 확장자를 쓰지 않는다. 기본적으로 py 파일로 출력되며, 생략하면 mavlink.py으로 출력된다.
  • XML_FILENAME : 입력할 MAVLink 메시지를 정의한 *.xml 파일을 경로를 포함하여 입력한다.

이렇게 자동 생성된 파이썬 코드 *.py 파일을 앞서 언급한 pymavlink 패키지 위치의 MAVLink 버전 폴더 [PYMAVLINK_PATH]\dialects\v20 에 놓아주면 pymavlink 에서 사용할 수 있다.

예시로 보면 해당 위치에는 다음과 같이 MAVLink 메시지의 정의 파일 *.xml 과 메시지 정의를 파이썬에서 쓸 수 있도록 만들어둔 라이브러리 파일인 *.py 파일이 위치한다. 

 

 

 

Reference

[1] https://mavlink.io/en/

[2] https://mavlink.io/kr/messages/common.html

[3] https://mavlink.io/en/mavgen_python/

[4] https://mavlink.io/en/messages/

 

** EOF **

728x90

+ Recent posts