openpilot v0.9.0 release

date: 2022-11-16T06:35:40
master commit: 58b84fb401a804967aa0dd5ee66fafa90194fd30
This commit is contained in:
Vehicle Researcher
2022-11-16 06:35:41 +00:00
parent 108478216b
commit b47ad523a3
406 changed files with 20722 additions and 9442 deletions
+39 -16
View File
@@ -376,13 +376,31 @@ class CanClient():
self._recv_buffer()
class IsoTpMessage():
def __init__(self, can_client: CanClient, timeout: float = 1, debug: bool = False, max_len: int = 8):
def __init__(self, can_client: CanClient, timeout: float = 1, single_frame_mode: bool = False, separation_time: float = 0,
debug: bool = False, max_len: int = 8):
self._can_client = can_client
self.timeout = timeout
self.single_frame_mode = single_frame_mode
self.debug = debug
self.max_len = max_len
def send(self, dat: bytes) -> None:
# <= 127, separation time in milliseconds
# 0xF1 to 0xF9 UF, 100 to 900 microseconds
if 1e-4 <= separation_time <= 9e-4:
offset = int(round(separation_time, 4) * 1e4) - 1
separation_time = 0xF1 + offset
elif 0 <= separation_time <= 0.127:
separation_time = round(separation_time * 1000)
else:
raise Exception("Separation time not in range")
self.flow_control_msg = bytes([
0x30, # flow control
0x01 if self.single_frame_mode else 0x00, # block size
separation_time,
]).ljust(self.max_len, b"\x00")
def send(self, dat: bytes, setup_only: bool = False) -> None:
# throw away any stale data
self._can_client.recv(drain=True)
@@ -396,39 +414,42 @@ class IsoTpMessage():
self.rx_idx = 0
self.rx_done = False
if self.debug:
if self.debug and not setup_only:
print(f"ISO-TP: REQUEST - {hex(self._can_client.tx_addr)} 0x{bytes.hex(self.tx_dat)}")
self._tx_first_frame()
self._tx_first_frame(setup_only=setup_only)
def _tx_first_frame(self) -> None:
def _tx_first_frame(self, setup_only: bool = False) -> None:
if self.tx_len < self.max_len:
# single frame (send all bytes)
if self.debug:
if self.debug and not setup_only:
print(f"ISO-TP: TX - single frame - {hex(self._can_client.tx_addr)}")
msg = (bytes([self.tx_len]) + self.tx_dat).ljust(self.max_len, b"\x00")
self.tx_done = True
else:
# first frame (send first 6 bytes)
if self.debug:
if self.debug and not setup_only:
print(f"ISO-TP: TX - first frame - {hex(self._can_client.tx_addr)}")
msg = (struct.pack("!H", 0x1000 | self.tx_len) + self.tx_dat[:self.max_len - 2]).ljust(self.max_len - 2, b"\x00")
self._can_client.send([msg])
if not setup_only:
self._can_client.send([msg])
def recv(self, timeout=None) -> Optional[bytes]:
def recv(self, timeout=None) -> Tuple[Optional[bytes], bool]:
if timeout is None:
timeout = self.timeout
start_time = time.monotonic()
updated = False
try:
while True:
for msg in self._can_client.recv():
self._isotp_rx_next(msg)
start_time = time.monotonic()
updated = True
if self.tx_done and self.rx_done:
return self.rx_dat
return self.rx_dat, updated
# no timeout indicates non-blocking
if timeout == 0:
return None
return None, updated
if time.monotonic() - start_time > timeout:
raise MessageTimeoutError("timeout waiting for response")
finally:
@@ -456,9 +477,8 @@ class IsoTpMessage():
print(f"ISO-TP: RX - first frame - {hex(self._can_client.rx_addr)} idx={self.rx_idx} done={self.rx_done}")
if self.debug:
print(f"ISO-TP: TX - flow control continue - {hex(self._can_client.tx_addr)}")
# send flow control message (send all bytes)
msg = b"\x30\x00\x00".ljust(self.max_len, b"\x00")
self._can_client.send([msg])
# send flow control message
self._can_client.send([self.flow_control_msg])
return
# consecutive rx frame
@@ -470,6 +490,9 @@ class IsoTpMessage():
self.rx_dat += rx_data[1:1 + rx_size]
if self.rx_len == len(self.rx_dat):
self.rx_done = True
elif self.single_frame_mode:
# notify ECU to send next frame
self._can_client.send([self.flow_control_msg])
if self.debug:
print(f"ISO-TP: RX - consecutive frame - {hex(self._can_client.rx_addr)} idx={self.rx_idx} done={self.rx_done}")
return
@@ -548,12 +571,12 @@ class UdsClient():
req += data
# send request, wait for response
isotp_msg = IsoTpMessage(self._can_client, self.timeout, self.debug)
isotp_msg = IsoTpMessage(self._can_client, timeout=self.timeout, debug=self.debug)
isotp_msg.send(req)
response_pending = False
while True:
timeout = self.response_pending_timeout if response_pending else self.timeout
resp = isotp_msg.recv(timeout)
resp, _ = isotp_msg.recv(timeout)
if resp is None:
continue