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.
96 lines
2.8 KiB
96 lines
2.8 KiB
6 years ago
|
#!/usr/bin/env python
|
||
|
import time
|
||
|
from common.realtime import sec_since_boot
|
||
|
import selfdrive.messaging as messaging
|
||
|
from selfdrive.boardd.boardd import can_list_to_can_capnp
|
||
|
|
||
|
def get_vin(logcan, sendcan):
|
||
|
|
||
|
# works on standard 11-bit addresses for diagnostic. Tested on Toyota and Subaru;
|
||
|
# Honda uses the extended 29-bit addresses, and unfortunately only works from OBDII
|
||
|
query_msg = [[0x7df, 0, '\x02\x09\x02'.ljust(8, "\x00"), 0],
|
||
|
[0x7e0, 0, '\x30'.ljust(8, "\x00"), 0]]
|
||
|
|
||
|
cnts = [1, 2] # Number of messages to wait for at each iteration
|
||
|
vin_valid = True
|
||
|
|
||
|
dat = []
|
||
|
for i in range(len(query_msg)):
|
||
|
cnt = 0
|
||
|
sendcan.send(can_list_to_can_capnp([query_msg[i]], msgtype='sendcan'))
|
||
|
got_response = False
|
||
|
t_start = sec_since_boot()
|
||
|
while sec_since_boot() - t_start < 0.05 and not got_response:
|
||
|
for a in messaging.drain_sock(logcan):
|
||
|
for can in a.can:
|
||
|
if can.src == 0 and can.address == 0x7e8:
|
||
|
vin_valid = vin_valid and is_vin_response_valid(can.dat, i, cnt)
|
||
|
dat += can.dat[2:] if i == 0 else can.dat[1:]
|
||
|
cnt += 1
|
||
|
if cnt == cnts[i]:
|
||
|
got_response = True
|
||
|
time.sleep(0.01)
|
||
|
|
||
|
return "".join(dat[3:]) if vin_valid else ""
|
||
|
|
||
|
"""
|
||
|
if 'vin' not in gctx:
|
||
|
print "getting vin"
|
||
|
gctx['vin'] = query_vin()[3:]
|
||
|
print "got VIN %s" % (gctx['vin'],)
|
||
|
cloudlog.info("got VIN %s" % (gctx['vin'],))
|
||
|
|
||
|
# *** determine platform based on VIN ****
|
||
|
if vin.startswith("19UDE2F36G"):
|
||
|
print "ACURA ILX 2016"
|
||
|
self.civic = False
|
||
|
else:
|
||
|
# TODO: add Honda check explicitly
|
||
|
print "HONDA CIVIC 2016"
|
||
|
self.civic = True
|
||
|
|
||
|
# *** special case VIN of Acura test platform
|
||
|
if vin == "19UDE2F36GA001322":
|
||
|
print "comma.ai test platform detected"
|
||
|
# it has a gas interceptor and a torque mod
|
||
|
self.torque_mod = True
|
||
|
"""
|
||
|
|
||
|
|
||
|
# sanity checks on response messages from vin query
|
||
|
def is_vin_response_valid(can_dat, step, cnt):
|
||
|
|
||
|
can_dat = [ord(i) for i in can_dat]
|
||
|
|
||
|
if len(can_dat) != 8:
|
||
|
# ISO-TP meesages are all 8 bytes
|
||
|
return False
|
||
|
|
||
|
if step == 0:
|
||
|
# VIN does not fit in a single message and it's 20 bytes of data
|
||
|
if can_dat[0] != 0x10 or can_dat[1] != 0x14:
|
||
|
return False
|
||
|
|
||
|
if step == 1 and cnt == 0:
|
||
|
# first response after a CONTINUE query is sent
|
||
|
if can_dat[0] != 0x21:
|
||
|
return False
|
||
|
|
||
|
if step == 1 and cnt == 1:
|
||
|
# second response after a CONTINUE query is sent
|
||
|
if can_dat[0] != 0x22:
|
||
|
return False
|
||
|
|
||
|
return True
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
import zmq
|
||
|
from selfdrive.services import service_list
|
||
|
context = zmq.Context()
|
||
|
logcan = messaging.sub_sock(context, service_list['can'].port)
|
||
|
sendcan = messaging.pub_sock(context, service_list['sendcan'].port)
|
||
|
time.sleep(1.) # give time to sendcan socket to start
|
||
|
|
||
|
print get_vin(logcan, sendcan)
|