112 lines
3.3 KiB
Python
112 lines
3.3 KiB
Python
|
#!/usr/bin/env python
|
||
|
|
||
|
'''
|
||
|
convert a MAVLink tlog file to a MATLab mfile
|
||
|
'''
|
||
|
from __future__ import print_function
|
||
|
from builtins import range
|
||
|
|
||
|
import os
|
||
|
import re
|
||
|
import sys
|
||
|
from pymavlink import mavutil
|
||
|
|
||
|
def process_tlog(filename):
|
||
|
'''convert a tlog to a .m file'''
|
||
|
|
||
|
is_py2 = sys.version_info < (3,0)
|
||
|
|
||
|
print("Processing %s" % filename)
|
||
|
|
||
|
mlog = mavutil.mavlink_connection(filename, dialect=args.dialect, zero_time_base=True)
|
||
|
|
||
|
# first walk the entire file, grabbing all messages into a hash of lists,
|
||
|
#and the first message of each type into a hash
|
||
|
msg_types = {}
|
||
|
msg_lists = {}
|
||
|
|
||
|
types = args.types
|
||
|
if types is not None:
|
||
|
types = types.split(',')
|
||
|
|
||
|
# note that Octave doesn't like any extra '.', '*', '-', characters in the filename
|
||
|
(head, tail) = os.path.split(filename)
|
||
|
basename = '.'.join(tail.split('.')[:-1])
|
||
|
mfilename = re.sub('[\.\-\+\*]','_', basename) + '.m'
|
||
|
# Octave also doesn't like files that don't start with a letter
|
||
|
if re.match('^[a-zA-z]', mfilename) is None:
|
||
|
mfilename = 'm_' + mfilename
|
||
|
|
||
|
if head is not None:
|
||
|
mfilename = os.path.join(head, mfilename)
|
||
|
print("Creating %s" % mfilename)
|
||
|
|
||
|
f = open(mfilename, "w")
|
||
|
|
||
|
type_counters = {}
|
||
|
|
||
|
while True:
|
||
|
m = mlog.recv_match(condition=args.condition)
|
||
|
if m is None:
|
||
|
break
|
||
|
|
||
|
if types is not None and m.get_type() not in types:
|
||
|
continue
|
||
|
if m.get_type() == 'BAD_DATA':
|
||
|
continue
|
||
|
|
||
|
fieldnames = m._fieldnames
|
||
|
mtype = m.get_type()
|
||
|
if mtype in ['FMT', 'PARM']:
|
||
|
continue
|
||
|
|
||
|
if mtype not in type_counters:
|
||
|
type_counters[mtype] = 0
|
||
|
f.write("%s.columns = {'timestamp'" % mtype)
|
||
|
for field in fieldnames:
|
||
|
val = getattr(m, field)
|
||
|
|
||
|
if is_py2:
|
||
|
if isinstance(val,unicode): # NOQA
|
||
|
val = str(val)
|
||
|
|
||
|
if not isinstance(val, str):
|
||
|
if type(val) is not list:
|
||
|
f.write(",'%s'" % field)
|
||
|
else:
|
||
|
for i in range(0, len(val)):
|
||
|
f.write(",'%s%d'" % (field, i + 1))
|
||
|
f.write("};\n")
|
||
|
|
||
|
type_counters[mtype] += 1
|
||
|
f.write("%s.data(%u,:) = [%f" % (mtype, type_counters[mtype], m._timestamp))
|
||
|
for field in m._fieldnames:
|
||
|
val = getattr(m, field)
|
||
|
|
||
|
if is_py2:
|
||
|
if isinstance(val,unicode): # NOQA
|
||
|
val = str(val)
|
||
|
|
||
|
if not isinstance(val, str):
|
||
|
if type(val) is not list:
|
||
|
f.write(",%.20g" % val)
|
||
|
else:
|
||
|
for i in range(0, len(val)):
|
||
|
f.write(",%.20g" % val[i])
|
||
|
f.write("];\n")
|
||
|
f.close()
|
||
|
|
||
|
from argparse import ArgumentParser
|
||
|
parser = ArgumentParser(description=__doc__)
|
||
|
|
||
|
parser.add_argument("--condition", default=None, help="select packets by condition")
|
||
|
parser.add_argument("-o", "--output", default=None, help="output filename")
|
||
|
parser.add_argument("--types", default=None, help="types of messages (comma separated)")
|
||
|
parser.add_argument("--dialect", default="ardupilotmega", help="MAVLink dialect")
|
||
|
parser.add_argument("logs", metavar="LOG", nargs="+")
|
||
|
args = parser.parse_args()
|
||
|
|
||
|
|
||
|
for filename in args.logs:
|
||
|
process_tlog(filename)
|