245 lines
6.7 KiB
Python
245 lines
6.7 KiB
Python
import os
|
|
import time
|
|
import random
|
|
import threading
|
|
from panda import Panda
|
|
from nose.tools import assert_equal, assert_less, assert_greater
|
|
from .helpers import panda_jungle, start_heartbeat_thread, reset_pandas, time_many_sends, test_all_pandas, test_all_gen2_pandas, clear_can_buffers, panda_connect_and_init
|
|
|
|
# Reset the pandas before running tests
|
|
def aaaa_reset_before_tests():
|
|
reset_pandas()
|
|
|
|
@test_all_pandas
|
|
@panda_connect_and_init
|
|
def test_send_recv(p):
|
|
def test(p_send, p_recv):
|
|
p_send.set_can_loopback(False)
|
|
p_recv.set_can_loopback(False)
|
|
|
|
p_send.can_send_many([(0x1ba, 0, b"message", 0)] * 2)
|
|
time.sleep(0.05)
|
|
p_recv.can_recv()
|
|
p_send.can_recv()
|
|
|
|
busses = [0, 1, 2]
|
|
|
|
for bus in busses:
|
|
for speed in [100, 250, 500, 750, 1000]:
|
|
p_send.set_can_speed_kbps(bus, speed)
|
|
p_recv.set_can_speed_kbps(bus, speed)
|
|
time.sleep(0.05)
|
|
|
|
clear_can_buffers(p_send)
|
|
clear_can_buffers(p_recv)
|
|
|
|
comp_kbps = time_many_sends(p_send, bus, p_recv, two_pandas=True)
|
|
|
|
saturation_pct = (comp_kbps / speed) * 100.0
|
|
assert_greater(saturation_pct, 80)
|
|
assert_less(saturation_pct, 100)
|
|
|
|
print("two pandas bus {}, 100 messages at speed {:4d}, comp speed is {:7.2f}, percent {:6.2f}".format(bus, speed, comp_kbps, saturation_pct))
|
|
|
|
# Start heartbeat
|
|
start_heartbeat_thread(p)
|
|
|
|
# Set safety mode and power saving
|
|
p.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
|
|
p.set_power_save(False)
|
|
|
|
try:
|
|
# Run tests in both directions
|
|
test(p, panda_jungle)
|
|
test(panda_jungle, p)
|
|
except Exception as e:
|
|
# Raise errors again, we don't want them to get lost
|
|
raise e
|
|
finally:
|
|
# Set back to silent mode
|
|
p.set_safety_mode(Panda.SAFETY_SILENT)
|
|
|
|
@test_all_pandas
|
|
@panda_connect_and_init
|
|
def test_latency(p):
|
|
def test(p_send, p_recv):
|
|
p_send.set_can_loopback(False)
|
|
p_recv.set_can_loopback(False)
|
|
|
|
p_send.set_can_speed_kbps(0, 100)
|
|
p_recv.set_can_speed_kbps(0, 100)
|
|
time.sleep(0.05)
|
|
|
|
p_send.can_send_many([(0x1ba, 0, b"testmsg", 0)] * 10)
|
|
time.sleep(0.05)
|
|
p_recv.can_recv()
|
|
p_send.can_recv()
|
|
|
|
busses = [0, 1, 2]
|
|
|
|
for bus in busses:
|
|
for speed in [100, 250, 500, 750, 1000]:
|
|
p_send.set_can_speed_kbps(bus, speed)
|
|
p_recv.set_can_speed_kbps(bus, speed)
|
|
time.sleep(0.1)
|
|
|
|
# clear can buffers
|
|
clear_can_buffers(p_send)
|
|
clear_can_buffers(p_recv)
|
|
|
|
latencies = []
|
|
comp_kbps_list = []
|
|
saturation_pcts = []
|
|
|
|
num_messages = 100
|
|
|
|
for i in range(num_messages):
|
|
st = time.time()
|
|
p_send.can_send(0x1ab, b"message", bus)
|
|
r = []
|
|
while len(r) < 1 and (time.time() - st) < 5:
|
|
r = p_recv.can_recv()
|
|
et = time.time()
|
|
r_echo = []
|
|
while len(r_echo) < 1 and (time.time() - st) < 10:
|
|
r_echo = p_send.can_recv()
|
|
|
|
if len(r) == 0 or len(r_echo) == 0:
|
|
print("r: {}, r_echo: {}".format(r, r_echo))
|
|
|
|
assert_equal(len(r), 1)
|
|
assert_equal(len(r_echo), 1)
|
|
|
|
et = (et - st) * 1000.0
|
|
comp_kbps = (1 + 11 + 1 + 1 + 1 + 4 + 8 * 8 + 15 + 1 + 1 + 1 + 7) / et
|
|
latency = et - ((1 + 11 + 1 + 1 + 1 + 4 + 8 * 8 + 15 + 1 + 1 + 1 + 7) / speed)
|
|
|
|
assert_less(latency, 5.0)
|
|
|
|
saturation_pct = (comp_kbps / speed) * 100.0
|
|
latencies.append(latency)
|
|
comp_kbps_list.append(comp_kbps)
|
|
saturation_pcts.append(saturation_pct)
|
|
|
|
average_latency = sum(latencies) / num_messages
|
|
assert_less(average_latency, 1.0)
|
|
average_comp_kbps = sum(comp_kbps_list) / num_messages
|
|
average_saturation_pct = sum(saturation_pcts) / num_messages
|
|
|
|
print("two pandas bus {}, {} message average at speed {:4d}, latency is {:5.3f}ms, comp speed is {:7.2f}, percent {:6.2f}"
|
|
.format(bus, num_messages, speed, average_latency, average_comp_kbps, average_saturation_pct))
|
|
|
|
# Start heartbeat
|
|
start_heartbeat_thread(p)
|
|
|
|
# Set safety mode and power saving
|
|
p.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
|
|
p.set_power_save(False)
|
|
|
|
try:
|
|
# Run tests in both directions
|
|
test(p, panda_jungle)
|
|
test(panda_jungle, p)
|
|
except Exception as e:
|
|
# Raise errors again, we don't want them to get lost
|
|
raise e
|
|
finally:
|
|
# Set back to silent mode
|
|
p.set_safety_mode(Panda.SAFETY_SILENT)
|
|
|
|
|
|
@test_all_gen2_pandas
|
|
@panda_connect_and_init
|
|
def test_gen2_loopback(p):
|
|
def test(p_send, p_recv):
|
|
for bus in range(4):
|
|
obd = False
|
|
if bus == 3:
|
|
obd = True
|
|
bus = 1
|
|
|
|
# Clear buses
|
|
clear_can_buffers(p_send)
|
|
clear_can_buffers(p_recv)
|
|
|
|
# Send a random string
|
|
addr = random.randint(1, 2000)
|
|
string = b"test" + os.urandom(4)
|
|
p_send.set_obd(obd)
|
|
p_recv.set_obd(obd)
|
|
time.sleep(0.2)
|
|
p_send.can_send(addr, string, bus)
|
|
time.sleep(0.2)
|
|
|
|
content = p_recv.can_recv()
|
|
|
|
# Check amount of messages
|
|
assert len(content) == 1
|
|
|
|
# Check content
|
|
assert content[0][0] == addr and content[0][2] == string
|
|
|
|
# Check bus
|
|
assert content[0][3] == bus
|
|
|
|
print("Bus:", bus, "OBD:", obd, "OK")
|
|
|
|
# Start heartbeat
|
|
start_heartbeat_thread(p)
|
|
|
|
# Set safety mode and power saving
|
|
p.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
|
|
p.set_power_save(False)
|
|
|
|
try:
|
|
# Run tests in both directions
|
|
test(p, panda_jungle)
|
|
test(panda_jungle, p)
|
|
except Exception as e:
|
|
# Raise errors again, we don't want them to get lost
|
|
raise e
|
|
finally:
|
|
# Set back to silent mode
|
|
p.set_safety_mode(Panda.SAFETY_SILENT)
|
|
|
|
@test_all_pandas
|
|
@panda_connect_and_init
|
|
def test_bulk_write(p):
|
|
# The TX buffers on pandas is 0x100 in length.
|
|
NUM_MESSAGES_PER_BUS = 10000
|
|
|
|
def flood_tx(panda):
|
|
print('Sending!')
|
|
msg = b"\xaa" * 4
|
|
packet = [[0xaa, None, msg, 0], [0xaa, None, msg, 1], [0xaa, None, msg, 2]] * NUM_MESSAGES_PER_BUS
|
|
|
|
# Disable timeout
|
|
panda.can_send_many(packet, timeout=0)
|
|
print(f"Done sending {3*NUM_MESSAGES_PER_BUS} messages!")
|
|
|
|
# Start heartbeat
|
|
start_heartbeat_thread(p)
|
|
|
|
# Set safety mode and power saving
|
|
p.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
|
|
p.set_power_save(False)
|
|
|
|
# Start transmisson
|
|
threading.Thread(target=flood_tx, args=(p,)).start()
|
|
|
|
# Receive as much as we can in a few second time period
|
|
rx = []
|
|
old_len = 0
|
|
start_time = time.time()
|
|
while time.time() - start_time < 2 or len(rx) > old_len:
|
|
old_len = len(rx)
|
|
rx.extend(panda_jungle.can_recv())
|
|
print(f"Received {len(rx)} messages")
|
|
|
|
# All messages should have been received
|
|
if len(rx) != 3 * NUM_MESSAGES_PER_BUS:
|
|
Exception("Did not receive all messages!")
|
|
|
|
# Set back to silent mode
|
|
p.set_safety_mode(Panda.SAFETY_SILENT)
|