mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-05-30 13:15:32 +08:00
First stab at Python 2 and 3 compatibilty
This commit is contained in:
+71
-1
@@ -21,6 +21,17 @@ __version__ = "1.2"
|
|||||||
|
|
||||||
import struct, sys
|
import struct, sys
|
||||||
|
|
||||||
|
from pypreprocessor import pypreprocessor
|
||||||
|
|
||||||
|
#exclude
|
||||||
|
if sys.version[:3].split('.')[0] == '2':
|
||||||
|
pypreprocessor.defines.append('python2')
|
||||||
|
if sys.version[:3].split('.')[0] == '3':
|
||||||
|
pypreprocessor.defines.append('python3')
|
||||||
|
|
||||||
|
pypreprocessor.parse()
|
||||||
|
#endexclude
|
||||||
|
|
||||||
class SDLog2Parser:
|
class SDLog2Parser:
|
||||||
BLOCK_SIZE = 8192
|
BLOCK_SIZE = 8192
|
||||||
MSG_HEADER_LEN = 3
|
MSG_HEADER_LEN = 3
|
||||||
@@ -65,7 +76,11 @@ class SDLog2Parser:
|
|||||||
self.__msg_descrs = {} # message descriptions by message type map
|
self.__msg_descrs = {} # message descriptions by message type map
|
||||||
self.__msg_labels = {} # message labels by message name map
|
self.__msg_labels = {} # message labels by message name map
|
||||||
self.__msg_names = [] # message names in the same order as FORMAT messages
|
self.__msg_names = [] # message names in the same order as FORMAT messages
|
||||||
self.__buffer = "" # buffer for input binary data
|
#ifdef python2
|
||||||
|
self.__buffer = "" # buffer, python2
|
||||||
|
#else
|
||||||
|
self.__buffer = bytearray() # buffer for input binary data
|
||||||
|
#endif
|
||||||
self.__ptr = 0 # read pointer in buffer
|
self.__ptr = 0 # read pointer in buffer
|
||||||
self.__csv_columns = [] # CSV file columns in correct order in format "MSG.label"
|
self.__csv_columns = [] # CSV file columns in correct order in format "MSG.label"
|
||||||
self.__csv_data = {} # current values for all columns
|
self.__csv_data = {} # current values for all columns
|
||||||
@@ -114,15 +129,24 @@ class SDLog2Parser:
|
|||||||
self.__buffer = self.__buffer[self.__ptr:] + chunk
|
self.__buffer = self.__buffer[self.__ptr:] + chunk
|
||||||
self.__ptr = 0
|
self.__ptr = 0
|
||||||
while self.__bytesLeft() >= self.MSG_HEADER_LEN:
|
while self.__bytesLeft() >= self.MSG_HEADER_LEN:
|
||||||
|
#ifdef python2
|
||||||
head1 = ord(self.__buffer[self.__ptr])
|
head1 = ord(self.__buffer[self.__ptr])
|
||||||
head2 = ord(self.__buffer[self.__ptr+1])
|
head2 = ord(self.__buffer[self.__ptr+1])
|
||||||
|
#else
|
||||||
|
head1 = self.__buffer[self.__ptr]
|
||||||
|
head2 = self.__buffer[self.__ptr+1]
|
||||||
|
#endif
|
||||||
if (head1 != self.MSG_HEAD1 or head2 != self.MSG_HEAD2):
|
if (head1 != self.MSG_HEAD1 or head2 != self.MSG_HEAD2):
|
||||||
if self.__correct_errors:
|
if self.__correct_errors:
|
||||||
self.__ptr += 1
|
self.__ptr += 1
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
raise Exception("Invalid header at %i (0x%X): %02X %02X, must be %02X %02X" % (bytes_read + self.__ptr, bytes_read + self.__ptr, head1, head2, self.MSG_HEAD1, self.MSG_HEAD2))
|
raise Exception("Invalid header at %i (0x%X): %02X %02X, must be %02X %02X" % (bytes_read + self.__ptr, bytes_read + self.__ptr, head1, head2, self.MSG_HEAD1, self.MSG_HEAD2))
|
||||||
|
#ifdef python2
|
||||||
msg_type = ord(self.__buffer[self.__ptr+2])
|
msg_type = ord(self.__buffer[self.__ptr+2])
|
||||||
|
#else
|
||||||
|
msg_type = self.__buffer[self.__ptr+2]
|
||||||
|
#endif
|
||||||
if msg_type == self.MSG_TYPE_FORMAT:
|
if msg_type == self.MSG_TYPE_FORMAT:
|
||||||
# parse FORMAT message
|
# parse FORMAT message
|
||||||
if self.__bytesLeft() < self.MSG_FORMAT_PACKET_LEN:
|
if self.__bytesLeft() < self.MSG_FORMAT_PACKET_LEN:
|
||||||
@@ -170,7 +194,11 @@ class SDLog2Parser:
|
|||||||
if self.__file != None:
|
if self.__file != None:
|
||||||
print >> self.__file, self.__csv_delim.join(self.__csv_columns)
|
print >> self.__file, self.__csv_delim.join(self.__csv_columns)
|
||||||
else:
|
else:
|
||||||
|
#ifdef python2
|
||||||
print self.__csv_delim.join(self.__csv_columns)
|
print self.__csv_delim.join(self.__csv_columns)
|
||||||
|
#else
|
||||||
|
print(self.__csv_delim.join(self.__csv_columns))
|
||||||
|
#endif
|
||||||
|
|
||||||
def __printCSVRow(self):
|
def __printCSVRow(self):
|
||||||
s = []
|
s = []
|
||||||
@@ -185,16 +213,26 @@ class SDLog2Parser:
|
|||||||
if self.__file != None:
|
if self.__file != None:
|
||||||
print >> self.__file, self.__csv_delim.join(s)
|
print >> self.__file, self.__csv_delim.join(s)
|
||||||
else:
|
else:
|
||||||
|
#ifdef python2
|
||||||
print self.__csv_delim.join(s)
|
print self.__csv_delim.join(s)
|
||||||
|
#else
|
||||||
|
print(self.__csv_delim.join(s))
|
||||||
|
#endif
|
||||||
|
|
||||||
def __parseMsgDescr(self):
|
def __parseMsgDescr(self):
|
||||||
data = struct.unpack(self.MSG_FORMAT_STRUCT, self.__buffer[self.__ptr + 3 : self.__ptr + self.MSG_FORMAT_PACKET_LEN])
|
data = struct.unpack(self.MSG_FORMAT_STRUCT, self.__buffer[self.__ptr + 3 : self.__ptr + self.MSG_FORMAT_PACKET_LEN])
|
||||||
msg_type = data[0]
|
msg_type = data[0]
|
||||||
if msg_type != self.MSG_TYPE_FORMAT:
|
if msg_type != self.MSG_TYPE_FORMAT:
|
||||||
msg_length = data[1]
|
msg_length = data[1]
|
||||||
|
#ifdef python2
|
||||||
msg_name = data[2].strip("\0")
|
msg_name = data[2].strip("\0")
|
||||||
msg_format = data[3].strip("\0")
|
msg_format = data[3].strip("\0")
|
||||||
msg_labels = data[4].strip("\0").split(",")
|
msg_labels = data[4].strip("\0").split(",")
|
||||||
|
#else
|
||||||
|
msg_name = str(data[2], 'ascii').strip("\0")
|
||||||
|
msg_format = str(data[3], 'ascii').strip("\0")
|
||||||
|
msg_labels = str(data[4], 'ascii').strip("\0").split(",")
|
||||||
|
#endif
|
||||||
# Convert msg_format to struct.unpack format string
|
# Convert msg_format to struct.unpack format string
|
||||||
msg_struct = ""
|
msg_struct = ""
|
||||||
msg_mults = []
|
msg_mults = []
|
||||||
@@ -211,8 +249,13 @@ class SDLog2Parser:
|
|||||||
self.__msg_names.append(msg_name)
|
self.__msg_names.append(msg_name)
|
||||||
if self.__debug_out:
|
if self.__debug_out:
|
||||||
if self.__filterMsg(msg_name) != None:
|
if self.__filterMsg(msg_name) != None:
|
||||||
|
#ifdef python2
|
||||||
print "MSG FORMAT: type = %i, length = %i, name = %s, format = %s, labels = %s, struct = %s, mults = %s" % (
|
print "MSG FORMAT: type = %i, length = %i, name = %s, format = %s, labels = %s, struct = %s, mults = %s" % (
|
||||||
msg_type, msg_length, msg_name, msg_format, str(msg_labels), msg_struct, msg_mults)
|
msg_type, msg_length, msg_name, msg_format, str(msg_labels), msg_struct, msg_mults)
|
||||||
|
#else
|
||||||
|
print("MSG FORMAT: type = %i, length = %i, name = %s, format = %s, labels = %s, struct = %s, mults = %s" % (
|
||||||
|
msg_type, msg_length, msg_name, msg_format, str(msg_labels), msg_struct, msg_mults))
|
||||||
|
#endif
|
||||||
self.__ptr += self.MSG_FORMAT_PACKET_LEN
|
self.__ptr += self.MSG_FORMAT_PACKET_LEN
|
||||||
|
|
||||||
def __parseMsg(self, msg_descr):
|
def __parseMsg(self, msg_descr):
|
||||||
@@ -223,7 +266,11 @@ class SDLog2Parser:
|
|||||||
show_fields = self.__filterMsg(msg_name)
|
show_fields = self.__filterMsg(msg_name)
|
||||||
if (show_fields != None):
|
if (show_fields != None):
|
||||||
data = list(struct.unpack(msg_struct, self.__buffer[self.__ptr+self.MSG_HEADER_LEN:self.__ptr+msg_length]))
|
data = list(struct.unpack(msg_struct, self.__buffer[self.__ptr+self.MSG_HEADER_LEN:self.__ptr+msg_length]))
|
||||||
|
#ifdef python2
|
||||||
for i in xrange(len(data)):
|
for i in xrange(len(data)):
|
||||||
|
#else
|
||||||
|
for i in range(len(data)):
|
||||||
|
#endif
|
||||||
if type(data[i]) is str:
|
if type(data[i]) is str:
|
||||||
data[i] = data[i].strip("\0")
|
data[i] = data[i].strip("\0")
|
||||||
m = msg_mults[i]
|
m = msg_mults[i]
|
||||||
@@ -231,14 +278,26 @@ class SDLog2Parser:
|
|||||||
data[i] = data[i] * m
|
data[i] = data[i] * m
|
||||||
if self.__debug_out:
|
if self.__debug_out:
|
||||||
s = []
|
s = []
|
||||||
|
#ifdef python2
|
||||||
for i in xrange(len(data)):
|
for i in xrange(len(data)):
|
||||||
|
#else
|
||||||
|
for i in range(len(data)):
|
||||||
|
#endif
|
||||||
label = msg_labels[i]
|
label = msg_labels[i]
|
||||||
if show_fields == "*" or label in show_fields:
|
if show_fields == "*" or label in show_fields:
|
||||||
s.append(label + "=" + str(data[i]))
|
s.append(label + "=" + str(data[i]))
|
||||||
|
#ifdef python2
|
||||||
print "MSG %s: %s" % (msg_name, ", ".join(s))
|
print "MSG %s: %s" % (msg_name, ", ".join(s))
|
||||||
|
#else
|
||||||
|
print("MSG %s: %s" % (msg_name, ", ".join(s)))
|
||||||
|
#endif
|
||||||
else:
|
else:
|
||||||
# update CSV data buffer
|
# update CSV data buffer
|
||||||
|
#ifdef python2
|
||||||
for i in xrange(len(data)):
|
for i in xrange(len(data)):
|
||||||
|
#else
|
||||||
|
for i in range(len(data)):
|
||||||
|
#endif
|
||||||
label = msg_labels[i]
|
label = msg_labels[i]
|
||||||
if label in show_fields:
|
if label in show_fields:
|
||||||
self.__csv_data[msg_name + "_" + label] = data[i]
|
self.__csv_data[msg_name + "_" + label] = data[i]
|
||||||
@@ -250,6 +309,7 @@ class SDLog2Parser:
|
|||||||
|
|
||||||
def _main():
|
def _main():
|
||||||
if len(sys.argv) < 2:
|
if len(sys.argv) < 2:
|
||||||
|
#ifdef python2
|
||||||
print "Usage: python sdlog2_dump.py <log.bin> [-v] [-e] [-d delimiter] [-n null] [-m MSG[.field1,field2,...]] [-t TIME_MSG_NAME]\n"
|
print "Usage: python sdlog2_dump.py <log.bin> [-v] [-e] [-d delimiter] [-n null] [-m MSG[.field1,field2,...]] [-t TIME_MSG_NAME]\n"
|
||||||
print "\t-v\tUse plain debug output instead of CSV.\n"
|
print "\t-v\tUse plain debug output instead of CSV.\n"
|
||||||
print "\t-e\tRecover from errors.\n"
|
print "\t-e\tRecover from errors.\n"
|
||||||
@@ -258,6 +318,16 @@ def _main():
|
|||||||
print "\t-m MSG[.field1,field2,...]\n\t\tDump only messages of specified type, and only specified fields.\n\t\tMultiple -m options allowed."
|
print "\t-m MSG[.field1,field2,...]\n\t\tDump only messages of specified type, and only specified fields.\n\t\tMultiple -m options allowed."
|
||||||
print "\t-t\tSpecify TIME message name to group data messages by time and significantly reduce duplicate output.\n"
|
print "\t-t\tSpecify TIME message name to group data messages by time and significantly reduce duplicate output.\n"
|
||||||
print "\t-fPrint to file instead of stdout"
|
print "\t-fPrint to file instead of stdout"
|
||||||
|
#else
|
||||||
|
print("Usage: python sdlog2_dump.py <log.bin> [-v] [-e] [-d delimiter] [-n null] [-m MSG[.field1,field2,...]] [-t TIME_MSG_NAME]\n")
|
||||||
|
print("\t-v\tUse plain debug output instead of CSV.\n")
|
||||||
|
print("\t-e\tRecover from errors.\n")
|
||||||
|
print("\t-d\tUse \"delimiter\" in CSV. Default is \",\".\n")
|
||||||
|
print("\t-n\tUse \"null\" as placeholder for empty values in CSV. Default is empty.\n")
|
||||||
|
print("\t-m MSG[.field1,field2,...]\n\t\tDump only messages of specified type, and only specified fields.\n\t\tMultiple -m options allowed.")
|
||||||
|
print("\t-t\tSpecify TIME message name to group data messages by time and significantly reduce duplicate output.\n")
|
||||||
|
print("\t-fPrint to file instead of stdout")
|
||||||
|
#endif
|
||||||
return
|
return
|
||||||
fn = sys.argv[1]
|
fn = sys.argv[1]
|
||||||
debug_out = False
|
debug_out = False
|
||||||
|
|||||||
Reference in New Issue
Block a user