aboutsummaryrefslogtreecommitdiff
path: root/Tools
diff options
context:
space:
mode:
authorLorenz Meier <lm@inf.ethz.ch>2013-08-12 23:50:29 +0200
committerLorenz Meier <lm@inf.ethz.ch>2013-08-12 23:50:29 +0200
commit487497d66eab5846f133ed2da1a1f72356c24668 (patch)
tree7f89a0ed96f824859501224117ef70bc08eb59d4 /Tools
parentd3d9d059c0c0780541d9dfd9c44b1f521298f5b6 (diff)
downloadpx4-firmware-487497d66eab5846f133ed2da1a1f72356c24668.tar.gz
px4-firmware-487497d66eab5846f133ed2da1a1f72356c24668.tar.bz2
px4-firmware-487497d66eab5846f133ed2da1a1f72356c24668.zip
Added Python 2 / 3 Windows / Linux / Mac OS converter script. So much for cross-platform / version agnostic
Diffstat (limited to 'Tools')
-rw-r--r--Tools/README.txt13
-rw-r--r--Tools/sdlog2_dump.py86
2 files changed, 22 insertions, 77 deletions
diff --git a/Tools/README.txt b/Tools/README.txt
new file mode 100644
index 000000000..abeb9a4c7
--- /dev/null
+++ b/Tools/README.txt
@@ -0,0 +1,13 @@
+====== PX4 LOG CONVERSION ======
+
+On each log session (commonly started and stopped by arming and disarming the vehicle) a new file logxxx.bin is created. In many cases there will be only one logfile named log001.bin (only one flight).
+
+There are two conversion scripts in this ZIP file:
+
+logconv.m: This is a MATLAB script which will automatically convert and display the flight data with a GUI. If running this script, the second script can be ignored.
+
+sdlog2_dump.py: This is a Python script (compatible with v2 and v3) which converts the self-describing binary log format to a CSV file. To export a CSV file from within a shell (Windows CMD or BASH on Linux / Mac OS), run:
+
+python sdlog2_dump.py log001.bin -f "export.csv" -t "TIME" -d "," -n ""
+
+Python can be downloaded from http://python.org, but is available as default on Mac OS and Linux. \ No newline at end of file
diff --git a/Tools/sdlog2_dump.py b/Tools/sdlog2_dump.py
index 0ffb38176..bb109d6f3 100644
--- a/Tools/sdlog2_dump.py
+++ b/Tools/sdlog2_dump.py
@@ -1,6 +1,8 @@
#!/usr/bin/env python
-"""Dump binary log generated by sdlog2 or APM as CSV
+from __future__ import print_function
+
+"""Dump binary log generated by PX4's sdlog2 or APM as CSV
Usage: python sdlog2_dump.py <log.bin> [-v] [-e] [-d delimiter] [-n null] [-m MSG[.field1,field2,...]]
@@ -21,17 +23,6 @@ __version__ = "1.2"
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:
BLOCK_SIZE = 8192
MSG_HEADER_LEN = 3
@@ -76,11 +67,7 @@ class SDLog2Parser:
self.__msg_descrs = {} # message descriptions by message type map
self.__msg_labels = {} # message labels by message name map
self.__msg_names = [] # message names in the same order as FORMAT messages
- #ifdef python2
- self.__buffer = "" # buffer, python2
- #else
- self.__buffer = bytearray() # buffer for input binary data
- #endif
+ self.__buffer = "" # buffer for input binary data
self.__ptr = 0 # read pointer in buffer
self.__csv_columns = [] # CSV file columns in correct order in format "MSG.label"
self.__csv_data = {} # current values for all columns
@@ -129,24 +116,15 @@ class SDLog2Parser:
self.__buffer = self.__buffer[self.__ptr:] + chunk
self.__ptr = 0
while self.__bytesLeft() >= self.MSG_HEADER_LEN:
- #ifdef python2
head1 = ord(self.__buffer[self.__ptr])
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 self.__correct_errors:
self.__ptr += 1
continue
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))
- #ifdef python2
msg_type = ord(self.__buffer[self.__ptr+2])
- #else
- msg_type = self.__buffer[self.__ptr+2]
- #endif
if msg_type == self.MSG_TYPE_FORMAT:
# parse FORMAT message
if self.__bytesLeft() < self.MSG_FORMAT_PACKET_LEN:
@@ -192,13 +170,9 @@ class SDLog2Parser:
self.__csv_columns.append(full_label)
self.__csv_data[full_label] = None
if self.__file != None:
- print >> self.__file, self.__csv_delim.join(self.__csv_columns)
+ print(self.__csv_delim.join(self.__csv_columns), file=self.__file)
else:
- #ifdef python2
- print self.__csv_delim.join(self.__csv_columns)
- #else
print(self.__csv_delim.join(self.__csv_columns))
- #endif
def __printCSVRow(self):
s = []
@@ -211,28 +185,18 @@ class SDLog2Parser:
s.append(v)
if self.__file != None:
- print >> self.__file, self.__csv_delim.join(s)
+ print(self.__csv_delim.join(s), file=self.__file)
else:
- #ifdef python2
- print self.__csv_delim.join(s)
- #else
print(self.__csv_delim.join(s))
- #endif
def __parseMsgDescr(self):
data = struct.unpack(self.MSG_FORMAT_STRUCT, self.__buffer[self.__ptr + 3 : self.__ptr + self.MSG_FORMAT_PACKET_LEN])
msg_type = data[0]
if msg_type != self.MSG_TYPE_FORMAT:
msg_length = data[1]
- #ifdef python2
- msg_name = data[2].strip("\0")
- msg_format = data[3].strip("\0")
- 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
+ msg_name = str(data[2]).strip("\0")
+ msg_format = str(data[3]).strip("\0")
+ msg_labels = str(data[4]).strip("\0").split(",")
# Convert msg_format to struct.unpack format string
msg_struct = ""
msg_mults = []
@@ -249,13 +213,8 @@ class SDLog2Parser:
self.__msg_names.append(msg_name)
if self.__debug_out:
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" % (
- 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
def __parseMsg(self, msg_descr):
@@ -266,11 +225,7 @@ class SDLog2Parser:
show_fields = self.__filterMsg(msg_name)
if (show_fields != None):
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)):
- #else
for i in range(len(data)):
- #endif
if type(data[i]) is str:
data[i] = data[i].strip("\0")
m = msg_mults[i]
@@ -278,26 +233,14 @@ class SDLog2Parser:
data[i] = data[i] * m
if self.__debug_out:
s = []
- #ifdef python2
- for i in xrange(len(data)):
- #else
for i in range(len(data)):
- #endif
label = msg_labels[i]
if show_fields == "*" or label in show_fields:
s.append(label + "=" + str(data[i]))
- #ifdef python2
- print "MSG %s: %s" % (msg_name, ", ".join(s))
- #else
print("MSG %s: %s" % (msg_name, ", ".join(s)))
- #endif
else:
# update CSV data buffer
- #ifdef python2
- for i in xrange(len(data)):
- #else
for i in range(len(data)):
- #endif
label = msg_labels[i]
if label in show_fields:
self.__csv_data[msg_name + "_" + label] = data[i]
@@ -309,16 +252,6 @@ class SDLog2Parser:
def _main():
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 "\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"
- #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")
@@ -327,7 +260,6 @@ 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-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
fn = sys.argv[1]
debug_out = False