openpilot is an open source driver assistance system. openpilot performs the functions of Automated Lane Centering and Adaptive Cruise Control for over 200 supported car makes and models.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

87 lines
3.0 KiB

#!/usr/bin/env python
import binascii
import csv
import sys
class Message():
"""Details about a specific message ID."""
def __init__(self, message_id):
self.message_id = message_id
self.ones = [0] * 8 # bit set if 1 is always seen
self.zeros = [0] * 8 # bit set if 0 is always seen
def printBitDiff(self, other):
"""Prints bits that transition from always zero to always 1 and vice versa."""
for i in xrange(len(self.ones)):
zero_to_one = other.zeros[i] & self.ones[i]
if zero_to_one:
print 'id %s 0 -> 1 at byte %d bitmask %d' % (self.message_id, i, zero_to_one)
one_to_zero = other.ones[i] & self.zeros[i]
if one_to_zero:
print 'id %s 1 -> 0 at byte %d bitmask %d' % (self.message_id, i, one_to_zero)
class Info():
"""A collection of Messages."""
def __init__(self):
self.messages = {} # keyed by MessageID
def load(self, filename, start, end):
"""Given a CSV file, adds information about message IDs and their values."""
with open(filename, 'rb') as input:
reader = csv.reader(input)
next(reader, None) # skip the CSV header
for row in reader:
if not len(row): continue
time = float(row[0])
bus = int(row[2])
if time < start or bus > 127:
continue
elif time > end:
break
if row[1].startswith('0x'):
message_id = row[1][2:] # remove leading '0x'
else:
message_id = hex(int(row[1]))[2:] # old message IDs are in decimal
if row[3].startswith('0x'):
data = row[3][2:] # remove leading '0x'
else:
data = row[3]
new_message = False
if message_id not in self.messages:
self.messages[message_id] = Message(message_id)
new_message = True
message = self.messages[message_id]
bytes = bytearray.fromhex(data)
for i in xrange(len(bytes)):
ones = int(bytes[i])
message.ones[i] = ones if new_message else message.ones[i] & ones
# Inverts the data and masks it to a byte to get the zeros as ones.
zeros = (~int(bytes[i])) & 0xff
message.zeros[i] = zeros if new_message else message.zeros[i] & zeros
def PrintUnique(log_file, low_range, high_range):
# find messages with bits that are always low
start, end = map(float, low_range.split('-'))
low = Info()
low.load(log_file, start, end)
# find messages with bits that are always high
start, end = map(float, high_range.split('-'))
high = Info()
high.load(log_file, start, end)
# print messages that go from low to high
found = False
for message_id in high.messages:
if message_id in low.messages:
high.messages[message_id].printBitDiff(low.messages[message_id])
found = True
if not found: print 'No messages that transition from always low to always high found!'
if __name__ == "__main__":
if len(sys.argv) < 4:
print 'Usage:\n%s log.csv <low-start>-<low-end> <high-start>-<high-end>' % sys.argv[0]
sys.exit(0)
PrintUnique(sys.argv[1], sys.argv[2], sys.argv[3])