mirror of https://github.com/commaai/panda.git
Merge branch 'master' into tesla
This commit is contained in:
commit
527fb0ceb3
|
@ -37,7 +37,7 @@ RUN pip3 install --break-system-packages --no-cache-dir $PYTHONPATH/panda/[dev]
|
||||||
|
|
||||||
# TODO: this should be a "pip install" or not even in this repo at all
|
# TODO: this should be a "pip install" or not even in this repo at all
|
||||||
RUN git config --global --add safe.directory $PYTHONPATH/panda
|
RUN git config --global --add safe.directory $PYTHONPATH/panda
|
||||||
ENV OPENDBC_REF="5ed7a834a4e0e24c3968dd1e98ceb4b9d5f9791a"
|
ENV OPENDBC_REF="e1ce3619a5db661ef2b406ccf258a253baf6eebc"
|
||||||
RUN cd /tmp/ && \
|
RUN cd /tmp/ && \
|
||||||
git clone --depth 1 https://github.com/commaai/opendbc opendbc_repo && \
|
git clone --depth 1 https://github.com/commaai/opendbc opendbc_repo && \
|
||||||
cd opendbc_repo && git fetch origin $OPENDBC_REF && git checkout FETCH_HEAD && rm -rf .git/ && \
|
cd opendbc_repo && git fetch origin $OPENDBC_REF && git checkout FETCH_HEAD && rm -rf .git/ && \
|
||||||
|
|
|
@ -1,13 +1,29 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
import re
|
||||||
from panda import PandaJungle
|
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__":
|
if __name__ == "__main__":
|
||||||
jungle = PandaJungle()
|
jungle = PandaJungle()
|
||||||
|
|
||||||
while True:
|
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):
|
for bus in range(3):
|
||||||
print(bus, jungle.can_health(bus))
|
print(f"\nBus {bus}:")
|
||||||
|
health = jungle.can_health(bus)
|
||||||
|
for key, value in health.items():
|
||||||
|
print(f"{key}: {colorize_errors(value)} ", end=" ")
|
||||||
print()
|
print()
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
|
@ -12,22 +12,27 @@ def sec_since_boot():
|
||||||
|
|
||||||
def can_printer():
|
def can_printer():
|
||||||
p = PandaJungle()
|
p = PandaJungle()
|
||||||
|
print(f"Connected to: {p._serial}: {p.get_version()}")
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
p.can_clear(0xFFFF)
|
||||||
|
|
||||||
start = sec_since_boot()
|
start = sec_since_boot()
|
||||||
lp = sec_since_boot()
|
lp = sec_since_boot()
|
||||||
msgs = defaultdict(list)
|
msgs = defaultdict(list)
|
||||||
canbus = int(os.getenv("CAN", "0"))
|
canbus = os.getenv("CAN")
|
||||||
while True:
|
while True:
|
||||||
can_recv = p.can_recv()
|
can_recv = p.can_recv()
|
||||||
for address, dat, src in can_recv:
|
for address,dat, src in can_recv:
|
||||||
if src == canbus:
|
if canbus is None or str(src) == canbus:
|
||||||
msgs[address].append(dat)
|
msgs[address].append((dat, src))
|
||||||
|
|
||||||
if sec_since_boot() - lp > 0.1:
|
if sec_since_boot() - lp > 0.1:
|
||||||
dd = chr(27) + "[2J"
|
dd = chr(27) + "[2J"
|
||||||
dd += "%5.2f\n" % (sec_since_boot() - start)
|
dd += "%5.2f\n" % (sec_since_boot() - start)
|
||||||
for k,v in sorted(zip(list(msgs.keys()), [binascii.hexlify(x[-1]) for x in list(msgs.values())], strict=True)):
|
for k, v in sorted(msgs.items()):
|
||||||
dd += "%s(%6d) %s\n" % ("%04X(%4d)" % (k,k),len(msgs[k]), v)
|
last_msg, last_src = v[-1]
|
||||||
|
dd += "%d: %s(%6d): %s\n" % (last_src, "%04X(%4d)" % (k, k), len(v), binascii.hexlify(last_msg).decode())
|
||||||
print(dd)
|
print(dd)
|
||||||
lp = sec_since_boot()
|
lp = sec_since_boot()
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
import os
|
||||||
|
import random
|
||||||
|
from panda import PandaJungle
|
||||||
|
|
||||||
|
def get_test_string():
|
||||||
|
return b"test" + os.urandom(10)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
p = PandaJungle()
|
||||||
|
|
||||||
|
p.set_safety_mode(PandaJungle.SAFETY_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)
|
|
@ -3,8 +3,16 @@
|
||||||
#include "safety_declarations.h"
|
#include "safety_declarations.h"
|
||||||
|
|
||||||
// Stock longitudinal
|
// Stock longitudinal
|
||||||
#define TOYOTA_COMMON_TX_MSGS \
|
#define TOYOTA_BASE_TX_MSGS \
|
||||||
{0x2E4, 0, 5}, {0x191, 0, 8}, {0x412, 0, 8}, {0x343, 0, 8}, {0x1D2, 0, 8}, /* LKAS + LTA + ACC & PCM cancel cmds */ \
|
{0x191, 0, 8}, {0x412, 0, 8}, {0x343, 0, 8}, {0x1D2, 0, 8}, /* LKAS + LTA + ACC & PCM cancel cmds */ \
|
||||||
|
|
||||||
|
#define TOYOTA_COMMON_TX_MSGS \
|
||||||
|
TOYOTA_BASE_TX_MSGS \
|
||||||
|
{0x2E4, 0, 5}, \
|
||||||
|
|
||||||
|
#define TOYOTA_COMMON_SECOC_TX_MSGS \
|
||||||
|
TOYOTA_BASE_TX_MSGS \
|
||||||
|
{0x2E4, 0, 8}, {0x131, 0, 8}, \
|
||||||
|
|
||||||
#define TOYOTA_COMMON_LONG_TX_MSGS \
|
#define TOYOTA_COMMON_LONG_TX_MSGS \
|
||||||
TOYOTA_COMMON_TX_MSGS \
|
TOYOTA_COMMON_TX_MSGS \
|
||||||
|
@ -16,10 +24,13 @@
|
||||||
#define TOYOTA_COMMON_RX_CHECKS(lta) \
|
#define TOYOTA_COMMON_RX_CHECKS(lta) \
|
||||||
{.msg = {{ 0xaa, 0, 8, .check_checksum = false, .frequency = 83U}, { 0 }, { 0 }}}, \
|
{.msg = {{ 0xaa, 0, 8, .check_checksum = false, .frequency = 83U}, { 0 }, { 0 }}}, \
|
||||||
{.msg = {{0x260, 0, 8, .check_checksum = true, .quality_flag = (lta), .frequency = 50U}, { 0 }, { 0 }}}, \
|
{.msg = {{0x260, 0, 8, .check_checksum = true, .quality_flag = (lta), .frequency = 50U}, { 0 }, { 0 }}}, \
|
||||||
{.msg = {{0x1D2, 0, 8, .check_checksum = true, .frequency = 33U}, { 0 }, { 0 }}}, \
|
{.msg = {{0x1D2, 0, 8, .check_checksum = true, .frequency = 33U}, \
|
||||||
{.msg = {{0x224, 0, 8, .check_checksum = false, .frequency = 40U}, \
|
{0x176, 0, 8, .check_checksum = true, .frequency = 32U}, { 0 }}}, \
|
||||||
{0x226, 0, 8, .check_checksum = false, .frequency = 40U}, { 0 }}}, \
|
{.msg = {{0x101, 0, 8, .check_checksum = false, .frequency = 50U}, \
|
||||||
|
{0x224, 0, 8, .check_checksum = false, .frequency = 40U}, \
|
||||||
|
{0x226, 0, 8, .check_checksum = false, .frequency = 40U}}}, \
|
||||||
|
|
||||||
|
static bool toyota_secoc = false;
|
||||||
static bool toyota_alt_brake = false;
|
static bool toyota_alt_brake = false;
|
||||||
static bool toyota_stock_longitudinal = false;
|
static bool toyota_stock_longitudinal = false;
|
||||||
static bool toyota_lta = false;
|
static bool toyota_lta = false;
|
||||||
|
@ -87,14 +98,31 @@ static void toyota_rx_hook(const CANPacket_t *to_push) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// enter controls on rising edge of ACC, exit controls on ACC off
|
// enter controls on rising edge of ACC, exit controls on ACC off
|
||||||
// exit controls on rising edge of gas press
|
// exit controls on rising edge of gas press, if not alternative experience
|
||||||
if (addr == 0x1D2) {
|
// exit controls on rising edge of brake press
|
||||||
// 5th bit is CRUISE_ACTIVE
|
if (toyota_secoc) {
|
||||||
bool cruise_engaged = GET_BIT(to_push, 5U);
|
if (addr == 0x176) {
|
||||||
pcm_cruise_check(cruise_engaged);
|
bool cruise_engaged = GET_BIT(to_push, 5U); // PCM_CRUISE.CRUISE_ACTIVE
|
||||||
|
pcm_cruise_check(cruise_engaged);
|
||||||
// sample gas pedal
|
}
|
||||||
gas_pressed = !GET_BIT(to_push, 4U);
|
if (addr == 0x116) {
|
||||||
|
gas_pressed = GET_BYTE(to_push, 1) != 0U; // GAS_PEDAL.GAS_PEDAL_USER
|
||||||
|
}
|
||||||
|
if (addr == 0x101) {
|
||||||
|
brake_pressed = GET_BIT(to_push, 3U); // BRAKE_MODULE.BRAKE_PRESSED (toyota_rav4_prime_generated.dbc)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (addr == 0x1D2) {
|
||||||
|
bool cruise_engaged = GET_BIT(to_push, 5U); // PCM_CRUISE.CRUISE_ACTIVE
|
||||||
|
pcm_cruise_check(cruise_engaged);
|
||||||
|
gas_pressed = !GET_BIT(to_push, 4U); // PCM_CRUISE.GAS_RELEASED
|
||||||
|
}
|
||||||
|
if (!toyota_alt_brake && (addr == 0x226)) {
|
||||||
|
brake_pressed = GET_BIT(to_push, 37U); // BRAKE_MODULE.BRAKE_PRESSED (toyota_nodsu_pt_generated.dbc)
|
||||||
|
}
|
||||||
|
if (toyota_alt_brake && (addr == 0x224)) {
|
||||||
|
brake_pressed = GET_BIT(to_push, 5U); // BRAKE_MODULE.BRAKE_PRESSED (toyota_new_mc_pt_generated.dbc)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// sample speed
|
// sample speed
|
||||||
|
@ -111,12 +139,6 @@ static void toyota_rx_hook(const CANPacket_t *to_push) {
|
||||||
UPDATE_VEHICLE_SPEED(speed / 4.0 * 0.01 / 3.6);
|
UPDATE_VEHICLE_SPEED(speed / 4.0 * 0.01 / 3.6);
|
||||||
}
|
}
|
||||||
|
|
||||||
// most cars have brake_pressed on 0x226, corolla and rav4 on 0x224
|
|
||||||
if (((addr == 0x224) && toyota_alt_brake) || ((addr == 0x226) && !toyota_alt_brake)) {
|
|
||||||
uint8_t bit = (addr == 0x224) ? 5U : 37U;
|
|
||||||
brake_pressed = GET_BIT(to_push, bit);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool stock_ecu_detected = addr == 0x2E4; // STEERING_LKA
|
bool stock_ecu_detected = addr == 0x2E4; // STEERING_LKA
|
||||||
if (!toyota_stock_longitudinal && (addr == 0x343)) {
|
if (!toyota_stock_longitudinal && (addr == 0x343)) {
|
||||||
stock_ecu_detected = true; // ACC_CONTROL
|
stock_ecu_detected = true; // ACC_CONTROL
|
||||||
|
@ -203,7 +225,7 @@ static bool toyota_tx_hook(const CANPacket_t *to_send) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// LTA angle steering check
|
// STEERING_LTA angle steering check
|
||||||
if (addr == 0x191) {
|
if (addr == 0x191) {
|
||||||
// check the STEER_REQUEST, STEER_REQUEST_2, TORQUE_WIND_DOWN, STEER_ANGLE_CMD signals
|
// check the STEER_REQUEST, STEER_REQUEST_2, TORQUE_WIND_DOWN, STEER_ANGLE_CMD signals
|
||||||
bool lta_request = GET_BIT(to_send, 0U);
|
bool lta_request = GET_BIT(to_send, 0U);
|
||||||
|
@ -251,6 +273,20 @@ static bool toyota_tx_hook(const CANPacket_t *to_send) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// STEERING_LTA_2 angle steering check (SecOC)
|
||||||
|
if (toyota_secoc && (addr == 0x131)) {
|
||||||
|
// SecOC cars block any form of LTA actuation for now
|
||||||
|
bool lta_request = GET_BIT(to_send, 3U); // STEERING_LTA_2.STEER_REQUEST
|
||||||
|
bool lta_request2 = GET_BIT(to_send, 0U); // STEERING_LTA_2.STEER_REQUEST_2
|
||||||
|
int lta_angle_msb = GET_BYTE(to_send, 2); // STEERING_LTA_2.STEER_ANGLE_CMD (MSB)
|
||||||
|
int lta_angle_lsb = GET_BYTE(to_send, 3); // STEERING_LTA_2.STEER_ANGLE_CMD (LSB)
|
||||||
|
|
||||||
|
bool actuation = lta_request || lta_request2 || (lta_angle_msb != 0) || (lta_angle_lsb != 0);
|
||||||
|
if (actuation) {
|
||||||
|
tx = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// STEER: safety check on bytes 2-3
|
// STEER: safety check on bytes 2-3
|
||||||
if (addr == 0x2E4) {
|
if (addr == 0x2E4) {
|
||||||
int desired_torque = (GET_BYTE(to_send, 1) << 8) | GET_BYTE(to_send, 2);
|
int desired_torque = (GET_BYTE(to_send, 1) << 8) | GET_BYTE(to_send, 2);
|
||||||
|
@ -286,6 +322,10 @@ static safety_config toyota_init(uint16_t param) {
|
||||||
TOYOTA_COMMON_TX_MSGS
|
TOYOTA_COMMON_TX_MSGS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const CanMsg TOYOTA_SECOC_TX_MSGS[] = {
|
||||||
|
TOYOTA_COMMON_SECOC_TX_MSGS
|
||||||
|
};
|
||||||
|
|
||||||
static const CanMsg TOYOTA_LONG_TX_MSGS[] = {
|
static const CanMsg TOYOTA_LONG_TX_MSGS[] = {
|
||||||
TOYOTA_COMMON_LONG_TX_MSGS
|
TOYOTA_COMMON_LONG_TX_MSGS
|
||||||
};
|
};
|
||||||
|
@ -298,6 +338,11 @@ static safety_config toyota_init(uint16_t param) {
|
||||||
const uint32_t TOYOTA_PARAM_STOCK_LONGITUDINAL = 2UL << TOYOTA_PARAM_OFFSET;
|
const uint32_t TOYOTA_PARAM_STOCK_LONGITUDINAL = 2UL << TOYOTA_PARAM_OFFSET;
|
||||||
const uint32_t TOYOTA_PARAM_LTA = 4UL << TOYOTA_PARAM_OFFSET;
|
const uint32_t TOYOTA_PARAM_LTA = 4UL << TOYOTA_PARAM_OFFSET;
|
||||||
|
|
||||||
|
#ifdef ALLOW_DEBUG
|
||||||
|
const uint32_t TOYOTA_PARAM_SECOC = 8UL << TOYOTA_PARAM_OFFSET;
|
||||||
|
toyota_secoc = GET_FLAG(param, TOYOTA_PARAM_SECOC);
|
||||||
|
#endif
|
||||||
|
|
||||||
toyota_alt_brake = GET_FLAG(param, TOYOTA_PARAM_ALT_BRAKE);
|
toyota_alt_brake = GET_FLAG(param, TOYOTA_PARAM_ALT_BRAKE);
|
||||||
toyota_stock_longitudinal = GET_FLAG(param, TOYOTA_PARAM_STOCK_LONGITUDINAL);
|
toyota_stock_longitudinal = GET_FLAG(param, TOYOTA_PARAM_STOCK_LONGITUDINAL);
|
||||||
toyota_lta = GET_FLAG(param, TOYOTA_PARAM_LTA);
|
toyota_lta = GET_FLAG(param, TOYOTA_PARAM_LTA);
|
||||||
|
@ -305,7 +350,11 @@ static safety_config toyota_init(uint16_t param) {
|
||||||
|
|
||||||
safety_config ret;
|
safety_config ret;
|
||||||
if (toyota_stock_longitudinal) {
|
if (toyota_stock_longitudinal) {
|
||||||
SET_TX_MSGS(TOYOTA_TX_MSGS, ret);
|
if (toyota_secoc) {
|
||||||
|
SET_TX_MSGS(TOYOTA_SECOC_TX_MSGS, ret);
|
||||||
|
} else {
|
||||||
|
SET_TX_MSGS(TOYOTA_TX_MSGS, ret);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
SET_TX_MSGS(TOYOTA_LONG_TX_MSGS, ret);
|
SET_TX_MSGS(TOYOTA_LONG_TX_MSGS, ret);
|
||||||
}
|
}
|
||||||
|
@ -340,6 +389,8 @@ static int toyota_fwd_hook(int bus_num, int addr) {
|
||||||
// block stock lkas messages and stock acc messages (if OP is doing ACC)
|
// block stock lkas messages and stock acc messages (if OP is doing ACC)
|
||||||
// in TSS2, 0x191 is LTA which we need to block to avoid controls collision
|
// in TSS2, 0x191 is LTA which we need to block to avoid controls collision
|
||||||
bool is_lkas_msg = ((addr == 0x2E4) || (addr == 0x412) || (addr == 0x191));
|
bool is_lkas_msg = ((addr == 0x2E4) || (addr == 0x412) || (addr == 0x191));
|
||||||
|
// on SecOC cars 0x131 is also LTA
|
||||||
|
is_lkas_msg |= toyota_secoc && (addr == 0x131);
|
||||||
// in TSS2 the camera does ACC as well, so filter 0x343
|
// in TSS2 the camera does ACC as well, so filter 0x343
|
||||||
bool is_acc_msg = (addr == 0x343);
|
bool is_acc_msg = (addr == 0x343);
|
||||||
bool block_msg = is_lkas_msg || (is_acc_msg && !toyota_stock_longitudinal);
|
bool block_msg = is_lkas_msg || (is_acc_msg && !toyota_stock_longitudinal);
|
||||||
|
|
|
@ -187,6 +187,7 @@ class Panda:
|
||||||
FLAG_TOYOTA_ALT_BRAKE = (1 << 8)
|
FLAG_TOYOTA_ALT_BRAKE = (1 << 8)
|
||||||
FLAG_TOYOTA_STOCK_LONGITUDINAL = (2 << 8)
|
FLAG_TOYOTA_STOCK_LONGITUDINAL = (2 << 8)
|
||||||
FLAG_TOYOTA_LTA = (4 << 8)
|
FLAG_TOYOTA_LTA = (4 << 8)
|
||||||
|
FLAG_TOYOTA_SECOC = (8 << 8)
|
||||||
|
|
||||||
FLAG_HONDA_ALT_BRAKE = 1
|
FLAG_HONDA_ALT_BRAKE = 1
|
||||||
FLAG_HONDA_BOSCH_LONG = 2
|
FLAG_HONDA_BOSCH_LONG = 2
|
||||||
|
@ -513,22 +514,22 @@ class Panda:
|
||||||
assert last_sector < 7, "Binary too large! Risk of overwriting provisioning chunk."
|
assert last_sector < 7, "Binary too large! Risk of overwriting provisioning chunk."
|
||||||
|
|
||||||
# unlock flash
|
# unlock flash
|
||||||
logger.warning("flash: unlocking")
|
logger.info("flash: unlocking")
|
||||||
handle.controlWrite(Panda.REQUEST_IN, 0xb1, 0, 0, b'')
|
handle.controlWrite(Panda.REQUEST_IN, 0xb1, 0, 0, b'')
|
||||||
|
|
||||||
# erase sectors
|
# erase sectors
|
||||||
logger.warning(f"flash: erasing sectors 1 - {last_sector}")
|
logger.info(f"flash: erasing sectors 1 - {last_sector}")
|
||||||
for i in range(1, last_sector + 1):
|
for i in range(1, last_sector + 1):
|
||||||
handle.controlWrite(Panda.REQUEST_IN, 0xb2, i, 0, b'')
|
handle.controlWrite(Panda.REQUEST_IN, 0xb2, i, 0, b'')
|
||||||
|
|
||||||
# flash over EP2
|
# flash over EP2
|
||||||
STEP = 0x10
|
STEP = 0x10
|
||||||
logger.warning("flash: flashing")
|
logger.info("flash: flashing")
|
||||||
for i in range(0, len(code), STEP):
|
for i in range(0, len(code), STEP):
|
||||||
handle.bulkWrite(2, code[i:i + STEP])
|
handle.bulkWrite(2, code[i:i + STEP])
|
||||||
|
|
||||||
# reset
|
# reset
|
||||||
logger.warning("flash: resetting")
|
logger.info("flash: resetting")
|
||||||
try:
|
try:
|
||||||
handle.controlWrite(Panda.REQUEST_IN, 0xd8, 0, 0, b'', expect_disconnect=True)
|
handle.controlWrite(Panda.REQUEST_IN, 0xd8, 0, 0, b'', expect_disconnect=True)
|
||||||
except Exception:
|
except Exception:
|
||||||
|
@ -536,7 +537,7 @@ class Panda:
|
||||||
|
|
||||||
def flash(self, fn=None, code=None, reconnect=True):
|
def flash(self, fn=None, code=None, reconnect=True):
|
||||||
if self.up_to_date(fn=fn):
|
if self.up_to_date(fn=fn):
|
||||||
logger.debug("flash: already up to date")
|
logger.info("flash: already up to date")
|
||||||
return
|
return
|
||||||
|
|
||||||
if not fn:
|
if not fn:
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
import time
|
||||||
|
import re
|
||||||
|
from panda import Panda
|
||||||
|
|
||||||
|
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__":
|
||||||
|
|
||||||
|
panda = Panda()
|
||||||
|
while True:
|
||||||
|
print(chr(27) + "[2J") # clear screen
|
||||||
|
print("Connected to " + ("internal panda" if panda.is_internal() else "External panda") + f" id: {panda.get_serial()[0]}: {panda.get_version()}")
|
||||||
|
for bus in range(3):
|
||||||
|
print(f"\nBus {bus}:")
|
||||||
|
health = panda.can_health(bus)
|
||||||
|
for key, value in health.items():
|
||||||
|
print(f"{key}: {colorize_errors(value)} ", end=" ")
|
||||||
|
print()
|
||||||
|
time.sleep(1)
|
|
@ -12,28 +12,28 @@ def sec_since_boot():
|
||||||
|
|
||||||
def can_printer():
|
def can_printer():
|
||||||
p = Panda()
|
p = Panda()
|
||||||
|
print(f"Connected to id: {p.get_serial()[0]}: {p.get_version()}")
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
p.can_clear(0xFFFF)
|
||||||
p.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
|
p.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
|
||||||
|
|
||||||
start = sec_since_boot()
|
start = sec_since_boot()
|
||||||
lp = sec_since_boot()
|
lp = sec_since_boot()
|
||||||
msgs = defaultdict(list)
|
msgs = defaultdict(list)
|
||||||
|
canbus = os.getenv("CAN")
|
||||||
canbus = int(os.getenv("CAN", "0"))
|
|
||||||
if canbus == 3:
|
|
||||||
canbus = 1
|
|
||||||
p.set_obd(True)
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
can_recv = p.can_recv()
|
can_recv = p.can_recv()
|
||||||
for address, dat, src in can_recv:
|
for address, dat, src in can_recv:
|
||||||
if src == canbus:
|
if canbus is None or str(src) == canbus:
|
||||||
msgs[address].append(dat)
|
msgs[address].append((dat, src))
|
||||||
|
|
||||||
if sec_since_boot() - lp > 0.1:
|
if sec_since_boot() - lp > 0.1:
|
||||||
dd = chr(27) + "[2J"
|
dd = chr(27) + "[2J"
|
||||||
dd += "%5.2f\n" % (sec_since_boot() - start)
|
dd += "%5.2f\n" % (sec_since_boot() - start)
|
||||||
for k, v in sorted(zip(list(msgs.keys()), [binascii.hexlify(x[-1]) for x in list(msgs.values())], strict=True)):
|
for k, v in sorted(msgs.items()):
|
||||||
dd += "%s(%6d) %s\n" % ("%04X(%4d)" % (k, k), len(msgs[k]), v)
|
last_msg, last_src = v[-1]
|
||||||
|
dd += "%d: %s(%6d): %s\n" % (last_src, "%04X(%4d)" % (k, k), len(v), binascii.hexlify(last_msg).decode())
|
||||||
print(dd)
|
print(dd)
|
||||||
lp = sec_since_boot()
|
lp = sec_since_boot()
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,8 @@ $DIR/install_mull.sh
|
||||||
|
|
||||||
GIT_REF="${GIT_REF:-origin/master}"
|
GIT_REF="${GIT_REF:-origin/master}"
|
||||||
GIT_ROOT=$(git rev-parse --show-toplevel)
|
GIT_ROOT=$(git rev-parse --show-toplevel)
|
||||||
echo -e "mutators:\n - cxx_all" > $GIT_ROOT/mull.yml
|
MULL_OPS="mutators: [cxx_increment, cxx_decrement, cxx_comparison, cxx_boundary, cxx_bitwise_assignment, cxx_bitwise, cxx_arithmetic_assignment, cxx_arithmetic, cxx_remove_negation]"
|
||||||
|
echo -e "$MULL_OPS" > $GIT_ROOT/mull.yml
|
||||||
scons --mutation -j$(nproc) -D
|
scons --mutation -j$(nproc) -D
|
||||||
echo -e "timeout: 10000\ngitDiffRef: $GIT_REF\ngitProjectRoot: $GIT_ROOT" >> $GIT_ROOT/mull.yml
|
echo -e "timeout: 10000\ngitDiffRef: $GIT_REF\ngitProjectRoot: $GIT_ROOT" >> $GIT_ROOT/mull.yml
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import panda.tests.safety.common as common
|
||||||
from panda.tests.safety.common import CANPackerPanda
|
from panda.tests.safety.common import CANPackerPanda
|
||||||
|
|
||||||
TOYOTA_COMMON_TX_MSGS = [[0x2E4, 0], [0x191, 0], [0x412, 0], [0x343, 0], [0x1D2, 0]] # LKAS + LTA + ACC & PCM cancel cmds
|
TOYOTA_COMMON_TX_MSGS = [[0x2E4, 0], [0x191, 0], [0x412, 0], [0x343, 0], [0x1D2, 0]] # LKAS + LTA + ACC & PCM cancel cmds
|
||||||
|
TOYOTA_SECOC_TX_MSGS = [[0x131, 0]] + TOYOTA_COMMON_TX_MSGS
|
||||||
TOYOTA_COMMON_LONG_TX_MSGS = [[0x283, 0], [0x2E6, 0], [0x2E7, 0], [0x33E, 0], [0x344, 0], [0x365, 0], [0x366, 0], [0x4CB, 0], # DSU bus 0
|
TOYOTA_COMMON_LONG_TX_MSGS = [[0x283, 0], [0x2E6, 0], [0x2E7, 0], [0x33E, 0], [0x344, 0], [0x365, 0], [0x366, 0], [0x4CB, 0], # DSU bus 0
|
||||||
[0x128, 1], [0x141, 1], [0x160, 1], [0x161, 1], [0x470, 1], # DSU bus 1
|
[0x128, 1], [0x141, 1], [0x160, 1], [0x161, 1], [0x470, 1], # DSU bus 1
|
||||||
[0x411, 0], # PCS_HUD
|
[0x411, 0], # PCS_HUD
|
||||||
|
@ -107,7 +108,8 @@ class TestToyotaSafetyBase(common.PandaCarSafetyTest, common.LongitudinalAccelSa
|
||||||
self.safety.set_controls_allowed(engaged)
|
self.safety.set_controls_allowed(engaged)
|
||||||
|
|
||||||
should_tx = not req and not req2 and angle == 0 and torque_wind_down == 0
|
should_tx = not req and not req2 and angle == 0 and torque_wind_down == 0
|
||||||
self.assertEqual(should_tx, self._tx(self._lta_msg(req, req2, angle, torque_wind_down)))
|
self.assertEqual(should_tx, self._tx(self._lta_msg(req, req2, angle, torque_wind_down)),
|
||||||
|
f"{req=} {req2=} {angle=} {torque_wind_down=}")
|
||||||
|
|
||||||
def test_rx_hook(self):
|
def test_rx_hook(self):
|
||||||
# checksum checks
|
# checksum checks
|
||||||
|
@ -324,5 +326,38 @@ class TestToyotaStockLongitudinalAngle(TestToyotaStockLongitudinalBase, TestToyo
|
||||||
self.safety.init_tests()
|
self.safety.init_tests()
|
||||||
|
|
||||||
|
|
||||||
|
class TestToyotaSecOcSafety(TestToyotaStockLongitudinalBase):
|
||||||
|
|
||||||
|
TX_MSGS = TOYOTA_SECOC_TX_MSGS
|
||||||
|
RELAY_MALFUNCTION_ADDRS = {0: (0x2E4,)}
|
||||||
|
FWD_BLACKLISTED_ADDRS = {2: [0x2E4, 0x412, 0x191, 0x131]}
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.packer = CANPackerPanda("toyota_rav4_prime_generated")
|
||||||
|
self.safety = libpanda_py.libpanda
|
||||||
|
self.safety.set_safety_hooks(Panda.SAFETY_TOYOTA, self.EPS_SCALE | Panda.FLAG_TOYOTA_STOCK_LONGITUDINAL | Panda.FLAG_TOYOTA_SECOC)
|
||||||
|
self.safety.init_tests()
|
||||||
|
|
||||||
|
# This platform also has alternate brake and PCM messages, but same naming in the DBC, so same packers work
|
||||||
|
|
||||||
|
def _user_gas_msg(self, gas):
|
||||||
|
values = {"GAS_PEDAL_USER": gas}
|
||||||
|
return self.packer.make_can_msg_panda("GAS_PEDAL", 0, values)
|
||||||
|
|
||||||
|
# This platform sends both STEERING_LTA (same as other Toyota) and STEERING_LTA_2 (SecOC signed)
|
||||||
|
# STEERING_LTA is checked for no-actuation by the base class, STEERING_LTA_2 is checked for no-actuation below
|
||||||
|
|
||||||
|
def _lta_2_msg(self, req, req2, angle_cmd, torque_wind_down=100):
|
||||||
|
values = {"STEER_REQUEST": req, "STEER_REQUEST_2": req2, "STEER_ANGLE_CMD": angle_cmd}
|
||||||
|
return self.packer.make_can_msg_panda("STEERING_LTA_2", 0, values)
|
||||||
|
|
||||||
|
def test_lta_2_steer_cmd(self):
|
||||||
|
for engaged, req, req2, angle in itertools.product([True, False], [0, 1], [0, 1], np.linspace(-20, 20, 5)):
|
||||||
|
self.safety.set_controls_allowed(engaged)
|
||||||
|
|
||||||
|
should_tx = not req and not req2 and angle == 0
|
||||||
|
self.assertEqual(should_tx, self._tx(self._lta_2_msg(req, req2, angle)), f"{req=} {req2=} {angle=}")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
Loading…
Reference in New Issue