mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-08-23 09:13:43 +08:00
Squashed 'panda/' changes from 30c7ca8a5..256d274e7
256d274e7 Fix Mac installation instruction per: https://github.com/commaai/panda/pull/308/files
bfd8ff1b1 Update cppcheck commit with more coverage
b143a1cf9 Fixed Misra complaint
606f1d913 Fixed RTC on non-uno boards, second try. Cannot work when there is no xtal.
933c75770 Fix RTC on non-uno boards (#311)
48d0d0c78 VW button spam: fix safety and add tests (#306)
6cccf969a Fan and IR at 0 when in power savings mode (#309)
05373282a board get_sdk scripts were left on python2
de18a7ef1 bump version after uno merge
1965817d3 Changed default values for testing
a12a148d5 Uno (#274)
7d29dc5a2 bump panda version. We really need a better way
40075321d VW: stricter limits to comply with comma safety policy
e2e2be92c add safety mode to health packet
101238c7f turned on VW ignition based CAN logic
a0d8d5dae fix misra 5.3: check_ignition is intended as check_started and can't be used twice
ea636de61 made check_ignition function to both look at ignition_line and ignition_can
1102e6965 make ignition logic common for all cars (#303)
3a110c6f6 bump version after CMSIS core upgrade
55dfa5230 Update core to CMSIS 5.6 release (#251)
ee864907c fix linter 2
f410b110d fix linter
55957d6e4 proper python3 exception inheritance
6ba0f47b5 fix linter errors
5c49fe050 Merge pull request #145 from gregjhogan/uds
0f361999b timeout is float
396d6aad5 safety_replay only installs few extra requirements
25af7d301 Misra also need python 3 env
7434c5ce2 centralize requirements for tests
a0c37c70a coverage not needed in linter reqs
fce38a91d Linter python (#299)
62e2f5caa update cppcheck commit
711810d2f more uds debug
4454e3a6b better CAN comm abstraction
6b1f28f57 fix more encoding and some bytes cleanup (#300)
43adad311 fix WARNING_INDICATOR_REQUESTED name
9c857da37 0x
b64d6fa5d typing
768fdf7e1 bytes() > chr().encode()
1be15ea93 custom errors from thread
68da8315f more python3
eb358e81c uds lib example
4f288586d updates for python3
932745f62 support tx flow control for chunked messages
b1c371292 add timeout param
cdf2f626b bug fixes
b1a319577 fix rx message filtering bug
80fb6a6fa convert uds lib to class
59cd2b47f handle separation time in microseconds
4429600d8 fix separation time parsing
c641e66f7 fix typo
48b8dcc6f fix flow control delay scale
78f413d88 flow control delay
33a5167d9 bug fixes
8ee89a091 multi-frame tx
5e89a9c72 clear rx buffer and numeric error ids
966230063 fix remaining size calculation
01ef1fae3 zero pad messages before sending
1ddc9735d uds can communication
dca176e71 syntax errors
95be4811e SERVICE_TYPE enum
98e73b51d more UDS message type implementation
c1c5b0356 uds lib
162f4853d fix chr to bytes conversions (#298)
4972376de Update VW regression test to follow Comma safety index refactoring (#296)
f9053f5df more Python 3 fixes, attempting to fix jenkins wifi regresison test (#295)
2f9e07628 Panda safety code for Volkswagen, Audi, SEAT, and Škoda (#293)
git-subtree-dir: panda
git-subtree-split: 256d274e760ce00d4e5ff5e0d9b86d0fb5924568
old-commit-hash: 22023ebd58
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
import os
|
||||
from panda import build_st
|
||||
|
||||
def test_build_panda():
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import os
|
||||
from panda import Panda
|
||||
from .helpers import panda_type_to_serial, test_white_and_grey, test_all_pandas, panda_connect_and_init
|
||||
from .helpers import test_all_pandas, panda_connect_and_init
|
||||
|
||||
@test_all_pandas
|
||||
@panda_connect_and_init
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
from panda import Panda
|
||||
@@ -180,6 +178,6 @@ def test_gmlan_bad_toggle(p):
|
||||
@test_all_pandas
|
||||
@panda_connect_and_init
|
||||
def test_serial_debug(p):
|
||||
junk = p.serial_read(Panda.SERIAL_DEBUG)
|
||||
_ = p.serial_read(Panda.SERIAL_DEBUG) # junk
|
||||
p.call_control_api(0xc0)
|
||||
assert(p.serial_read(Panda.SERIAL_DEBUG).startswith(b"can "))
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
import os
|
||||
import time
|
||||
from panda import Panda
|
||||
from .helpers import connect_wifi, test_white, test_all_pandas, panda_type_to_serial, panda_connect_and_init
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
|
||||
import time
|
||||
from panda import Panda
|
||||
from .helpers import time_many_sends, connect_wifi, test_white, panda_type_to_serial
|
||||
from nose.tools import timed, assert_equal, assert_less, assert_greater
|
||||
|
||||
@test_white
|
||||
@panda_type_to_serial
|
||||
|
||||
@@ -3,7 +3,7 @@ import sys
|
||||
import time
|
||||
from .helpers import time_many_sends, connect_wifi, test_white, panda_type_to_serial
|
||||
from panda import Panda, PandaWifiStreaming
|
||||
from nose.tools import timed, assert_equal, assert_less, assert_greater
|
||||
from nose.tools import assert_less, assert_greater
|
||||
|
||||
@test_white
|
||||
@panda_type_to_serial
|
||||
|
||||
@@ -171,7 +171,7 @@ def test_black_loopback(panda0, panda1):
|
||||
time.sleep(0.1)
|
||||
|
||||
# check for receive
|
||||
cans_echo = send_panda.can_recv()
|
||||
_ = send_panda.can_recv() # cans echo
|
||||
cans_loop = recv_panda.can_recv()
|
||||
|
||||
loop_buses = []
|
||||
|
||||
@@ -2,13 +2,12 @@ import os
|
||||
import sys
|
||||
import time
|
||||
import random
|
||||
import binascii
|
||||
import subprocess
|
||||
import requests
|
||||
import _thread
|
||||
from functools import wraps
|
||||
from panda import Panda
|
||||
from nose.tools import timed, assert_equal, assert_less, assert_greater
|
||||
from nose.tools import assert_equal
|
||||
from parameterized import parameterized, param
|
||||
|
||||
SPEED_NORMAL = 500
|
||||
@@ -50,7 +49,7 @@ def connect_wifi(serial=None):
|
||||
|
||||
FNULL = open(os.devnull, 'w')
|
||||
def _connect_wifi(dongle_id, pw, insecure_okay=False):
|
||||
ssid = "panda-" + dongle_id.decode("utf8")
|
||||
ssid = "panda-" + dongle_id
|
||||
|
||||
r = subprocess.call(["ping", "-W", "4", "-c", "1", "192.168.0.10"], stdout=FNULL, stderr=subprocess.STDOUT)
|
||||
if not r:
|
||||
@@ -69,7 +68,7 @@ def _connect_wifi(dongle_id, pw, insecure_okay=False):
|
||||
if sys.platform == "darwin":
|
||||
os.system("networksetup -setairportnetwork en0 %s %s" % (ssid, pw))
|
||||
else:
|
||||
wlan_interface = subprocess.check_output(["sh", "-c", "iw dev | awk '/Interface/ {print $2}'"]).strip()
|
||||
wlan_interface = subprocess.check_output(["sh", "-c", "iw dev | awk '/Interface/ {print $2}'"]).strip().decode('utf8')
|
||||
cnt = 0
|
||||
MAX_TRIES = 10
|
||||
while cnt < MAX_TRIES:
|
||||
@@ -87,13 +86,13 @@ def _connect_wifi(dongle_id, pw, insecure_okay=False):
|
||||
if "-pair" in wifi_scan[0]:
|
||||
os.system("nmcli d wifi connect %s-pair" % (ssid))
|
||||
connect_cnt = 0
|
||||
MAX_TRIES = 20
|
||||
MAX_TRIES = 100
|
||||
while connect_cnt < MAX_TRIES:
|
||||
connect_cnt += 1
|
||||
r = subprocess.call(["ping", "-W", "4", "-c", "1", "192.168.0.10"], stdout=FNULL, stderr=subprocess.STDOUT)
|
||||
if r:
|
||||
print("Waiting for panda to ping...")
|
||||
time.sleep(0.1)
|
||||
time.sleep(0.5)
|
||||
else:
|
||||
break
|
||||
if insecure_okay:
|
||||
|
||||
@@ -11,9 +11,6 @@ import time
|
||||
import random
|
||||
import argparse
|
||||
|
||||
from hexdump import hexdump
|
||||
from itertools import permutations
|
||||
|
||||
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), ".."))
|
||||
from panda import Panda
|
||||
|
||||
@@ -33,7 +30,7 @@ def run_test(sleep_duration):
|
||||
pandas[0] = Panda(pandas[0])
|
||||
pandas[1] = Panda(pandas[1])
|
||||
|
||||
# find out the hardware types
|
||||
# find out the hardware types
|
||||
if not pandas[0].is_black() or not pandas[1].is_black():
|
||||
print("Connect two black pandas to run this test!")
|
||||
assert False
|
||||
@@ -66,14 +63,14 @@ def run_test(sleep_duration):
|
||||
test_buses(pandas[0], pandas[1], test_array, sleep_duration)
|
||||
print("***************** TESTING (1 --> 0) *****************")
|
||||
test_buses(pandas[1], pandas[0], test_array, sleep_duration)
|
||||
|
||||
|
||||
|
||||
def test_buses(send_panda, recv_panda, test_array, sleep_duration):
|
||||
for send_bus, send_obd, recv_obd, recv_buses in test_array:
|
||||
send_panda.send_heartbeat()
|
||||
recv_panda.send_heartbeat()
|
||||
print("\nSend bus:", send_bus, " Send OBD:", send_obd, " Recv OBD:", recv_obd)
|
||||
|
||||
|
||||
# set OBD on pandas
|
||||
send_panda.set_gmlan(True if send_obd else None)
|
||||
recv_panda.set_gmlan(True if recv_obd else None)
|
||||
@@ -92,7 +89,7 @@ def test_buses(send_panda, recv_panda, test_array, sleep_duration):
|
||||
time.sleep(0.1)
|
||||
|
||||
# check for receive
|
||||
cans_echo = send_panda.can_recv()
|
||||
_ = send_panda.can_recv() # cans echo
|
||||
cans_loop = recv_panda.can_recv()
|
||||
|
||||
loop_buses = []
|
||||
@@ -101,7 +98,7 @@ def test_buses(send_panda, recv_panda, test_array, sleep_duration):
|
||||
loop_buses.append(loop[3])
|
||||
if len(cans_loop) == 0:
|
||||
print(" No loop")
|
||||
|
||||
|
||||
# test loop buses
|
||||
recv_buses.sort()
|
||||
loop_buses.sort()
|
||||
|
||||
@@ -11,9 +11,6 @@ import time
|
||||
import random
|
||||
import argparse
|
||||
|
||||
from hexdump import hexdump
|
||||
from itertools import permutations
|
||||
|
||||
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), ".."))
|
||||
from panda import Panda
|
||||
|
||||
@@ -118,10 +115,10 @@ def test_buses(black_panda, other_panda, direction, test_array, sleep_duration):
|
||||
|
||||
# check for receive
|
||||
if direction:
|
||||
cans_echo = black_panda.can_recv()
|
||||
_ = black_panda.can_recv() # can echo
|
||||
cans_loop = other_panda.can_recv()
|
||||
else:
|
||||
cans_echo = other_panda.can_recv()
|
||||
_ = other_panda.can_recv() # can echo
|
||||
cans_loop = black_panda.can_recv()
|
||||
|
||||
loop_buses = []
|
||||
|
||||
@@ -11,9 +11,6 @@ import time
|
||||
import random
|
||||
import argparse
|
||||
|
||||
from hexdump import hexdump
|
||||
from itertools import permutations
|
||||
|
||||
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), ".."))
|
||||
from panda import Panda
|
||||
|
||||
@@ -42,7 +39,7 @@ def run_test(sleep_duration):
|
||||
|
||||
black_panda = None
|
||||
other_panda = None
|
||||
|
||||
|
||||
# find out which one is black
|
||||
if pandas[0].is_black() and not pandas[1].is_black():
|
||||
black_panda = pandas[0]
|
||||
@@ -69,7 +66,7 @@ def run_test(sleep_duration):
|
||||
test_buses(black_panda, other_panda, True, [(0, False, [0]), (1, False, [1]), (2, False, [2]), (1, True, [0])], sleep_duration)
|
||||
test_buses(black_panda, other_panda, False, [(0, False, [0]), (1, False, [1]), (2, False, [2]), (0, True, [0, 1])], sleep_duration)
|
||||
counter += 1
|
||||
|
||||
|
||||
runtime = time.time() - start_time
|
||||
print("Number of cycles:", counter, "Non-zero bus errors:", nonzero_bus_errors, "Zero bus errors:", zero_bus_errors, "Content errors:", content_errors, "Runtime: ", runtime)
|
||||
|
||||
@@ -80,7 +77,7 @@ def run_test(sleep_duration):
|
||||
black_panda.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
|
||||
time.sleep(1)
|
||||
temp_start_time = time.time()
|
||||
|
||||
|
||||
|
||||
def test_buses(black_panda, other_panda, direction, test_array, sleep_duration):
|
||||
global nonzero_bus_errors, zero_bus_errors, content_errors
|
||||
@@ -94,7 +91,7 @@ def test_buses(black_panda, other_panda, direction, test_array, sleep_duration):
|
||||
black_panda.send_heartbeat()
|
||||
other_panda.send_heartbeat()
|
||||
print("\ntest can: ", send_bus, " OBD: ", obd)
|
||||
|
||||
|
||||
# set OBD on black panda
|
||||
black_panda.set_gmlan(True if obd else None)
|
||||
|
||||
@@ -109,7 +106,7 @@ def test_buses(black_panda, other_panda, direction, test_array, sleep_duration):
|
||||
other_panda.can_clear(recv_bus)
|
||||
else:
|
||||
black_panda.can_clear(recv_bus)
|
||||
|
||||
|
||||
black_panda.can_recv()
|
||||
other_panda.can_recv()
|
||||
|
||||
@@ -124,10 +121,10 @@ def test_buses(black_panda, other_panda, direction, test_array, sleep_duration):
|
||||
|
||||
# check for receive
|
||||
if direction:
|
||||
cans_echo = black_panda.can_recv()
|
||||
_ = black_panda.can_recv() # cans echo
|
||||
cans_loop = other_panda.can_recv()
|
||||
else:
|
||||
cans_echo = other_panda.can_recv()
|
||||
_ = other_panda.can_recv() # cans echo
|
||||
cans_loop = black_panda.can_recv()
|
||||
|
||||
loop_buses = []
|
||||
@@ -141,7 +138,7 @@ def test_buses(black_panda, other_panda, direction, test_array, sleep_duration):
|
||||
print(" No loop")
|
||||
if not os.getenv("NOASSERT"):
|
||||
assert False
|
||||
|
||||
|
||||
# test loop buses
|
||||
recv_buses.sort()
|
||||
loop_buses.sort()
|
||||
|
||||
@@ -10,9 +10,6 @@ import time
|
||||
import random
|
||||
import argparse
|
||||
|
||||
from hexdump import hexdump
|
||||
from itertools import permutations
|
||||
|
||||
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), ".."))
|
||||
from panda import Panda
|
||||
|
||||
@@ -46,7 +43,7 @@ def run_test(sleep_duration):
|
||||
|
||||
black_panda = None
|
||||
other_panda = None
|
||||
|
||||
|
||||
if type0 == "\x03" and type1 != "\x03":
|
||||
black_panda = pandas[0]
|
||||
other_panda = pandas[1]
|
||||
@@ -86,15 +83,15 @@ def run_test(sleep_duration):
|
||||
assert False
|
||||
|
||||
counter += 1
|
||||
print("Number of cycles:", counter, "Open errors:", open_errors, "Closed errors:", closed_errors, "Content errors:", content_errors)
|
||||
print("Number of cycles:", counter, "Open errors:", open_errors, "Closed errors:", closed_errors, "Content errors:", content_errors)
|
||||
|
||||
def test_buses(black_panda, other_panda, test_obj):
|
||||
global content_errors
|
||||
send_bus, obd, recv_buses = test_obj
|
||||
|
||||
|
||||
black_panda.send_heartbeat()
|
||||
other_panda.send_heartbeat()
|
||||
|
||||
|
||||
# Set OBD on send panda
|
||||
other_panda.set_gmlan(True if obd else None)
|
||||
|
||||
@@ -103,7 +100,7 @@ def test_buses(black_panda, other_panda, test_obj):
|
||||
|
||||
for recv_bus in recv_buses:
|
||||
black_panda.can_clear(recv_bus)
|
||||
|
||||
|
||||
black_panda.can_recv()
|
||||
other_panda.can_recv()
|
||||
|
||||
@@ -114,7 +111,7 @@ def test_buses(black_panda, other_panda, test_obj):
|
||||
time.sleep(0.05)
|
||||
|
||||
# check for receive
|
||||
cans_echo = other_panda.can_recv()
|
||||
_ = other_panda.can_recv() # can echo
|
||||
cans_loop = black_panda.can_recv()
|
||||
|
||||
loop_buses = []
|
||||
@@ -122,7 +119,7 @@ def test_buses(black_panda, other_panda, test_obj):
|
||||
if (loop[0] != at) or (loop[2] != st):
|
||||
content_errors += 1
|
||||
loop_buses.append(loop[3])
|
||||
|
||||
|
||||
# test loop buses
|
||||
recv_buses.sort()
|
||||
loop_buses.sort()
|
||||
|
||||
@@ -109,9 +109,9 @@ class ELMCarSimulator():
|
||||
print(" LIN Reply (%x)" % to_addr, binascii.hexlify(msg))
|
||||
|
||||
PHYS_ADDR = 0x80
|
||||
FUNC_ADDR = 0xC0
|
||||
#FUNC_ADDR = 0xC0
|
||||
RECV = 0xF1
|
||||
SEND = 0x33 # Car OBD Functional Address
|
||||
#SEND = 0x33 # Car OBD Functional Address
|
||||
headers = struct.pack("BBB", PHYS_ADDR | len(msg), RECV, to_addr)
|
||||
if not self.__silent:
|
||||
print(" Sending LIN", binascii.hexlify(headers+msg),
|
||||
@@ -172,7 +172,7 @@ class ELMCarSimulator():
|
||||
|
||||
while not self.__stop:
|
||||
for address, ts, data, src in self.panda.can_recv():
|
||||
if self.__on and src is 0 and len(data) == 8 and data[0] >= 2:
|
||||
if self.__on and src == 0 and len(data) == 8 and data[0] >= 2:
|
||||
if not self.__silent:
|
||||
print("Processing CAN message", src, hex(address), binascii.hexlify(data))
|
||||
self.__can_process_msg(data[1], data[2], address, ts, data, src)
|
||||
|
||||
+30
-32
@@ -1,16 +1,14 @@
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import socket
|
||||
import select
|
||||
import pytest
|
||||
import struct
|
||||
|
||||
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), ".."))
|
||||
from . import elm_car_simulator
|
||||
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), "..", ".."))
|
||||
from panda import Panda
|
||||
from panda.tests import elm_car_simulator
|
||||
|
||||
def elm_connect():
|
||||
s = socket.create_connection(("192.168.0.10", 35000))
|
||||
@@ -234,35 +232,35 @@ def test_elm_send_lin_multiline_msg():
|
||||
|
||||
send_compare(s, b'0902\r', # headers OFF, Spaces ON
|
||||
b"BUS INIT: OK\r"
|
||||
"49 02 01 00 00 00 31 \r"
|
||||
"49 02 02 44 34 47 50 \r"
|
||||
"49 02 03 30 30 52 35 \r"
|
||||
"49 02 04 35 42 31 32 \r"
|
||||
"49 02 05 33 34 35 36 \r\r>")
|
||||
b"49 02 01 00 00 00 31 \r"
|
||||
b"49 02 02 44 34 47 50 \r"
|
||||
b"49 02 03 30 30 52 35 \r"
|
||||
b"49 02 04 35 42 31 32 \r"
|
||||
b"49 02 05 33 34 35 36 \r\r>")
|
||||
|
||||
send_compare(s, b'ATS0\r', b'OK\r\r>') # Spaces OFF
|
||||
send_compare(s, b'0902\r', # Headers OFF, Spaces OFF
|
||||
b"49020100000031\r"
|
||||
"49020244344750\r"
|
||||
"49020330305235\r"
|
||||
"49020435423132\r"
|
||||
"49020533343536\r\r>")
|
||||
b"49020244344750\r"
|
||||
b"49020330305235\r"
|
||||
b"49020435423132\r"
|
||||
b"49020533343536\r\r>")
|
||||
|
||||
send_compare(s, b'ATH1\r', b'OK\r\r>') # Headers ON
|
||||
send_compare(s, b'0902\r', # Headers ON, Spaces OFF
|
||||
b"87F1104902010000003105\r"
|
||||
"87F11049020244344750E4\r"
|
||||
"87F11049020330305235BD\r"
|
||||
"87F11049020435423132B1\r"
|
||||
"87F11049020533343536AA\r\r>")
|
||||
b"87F11049020244344750E4\r"
|
||||
b"87F11049020330305235BD\r"
|
||||
b"87F11049020435423132B1\r"
|
||||
b"87F11049020533343536AA\r\r>")
|
||||
|
||||
send_compare(s, b'ATS1\r', b'OK\r\r>') # Spaces ON
|
||||
send_compare(s, b'0902\r', # Headers ON, Spaces ON
|
||||
b"87 F1 10 49 02 01 00 00 00 31 05 \r"
|
||||
"87 F1 10 49 02 02 44 34 47 50 E4 \r"
|
||||
"87 F1 10 49 02 03 30 30 52 35 BD \r"
|
||||
"87 F1 10 49 02 04 35 42 31 32 B1 \r"
|
||||
"87 F1 10 49 02 05 33 34 35 36 AA \r\r>")
|
||||
b"87 F1 10 49 02 02 44 34 47 50 E4 \r"
|
||||
b"87 F1 10 49 02 03 30 30 52 35 BD \r"
|
||||
b"87 F1 10 49 02 04 35 42 31 32 B1 \r"
|
||||
b"87 F1 10 49 02 05 33 34 35 36 AA \r\r>")
|
||||
finally:
|
||||
sim.stop()
|
||||
sim.join()
|
||||
@@ -322,7 +320,7 @@ def test_elm_panda_safety_mode_KWPFast():
|
||||
|
||||
def kline_send(p, x, bus=2):
|
||||
p.kline_drain(bus=bus)
|
||||
p._handle.bulkWrite(2, chr(bus).encode()+x)
|
||||
p._handle.bulkWrite(2, bytes([bus]) + x)
|
||||
return timed_recv_check(p, bus, x)
|
||||
|
||||
def did_send(priority, toaddr, fromaddr, dat, bus=2, checkbyte=None):
|
||||
@@ -461,7 +459,7 @@ def test_elm_send_can_multimsg():
|
||||
sim.can_add_extra_noise(b'\x03\x41\x0D\xFA', addr=0x7E9)# Inject message into the stream
|
||||
send_compare(s, b'010D\r',
|
||||
b"7E8 03 41 0D 53 \r"
|
||||
"7E9 03 41 0D FA \r\r>") # Check it was ignored.
|
||||
b"7E9 03 41 0D FA \r\r>") # Check it was ignored.
|
||||
finally:
|
||||
sim.stop()
|
||||
sim.join()
|
||||
@@ -503,28 +501,28 @@ def test_elm_send_can_multiline_msg():
|
||||
|
||||
send_compare(s, b'0902\r', # headers OFF, Spaces ON
|
||||
b"014 \r"
|
||||
"0: 49 02 01 31 44 34 \r"
|
||||
"1: 47 50 30 30 52 35 35 \r"
|
||||
"2: 42 31 32 33 34 35 36 \r\r>")
|
||||
b"0: 49 02 01 31 44 34 \r"
|
||||
b"1: 47 50 30 30 52 35 35 \r"
|
||||
b"2: 42 31 32 33 34 35 36 \r\r>")
|
||||
|
||||
send_compare(s, b'ATS0\r', b'OK\r\r>') # Spaces OFF
|
||||
send_compare(s, b'0902\r', # Headers OFF, Spaces OFF
|
||||
b"014\r"
|
||||
"0:490201314434\r"
|
||||
"1:47503030523535\r"
|
||||
"2:42313233343536\r\r>")
|
||||
b"0:490201314434\r"
|
||||
b"1:47503030523535\r"
|
||||
b"2:42313233343536\r\r>")
|
||||
|
||||
send_compare(s, b'ATH1\r', b'OK\r\r>') # Headers ON
|
||||
send_compare(s, b'0902\r', # Headers ON, Spaces OFF
|
||||
b"7E81014490201314434\r"
|
||||
"7E82147503030523535\r"
|
||||
"7E82242313233343536\r\r>")
|
||||
b"7E82147503030523535\r"
|
||||
b"7E82242313233343536\r\r>")
|
||||
|
||||
send_compare(s, b'ATS1\r', b'OK\r\r>') # Spaces ON
|
||||
send_compare(s, b'0902\r', # Headers ON, Spaces ON
|
||||
b"7E8 10 14 49 02 01 31 44 34 \r"
|
||||
"7E8 21 47 50 30 30 52 35 35 \r"
|
||||
"7E8 22 42 31 32 33 34 35 36 \r\r>")
|
||||
b"7E8 21 47 50 30 30 52 35 35 \r"
|
||||
b"7E8 22 42 31 32 33 34 35 36 \r\r>")
|
||||
finally:
|
||||
sim.stop()
|
||||
sim.join()
|
||||
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env python
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), ".."))
|
||||
from panda import Panda
|
||||
|
||||
power = 0
|
||||
if __name__ == "__main__":
|
||||
p = Panda()
|
||||
while True:
|
||||
p.set_fan_power(power)
|
||||
time.sleep(5)
|
||||
print("Power: ", power, "RPM: ", str(p.get_fan_rpm()))
|
||||
power += 10
|
||||
power %=100
|
||||
@@ -1,17 +1,16 @@
|
||||
#!/usr/bin/env python3
|
||||
import time
|
||||
from panda import Panda
|
||||
|
||||
p = Panda()
|
||||
p.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
|
||||
p.set_gmlan(bus=2)
|
||||
#p.can_send(0xaaa, "\x00\x00", bus=3)
|
||||
#p.can_send(0xaaa, b"\x00\x00", bus=3)
|
||||
last_add = None
|
||||
while 1:
|
||||
ret = p.can_recv()
|
||||
if len(ret) > 0:
|
||||
add = ret[0][0]
|
||||
if last_add is not None and add != last_add+1:
|
||||
print("MISS %d %d" % (last_add, add))
|
||||
if last_add is not None and add != last_add + 1:
|
||||
print("MISS: ", last_add, add)
|
||||
last_add = add
|
||||
print(ret)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# pylint: skip-file
|
||||
import numpy as np
|
||||
import visa
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
+19
-23
@@ -77,7 +77,7 @@ def init_gps(panda):
|
||||
|
||||
# Upping baud rate
|
||||
print("Upping GPS baud rate")
|
||||
msg = add_nmea_checksum("$PUBX,41,1,0007,0003,%d,0" % GPS_BAUD)+"\r\n"
|
||||
msg = str.encode(add_nmea_checksum("$PUBX,41,1,0007,0003,%d,0" % GPS_BAUD)+"\r\n")
|
||||
ser.write(msg)
|
||||
time.sleep(1) # needs a wait for it to actually send
|
||||
|
||||
@@ -86,24 +86,24 @@ def init_gps(panda):
|
||||
|
||||
# Sending all config messages boardd sends
|
||||
print("Sending config")
|
||||
ser.write("\xB5\x62\x06\x00\x14\x00\x03\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x00\x00\x00\x00\x00\x1E\x7F")
|
||||
ser.write("\xB5\x62\x06\x3E\x00\x00\x44\xD2")
|
||||
ser.write("\xB5\x62\x06\x00\x14\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\x35")
|
||||
ser.write("\xB5\x62\x06\x00\x14\x00\x01\x00\x00\x00\xC0\x08\x00\x00\x00\x08\x07\x00\x01\x00\x01\x00\x00\x00\x00\x00\xF4\x80")
|
||||
ser.write("\xB5\x62\x06\x00\x14\x00\x04\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1D\x85")
|
||||
ser.write("\xB5\x62\x06\x00\x00\x00\x06\x18")
|
||||
ser.write("\xB5\x62\x06\x00\x01\x00\x01\x08\x22")
|
||||
ser.write("\xB5\x62\x06\x00\x01\x00\x02\x09\x23")
|
||||
ser.write("\xB5\x62\x06\x00\x01\x00\x03\x0A\x24")
|
||||
ser.write("\xB5\x62\x06\x08\x06\x00\x64\x00\x01\x00\x00\x00\x79\x10")
|
||||
ser.write("\xB5\x62\x06\x24\x24\x00\x05\x00\x04\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5A\x63")
|
||||
ser.write("\xB5\x62\x06\x1E\x14\x00\x00\x00\x00\x00\x01\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3C\x37")
|
||||
ser.write("\xB5\x62\x06\x24\x00\x00\x2A\x84")
|
||||
ser.write("\xB5\x62\x06\x23\x00\x00\x29\x81")
|
||||
ser.write("\xB5\x62\x06\x1E\x00\x00\x24\x72")
|
||||
ser.write("\xB5\x62\x06\x01\x03\x00\x01\x07\x01\x13\x51")
|
||||
ser.write("\xB5\x62\x06\x01\x03\x00\x02\x15\x01\x22\x70")
|
||||
ser.write("\xB5\x62\x06\x01\x03\x00\x02\x13\x01\x20\x6C")
|
||||
ser.write(b"\xB5\x62\x06\x00\x14\x00\x03\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x00\x00\x00\x00\x00\x1E\x7F")
|
||||
ser.write(b"\xB5\x62\x06\x3E\x00\x00\x44\xD2")
|
||||
ser.write(b"\xB5\x62\x06\x00\x14\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\x35")
|
||||
ser.write(b"\xB5\x62\x06\x00\x14\x00\x01\x00\x00\x00\xC0\x08\x00\x00\x00\x08\x07\x00\x01\x00\x01\x00\x00\x00\x00\x00\xF4\x80")
|
||||
ser.write(b"\xB5\x62\x06\x00\x14\x00\x04\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1D\x85")
|
||||
ser.write(b"\xB5\x62\x06\x00\x00\x00\x06\x18")
|
||||
ser.write(b"\xB5\x62\x06\x00\x01\x00\x01\x08\x22")
|
||||
ser.write(b"\xB5\x62\x06\x00\x01\x00\x02\x09\x23")
|
||||
ser.write(b"\xB5\x62\x06\x00\x01\x00\x03\x0A\x24")
|
||||
ser.write(b"\xB5\x62\x06\x08\x06\x00\x64\x00\x01\x00\x00\x00\x79\x10")
|
||||
ser.write(b"\xB5\x62\x06\x24\x24\x00\x05\x00\x04\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5A\x63")
|
||||
ser.write(b"\xB5\x62\x06\x1E\x14\x00\x00\x00\x00\x00\x01\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3C\x37")
|
||||
ser.write(b"\xB5\x62\x06\x24\x00\x00\x2A\x84")
|
||||
ser.write(b"\xB5\x62\x06\x23\x00\x00\x29\x81")
|
||||
ser.write(b"\xB5\x62\x06\x1E\x00\x00\x24\x72")
|
||||
ser.write(b"\xB5\x62\x06\x01\x03\x00\x01\x07\x01\x13\x51")
|
||||
ser.write(b"\xB5\x62\x06\x01\x03\x00\x02\x15\x01\x22\x70")
|
||||
ser.write(b"\xB5\x62\x06\x01\x03\x00\x02\x13\x01\x20\x6C")
|
||||
|
||||
print("Initialized GPS")
|
||||
|
||||
@@ -163,7 +163,3 @@ if __name__ == "__main__":
|
||||
print("Total max failures: ", max_failures)
|
||||
received_messages = 0
|
||||
received_bytes = 0
|
||||
|
||||
|
||||
|
||||
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env python
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), ".."))
|
||||
from panda import Panda
|
||||
|
||||
power = 0
|
||||
if __name__ == "__main__":
|
||||
p = Panda()
|
||||
while True:
|
||||
p.set_ir_power(power)
|
||||
print("Power: ", str(power))
|
||||
time.sleep(1)
|
||||
power += 10
|
||||
power %=100
|
||||
@@ -14,5 +14,4 @@ RUN pyenv install 3.7.3
|
||||
RUN pyenv global 3.7.3
|
||||
RUN pyenv rehash
|
||||
|
||||
COPY tests/safety/requirements.txt /panda/tests/safety/requirements.txt
|
||||
COPY . /panda
|
||||
|
||||
@@ -20,7 +20,7 @@ if __name__ == "__main__":
|
||||
res = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
|
||||
print(res)
|
||||
found_bad_language = True
|
||||
except subprocess.CalledProcessError as e:
|
||||
except subprocess.CalledProcessError:
|
||||
pass
|
||||
if found_bad_language:
|
||||
sys.exit("Failed: found bad language")
|
||||
|
||||
@@ -0,0 +1,585 @@
|
||||
[MASTER]
|
||||
|
||||
# A comma-separated list of package or module names from where C extensions may
|
||||
# be loaded. Extensions are loading into the active Python interpreter and may
|
||||
# run arbitrary code
|
||||
extension-pkg-whitelist=scipy
|
||||
|
||||
# Add files or directories to the blacklist. They should be base names, not
|
||||
# paths.
|
||||
ignore=CVS
|
||||
|
||||
# Add files or directories matching the regex patterns to the blacklist. The
|
||||
# regex matches against base names, not paths.
|
||||
ignore-patterns=
|
||||
|
||||
# Python code to execute, usually for sys.path manipulation such as
|
||||
# pygtk.require().
|
||||
#init-hook=
|
||||
|
||||
# Use multiple processes to speed up Pylint.
|
||||
jobs=4
|
||||
|
||||
# List of plugins (as comma separated values of python modules names) to load,
|
||||
# usually to register additional checkers.
|
||||
load-plugins=
|
||||
|
||||
# Pickle collected data for later comparisons.
|
||||
persistent=yes
|
||||
|
||||
# Specify a configuration file.
|
||||
#rcfile=
|
||||
|
||||
# When enabled, pylint would attempt to guess common misconfiguration and emit
|
||||
# user-friendly hints instead of false-positive error messages
|
||||
suggestion-mode=yes
|
||||
|
||||
# Allow loading of arbitrary C extensions. Extensions are imported into the
|
||||
# active Python interpreter and may run arbitrary code.
|
||||
unsafe-load-any-extension=no
|
||||
|
||||
|
||||
[MESSAGES CONTROL]
|
||||
|
||||
# Only show warnings with the listed confidence levels. Leave empty to show
|
||||
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
|
||||
confidence=
|
||||
|
||||
# Disable the message, report, category or checker with the given id(s). You
|
||||
# can either give multiple identifiers separated by comma (,) or put this
|
||||
# option multiple times (only on the command line, not in the configuration
|
||||
# file where it should appear only once).You can also use "--disable=all" to
|
||||
# disable everything first and then reenable specific checks. For example, if
|
||||
# you want to run only the similarities checker, you can use "--disable=all
|
||||
# --enable=similarities". If you want to run only the classes checker, but have
|
||||
# no Warning level messages displayed, use"--disable=all --enable=classes
|
||||
# --disable=W"
|
||||
disable=print-statement,
|
||||
parameter-unpacking,
|
||||
unpacking-in-except,
|
||||
old-raise-syntax,
|
||||
backtick,
|
||||
long-suffix,
|
||||
old-ne-operator,
|
||||
old-octal-literal,
|
||||
import-star-module-level,
|
||||
non-ascii-bytes-literal,
|
||||
raw-checker-failed,
|
||||
bad-inline-option,
|
||||
locally-disabled,
|
||||
locally-enabled,
|
||||
file-ignored,
|
||||
suppressed-message,
|
||||
useless-suppression,
|
||||
deprecated-pragma,
|
||||
apply-builtin,
|
||||
basestring-builtin,
|
||||
buffer-builtin,
|
||||
cmp-builtin,
|
||||
coerce-builtin,
|
||||
execfile-builtin,
|
||||
file-builtin,
|
||||
long-builtin,
|
||||
raw_input-builtin,
|
||||
reduce-builtin,
|
||||
standarderror-builtin,
|
||||
unicode-builtin,
|
||||
xrange-builtin,
|
||||
coerce-method,
|
||||
delslice-method,
|
||||
getslice-method,
|
||||
setslice-method,
|
||||
no-absolute-import,
|
||||
old-division,
|
||||
dict-iter-method,
|
||||
dict-view-method,
|
||||
next-method-called,
|
||||
metaclass-assignment,
|
||||
indexing-exception,
|
||||
raising-string,
|
||||
reload-builtin,
|
||||
oct-method,
|
||||
hex-method,
|
||||
nonzero-method,
|
||||
cmp-method,
|
||||
input-builtin,
|
||||
round-builtin,
|
||||
intern-builtin,
|
||||
unichr-builtin,
|
||||
map-builtin-not-iterating,
|
||||
zip-builtin-not-iterating,
|
||||
range-builtin-not-iterating,
|
||||
filter-builtin-not-iterating,
|
||||
using-cmp-argument,
|
||||
eq-without-hash,
|
||||
div-method,
|
||||
idiv-method,
|
||||
rdiv-method,
|
||||
exception-message-attribute,
|
||||
invalid-str-codec,
|
||||
sys-max-int,
|
||||
bad-python3-import,
|
||||
deprecated-string-function,
|
||||
deprecated-str-translate-call,
|
||||
deprecated-itertools-function,
|
||||
deprecated-types-field,
|
||||
next-method-defined,
|
||||
dict-items-not-iterating,
|
||||
dict-keys-not-iterating,
|
||||
dict-values-not-iterating,
|
||||
bad-indentation,
|
||||
line-too-long,
|
||||
missing-docstring,
|
||||
multiple-statements,
|
||||
bad-continuation,
|
||||
invalid-name,
|
||||
too-many-arguments,
|
||||
too-many-locals,
|
||||
superfluous-parens,
|
||||
bad-whitespace,
|
||||
too-many-instance-attributes,
|
||||
wrong-import-position,
|
||||
ungrouped-imports,
|
||||
wrong-import-order,
|
||||
protected-access,
|
||||
trailing-whitespace,
|
||||
too-many-branches,
|
||||
too-few-public-methods,
|
||||
too-many-statements,
|
||||
trailing-newlines,
|
||||
attribute-defined-outside-init,
|
||||
too-many-return-statements,
|
||||
too-many-public-methods,
|
||||
unused-argument,
|
||||
old-style-class,
|
||||
no-init,
|
||||
len-as-condition,
|
||||
unneeded-not,
|
||||
no-self-use,
|
||||
multiple-imports,
|
||||
no-else-return,
|
||||
logging-not-lazy,
|
||||
fixme,
|
||||
redefined-outer-name,
|
||||
unused-variable,
|
||||
unsubscriptable-object,
|
||||
expression-not-assigned,
|
||||
too-many-boolean-expressions,
|
||||
consider-using-ternary,
|
||||
invalid-unary-operand-type,
|
||||
relative-import,
|
||||
deprecated-lambda
|
||||
|
||||
|
||||
# Enable the message, report, category or checker with the given id(s). You can
|
||||
# either give multiple identifier separated by comma (,) or put this option
|
||||
# multiple time (only on the command line, not in the configuration file where
|
||||
# it should appear only once). See also the "--disable" option for examples.
|
||||
enable=c-extension-no-member
|
||||
|
||||
|
||||
[REPORTS]
|
||||
|
||||
# Python expression which should return a note less than 10 (10 is the highest
|
||||
# note). You have access to the variables errors warning, statement which
|
||||
# respectively contain the number of errors / warnings messages and the total
|
||||
# number of statements analyzed. This is used by the global evaluation report
|
||||
# (RP0004).
|
||||
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
|
||||
|
||||
# Template used to display messages. This is a python new-style format string
|
||||
# used to format the message information. See doc for all details
|
||||
#msg-template=
|
||||
|
||||
# Set the output format. Available formats are text, parseable, colorized, json
|
||||
# and msvs (visual studio).You can also give a reporter class, eg
|
||||
# mypackage.mymodule.MyReporterClass.
|
||||
output-format=text
|
||||
|
||||
# Tells whether to display a full report or only the messages
|
||||
reports=no
|
||||
|
||||
# Activate the evaluation score.
|
||||
score=yes
|
||||
|
||||
|
||||
[REFACTORING]
|
||||
|
||||
# Maximum number of nested blocks for function / method body
|
||||
max-nested-blocks=5
|
||||
|
||||
# Complete name of functions that never returns. When checking for
|
||||
# inconsistent-return-statements if a never returning function is called then
|
||||
# it will be considered as an explicit return statement and no message will be
|
||||
# printed.
|
||||
never-returning-functions=optparse.Values,sys.exit
|
||||
|
||||
|
||||
[LOGGING]
|
||||
|
||||
# Logging modules to check that the string format arguments are in logging
|
||||
# function parameter format
|
||||
logging-modules=logging
|
||||
|
||||
|
||||
[SPELLING]
|
||||
|
||||
# Limits count of emitted suggestions for spelling mistakes
|
||||
max-spelling-suggestions=4
|
||||
|
||||
# Spelling dictionary name. Available dictionaries: none. To make it working
|
||||
# install python-enchant package.
|
||||
spelling-dict=
|
||||
|
||||
# List of comma separated words that should not be checked.
|
||||
spelling-ignore-words=
|
||||
|
||||
# A path to a file that contains private dictionary; one word per line.
|
||||
spelling-private-dict-file=
|
||||
|
||||
# Tells whether to store unknown words to indicated private dictionary in
|
||||
# --spelling-private-dict-file option instead of raising a message.
|
||||
spelling-store-unknown-words=no
|
||||
|
||||
|
||||
[MISCELLANEOUS]
|
||||
|
||||
# List of note tags to take in consideration, separated by a comma.
|
||||
notes=FIXME,
|
||||
XXX,
|
||||
TODO
|
||||
|
||||
|
||||
[SIMILARITIES]
|
||||
|
||||
# Ignore comments when computing similarities.
|
||||
ignore-comments=yes
|
||||
|
||||
# Ignore docstrings when computing similarities.
|
||||
ignore-docstrings=yes
|
||||
|
||||
# Ignore imports when computing similarities.
|
||||
ignore-imports=no
|
||||
|
||||
# Minimum lines number of a similarity.
|
||||
min-similarity-lines=4
|
||||
|
||||
|
||||
[TYPECHECK]
|
||||
|
||||
# List of decorators that produce context managers, such as
|
||||
# contextlib.contextmanager. Add to this list to register other decorators that
|
||||
# produce valid context managers.
|
||||
contextmanager-decorators=contextlib.contextmanager
|
||||
|
||||
# List of members which are set dynamically and missed by pylint inference
|
||||
# system, and so shouldn't trigger E1101 when accessed. Python regular
|
||||
# expressions are accepted.
|
||||
generated-members=capnp.* cereal.* pygame.* zmq.* setproctitle.* smbus2.* usb1.* serial.* cv2.*
|
||||
|
||||
# Tells whether missing members accessed in mixin class should be ignored. A
|
||||
# mixin class is detected if its name ends with "mixin" (case insensitive).
|
||||
ignore-mixin-members=yes
|
||||
|
||||
# This flag controls whether pylint should warn about no-member and similar
|
||||
# checks whenever an opaque object is returned when inferring. The inference
|
||||
# can return multiple potential results while evaluating a Python object, but
|
||||
# some branches might not be evaluated, which results in partial inference. In
|
||||
# that case, it might be useful to still emit no-member and other checks for
|
||||
# the rest of the inferred objects.
|
||||
ignore-on-opaque-inference=yes
|
||||
|
||||
# List of class names for which member attributes should not be checked (useful
|
||||
# for classes with dynamically set attributes). This supports the use of
|
||||
# qualified names.
|
||||
ignored-classes=optparse.Values,thread._local,_thread._local
|
||||
|
||||
# List of module names for which member attributes should not be checked
|
||||
# (useful for modules/projects where namespaces are manipulated during runtime
|
||||
# and thus existing member attributes cannot be deduced by static analysis. It
|
||||
# supports qualified module names, as well as Unix pattern matching.
|
||||
ignored-modules=flask setproctitle usb1 flask.ext.socketio smbus2 usb1.*
|
||||
|
||||
# Show a hint with possible names when a member name was not found. The aspect
|
||||
# of finding the hint is based on edit distance.
|
||||
missing-member-hint=yes
|
||||
|
||||
# The minimum edit distance a name should have in order to be considered a
|
||||
# similar match for a missing member name.
|
||||
missing-member-hint-distance=1
|
||||
|
||||
# The total number of similar names that should be taken in consideration when
|
||||
# showing a hint for a missing member.
|
||||
missing-member-max-choices=1
|
||||
|
||||
|
||||
[VARIABLES]
|
||||
|
||||
# List of additional names supposed to be defined in builtins. Remember that
|
||||
# you should avoid to define new builtins when possible.
|
||||
additional-builtins=
|
||||
|
||||
# Tells whether unused global variables should be treated as a violation.
|
||||
allow-global-unused-variables=yes
|
||||
|
||||
# List of strings which can identify a callback function by name. A callback
|
||||
# name must start or end with one of those strings.
|
||||
callbacks=cb_,
|
||||
_cb
|
||||
|
||||
# A regular expression matching the name of dummy variables (i.e. expectedly
|
||||
# not used).
|
||||
dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
|
||||
|
||||
# Argument names that match this expression will be ignored. Default to name
|
||||
# with leading underscore
|
||||
ignored-argument-names=_.*|^ignored_|^unused_
|
||||
|
||||
# Tells whether we should check for unused import in __init__ files.
|
||||
init-import=no
|
||||
|
||||
# List of qualified module names which can have objects that can redefine
|
||||
# builtins.
|
||||
redefining-builtins-modules=six.moves,past.builtins,future.builtins
|
||||
|
||||
|
||||
[FORMAT]
|
||||
|
||||
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
|
||||
expected-line-ending-format=
|
||||
|
||||
# Regexp for a line that is allowed to be longer than the limit.
|
||||
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
|
||||
|
||||
# Number of spaces of indent required inside a hanging or continued line.
|
||||
indent-after-paren=4
|
||||
|
||||
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
|
||||
# tab).
|
||||
indent-string=' '
|
||||
|
||||
# Maximum number of characters on a single line.
|
||||
max-line-length=100
|
||||
|
||||
# Maximum number of lines in a module
|
||||
max-module-lines=1000
|
||||
|
||||
# List of optional constructs for which whitespace checking is disabled. `dict-
|
||||
# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
|
||||
# `trailing-comma` allows a space between comma and closing bracket: (a, ).
|
||||
# `empty-line` allows space-only lines.
|
||||
no-space-check=trailing-comma,
|
||||
dict-separator
|
||||
|
||||
# Allow the body of a class to be on the same line as the declaration if body
|
||||
# contains single statement.
|
||||
single-line-class-stmt=no
|
||||
|
||||
# Allow the body of an if to be on the same line as the test if there is no
|
||||
# else.
|
||||
single-line-if-stmt=no
|
||||
|
||||
|
||||
[BASIC]
|
||||
|
||||
# Naming style matching correct argument names
|
||||
argument-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct argument names. Overrides argument-
|
||||
# naming-style
|
||||
#argument-rgx=
|
||||
|
||||
# Naming style matching correct attribute names
|
||||
attr-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct attribute names. Overrides attr-naming-
|
||||
# style
|
||||
#attr-rgx=
|
||||
|
||||
# Bad variable names which should always be refused, separated by a comma
|
||||
bad-names=foo,
|
||||
bar,
|
||||
baz,
|
||||
toto,
|
||||
tutu,
|
||||
tata
|
||||
|
||||
# Naming style matching correct class attribute names
|
||||
class-attribute-naming-style=any
|
||||
|
||||
# Regular expression matching correct class attribute names. Overrides class-
|
||||
# attribute-naming-style
|
||||
#class-attribute-rgx=
|
||||
|
||||
# Naming style matching correct class names
|
||||
class-naming-style=PascalCase
|
||||
|
||||
# Regular expression matching correct class names. Overrides class-naming-style
|
||||
#class-rgx=
|
||||
|
||||
# Naming style matching correct constant names
|
||||
const-naming-style=UPPER_CASE
|
||||
|
||||
# Regular expression matching correct constant names. Overrides const-naming-
|
||||
# style
|
||||
#const-rgx=
|
||||
|
||||
# Minimum line length for functions/classes that require docstrings, shorter
|
||||
# ones are exempt.
|
||||
docstring-min-length=-1
|
||||
|
||||
# Naming style matching correct function names
|
||||
function-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct function names. Overrides function-
|
||||
# naming-style
|
||||
#function-rgx=
|
||||
|
||||
# Good variable names which should always be accepted, separated by a comma
|
||||
good-names=i,
|
||||
j,
|
||||
k,
|
||||
ex,
|
||||
Run,
|
||||
_
|
||||
|
||||
# Include a hint for the correct naming format with invalid-name
|
||||
include-naming-hint=no
|
||||
|
||||
# Naming style matching correct inline iteration names
|
||||
inlinevar-naming-style=any
|
||||
|
||||
# Regular expression matching correct inline iteration names. Overrides
|
||||
# inlinevar-naming-style
|
||||
#inlinevar-rgx=
|
||||
|
||||
# Naming style matching correct method names
|
||||
method-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct method names. Overrides method-naming-
|
||||
# style
|
||||
#method-rgx=
|
||||
|
||||
# Naming style matching correct module names
|
||||
module-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct module names. Overrides module-naming-
|
||||
# style
|
||||
#module-rgx=
|
||||
|
||||
# Colon-delimited sets of names that determine each other's naming style when
|
||||
# the name regexes allow several styles.
|
||||
name-group=
|
||||
|
||||
# Regular expression which should only match function or class names that do
|
||||
# not require a docstring.
|
||||
no-docstring-rgx=^_
|
||||
|
||||
# List of decorators that produce properties, such as abc.abstractproperty. Add
|
||||
# to this list to register other decorators that produce valid properties.
|
||||
property-classes=abc.abstractproperty
|
||||
|
||||
# Naming style matching correct variable names
|
||||
variable-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct variable names. Overrides variable-
|
||||
# naming-style
|
||||
#variable-rgx=
|
||||
|
||||
|
||||
[DESIGN]
|
||||
|
||||
# Maximum number of arguments for function / method
|
||||
max-args=5
|
||||
|
||||
# Maximum number of attributes for a class (see R0902).
|
||||
max-attributes=7
|
||||
|
||||
# Maximum number of boolean expressions in a if statement
|
||||
max-bool-expr=5
|
||||
|
||||
# Maximum number of branch for function / method body
|
||||
max-branches=12
|
||||
|
||||
# Maximum number of locals for function / method body
|
||||
max-locals=15
|
||||
|
||||
# Maximum number of parents for a class (see R0901).
|
||||
max-parents=7
|
||||
|
||||
# Maximum number of public methods for a class (see R0904).
|
||||
max-public-methods=20
|
||||
|
||||
# Maximum number of return / yield for function / method body
|
||||
max-returns=6
|
||||
|
||||
# Maximum number of statements in function / method body
|
||||
max-statements=50
|
||||
|
||||
# Minimum number of public methods for a class (see R0903).
|
||||
min-public-methods=2
|
||||
|
||||
|
||||
[CLASSES]
|
||||
|
||||
# List of method names used to declare (i.e. assign) instance attributes.
|
||||
defining-attr-methods=__init__,
|
||||
__new__,
|
||||
setUp
|
||||
|
||||
# List of member names, which should be excluded from the protected access
|
||||
# warning.
|
||||
exclude-protected=_asdict,
|
||||
_fields,
|
||||
_replace,
|
||||
_source,
|
||||
_make
|
||||
|
||||
# List of valid names for the first argument in a class method.
|
||||
valid-classmethod-first-arg=cls
|
||||
|
||||
# List of valid names for the first argument in a metaclass class method.
|
||||
valid-metaclass-classmethod-first-arg=mcs
|
||||
|
||||
|
||||
[IMPORTS]
|
||||
|
||||
# Allow wildcard imports from modules that define __all__.
|
||||
allow-wildcard-with-all=no
|
||||
|
||||
# Analyse import fallback blocks. This can be used to support both Python 2 and
|
||||
# 3 compatible code, which means that the block might have code that exists
|
||||
# only in one or another interpreter, leading to false positives when analysed.
|
||||
analyse-fallback-blocks=no
|
||||
|
||||
# Deprecated modules which should not be used, separated by a comma
|
||||
deprecated-modules=regsub,
|
||||
TERMIOS,
|
||||
Bastion,
|
||||
rexec
|
||||
|
||||
# Create a graph of external dependencies in the given file (report RP0402 must
|
||||
# not be disabled)
|
||||
ext-import-graph=
|
||||
|
||||
# Create a graph of every (i.e. internal and external) dependencies in the
|
||||
# given file (report RP0402 must not be disabled)
|
||||
import-graph=
|
||||
|
||||
# Create a graph of internal dependencies in the given file (report RP0402 must
|
||||
# not be disabled)
|
||||
int-import-graph=
|
||||
|
||||
# Force import order to recognize a module as part of the standard
|
||||
# compatibility libraries.
|
||||
known-standard-library=
|
||||
|
||||
# Force import order to recognize a module as part of a third party library.
|
||||
known-third-party=enchant
|
||||
|
||||
|
||||
[EXCEPTIONS]
|
||||
|
||||
# Exceptions that will emit a warning when being caught. Defaults to
|
||||
# "Exception"
|
||||
overgeneral-exceptions=Exception
|
||||
@@ -0,0 +1,19 @@
|
||||
FROM ubuntu:16.04
|
||||
|
||||
RUN apt-get update && apt-get install -y make python python-pip locales curl git zlib1g-dev libffi-dev bzip2 libssl-dev
|
||||
|
||||
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen
|
||||
ENV LANG en_US.UTF-8
|
||||
ENV LANGUAGE en_US:en
|
||||
ENV LC_ALL en_US.UTF-8
|
||||
|
||||
RUN curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
|
||||
|
||||
ENV PATH="/root/.pyenv/bin:/root/.pyenv/shims:${PATH}"
|
||||
RUN pyenv install 3.7.3
|
||||
RUN pyenv global 3.7.3
|
||||
RUN pyenv rehash
|
||||
|
||||
COPY requirements.txt /tmp/
|
||||
RUN pip install -r /tmp/requirements.txt
|
||||
COPY . /panda
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
RESULT=$(python3 -m flake8 --select=F $(find ../../ -type f | grep -v "/boardesp/" | grep -v "/cppcheck/" | grep "\.py$"))
|
||||
if [[ $RESULT ]]; then
|
||||
echo "Pyflakes found errors in the code. Please fix and try again"
|
||||
echo "$RESULT"
|
||||
exit 1
|
||||
fi
|
||||
Executable
+11
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
python3 -m pylint --disable=R,C,W $(find ../../ -type f | grep -v "/boardesp/" | grep -v "/cppcheck/" | grep "\.py$")
|
||||
|
||||
exit_status=$?
|
||||
(( res = exit_status & 3 ))
|
||||
|
||||
if [[ $res != 0 ]]; then
|
||||
echo "Pylint found errors in the code. Please fix and try again"
|
||||
exit 1
|
||||
fi
|
||||
@@ -30,7 +30,7 @@ if __name__ == "__main__":
|
||||
baudrate = 460800
|
||||
|
||||
print("upping baud rate")
|
||||
msg = add_nmea_checksum("$PUBX,41,1,0007,0003,%d,0" % baudrate)+"\r\n"
|
||||
msg = str.encode(add_nmea_checksum("$PUBX,41,1,0007,0003,%d,0" % baudrate)+"\r\n")
|
||||
print(msg)
|
||||
ser.write(msg)
|
||||
time.sleep(0.1) # needs a wait for it to actually send
|
||||
|
||||
@@ -55,7 +55,7 @@ def run_test_w_pandas(pandas, sleep_duration):
|
||||
|
||||
# send the characters
|
||||
st = get_test_string()
|
||||
st = b"\xaa"+chr(len(st)+3).encode()+st
|
||||
st = bytes([0xaa, len(st) + 3]) + st
|
||||
h[ho[0]].kline_send(st, bus=bus, checksum=False)
|
||||
|
||||
# check for receive
|
||||
|
||||
+16
-3
@@ -1,6 +1,19 @@
|
||||
FROM ubuntu:16.04
|
||||
|
||||
RUN apt-get update && apt-get install -y make python python-pip git
|
||||
COPY tests/safety/requirements.txt /panda/tests/safety/requirements.txt
|
||||
RUN pip install -r /panda/tests/safety/requirements.txt
|
||||
RUN apt-get update && apt-get install -y clang make python python-pip git curl locales zlib1g-dev libffi-dev bzip2 libssl-dev libbz2-dev libusb-1.0-0
|
||||
|
||||
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen
|
||||
ENV LANG en_US.UTF-8
|
||||
ENV LANGUAGE en_US:en
|
||||
ENV LC_ALL en_US.UTF-8
|
||||
|
||||
RUN curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
|
||||
|
||||
ENV PATH="/root/.pyenv/bin:/root/.pyenv/shims:${PATH}"
|
||||
RUN pyenv install 3.7.3
|
||||
RUN pyenv global 3.7.3
|
||||
RUN pyenv rehash
|
||||
|
||||
COPY requirements.txt /tmp/
|
||||
RUN pip install -r /tmp/requirements.txt
|
||||
COPY . /panda
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
2.6 X (Cppcheck)
|
||||
2.7
|
||||
3.1 X (Addon)
|
||||
3.2
|
||||
3.2 X (Addon)
|
||||
4.1 X (Addon)
|
||||
4.2
|
||||
4.2 X (Addon)
|
||||
5.1 X (Addon)
|
||||
5.2 X (Addon)
|
||||
5.3 X (Addon)
|
||||
@@ -123,7 +123,7 @@
|
||||
20.12
|
||||
20.13 X (Addon)
|
||||
20.14 X (Addon)
|
||||
21.1
|
||||
21.1 X (Addon)
|
||||
21.2
|
||||
21.3 X (Addon)
|
||||
21.4 X (Addon)
|
||||
@@ -134,7 +134,7 @@
|
||||
21.9 X (Addon)
|
||||
21.10 X (Addon)
|
||||
21.11 X (Addon)
|
||||
21.12
|
||||
21.12 X (Addon)
|
||||
22.1 X (Cppcheck)
|
||||
22.2 X (Cppcheck)
|
||||
22.3
|
||||
|
||||
@@ -4,3 +4,5 @@ misra.19.2
|
||||
misra.11.4
|
||||
# Advisory: casting from void pointer to type pointer is ok. Done by STM libraries as well
|
||||
misra.11.5
|
||||
# Required: it's ok re-defining potentially reserved Macro names. Not likely to cause confusion
|
||||
misra.21.1
|
||||
|
||||
@@ -4,7 +4,7 @@ mkdir /tmp/misra || true
|
||||
git clone https://github.com/danmar/cppcheck.git || true
|
||||
cd cppcheck
|
||||
git fetch
|
||||
git checkout ff7dba91e177dfb712477faddb9e91bece7e743c
|
||||
git checkout bdd41151ed550e3d240a6dd6847859216b7ad736
|
||||
make -j4
|
||||
cd ../../../
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
import time
|
||||
import struct
|
||||
import argparse
|
||||
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env python
|
||||
import os
|
||||
import sys
|
||||
import datetime
|
||||
|
||||
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), ".."))
|
||||
from panda import Panda
|
||||
|
||||
if __name__ == "__main__":
|
||||
p = Panda()
|
||||
|
||||
p.set_datetime(datetime.datetime.now())
|
||||
print(p.get_datetime())
|
||||
@@ -14,6 +14,7 @@ RUN pyenv install 3.7.3
|
||||
RUN pyenv global 3.7.3
|
||||
RUN pyenv rehash
|
||||
|
||||
COPY tests/safety/requirements.txt requirements.txt
|
||||
RUN pip install -r requirements.txt
|
||||
COPY requirements.txt /tmp/
|
||||
RUN pip install -r /tmp/requirements.txt
|
||||
|
||||
COPY . /panda
|
||||
|
||||
@@ -30,6 +30,8 @@ typedef struct
|
||||
uint32_t CNT;
|
||||
} TIM_TypeDef;
|
||||
|
||||
bool board_has_relay(void);
|
||||
|
||||
void set_controls_allowed(bool c);
|
||||
bool get_controls_allowed(void);
|
||||
void set_long_controls_allowed(bool c);
|
||||
@@ -94,6 +96,11 @@ void set_subaru_desired_torque_last(int t);
|
||||
void set_subaru_rt_torque_last(int t);
|
||||
void set_subaru_torque_driver(int min, int max);
|
||||
|
||||
void init_tests_volkswagen(void);
|
||||
void set_volkswagen_desired_torque_last(int t);
|
||||
void set_volkswagen_rt_torque_last(int t);
|
||||
void set_volkswagen_torque_driver(int min, int max);
|
||||
int get_volkswagen_gas_prev(void);
|
||||
|
||||
""")
|
||||
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
cffi==1.11.4
|
||||
numpy==1.14.5
|
||||
libusb1==1.6.6
|
||||
requests
|
||||
+44
-10
@@ -29,10 +29,27 @@ struct sample_t gm_torque_driver;
|
||||
struct sample_t hyundai_torque_driver;
|
||||
struct sample_t chrysler_torque_meas;
|
||||
struct sample_t subaru_torque_driver;
|
||||
struct sample_t volkswagen_torque_driver;
|
||||
|
||||
TIM_TypeDef timer;
|
||||
TIM_TypeDef *TIM2 = &timer;
|
||||
|
||||
// from board_declarations.h
|
||||
#define HW_TYPE_UNKNOWN 0U
|
||||
#define HW_TYPE_WHITE_PANDA 1U
|
||||
#define HW_TYPE_GREY_PANDA 2U
|
||||
#define HW_TYPE_BLACK_PANDA 3U
|
||||
#define HW_TYPE_PEDAL 4U
|
||||
#define HW_TYPE_UNO 5U
|
||||
|
||||
// from main_declarations.h
|
||||
uint8_t hw_type = HW_TYPE_UNKNOWN;
|
||||
|
||||
// from board.h
|
||||
bool board_has_relay(void) {
|
||||
return hw_type == HW_TYPE_BLACK_PANDA || hw_type == HW_TYPE_UNO;
|
||||
}
|
||||
|
||||
// from config.h
|
||||
#define MIN(a,b) \
|
||||
({ __typeof__ (a) _a = (a); \
|
||||
@@ -52,16 +69,6 @@ TIM_TypeDef *TIM2 = &timer;
|
||||
#define GET_BYTES_04(msg) ((msg)->RDLR)
|
||||
#define GET_BYTES_48(msg) ((msg)->RDHR)
|
||||
|
||||
// from board_declarations.h
|
||||
#define HW_TYPE_UNKNOWN 0U
|
||||
#define HW_TYPE_WHITE_PANDA 1U
|
||||
#define HW_TYPE_GREY_PANDA 2U
|
||||
#define HW_TYPE_BLACK_PANDA 3U
|
||||
#define HW_TYPE_PEDAL 4U
|
||||
|
||||
// from main_declarations.h
|
||||
uint8_t hw_type = 0U;
|
||||
|
||||
#define UNUSED(x) (void)(x)
|
||||
|
||||
#define PANDA
|
||||
@@ -155,6 +162,11 @@ void set_subaru_torque_driver(int min, int max){
|
||||
subaru_torque_driver.max = max;
|
||||
}
|
||||
|
||||
void set_volkswagen_torque_driver(int min, int max){
|
||||
volkswagen_torque_driver.min = min;
|
||||
volkswagen_torque_driver.max = max;
|
||||
}
|
||||
|
||||
int get_chrysler_torque_meas_min(void){
|
||||
return chrysler_torque_meas.min;
|
||||
}
|
||||
@@ -199,6 +211,10 @@ void set_subaru_rt_torque_last(int t){
|
||||
subaru_rt_torque_last = t;
|
||||
}
|
||||
|
||||
void set_volkswagen_rt_torque_last(int t){
|
||||
volkswagen_rt_torque_last = t;
|
||||
}
|
||||
|
||||
void set_toyota_desired_torque_last(int t){
|
||||
toyota_desired_torque_last = t;
|
||||
}
|
||||
@@ -223,6 +239,14 @@ void set_subaru_desired_torque_last(int t){
|
||||
subaru_desired_torque_last = t;
|
||||
}
|
||||
|
||||
void set_volkswagen_desired_torque_last(int t){
|
||||
volkswagen_desired_torque_last = t;
|
||||
}
|
||||
|
||||
int get_volkswagen_gas_prev(void){
|
||||
return volkswagen_gas_prev;
|
||||
}
|
||||
|
||||
bool get_honda_moving(void){
|
||||
return honda_moving;
|
||||
}
|
||||
@@ -316,6 +340,16 @@ void init_tests_subaru(void){
|
||||
set_timer(0);
|
||||
}
|
||||
|
||||
void init_tests_volkswagen(void){
|
||||
init_tests();
|
||||
volkswagen_torque_driver.min = 0;
|
||||
volkswagen_torque_driver.max = 0;
|
||||
volkswagen_desired_torque_last = 0;
|
||||
volkswagen_rt_torque_last = 0;
|
||||
volkswagen_ts_last = 0;
|
||||
set_timer(0);
|
||||
}
|
||||
|
||||
void init_tests_honda(void){
|
||||
init_tests();
|
||||
honda_moving = false;
|
||||
|
||||
@@ -6,11 +6,12 @@
|
||||
# HW_TYPE_GREY_PANDA 2U
|
||||
# HW_TYPE_BLACK_PANDA 3U
|
||||
# HW_TYPE_PEDAL 4U
|
||||
# HW_TYPE_UNO 5U
|
||||
|
||||
# Make sure test fails if one HW_TYPE fails
|
||||
set -e
|
||||
|
||||
for hw_type in 0 1 2 3 4
|
||||
for hw_type in 0 1 2 3 4 5
|
||||
do
|
||||
echo "Testing HW_TYPE: $hw_type"
|
||||
HW_TYPE=$hw_type python -m unittest discover .
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
import unittest
|
||||
import numpy as np
|
||||
import libpandasafety_py
|
||||
import libpandasafety_py # pylint: disable=import-error
|
||||
from panda import Panda
|
||||
|
||||
MAX_RATE_UP = 2
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
import csv
|
||||
import glob
|
||||
import unittest
|
||||
import numpy as np
|
||||
import libpandasafety_py
|
||||
import libpandasafety_py # pylint: disable=import-error
|
||||
from panda import Panda
|
||||
|
||||
MAX_RATE_UP = 3
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
import unittest
|
||||
import numpy as np
|
||||
import libpandasafety_py
|
||||
import libpandasafety_py # pylint: disable=import-error
|
||||
from panda import Panda
|
||||
|
||||
MAX_RATE_UP = 7
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
import unittest
|
||||
import numpy as np
|
||||
import libpandasafety_py
|
||||
import libpandasafety_py # pylint: disable=import-error
|
||||
from panda import Panda
|
||||
|
||||
MAX_BRAKE = 255
|
||||
@@ -34,9 +34,9 @@ class TestHondaSafety(unittest.TestCase):
|
||||
to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *')
|
||||
to_send[0].RIR = msg << 21
|
||||
to_send[0].RDLR = buttons << 5
|
||||
is_panda_black = self.safety.get_hw_type() == 3 # black_panda
|
||||
has_relay = self.safety.board_has_relay()
|
||||
honda_bosch_hardware = self.safety.get_honda_bosch_hardware()
|
||||
bus = 1 if is_panda_black and honda_bosch_hardware else 0
|
||||
bus = 1 if has_relay and honda_bosch_hardware else 0
|
||||
to_send[0].RDTR = bus << 4
|
||||
|
||||
return to_send
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
import unittest
|
||||
import numpy as np
|
||||
import libpandasafety_py
|
||||
import libpandasafety_py # pylint: disable=import-error
|
||||
from panda import Panda
|
||||
|
||||
MAX_BRAKE = 255
|
||||
@@ -22,12 +21,13 @@ class TestHondaSafety(unittest.TestCase):
|
||||
return to_send
|
||||
|
||||
def test_fwd_hook(self):
|
||||
buss = list(range(0x0, 0x3))
|
||||
msgs = list(range(0x1, 0x800))
|
||||
is_panda_black = self.safety.get_hw_type() == 3 # black panda
|
||||
bus_rdr_cam = 2 if is_panda_black else 1
|
||||
bus_rdr_car = 0 if is_panda_black else 2
|
||||
bus_pt = 1 if is_panda_black else 0
|
||||
buss = range(0x0, 0x3)
|
||||
msgs = range(0x1, 0x800)
|
||||
#has_relay = self.safety.get_hw_type() == 3 # black panda
|
||||
has_relay = self.safety.board_has_relay()
|
||||
bus_rdr_cam = 2 if has_relay else 1
|
||||
bus_rdr_car = 0 if has_relay else 2
|
||||
bus_pt = 1 if has_relay else 0
|
||||
|
||||
blocked_msgs = [0xE4, 0x33D]
|
||||
for b in buss:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
import unittest
|
||||
import numpy as np
|
||||
import libpandasafety_py
|
||||
import libpandasafety_py # pylint: disable=import-error
|
||||
from panda import Panda
|
||||
|
||||
MAX_RATE_UP = 3
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
import unittest
|
||||
import numpy as np
|
||||
import libpandasafety_py
|
||||
import libpandasafety_py # pylint: disable=import-error
|
||||
from panda import Panda
|
||||
|
||||
MAX_RATE_UP = 50
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
import unittest
|
||||
import numpy as np
|
||||
import libpandasafety_py
|
||||
import libpandasafety_py # pylint: disable=import-error
|
||||
from panda import Panda
|
||||
|
||||
MAX_RATE_UP = 10
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
import unittest
|
||||
import numpy as np
|
||||
import libpandasafety_py
|
||||
import libpandasafety_py # pylint: disable=import-error
|
||||
from panda import Panda
|
||||
|
||||
IPAS_OVERRIDE_THRESHOLD = 200
|
||||
@@ -233,8 +233,8 @@ class TestToyotaSafety(unittest.TestCase):
|
||||
self.safety.safety_tx_hook(self._ipas_control_msg(a, 1))
|
||||
self.safety.set_controls_allowed(1)
|
||||
self.safety.safety_rx_hook(self._speed_msg(s))
|
||||
max_delta_up = int(np.interp(s, ANGLE_DELTA_BP, ANGLE_DELTA_V) * 2 / 3. + 1.)
|
||||
max_delta_down = int(np.interp(s, ANGLE_DELTA_BP, ANGLE_DELTA_VU) * 2 / 3. + 1.)
|
||||
#max_delta_up = int(np.interp(s, ANGLE_DELTA_BP, ANGLE_DELTA_V) * 2 / 3. + 1.)
|
||||
#max_delta_down = int(np.interp(s, ANGLE_DELTA_BP, ANGLE_DELTA_VU) * 2 / 3. + 1.)
|
||||
self.safety.safety_rx_hook(self._angle_meas_msg(a))
|
||||
self.assertTrue(self.safety.get_controls_allowed())
|
||||
self.safety.safety_rx_hook(self._angle_meas_msg(a + 150))
|
||||
|
||||
@@ -0,0 +1,247 @@
|
||||
#!/usr/bin/env python3
|
||||
import unittest
|
||||
import numpy as np
|
||||
import libpandasafety_py # pylint: disable=import-error
|
||||
from panda import Panda
|
||||
|
||||
MAX_RATE_UP = 4
|
||||
MAX_RATE_DOWN = 10
|
||||
MAX_STEER = 250
|
||||
|
||||
MAX_RT_DELTA = 75
|
||||
RT_INTERVAL = 250000
|
||||
|
||||
DRIVER_TORQUE_ALLOWANCE = 80
|
||||
DRIVER_TORQUE_FACTOR = 3
|
||||
|
||||
def sign(a):
|
||||
if a > 0:
|
||||
return 1
|
||||
else:
|
||||
return -1
|
||||
|
||||
class TestVolkswagenSafety(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUp(cls):
|
||||
cls.safety = libpandasafety_py.libpandasafety
|
||||
cls.safety.safety_set_mode(Panda.SAFETY_VOLKSWAGEN, 0)
|
||||
cls.safety.init_tests_volkswagen()
|
||||
|
||||
def _send_msg(self, bus, addr, length):
|
||||
to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *')
|
||||
to_send[0].RIR = addr << 21
|
||||
to_send[0].RDTR = length
|
||||
to_send[0].RDTR = bus << 4
|
||||
return to_send
|
||||
|
||||
def _set_prev_torque(self, t):
|
||||
self.safety.set_volkswagen_desired_torque_last(t)
|
||||
self.safety.set_volkswagen_rt_torque_last(t)
|
||||
|
||||
def _torque_driver_msg(self, torque):
|
||||
to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *')
|
||||
to_send[0].RIR = 0x9F << 21
|
||||
|
||||
t = abs(torque)
|
||||
to_send[0].RDHR = ((t & 0x1FFF) << 8)
|
||||
if torque < 0:
|
||||
to_send[0].RDHR |= 0x1 << 23
|
||||
return to_send
|
||||
|
||||
def _torque_msg(self, torque):
|
||||
to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *')
|
||||
to_send[0].RIR = 0x126 << 21
|
||||
|
||||
t = abs(torque)
|
||||
to_send[0].RDLR = (t & 0xFFF) << 16
|
||||
if torque < 0:
|
||||
to_send[0].RDLR |= 0x1 << 31
|
||||
return to_send
|
||||
|
||||
def _gas_msg(self, gas):
|
||||
to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *')
|
||||
to_send[0].RIR = 0x121 << 21
|
||||
to_send[0].RDLR = (gas & 0xFF) << 12
|
||||
|
||||
return to_send
|
||||
|
||||
def _button_msg(self, bit):
|
||||
to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *')
|
||||
to_send[0].RIR = 0x12B << 21
|
||||
to_send[0].RDLR = 1 << bit
|
||||
to_send[0].RDTR = 2 << 4
|
||||
|
||||
return to_send
|
||||
|
||||
def test_prev_gas(self):
|
||||
for g in range(0, 256):
|
||||
self.safety.safety_rx_hook(self._gas_msg(g))
|
||||
self.assertEqual(g, self.safety.get_volkswagen_gas_prev())
|
||||
|
||||
def test_default_controls_not_allowed(self):
|
||||
self.assertFalse(self.safety.get_controls_allowed())
|
||||
|
||||
def test_enable_control_allowed_from_cruise(self):
|
||||
to_push = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *')
|
||||
to_push[0].RIR = 0x122 << 21
|
||||
to_push[0].RDHR = 0x30000000
|
||||
|
||||
self.safety.safety_rx_hook(to_push)
|
||||
self.assertTrue(self.safety.get_controls_allowed())
|
||||
|
||||
def test_disable_control_allowed_from_cruise(self):
|
||||
to_push = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *')
|
||||
to_push[0].RIR = 0x122 << 21
|
||||
to_push[0].RDHR = 0
|
||||
|
||||
self.safety.set_controls_allowed(1)
|
||||
self.safety.safety_rx_hook(to_push)
|
||||
self.assertFalse(self.safety.get_controls_allowed())
|
||||
|
||||
def test_disengage_on_gas(self):
|
||||
for long_controls_allowed in [0, 1]:
|
||||
self.safety.set_long_controls_allowed(long_controls_allowed)
|
||||
self.safety.safety_rx_hook(self._gas_msg(0))
|
||||
self.safety.set_controls_allowed(True)
|
||||
self.safety.safety_rx_hook(self._gas_msg(1))
|
||||
if long_controls_allowed:
|
||||
self.assertFalse(self.safety.get_controls_allowed())
|
||||
else:
|
||||
self.assertTrue(self.safety.get_controls_allowed())
|
||||
self.safety.set_long_controls_allowed(True)
|
||||
|
||||
def test_allow_engage_with_gas_pressed(self):
|
||||
self.safety.safety_rx_hook(self._gas_msg(1))
|
||||
self.safety.set_controls_allowed(True)
|
||||
self.safety.safety_rx_hook(self._gas_msg(1))
|
||||
self.assertTrue(self.safety.get_controls_allowed())
|
||||
self.safety.safety_rx_hook(self._gas_msg(1))
|
||||
self.assertTrue(self.safety.get_controls_allowed())
|
||||
|
||||
|
||||
def test_steer_safety_check(self):
|
||||
for enabled in [0, 1]:
|
||||
for t in range(-500, 500):
|
||||
self.safety.set_controls_allowed(enabled)
|
||||
self._set_prev_torque(t)
|
||||
if abs(t) > MAX_STEER or (not enabled and abs(t) > 0):
|
||||
self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(t)))
|
||||
else:
|
||||
self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(t)))
|
||||
|
||||
def test_manually_enable_controls_allowed(self):
|
||||
self.safety.set_controls_allowed(1)
|
||||
self.assertTrue(self.safety.get_controls_allowed())
|
||||
self.safety.set_controls_allowed(0)
|
||||
self.assertFalse(self.safety.get_controls_allowed())
|
||||
|
||||
def test_spam_cancel_safety_check(self):
|
||||
BIT_CANCEL = 13
|
||||
BIT_RESUME = 19
|
||||
BIT_SET = 16
|
||||
self.safety.set_controls_allowed(0)
|
||||
self.assertTrue(self.safety.safety_tx_hook(self._button_msg(BIT_CANCEL)))
|
||||
self.assertFalse(self.safety.safety_tx_hook(self._button_msg(BIT_RESUME)))
|
||||
self.assertFalse(self.safety.safety_tx_hook(self._button_msg(BIT_SET)))
|
||||
# do not block resume if we are engaged already
|
||||
self.safety.set_controls_allowed(1)
|
||||
self.assertTrue(self.safety.safety_tx_hook(self._button_msg(BIT_RESUME)))
|
||||
|
||||
def test_non_realtime_limit_up(self):
|
||||
self.safety.set_volkswagen_torque_driver(0, 0)
|
||||
self.safety.set_controls_allowed(True)
|
||||
|
||||
self._set_prev_torque(0)
|
||||
self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(MAX_RATE_UP)))
|
||||
self._set_prev_torque(0)
|
||||
self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(-MAX_RATE_UP)))
|
||||
|
||||
self._set_prev_torque(0)
|
||||
self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(MAX_RATE_UP + 1)))
|
||||
self.safety.set_controls_allowed(True)
|
||||
self._set_prev_torque(0)
|
||||
self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(-MAX_RATE_UP - 1)))
|
||||
|
||||
def test_non_realtime_limit_down(self):
|
||||
self.safety.set_volkswagen_torque_driver(0, 0)
|
||||
self.safety.set_controls_allowed(True)
|
||||
|
||||
def test_against_torque_driver(self):
|
||||
self.safety.set_controls_allowed(True)
|
||||
|
||||
for sign in [-1, 1]:
|
||||
for t in np.arange(0, DRIVER_TORQUE_ALLOWANCE + 1, 1):
|
||||
t *= -sign
|
||||
self.safety.set_volkswagen_torque_driver(t, t)
|
||||
self._set_prev_torque(MAX_STEER * sign)
|
||||
self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(MAX_STEER * sign)))
|
||||
|
||||
self.safety.set_volkswagen_torque_driver(DRIVER_TORQUE_ALLOWANCE + 1, DRIVER_TORQUE_ALLOWANCE + 1)
|
||||
self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(-MAX_STEER)))
|
||||
|
||||
# spot check some individual cases
|
||||
for sign in [-1, 1]:
|
||||
driver_torque = (DRIVER_TORQUE_ALLOWANCE + 10) * sign
|
||||
torque_desired = (MAX_STEER - 10 * DRIVER_TORQUE_FACTOR) * sign
|
||||
delta = 1 * sign
|
||||
self._set_prev_torque(torque_desired)
|
||||
self.safety.set_volkswagen_torque_driver(-driver_torque, -driver_torque)
|
||||
self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(torque_desired)))
|
||||
self._set_prev_torque(torque_desired + delta)
|
||||
self.safety.set_volkswagen_torque_driver(-driver_torque, -driver_torque)
|
||||
self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(torque_desired + delta)))
|
||||
|
||||
self._set_prev_torque(MAX_STEER * sign)
|
||||
self.safety.set_volkswagen_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign)
|
||||
self.assertTrue(self.safety.safety_tx_hook(self._torque_msg((MAX_STEER - MAX_RATE_DOWN) * sign)))
|
||||
self._set_prev_torque(MAX_STEER * sign)
|
||||
self.safety.set_volkswagen_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign)
|
||||
self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(0)))
|
||||
self._set_prev_torque(MAX_STEER * sign)
|
||||
self.safety.set_volkswagen_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign)
|
||||
self.assertFalse(self.safety.safety_tx_hook(self._torque_msg((MAX_STEER - MAX_RATE_DOWN + 1) * sign)))
|
||||
|
||||
|
||||
def test_realtime_limits(self):
|
||||
self.safety.set_controls_allowed(True)
|
||||
|
||||
for sign in [-1, 1]:
|
||||
self.safety.init_tests_volkswagen()
|
||||
self._set_prev_torque(0)
|
||||
self.safety.set_volkswagen_torque_driver(0, 0)
|
||||
for t in np.arange(0, MAX_RT_DELTA, 1):
|
||||
t *= sign
|
||||
self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(t)))
|
||||
self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA + 1))))
|
||||
|
||||
self._set_prev_torque(0)
|
||||
for t in np.arange(0, MAX_RT_DELTA, 1):
|
||||
t *= sign
|
||||
self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(t)))
|
||||
|
||||
# Increase timer to update rt_torque_last
|
||||
self.safety.set_timer(RT_INTERVAL + 1)
|
||||
self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA - 1))))
|
||||
self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA + 1))))
|
||||
|
||||
|
||||
def test_fwd_hook(self):
|
||||
buss = list(range(0x0, 0x2))
|
||||
msgs = list(range(0x1, 0x800))
|
||||
blocked_msgs_0to2 = []
|
||||
blocked_msgs_2to0 = [0x122, 0x397]
|
||||
for b in buss:
|
||||
for m in msgs:
|
||||
if b == 0:
|
||||
fwd_bus = -1 if m in blocked_msgs_0to2 else 2
|
||||
elif b == 1:
|
||||
fwd_bus = -1
|
||||
elif b == 2:
|
||||
fwd_bus = -1 if m in blocked_msgs_2to0 else 0
|
||||
|
||||
# assume len 8
|
||||
self.assertEqual(fwd_bus, self.safety.safety_fwd_hook(b, self._send_msg(b, m, 8)))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -14,8 +14,10 @@ RUN pyenv install 3.7.3
|
||||
RUN pyenv global 3.7.3
|
||||
RUN pyenv rehash
|
||||
|
||||
COPY tests/safety_replay/requirements.txt requirements.txt
|
||||
RUN pip install -r requirements.txt
|
||||
COPY requirements.txt /tmp/
|
||||
RUN pip install -r /tmp/requirements.txt
|
||||
COPY tests/safety_replay/requirements_extra.txt requirements_extra.txt
|
||||
RUN pip install -r requirements_extra.txt
|
||||
COPY tests/safety_replay/install_capnp.sh install_capnp.sh
|
||||
RUN ./install_capnp.sh
|
||||
|
||||
|
||||
@@ -2,12 +2,9 @@
|
||||
|
||||
import os
|
||||
import sys
|
||||
from panda import Panda
|
||||
import panda.tests.safety.libpandasafety_py as libpandasafety_py
|
||||
from panda.tests.safety_replay.helpers import is_steering_msg, get_steer_torque, \
|
||||
set_desired_torque_last, package_can_msg, \
|
||||
init_segment
|
||||
from tools.lib.logreader import LogReader
|
||||
from panda.tests.safety_replay.helpers import package_can_msg, init_segment
|
||||
from tools.lib.logreader import LogReader # pylint: disable=import-error
|
||||
|
||||
# replay a drive to check for safety violations
|
||||
def replay_drive(lr, safety_mode, param):
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
aenum
|
||||
cffi==1.11.4
|
||||
libusb1==1.6.6
|
||||
numpy==1.14.5
|
||||
requests
|
||||
subprocess32
|
||||
libarchive
|
||||
pycapnp
|
||||
@@ -0,0 +1,4 @@
|
||||
aenum
|
||||
subprocess32
|
||||
libarchive
|
||||
pycapnp
|
||||
@@ -5,7 +5,7 @@ import requests
|
||||
|
||||
from panda import Panda
|
||||
from replay_drive import replay_drive
|
||||
from tools.lib.logreader import LogReader
|
||||
from tools.lib.logreader import LogReader # pylint: disable=import-error
|
||||
|
||||
BASE_URL = "https://commadataci.blob.core.windows.net/openpilotci/"
|
||||
|
||||
|
||||
+1
-2
@@ -2,7 +2,6 @@
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import random
|
||||
|
||||
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), ".."))
|
||||
@@ -21,4 +20,4 @@ if __name__ == "__main__":
|
||||
st = get_test_string()[0:8]
|
||||
bus = random.randint(0, 2)
|
||||
p.can_send(at, st, bus)
|
||||
#print("Sent message on bus: ", bus)
|
||||
#print("Sent message on bus: ", bus)
|
||||
|
||||
@@ -25,7 +25,7 @@ if __name__ == "__main__":
|
||||
# p_in.can_recv()
|
||||
#sys.exit(0)
|
||||
|
||||
p_out.set_controls_allowed(True)
|
||||
p_out.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
|
||||
|
||||
set_out, set_in = set(), set()
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ def run_test_w_pandas(pandas, sleep_duration):
|
||||
print("H", h)
|
||||
|
||||
for hh in h:
|
||||
hh.set_controls_allowed(True)
|
||||
hh.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
|
||||
|
||||
# test both directions
|
||||
for ho in permutations(list(range(len(h))), r=2):
|
||||
@@ -55,7 +55,7 @@ def run_test_w_pandas(pandas, sleep_duration):
|
||||
|
||||
# send the characters
|
||||
st = get_test_string()
|
||||
st = b"\xaa"+chr(len(st)+3).encode()+st
|
||||
st = bytes([0xaa, len(st) + 3]) + st
|
||||
h[ho[0]].kline_send(st, bus=bus, checksum=False)
|
||||
|
||||
# check for receive
|
||||
@@ -70,8 +70,8 @@ def run_test_w_pandas(pandas, sleep_duration):
|
||||
time.sleep(sleep_duration)
|
||||
|
||||
# **** test can line loopback ****
|
||||
# for bus, gmlan in [(0, None), (1, False), (2, False), (1, True), (2, True)]:
|
||||
for bus, gmlan in [(0, None), (1, None)]:
|
||||
# for bus, gmlan in [(0, None), (1, False), (2, False), (1, True), (2, True)]:
|
||||
for bus, gmlan in [(0, None), (1, None)]:
|
||||
print("\ntest can", bus)
|
||||
# flush
|
||||
cans_echo = panda0.can_recv()
|
||||
|
||||
Reference in New Issue
Block a user