123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- #!/usr/bin/env python
- '''
- extract one mode type from a log
- '''
- from __future__ import print_function
- import os
- import struct
- from argparse import ArgumentParser
- parser = ArgumentParser(description=__doc__)
- parser.add_argument("--no-timestamps", dest="notimestamps", action='store_true', help="Log doesn't have timestamps")
- parser.add_argument("--robust", action='store_true', help="Enable robust parsing (skip over bad data)")
- parser.add_argument("--condition", default=None, help="select packets by condition")
- parser.add_argument("--mode", default='auto', help="mode to extract")
- parser.add_argument("--link", default=None, type=int, help="only extract specific comms link")
- parser.add_argument("logs", metavar="LOG", nargs="+")
- args = parser.parse_args()
- from pymavlink import mavutil
- def older_message(m, lastm):
- '''return true if m is older than lastm by timestamp'''
- atts = {'time_boot_ms' : 1.0e-3,
- 'time_unix_usec' : 1.0e-6,
- 'time_usec' : 1.0e-6}
- for a in list(atts.keys()):
- if hasattr(m, a):
- mul = atts[a]
- t1 = m.getattr(a) * mul
- t2 = lastm.getattr(a) * mul
- if t2 >= t1 and t2 - t1 < 60:
- return True
- return False
- def process(filename):
- '''process one logfile'''
- print("Processing %s" % filename)
- mlog = mavutil.mavlink_connection(filename, notimestamps=args.notimestamps,
- robust_parsing=args.robust)
- ext = os.path.splitext(filename)[1]
- isbin = ext in ['.bin', '.BIN']
- islog = ext in ['.log', '.LOG']
- output = None
- count = 1
- dirname = os.path.dirname(filename)
- if isbin or islog:
- extension = "bin"
- else:
- extension = "tlog"
- file_header = ''
- messages = []
- # we allow a list of modes that map to one mode number. This allows for --mode=AUTO,RTL and consider the RTL as part of AUTO
- modes = args.mode.upper().split(',')
- flightmode = None
- while True:
- m = mlog.recv_match()
- if m is None:
- break
- if args.link is not None and m._link != args.link:
- continue
- mtype = m.get_type()
- if mtype in messages:
- if older_message(m, messages[mtype]):
- continue
- # we don't use mlog.flightmode as that can be wrong if we are extracting a single link
- if mtype == 'HEARTBEAT' and m.get_srcComponent() != mavutil.mavlink.MAV_COMP_ID_GIMBAL and m.type != mavutil.mavlink.MAV_TYPE_GCS:
- flightmode = mavutil.mode_string_v10(m).upper()
- if mtype == 'MODE':
- flightmode = mlog.flightmode
- if (isbin or islog) and m.get_type() in ["FMT", "PARM", "CMD"]:
- file_header += m.get_msgbuf()
- if (isbin or islog) and m.get_type() == 'MSG' and m.Message.startswith("Ardu"):
- file_header += m.get_msgbuf()
- if m.get_type() in ['PARAM_VALUE','MISSION_ITEM']:
- timestamp = getattr(m, '_timestamp', None)
- file_header += struct.pack('>Q', timestamp*1.0e6) + m.get_msgbuf()
- if not mavutil.evaluate_condition(args.condition, mlog.messages):
- continue
- if flightmode in modes:
- if output is None:
- path = os.path.join(dirname, "%s%u.%s" % (modes[0], count, extension))
- count += 1
- print("Creating %s" % path)
- output = open(path, mode='wb')
- output.write(file_header)
- else:
- if output is not None:
- output.close()
- output = None
- if output and m.get_type() != 'BAD_DATA':
- timestamp = getattr(m, '_timestamp', None)
- if not isbin:
- output.write(struct.pack('>Q', timestamp*1.0e6))
- output.write(m.get_msgbuf())
- for filename in args.logs:
- process(filename)
|