Release 260111
This commit is contained in:
29
panda/board/jungle/scripts/can_health.py
Executable file
29
panda/board/jungle/scripts/can_health.py
Executable file
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env python3
|
||||
import time
|
||||
import re
|
||||
from panda import PandaJungle
|
||||
|
||||
RED = '\033[91m'
|
||||
GREEN = '\033[92m'
|
||||
|
||||
def colorize_errors(value):
|
||||
if isinstance(value, str):
|
||||
if re.search(r'(?i)No error', value):
|
||||
return f'{GREEN}{value}\033[0m'
|
||||
elif re.search(r'(?i)(?<!No error\s)(err|error)', value):
|
||||
return f'{RED}{value}\033[0m'
|
||||
return str(value)
|
||||
|
||||
if __name__ == "__main__":
|
||||
jungle = PandaJungle()
|
||||
|
||||
while True:
|
||||
print(chr(27) + "[2J") # clear screen
|
||||
print("Connected to " + ("internal panda" if jungle.is_internal() else "External panda") + f" id: {jungle.get_serial()[0]}: {jungle.get_version()}")
|
||||
for bus in range(3):
|
||||
print(f"\nBus {bus}:")
|
||||
health = jungle.can_health(bus)
|
||||
for key, value in health.items():
|
||||
print(f"{key}: {colorize_errors(value)} ", end=" ")
|
||||
print()
|
||||
time.sleep(1)
|
||||
44
panda/board/jungle/scripts/can_printer.py
Executable file
44
panda/board/jungle/scripts/can_printer.py
Executable file
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import time
|
||||
from collections import defaultdict
|
||||
import binascii
|
||||
|
||||
from panda import PandaJungle
|
||||
|
||||
# fake
|
||||
def sec_since_boot():
|
||||
return time.time()
|
||||
|
||||
def can_printer():
|
||||
p = PandaJungle()
|
||||
print(f"Connected to: {p._serial}: {p.get_version()}")
|
||||
time.sleep(1)
|
||||
|
||||
p.can_clear(0xFFFF)
|
||||
|
||||
start = sec_since_boot()
|
||||
lp = sec_since_boot()
|
||||
all_msgs = defaultdict(list)
|
||||
|
||||
canbus = os.getenv("CAN")
|
||||
if canbus == "3":
|
||||
p.set_obd(True)
|
||||
canbus = "1"
|
||||
|
||||
while True:
|
||||
can_recv = p.can_recv()
|
||||
for addr, dat, bus in can_recv:
|
||||
if canbus is None or str(bus) == canbus:
|
||||
all_msgs[(addr, bus)].append((dat))
|
||||
|
||||
if sec_since_boot() - lp > 0.1:
|
||||
dd = chr(27) + "[2J"
|
||||
dd += "%5.2f\n" % (sec_since_boot() - start)
|
||||
for (addr, bus), dat_log in sorted(all_msgs.items()):
|
||||
dd += "%d: %s(%6d): %s\n" % (bus, "%04X(%4d)" % (addr, addr), len(dat_log), binascii.hexlify(dat_log[-1]).decode())
|
||||
print(dd)
|
||||
lp = sec_since_boot()
|
||||
|
||||
if __name__ == "__main__":
|
||||
can_printer()
|
||||
38
panda/board/jungle/scripts/debug_console.py
Executable file
38
panda/board/jungle/scripts/debug_console.py
Executable file
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
from panda import PandaJungle
|
||||
|
||||
setcolor = ["\033[1;32;40m", "\033[1;31;40m"]
|
||||
unsetcolor = "\033[00m"
|
||||
|
||||
if __name__ == "__main__":
|
||||
while True:
|
||||
try:
|
||||
claim = os.getenv("CLAIM") is not None
|
||||
|
||||
serials = PandaJungle.list()
|
||||
if os.getenv("SERIAL"):
|
||||
serials = [x for x in serials if x==os.getenv("SERIAL")]
|
||||
|
||||
panda_jungles = [PandaJungle(x, claim=claim) for x in serials]
|
||||
|
||||
if not len(panda_jungles):
|
||||
sys.exit("no panda jungles found")
|
||||
|
||||
while True:
|
||||
for i, panda_jungle in enumerate(panda_jungles):
|
||||
while True:
|
||||
ret = panda_jungle.debug_read()
|
||||
if len(ret) > 0:
|
||||
sys.stdout.write(setcolor[i] + ret.decode('ascii') + unsetcolor)
|
||||
sys.stdout.flush()
|
||||
else:
|
||||
break
|
||||
time.sleep(0.01)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
print("panda jungle disconnected!")
|
||||
time.sleep(0.5)
|
||||
68
panda/board/jungle/scripts/echo_loopback_test.py
Executable file
68
panda/board/jungle/scripts/echo_loopback_test.py
Executable file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import time
|
||||
import contextlib
|
||||
import random
|
||||
from termcolor import cprint
|
||||
|
||||
from panda import PandaJungle
|
||||
|
||||
# This script is intended to be used in conjunction with the echo.py test script from panda.
|
||||
# It sends messages on bus 0, 1, 2 and checks for a reversed response to be sent back.
|
||||
|
||||
#################################################################
|
||||
############################# UTILS #############################
|
||||
#################################################################
|
||||
def print_colored(text, color):
|
||||
cprint(text + " "*40, color, end="\r")
|
||||
|
||||
def get_test_string():
|
||||
return b"test"+os.urandom(4)
|
||||
|
||||
#################################################################
|
||||
############################# TEST ##############################
|
||||
#################################################################
|
||||
|
||||
def test_loopback():
|
||||
for bus in range(3):
|
||||
# Clear can
|
||||
jungle.can_clear(bus)
|
||||
# Send a random message
|
||||
address = random.randint(1, 2000)
|
||||
data = get_test_string()
|
||||
jungle.can_send(address, data, bus)
|
||||
time.sleep(0.1)
|
||||
|
||||
# Make sure it comes back reversed
|
||||
incoming = jungle.can_recv()
|
||||
found = False
|
||||
for message in incoming:
|
||||
incomingAddress, incomingData, incomingBus = message
|
||||
if incomingAddress == address and incomingData == data[::-1] and incomingBus == bus:
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
cprint("\nFAILED", "red")
|
||||
raise AssertionError
|
||||
|
||||
#################################################################
|
||||
############################# MAIN ##############################
|
||||
#################################################################
|
||||
jungle = None
|
||||
counter = 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Connect to jungle silently
|
||||
print_colored("Connecting to jungle", "blue")
|
||||
with open(os.devnull, "w") as devnull:
|
||||
with contextlib.redirect_stdout(devnull):
|
||||
jungle = PandaJungle()
|
||||
jungle.set_panda_power(True)
|
||||
jungle.set_ignition(False)
|
||||
|
||||
# Run test
|
||||
while True:
|
||||
jungle.can_clear(0xFFFF)
|
||||
test_loopback()
|
||||
counter += 1
|
||||
print_colored(str(counter) + " loopback cycles complete", "blue")
|
||||
9
panda/board/jungle/scripts/get_version.py
Executable file
9
panda/board/jungle/scripts/get_version.py
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env python3
|
||||
from panda import PandaJungle
|
||||
|
||||
if __name__ == "__main__":
|
||||
for p in PandaJungle.list():
|
||||
pp = PandaJungle(p)
|
||||
print(f"{pp.get_serial()[0]}: {pp.get_version()}")
|
||||
|
||||
|
||||
21
panda/board/jungle/scripts/health_test.py
Executable file
21
panda/board/jungle/scripts/health_test.py
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env python3
|
||||
import time
|
||||
from pprint import pprint
|
||||
|
||||
from panda import PandaJungle
|
||||
|
||||
if __name__ == "__main__":
|
||||
i = 0
|
||||
pi = 0
|
||||
|
||||
pj = PandaJungle()
|
||||
while True:
|
||||
st = time.monotonic()
|
||||
while time.monotonic() - st < 1:
|
||||
pj.health()
|
||||
pj.can_health(0)
|
||||
i += 1
|
||||
pprint(pj.health())
|
||||
print(f"Speed: {i - pi}Hz")
|
||||
pi = i
|
||||
|
||||
141
panda/board/jungle/scripts/loopback_test.py
Executable file
141
panda/board/jungle/scripts/loopback_test.py
Executable file
@@ -0,0 +1,141 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import time
|
||||
import contextlib
|
||||
import random
|
||||
from termcolor import cprint
|
||||
|
||||
from opendbc.car.structs import CarParams
|
||||
from panda import Panda, PandaJungle
|
||||
|
||||
NUM_PANDAS_PER_TEST = 1
|
||||
FOR_RELEASE_BUILDS = os.getenv("RELEASE") is not None # Release builds do not have ALLOUTPUT mode
|
||||
|
||||
BUS_SPEEDS = [125, 500, 1000]
|
||||
|
||||
#################################################################
|
||||
############################# UTILS #############################
|
||||
#################################################################
|
||||
# To suppress the connection text
|
||||
def silent_panda_connect(serial):
|
||||
with open(os.devnull, "w") as devnull:
|
||||
with contextlib.redirect_stdout(devnull):
|
||||
panda = Panda(serial)
|
||||
return panda
|
||||
|
||||
def print_colored(text, color):
|
||||
cprint(text + " "*40, color, end="\r")
|
||||
|
||||
def connect_to_pandas():
|
||||
print_colored("Connecting to pandas", "blue")
|
||||
# Connect to pandas
|
||||
pandas = []
|
||||
for serial in panda_serials:
|
||||
pandas.append(silent_panda_connect(serial))
|
||||
print_colored("Connected", "blue")
|
||||
|
||||
def start_with_orientation(orientation):
|
||||
print_colored("Restarting pandas with orientation " + str(orientation), "blue")
|
||||
jungle.set_panda_power(False)
|
||||
jungle.set_harness_orientation(orientation)
|
||||
time.sleep(4)
|
||||
jungle.set_panda_power(True)
|
||||
time.sleep(2)
|
||||
connect_to_pandas()
|
||||
|
||||
def can_loopback(sender):
|
||||
receivers = list(filter((lambda p: (p != sender)), [jungle] + pandas))
|
||||
|
||||
for bus in range(4):
|
||||
obd = False
|
||||
if bus == 3:
|
||||
obd = True
|
||||
bus = 1
|
||||
|
||||
# Clear buses
|
||||
for receiver in receivers:
|
||||
receiver.set_obd(obd)
|
||||
receiver.can_clear(bus) # TX
|
||||
receiver.can_clear(0xFFFF) # RX
|
||||
|
||||
# Send a random string
|
||||
addr = 0x18DB33F1 if FOR_RELEASE_BUILDS else random.randint(1, 2000)
|
||||
string = b"test"+os.urandom(4)
|
||||
sender.set_obd(obd)
|
||||
time.sleep(0.2)
|
||||
sender.can_send(addr, string, bus)
|
||||
time.sleep(0.2)
|
||||
|
||||
# Check if all receivers have indeed received them in their receiving buffers
|
||||
for receiver in receivers:
|
||||
content = receiver.can_recv()
|
||||
|
||||
# Check amount of messages
|
||||
if len(content) != 1:
|
||||
raise Exception("Amount of received CAN messages (" + str(len(content)) + ") does not equal 1. Bus: " + str(bus) +" OBD: " + str(obd))
|
||||
|
||||
# Check content
|
||||
if content[0][0] != addr or content[0][1] != string:
|
||||
raise Exception("Received CAN message content or address does not match")
|
||||
|
||||
# Check bus
|
||||
if content[0][2] != bus:
|
||||
raise Exception("Received CAN message bus does not match")
|
||||
|
||||
#################################################################
|
||||
############################# TEST ##############################
|
||||
#################################################################
|
||||
|
||||
def test_loopback():
|
||||
# disable safety modes
|
||||
for panda in pandas:
|
||||
panda.set_safety_mode(CarParams.SafetyModel.elm327 if FOR_RELEASE_BUILDS else CarParams.SafetyModel.allOutput)
|
||||
|
||||
# perform loopback with jungle as a sender
|
||||
can_loopback(jungle)
|
||||
|
||||
# perform loopback with each possible panda as a sender
|
||||
for panda in pandas:
|
||||
can_loopback(panda)
|
||||
|
||||
# enable safety modes
|
||||
for panda in pandas:
|
||||
panda.set_safety_mode(CarParams.SafetyModel.silent)
|
||||
|
||||
#################################################################
|
||||
############################# MAIN ##############################
|
||||
#################################################################
|
||||
jungle = None
|
||||
pandas = [] # type: ignore
|
||||
panda_serials = []
|
||||
counter = 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Connect to jungle silently
|
||||
print_colored("Connecting to jungle", "blue")
|
||||
with open(os.devnull, "w") as devnull:
|
||||
with contextlib.redirect_stdout(devnull):
|
||||
jungle = PandaJungle()
|
||||
jungle.set_panda_power(True)
|
||||
jungle.set_ignition(False)
|
||||
|
||||
# Connect to <NUM_PANDAS_PER_TEST> new pandas before starting tests
|
||||
print_colored("Waiting for " + str(NUM_PANDAS_PER_TEST) + " pandas to be connected", "yellow")
|
||||
while True:
|
||||
connected_serials = Panda.list()
|
||||
if len(connected_serials) == NUM_PANDAS_PER_TEST:
|
||||
panda_serials = connected_serials
|
||||
break
|
||||
|
||||
start_with_orientation(PandaJungle.HARNESS_ORIENTATION_1)
|
||||
|
||||
# Set bus speeds
|
||||
for device in pandas + [jungle]:
|
||||
for bus in range(len(BUS_SPEEDS)):
|
||||
device.set_can_speed_kbps(bus, BUS_SPEEDS[bus])
|
||||
|
||||
# Run test
|
||||
while True:
|
||||
test_loopback()
|
||||
counter += 1
|
||||
print_colored(str(counter) + " loopback cycles complete", "blue")
|
||||
45
panda/board/jungle/scripts/panda_identification_test.py
Executable file
45
panda/board/jungle/scripts/panda_identification_test.py
Executable file
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import time
|
||||
import random
|
||||
import contextlib
|
||||
|
||||
from panda import PandaJungle
|
||||
from panda import Panda
|
||||
|
||||
PANDA_UNDER_TEST = Panda.HW_TYPE_UNO
|
||||
|
||||
panda_jungle = PandaJungle()
|
||||
|
||||
def silent_panda_connect():
|
||||
with open(os.devnull, "w") as devnull:
|
||||
with contextlib.redirect_stdout(devnull):
|
||||
panda = Panda()
|
||||
return panda
|
||||
|
||||
def reboot_panda(harness_orientation=PandaJungle.HARNESS_ORIENTATION_NONE, ignition=False):
|
||||
print(f"Restarting panda with harness orientation: {harness_orientation} and ignition: {ignition}")
|
||||
panda_jungle.set_panda_power(False)
|
||||
panda_jungle.set_harness_orientation(harness_orientation)
|
||||
panda_jungle.set_ignition(ignition)
|
||||
time.sleep(2)
|
||||
panda_jungle.set_panda_power(True)
|
||||
time.sleep(2)
|
||||
|
||||
count = 0
|
||||
if __name__ == "__main__":
|
||||
while True:
|
||||
ignition = random.randint(0, 1)
|
||||
harness_orientation = random.randint(0, 2)
|
||||
reboot_panda(harness_orientation, ignition)
|
||||
|
||||
p = silent_panda_connect()
|
||||
assert p.get_type() == PANDA_UNDER_TEST
|
||||
assert p.health()['car_harness_status'] == harness_orientation
|
||||
if harness_orientation != PandaJungle.HARNESS_ORIENTATION_NONE:
|
||||
assert p.health()['ignition_line'] == ignition
|
||||
|
||||
count += 1
|
||||
print(f"Passed {count} loops")
|
||||
|
||||
|
||||
21
panda/board/jungle/scripts/spam_can.py
Executable file
21
panda/board/jungle/scripts/spam_can.py
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import random
|
||||
from opendbc.car.structs import CarParams
|
||||
from panda import PandaJungle
|
||||
|
||||
def get_test_string():
|
||||
return b"test" + os.urandom(10)
|
||||
|
||||
if __name__ == "__main__":
|
||||
p = PandaJungle()
|
||||
|
||||
p.set_safety_mode(CarParams.SafetyModel.allOutput)
|
||||
|
||||
print("Spamming all buses...")
|
||||
while True:
|
||||
at = random.randint(1, 2000)
|
||||
st = get_test_string()[0:8]
|
||||
bus = random.randint(0, 2)
|
||||
p.can_send(at, st, bus)
|
||||
# print("Sent message on bus: ", bus)
|
||||
18
panda/board/jungle/scripts/start.py
Executable file
18
panda/board/jungle/scripts/start.py
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env python
|
||||
import sys
|
||||
|
||||
from panda import PandaJungle
|
||||
|
||||
if __name__ == "__main__":
|
||||
jungle = PandaJungle()
|
||||
|
||||
# If first argument specified, it sets the ignition (0 or 1)
|
||||
if len(sys.argv) > 1:
|
||||
if sys.argv[1] == '1':
|
||||
jungle.set_ignition(True)
|
||||
else:
|
||||
jungle.set_ignition(False)
|
||||
jungle.set_harness_orientation(1)
|
||||
jungle.set_panda_power(True)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user