diff --git a/Jenkinsfile b/Jenkinsfile
index 64ca4bfa24..bcdb7c99f4 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -145,10 +145,10 @@ pipeline {
stages {
stage('parallel tests') {
parallel {
- stage('Devel Tests') {
+ stage('C2: build') {
steps {
phone_steps("eon-build", [
- ["build devel", "cd $SOURCE_DIR/release && EXTRA_FILES='tools/' ./build_devel.sh"],
+ ["build master-ci", "cd $SOURCE_DIR/release && EXTRA_FILES='tools/' ./build_devel.sh"],
["build openpilot", "cd selfdrive/manager && ./build.py"],
["test manager", "python selfdrive/manager/test/test_manager.py"],
["onroad tests", "cd selfdrive/test/ && ./test_onroad.py"],
@@ -157,7 +157,7 @@ pipeline {
}
}
- stage('Replay Tests') {
+ stage('C2: replay') {
steps {
phone_steps("eon2", [
["build", "cd selfdrive/manager && ./build.py"],
@@ -166,7 +166,7 @@ pipeline {
}
}
- stage('HW + Unit Tests') {
+ stage('C2: HW + Unit Tests') {
steps {
phone_steps("eon", [
["build", "cd selfdrive/manager && ./build.py"],
@@ -201,19 +201,22 @@ pipeline {
}
*/
- stage('tici Build') {
+ stage('C3: build') {
environment {
R3_PUSH = "${env.BRANCH_NAME == 'master' ? '1' : ' '}"
}
steps {
phone_steps("tici", [
- ["build", "cd selfdrive/manager && ./build.py"],
+ ["build master-ci", "cd $SOURCE_DIR/release && EXTRA_FILES='tools/' ./build_devel.sh"],
+ ["build openpilot", "cd selfdrive/manager && ./build.py"],
+ ["test manager", "python selfdrive/manager/test/test_manager.py"],
["onroad tests", "cd selfdrive/test/ && ./test_onroad.py"],
+ ["test car interfaces", "cd selfdrive/car/tests/ && ./test_car_interfaces.py"],
])
}
}
- stage('HW + Unit Tests (tici)') {
+ stage('C3: HW + Unit Tests') {
steps {
phone_steps("tici2", [
["build", "cd selfdrive/manager && ./build.py"],
@@ -224,7 +227,7 @@ pipeline {
}
}
- stage('EON camerad') {
+ stage('C2: camerad') {
steps {
phone_steps("eon-party", [
["build", "cd selfdrive/manager && ./build.py"],
@@ -234,7 +237,7 @@ pipeline {
}
}
- stage('tici camerad') {
+ stage('C3: camerad') {
steps {
phone_steps("tici-party", [
["build", "cd selfdrive/manager && ./build.py"],
diff --git a/RELEASES.md b/RELEASES.md
index 42d5514ff3..12a90fba6c 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,16 +1,16 @@
-Version 0.8.12 (202X-XX-XX)
-========================
- * Volkswagen T-Roc 2021 support thanks to jyoung8607!
-
-Version 0.8.11 (2021-11-22)
+Version 0.8.11 (2021-11-29)
========================
+ * Support for CAN FD on the red panda
* Support for an external panda on the comma three
* Navigation: Show more detailed instructions when approaching maneuver
* Fixed occasional steering faults on GM cars thanks to jyoung8607!
* Nissan ECU firmware fingerprinting thanks to robin-reckmann, martinl, and razem-io!
* Cadillac Escalade ESV 2016 support thanks to Gibby!
+ * Genesis G70 2020 support thanks to tecandrew!
+ * Hyundai Santa Fe Hybrid 2022 support thanks to sunnyhaibin!
* Mazda CX-9 2021 support thanks to Jacar!
* Volkswagen Polo 2020 support thanks to jyoung8607!
+ * Volkswagen T-Roc 2021 support thanks to jyoung8607!
Version 0.8.10 (2021-11-01)
========================
diff --git a/cereal b/cereal
index 5edffa0f49..032aca6ca3 160000
--- a/cereal
+++ b/cereal
@@ -1 +1 @@
-Subproject commit 5edffa0f494abfa2e907c497cda0f64223a421e7
+Subproject commit 032aca6ca38a342e26fb9cc986b7f72b91cd9b55
diff --git a/docs/CARS.md b/docs/CARS.md
index e2b846c8f1..30f3131c72 100644
--- a/docs/CARS.md
+++ b/docs/CARS.md
@@ -93,6 +93,7 @@
| Chrysler | Pacifica Hybrid 2017-18 | Adaptive Cruise | Stock | 0mph | 9mph |
| Chrysler | Pacifica Hybrid 2019-21 | Adaptive Cruise | Stock | 0mph | 39mph |
| Genesis | G70 2018 | All | Stock | 0mph | 0mph |
+| Genesis | G70 2020 | All | Stock | 0mph | 0mph |
| Genesis | G80 2018 | All | Stock | 0mph | 0mph |
| Genesis | G90 2018 | All | Stock | 0mph | 0mph |
| GMC | Acadia 20181 | Adaptive Cruise | openpilot | 0mph | 7mph |
@@ -111,6 +112,7 @@
| Hyundai | Kona Hybrid 2020 | SCC + LKAS | Stock | 0mph | 0mph |
| Hyundai | Santa Fe 2019-20 | All | Stock | 0mph | 0mph |
| Hyundai | Santa Fe 2021-22 | All | Stock | 0mph | 0mph |
+| Hyundai | Santa Fe Hybrid 2022 | All | Stock | 0mph | 0mph |
| Hyundai | Sonata 2018-2019 | SCC + LKAS | Stock | 0mph | 0mph |
| Hyundai | Sonata Hybrid 2021-22 | All | Stock | 0mph | 0mph |
| Hyundai | Veloster 2019-20 | SCC + LKAS | Stock | 5mph | 0mph |
diff --git a/scripts/count_cars.py b/scripts/count_cars.py
index 3c8d7bb54a..a88d72610f 100755
--- a/scripts/count_cars.py
+++ b/scripts/count_cars.py
@@ -1,10 +1,15 @@
#!/usr/bin/env python3
import os
+from collections import Counter
+from pprint import pprint
+
from common.basedir import BASEDIR
with open(os.path.join(BASEDIR, "docs/CARS.md")) as f:
lines = f.readlines()
cars = [l for l in lines if l.strip().startswith("|") and l.strip().endswith("|") and
"Make" not in l and any(c.isalpha() for c in l)]
- print(''.join(cars))
- print(len(cars))
+
+ make_count = Counter([l.split('|')[1].split('|')[0].strip() for l in cars])
+ print("\n", "*"*20, len(cars), "total", "*"*20, "\n")
+ pprint(make_count)
diff --git a/selfdrive/boardd/boardd.cc b/selfdrive/boardd/boardd.cc
index ce73662e45..f9c4891d03 100644
--- a/selfdrive/boardd/boardd.cc
+++ b/selfdrive/boardd/boardd.cc
@@ -185,7 +185,7 @@ Panda *usb_connect(std::string serial="", uint32_t index=0) {
}
void can_send_thread(std::vector pandas, bool fake_send) {
- LOGD("start send thread");
+ set_thread_name("boardd_can_send");
AlignedBuffer aligned_buf;
Context * context = Context::create();
@@ -229,7 +229,7 @@ void can_send_thread(std::vector pandas, bool fake_send) {
}
void can_recv_thread(std::vector pandas) {
- LOGD("start recv thread");
+ set_thread_name("boardd_can_recv");
// can = 8006
PubMaster pm({"can"});
@@ -334,7 +334,6 @@ bool send_panda_states(PubMaster *pm, const std::vector &pandas, bool s
}
#endif
- // TODO: do we still need this?
if (!panda->comms_healthy) {
evt.setValid(false);
}
@@ -407,6 +406,8 @@ void send_peripheral_state(PubMaster *pm, Panda *panda) {
}
void panda_state_thread(PubMaster *pm, std::vector pandas, bool spoofing_started) {
+ set_thread_name("boardd_panda_state");
+
Params params;
Panda *peripheral_panda = pandas[0];
bool ignition_last = false;
@@ -424,6 +425,7 @@ void panda_state_thread(PubMaster *pm, std::vector pandas, bool spoofin
send_peripheral_state(pm, peripheral_panda);
ignition = send_panda_states(pm, pandas, spoofing_started);
+ // TODO: make this check fast, currently takes 16ms
// check if we have new pandas and are offroad
if (!ignition && (pandas.size() != Panda::list().size())) {
LOGW("Reconnecting to changed amount of pandas!");
@@ -454,7 +456,8 @@ void panda_state_thread(PubMaster *pm, std::vector pandas, bool spoofin
void peripheral_control_thread(Panda *panda) {
- LOGD("start peripheral control thread");
+ set_thread_name("boardd_peripheral_control");
+
SubMaster sm({"deviceState", "driverCameraState"});
uint64_t last_front_frame_t = 0;
@@ -552,6 +555,8 @@ static void pigeon_publish_raw(PubMaster &pm, const std::string &dat) {
}
void pigeon_thread(Panda *panda) {
+ set_thread_name("boardd_pigeon");
+
PubMaster pm({"ubloxRaw"});
bool ignition_last = false;
diff --git a/selfdrive/boardd/tests/test_boardd_loopback.py b/selfdrive/boardd/tests/test_boardd_loopback.py
index 43053b6b1a..24c6f2e300 100755
--- a/selfdrive/boardd/tests/test_boardd_loopback.py
+++ b/selfdrive/boardd/tests/test_boardd_loopback.py
@@ -4,33 +4,18 @@ import random
import time
import unittest
from collections import defaultdict
-from functools import wraps
import cereal.messaging as messaging
from cereal import car
from common.params import Params
from common.spinner import Spinner
from common.timeout import Timeout
-from panda import Panda
from selfdrive.boardd.boardd import can_list_to_can_capnp
from selfdrive.car import make_can_msg
from selfdrive.hardware import TICI
from selfdrive.test.helpers import phone_only, with_processes
-def reset_pandas(f):
- @wraps(f)
- def wrapper(*args, **kwargs):
- for serial in Panda.list():
- p = Panda(serial)
- for i in [0, 1, 2, 3, 0xFFFF]:
- p.can_clear(i)
- p.reset()
- p.close()
- f(*args, **kwargs)
- return wrapper
-
-
class TestBoardd(unittest.TestCase):
@classmethod
@@ -44,7 +29,6 @@ class TestBoardd(unittest.TestCase):
cls.spinner.close()
@phone_only
- @reset_pandas
@with_processes(['pandad'])
def test_loopback(self):
# wait for boardd to init
@@ -75,7 +59,7 @@ class TestBoardd(unittest.TestCase):
can = messaging.sub_sock('can', conflate=False, timeout=100)
time.sleep(0.2)
- n = 1000
+ n = 200
for i in range(n):
self.spinner.update(f"boardd loopback {i}/{n}")
diff --git a/selfdrive/car/__init__.py b/selfdrive/car/__init__.py
index ddb20fe549..408e0d075f 100644
--- a/selfdrive/car/__init__.py
+++ b/selfdrive/car/__init__.py
@@ -99,7 +99,7 @@ def crc8_pedal(data):
return crc
-def create_gas_command(packer, gas_amount, idx):
+def create_gas_interceptor_command(packer, gas_amount, idx):
# Common gas pedal msg generator
enable = gas_amount > 0.001
diff --git a/selfdrive/car/gm/interface.py b/selfdrive/car/gm/interface.py
index e9b5a13e7a..b06e5373aa 100755
--- a/selfdrive/car/gm/interface.py
+++ b/selfdrive/car/gm/interface.py
@@ -16,18 +16,24 @@ class CarInterface(CarInterfaceBase):
params = CarControllerParams()
return params.ACCEL_MIN, params.ACCEL_MAX
- # Volt determined by iteratively plotting and minimizing error for f(angle, speed) = steer.
+ # Determined by iteratively plotting and minimizing error for f(angle, speed) = steer.
@staticmethod
def get_steer_feedforward_volt(desired_angle, v_ego):
- # maps [-inf,inf] to [-1,1]: sigmoid(34.4 deg) = sigmoid(1) = 0.5
- # 1 / 0.02904609 = 34.4 deg ~= 36 deg ~= 1/10 circle? Arbitrary?
desired_angle *= 0.02904609
sigmoid = desired_angle / (1 + fabs(desired_angle))
return 0.10006696 * sigmoid * (v_ego + 3.12485927)
+ @staticmethod
+ def get_steer_feedforward_acadia(desired_angle, v_ego):
+ desired_angle *= 0.09760208
+ sigmoid = desired_angle / (1 + fabs(desired_angle))
+ return 0.04689655 * sigmoid * (v_ego + 10.028217)
+
def get_steer_feedforward_function(self):
- if self.CP.carFingerprint in [CAR.VOLT]:
+ if self.CP.carFingerprint == CAR.VOLT:
return self.get_steer_feedforward_volt
+ elif self.CP.carFingerprint == CAR.ACADIA:
+ return self.get_steer_feedforward_acadia
else:
return CarInterfaceBase.get_steer_feedforward_default
@@ -94,6 +100,7 @@ class CarInterface(CarInterfaceBase):
ret.steerRatio = 14.4 # end to end is 13.46
ret.steerRatioRear = 0.
ret.centerToFront = ret.wheelbase * 0.4
+ ret.lateralTuning.pid.kf = 1. # get_steer_feedforward_acadia()
elif candidate == CAR.BUICK_REGAL:
ret.minEnableSpeed = 18 * CV.MPH_TO_MS
@@ -121,7 +128,7 @@ class CarInterface(CarInterfaceBase):
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.13, 0.24], [0.01, 0.02]]
ret.lateralTuning.pid.kf = 0.000045
tire_stiffness_factor = 1.0
-
+
# TODO: get actual value, for now starting with reasonable value for
# civic and scaling by mass and wheelbase
ret.rotationalInertia = scale_rot_inertia(ret.mass, ret.wheelbase)
diff --git a/selfdrive/car/honda/carcontroller.py b/selfdrive/car/honda/carcontroller.py
index 1e0a35fdf5..d75be7c712 100644
--- a/selfdrive/car/honda/carcontroller.py
+++ b/selfdrive/car/honda/carcontroller.py
@@ -3,7 +3,7 @@ from cereal import car
from common.realtime import DT_CTRL
from selfdrive.controls.lib.drive_helpers import rate_limit
from common.numpy_fast import clip, interp
-from selfdrive.car import create_gas_command
+from selfdrive.car import create_gas_interceptor_command
from selfdrive.car.honda import hondacan
from selfdrive.car.honda.values import CruiseButtons, VISUAL_HUD, HONDA_BOSCH, HONDA_NIDEC_ALT_PCM_ACCEL, CarControllerParams
from opendbc.can.packer import CANPacker
@@ -236,7 +236,7 @@ class CarController():
apply_gas = clip(gas_mult * (gas - brake + wind_brake*3/4), 0., 1.)
else:
apply_gas = 0.0
- can_sends.append(create_gas_command(self.packer, apply_gas, idx))
+ can_sends.append(create_gas_interceptor_command(self.packer, apply_gas, idx))
hud = HUDData(int(pcm_accel), int(round(hud_v_cruise)), hud_car,
hud_lanes, fcw_display, acc_alert, steer_required)
diff --git a/selfdrive/car/honda/interface.py b/selfdrive/car/honda/interface.py
index 4aa6ec3815..802ce980ab 100755
--- a/selfdrive/car/honda/interface.py
+++ b/selfdrive/car/honda/interface.py
@@ -33,7 +33,7 @@ class CarInterface(CarInterfaceBase):
ret.carName = "honda"
if candidate in HONDA_BOSCH:
- ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.hondaBoschHarness)]
+ ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.hondaBosch)]
ret.radarOffCan = True
# Disable the radar and let openpilot control longitudinal
diff --git a/selfdrive/car/hyundai/carcontroller.py b/selfdrive/car/hyundai/carcontroller.py
index 19ff38129e..a8b70fcf90 100644
--- a/selfdrive/car/hyundai/carcontroller.py
+++ b/selfdrive/car/hyundai/carcontroller.py
@@ -104,7 +104,8 @@ class CarController():
# 20 Hz LFA MFA message
if frame % 5 == 0 and self.car_fingerprint in [CAR.SONATA, CAR.PALISADE, CAR.IONIQ, CAR.KIA_NIRO_EV, CAR.KIA_NIRO_HEV_2021,
CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.KIA_CEED, CAR.KIA_SELTOS, CAR.KONA_EV,
- CAR.ELANTRA_2021, CAR.ELANTRA_HEV_2021, CAR.SONATA_HYBRID, CAR.KONA_HEV, CAR.SANTA_FE_2022, CAR.KIA_K5_2021, CAR.IONIQ_HEV_2022]:
+ CAR.ELANTRA_2021, CAR.ELANTRA_HEV_2021, CAR.SONATA_HYBRID, CAR.KONA_HEV, CAR.SANTA_FE_2022,
+ CAR.KIA_K5_2021, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022, CAR.GENESIS_G70_2020]:
can_sends.append(create_lfahda_mfc(self.packer, enabled))
# 5 Hz ACC options
diff --git a/selfdrive/car/hyundai/hyundaican.py b/selfdrive/car/hyundai/hyundaican.py
index dd43ec1a81..c8130fd725 100644
--- a/selfdrive/car/hyundai/hyundaican.py
+++ b/selfdrive/car/hyundai/hyundaican.py
@@ -17,8 +17,9 @@ def create_lkas11(packer, frame, car_fingerprint, apply_steer, steer_req,
values["CF_Lkas_MsgCount"] = frame % 0x10
if car_fingerprint in [CAR.SONATA, CAR.PALISADE, CAR.KIA_NIRO_EV, CAR.KIA_NIRO_HEV_2021, CAR.SANTA_FE,
- CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.KIA_SELTOS, CAR.ELANTRA_2021,
- CAR.ELANTRA_HEV_2021, CAR.SONATA_HYBRID, CAR.KONA_EV, CAR.KONA_HEV, CAR.SANTA_FE_2022, CAR.KIA_K5_2021, CAR.IONIQ_HEV_2022]:
+ CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.KIA_SELTOS, CAR.ELANTRA_2021, CAR.GENESIS_G70_2020,
+ CAR.ELANTRA_HEV_2021, CAR.SONATA_HYBRID, CAR.KONA_EV, CAR.KONA_HEV, CAR.SANTA_FE_2022,
+ CAR.KIA_K5_2021, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022]:
values["CF_Lkas_LdwsActivemode"] = int(left_lane) + (int(right_lane) << 1)
values["CF_Lkas_LdwsOpt_USM"] = 2
diff --git a/selfdrive/car/hyundai/interface.py b/selfdrive/car/hyundai/interface.py
index 48e2a4647c..57b313e534 100644
--- a/selfdrive/car/hyundai/interface.py
+++ b/selfdrive/car/hyundai/interface.py
@@ -3,7 +3,7 @@ from cereal import car
from panda import Panda
from common.params import Params
from selfdrive.config import Conversions as CV
-from selfdrive.car.hyundai.values import CAR, EV_CAR, HYBRID_CAR, Buttons, CarControllerParams
+from selfdrive.car.hyundai.values import CAR, EV_CAR, HYBRID_CAR, LEGACY_SAFETY_MODE_CAR, Buttons, CarControllerParams
from selfdrive.car.hyundai.radar_interface import RADAR_START_ADDR
from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config
from selfdrive.car.interfaces import CarInterfaceBase
@@ -26,7 +26,7 @@ class CarInterface(CarInterfaceBase):
ret.radarOffCan = RADAR_START_ADDR not in fingerprint[1]
# WARNING: disabling radar also disables AEB (and we show the same warning on the instrument cluster as if you manually disabled AEB)
- ret.openpilotLongitudinalControl = Params().get_bool("DisableRadar") and candidate in [CAR.SONATA, CAR.SONATA_HYBRID, CAR.PALISADE, CAR.SANTA_FE]
+ ret.openpilotLongitudinalControl = Params().get_bool("DisableRadar") and (candidate not in LEGACY_SAFETY_MODE_CAR)
ret.pcmCruise = not ret.openpilotLongitudinalControl
@@ -45,7 +45,7 @@ class CarInterface(CarInterfaceBase):
ret.longitudinalActuatorDelayUpperBound = 1.0 # s
- if candidate in [CAR.SANTA_FE, CAR.SANTA_FE_2022]:
+ if candidate in [CAR.SANTA_FE, CAR.SANTA_FE_2022, CAR.SANTA_FE_HEV_2022]:
ret.lateralTuning.pid.kf = 0.00005
ret.mass = 3982. * CV.LB_TO_KG + STD_CARGO_KG
ret.wheelbase = 2.766
@@ -232,6 +232,13 @@ class CarInterface(CarInterfaceBase):
ret.mass = 1640.0 + STD_CARGO_KG
ret.wheelbase = 2.84
ret.steerRatio = 13.56
+ elif candidate == CAR.GENESIS_G70_2020:
+ ret.lateralTuning.pid.kf = 0.
+ ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]]
+ ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.112], [0.004]]
+ ret.mass = 3673.0 * CV.LB_TO_KG + STD_CARGO_KG
+ ret.wheelbase = 2.83
+ ret.steerRatio = 12.9
elif candidate == CAR.GENESIS_G80:
ret.lateralTuning.pid.kf = 0.00005
ret.mass = 2060. + STD_CARGO_KG
@@ -247,10 +254,7 @@ class CarInterface(CarInterfaceBase):
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.16], [0.01]]
# these cars require a special panda safety mode due to missing counters and checksums in the messages
- if candidate in [CAR.HYUNDAI_GENESIS, CAR.IONIQ_EV_2020, CAR.IONIQ_EV_LTD, CAR.IONIQ_PHEV, CAR.IONIQ, CAR.KONA_EV, CAR.KIA_SORENTO,
- CAR.SONATA_LF, CAR.KIA_NIRO_EV, CAR.KIA_OPTIMA, CAR.VELOSTER, CAR.KIA_STINGER,
- CAR.GENESIS_G70, CAR.GENESIS_G80, CAR.KIA_CEED, CAR.ELANTRA, CAR.IONIQ_HEV_2022]:
- assert not ret.openpilotLongitudinalControl # Legacy safety mode doesn't support longitudinal
+ if candidate in LEGACY_SAFETY_MODE_CAR:
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.hyundaiLegacy)]
# set appropriate safety param for gas signal
diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py
index 66c8f03d8f..ddcd00ba0c 100644
--- a/selfdrive/car/hyundai/values.py
+++ b/selfdrive/car/hyundai/values.py
@@ -10,9 +10,10 @@ class CarControllerParams:
ACCEL_MAX = 2.0 # m/s
def __init__(self, CP):
- if CP.carFingerprint in [CAR.SONATA, CAR.PALISADE, CAR.SANTA_FE, CAR.VELOSTER, CAR.GENESIS_G70,
+ if CP.carFingerprint in [CAR.SONATA, CAR.PALISADE, CAR.SANTA_FE, CAR.VELOSTER, CAR.GENESIS_G70, CAR.GENESIS_G70_2020,
CAR.IONIQ_EV_2020, CAR.KIA_CEED, CAR.KIA_SELTOS, CAR.ELANTRA_2021,
- CAR.ELANTRA_HEV_2021, CAR.SONATA_HYBRID, CAR.KONA_HEV, CAR.SANTA_FE_2022, CAR.KIA_K5_2021, CAR.KONA_EV, CAR.KONA, CAR.IONIQ_HEV_2022]:
+ CAR.ELANTRA_HEV_2021, CAR.SONATA_HYBRID, CAR.KONA_HEV, CAR.SANTA_FE_2022,
+ CAR.KIA_K5_2021, CAR.KONA_EV, CAR.KONA, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022]:
self.STEER_MAX = 384
else:
self.STEER_MAX = 255
@@ -39,6 +40,7 @@ class CAR:
KONA_HEV = "HYUNDAI KONA HYBRID 2020"
SANTA_FE = "HYUNDAI SANTA FE 2019"
SANTA_FE_2022 = "HYUNDAI SANTA FE 2022"
+ SANTA_FE_HEV_2022 = "HYUNDAI SANTA FE HYBRID 2022"
SONATA = "HYUNDAI SONATA 2020"
SONATA_LF = "HYUNDAI SONATA 2019"
PALISADE = "HYUNDAI PALISADE 2020"
@@ -60,6 +62,7 @@ class CAR:
# Genesis
GENESIS_G70 = "GENESIS G70 2018"
+ GENESIS_G70_2020 = "GENESIS G70 2020"
GENESIS_G80 = "GENESIS G80 2017"
GENESIS_G90 = "GENESIS G90 2017"
@@ -469,6 +472,23 @@ FW_VERSIONS = {
b'\xf1\x87954A02N250\x00\x00\x00\x00\x00\xf1\x81T02730A1 \xf1\x00T02601BL T02730A1 VTMPT25XXX730NS2\xa6\x06\x88\xf7',
],
},
+ CAR.SANTA_FE_HEV_2022: {
+ (Ecu.fwdRadar, 0x7d0, None): [
+ b'\xf1\x8799110CL500\xf1\x00TMhe SCC FHCUP 1.00 1.00 99110-CL500 ',
+ ],
+ (Ecu.eps, 0x7d4, None): [
+ b'\xf1\x00TM MDPS C 1.00 1.02 56310-CLAC0 4TSHC102',
+ ],
+ (Ecu.fwdCamera, 0x7c4, None): [
+ b'\xf1\x00TMH MFC AT USA LHD 1.00 1.03 99211-S1500 210224',
+ ],
+ (Ecu.transmission, 0x7e1, None): [
+ b'\xf1\x87959102T250\x00\x00\x00\x00\x00\xf1\x81E14\x00\x00\x00\x00\x00\x00\x00\xf1\x00PSBG2333 E14\x00\x00\x00\x00\x00\x00\x00TTM2H16SA2\x80\xd7l\xb2',
+ ],
+ (Ecu.engine, 0x7e0, None): [
+ b'\xf1\x87391312MTC1',
+ ],
+ },
CAR.KIA_STINGER: {
(Ecu.fwdRadar, 0x7d0, None): [
b'\xf1\x00CK__ SCC F_CUP 1.00 1.01 96400-J5100 ',
@@ -611,6 +631,25 @@ FW_VERSIONS = {
(Ecu.fwdCamera, 0x7c4, None): [b'\xf1\x00IK MFC AT USA LHD 1.00 1.01 95740-G9000 170920', ],
(Ecu.transmission, 0x7e1, None): [b'\xf1\x87VDJLT17895112DN4\x88fVf\x99\x88\x88\x88\x87fVe\x88vhwwUFU\x97eFex\x99\xff\xb7\x82\xf1\x81E25\x00\x00\x00\x00\x00\x00\x00\xf1\x00bcsh8p54 E25\x00\x00\x00\x00\x00\x00\x00SIK0T33NB2\x11\x1am\xda', ],
},
+ CAR.GENESIS_G70_2020: {
+ (Ecu.eps, 0x7d4, None): [
+ b'\xf1\x00IK MDPS R 1.00 1.07 57700-G9220 4I2VL107',
+ ],
+ (Ecu.transmission, 0x7e1, None): [
+ b'\xf1\x87VCJLP18407832DN3\x88vXfvUVT\x97eFU\x87d7v\x88eVeveFU\x89\x98\x7f\xff\xb2\xb0\xf1\x81E25\x00\x00\x00'
+ b'\x00\x00\x00\x00\xf1\x00bcsh8p54 E25\x00\x00\x00\x00\x00\x00\x00SIK0T33NB4\xecE\xefL',
+ ],
+ (Ecu.fwdRadar, 0x7d0, None): [
+ b'\xf1\x00IK__ SCC F-CUP 1.00 1.02 96400-G9100 ',
+ b'\xf1\x00IK__ SCC F-CUP 1.00 1.02 96400-G9100 \xf1\xa01.02',
+ ],
+ (Ecu.fwdCamera, 0x7c4, None): [
+ b'\xf1\x00IK MFC AT USA LHD 1.00 1.01 95740-G9000 170920',
+ ],
+ (Ecu.engine, 0x7e0, None): [
+ b'\xf1\x81640J0051\x00\x00\x00\x00\x00\x00\x00\x00',
+ ],
+ },
CAR.KONA: {
(Ecu.fwdRadar, 0x7d0, None): [b'\xf1\x00OS__ SCC F-CUP 1.00 1.00 95655-J9200 ', ],
(Ecu.esp, 0x7d1, None): [b'\xf1\x816V5RAK00018.ELF\xf1\x00\x00\x00\x00\x00\x00\x00', ],
@@ -912,7 +951,7 @@ FW_VERSIONS = {
}
CHECKSUM = {
- "crc8": [CAR.SANTA_FE, CAR.SONATA, CAR.PALISADE, CAR.KIA_SELTOS, CAR.ELANTRA_2021, CAR.ELANTRA_HEV_2021, CAR.SONATA_HYBRID, CAR.SANTA_FE_2022, CAR.KIA_K5_2021],
+ "crc8": [CAR.SANTA_FE, CAR.SONATA, CAR.PALISADE, CAR.KIA_SELTOS, CAR.ELANTRA_2021, CAR.ELANTRA_HEV_2021, CAR.SONATA_HYBRID, CAR.SANTA_FE_2022, CAR.KIA_K5_2021, CAR.SANTA_FE_HEV_2022],
"6B": [CAR.KIA_SORENTO, CAR.HYUNDAI_GENESIS],
}
@@ -920,15 +959,18 @@ FEATURES = {
# which message has the gear
"use_cluster_gears": set([CAR.ELANTRA, CAR.ELANTRA_GT_I30, CAR.KONA]),
"use_tcu_gears": set([CAR.KIA_OPTIMA, CAR.SONATA_LF, CAR.VELOSTER]),
- "use_elect_gears": set([CAR.KIA_NIRO_EV, CAR.KIA_NIRO_HEV, CAR.KIA_NIRO_HEV_2021, CAR.KIA_OPTIMA_H, CAR.IONIQ_EV_LTD, CAR.KONA_EV, CAR.IONIQ, CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.ELANTRA_HEV_2021,CAR.SONATA_HYBRID, CAR.KONA_HEV, CAR.IONIQ_HEV_2022]),
+ "use_elect_gears": set([CAR.KIA_NIRO_EV, CAR.KIA_NIRO_HEV, CAR.KIA_NIRO_HEV_2021, CAR.KIA_OPTIMA_H, CAR.IONIQ_EV_LTD, CAR.KONA_EV, CAR.IONIQ, CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.ELANTRA_HEV_2021,CAR.SONATA_HYBRID, CAR.KONA_HEV, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022]),
# these cars use the FCA11 message for the AEB and FCW signals, all others use SCC12
- "use_fca": set([CAR.SONATA, CAR.SONATA_HYBRID, CAR.ELANTRA, CAR.ELANTRA_2021, CAR.ELANTRA_HEV_2021, CAR.ELANTRA_GT_I30, CAR.KIA_STINGER, CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.KONA_EV, CAR.KIA_FORTE, CAR.KIA_NIRO_EV, CAR.PALISADE, CAR.GENESIS_G70, CAR.KONA, CAR.SANTA_FE, CAR.KIA_SELTOS, CAR.KONA_HEV, CAR.SANTA_FE_2022, CAR.KIA_K5_2021, CAR.IONIQ_HEV_2022]),
+ "use_fca": set([CAR.SONATA, CAR.SONATA_HYBRID, CAR.ELANTRA, CAR.ELANTRA_2021, CAR.ELANTRA_HEV_2021, CAR.ELANTRA_GT_I30, CAR.KIA_STINGER, CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.KONA_EV, CAR.KIA_FORTE, CAR.KIA_NIRO_EV, CAR.PALISADE, CAR.GENESIS_G70, CAR.GENESIS_G70_2020, CAR.KONA, CAR.SANTA_FE, CAR.KIA_SELTOS, CAR.KONA_HEV, CAR.SANTA_FE_2022, CAR.KIA_K5_2021, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022]),
}
-HYBRID_CAR = set([CAR.IONIQ_PHEV, CAR.ELANTRA_HEV_2021, CAR.KIA_NIRO_HEV, CAR.KIA_NIRO_HEV_2021, CAR.SONATA_HYBRID, CAR.KONA_HEV, CAR.IONIQ, CAR.IONIQ_HEV_2022]) # these cars use a different gas signal
+HYBRID_CAR = set([CAR.IONIQ_PHEV, CAR.ELANTRA_HEV_2021, CAR.KIA_NIRO_HEV, CAR.KIA_NIRO_HEV_2021, CAR.SONATA_HYBRID, CAR.KONA_HEV, CAR.IONIQ, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022]) # these cars use a different gas signal
EV_CAR = set([CAR.IONIQ_EV_2020, CAR.IONIQ_EV_LTD, CAR.KONA_EV, CAR.KIA_NIRO_EV])
+# these cars require a special panda safety mode due to missing counters and checksums in the messages
+LEGACY_SAFETY_MODE_CAR = set([CAR.HYUNDAI_GENESIS, CAR.IONIQ_EV_2020, CAR.IONIQ_EV_LTD, CAR.IONIQ_PHEV, CAR.IONIQ, CAR.KONA_EV, CAR.KIA_SORENTO, CAR.SONATA_LF, CAR.KIA_NIRO_EV, CAR.KIA_OPTIMA, CAR.VELOSTER, CAR.KIA_STINGER, CAR.GENESIS_G70, CAR.GENESIS_G80, CAR.KIA_CEED, CAR.ELANTRA, CAR.IONIQ_HEV_2022])
+
# If 0x500 is present on bus 1 it probably has a Mando radar outputting radar points.
# If no points are outputted by default it might be possible to turn it on using selfdrive/debug/hyundai_enable_radar_points.py
DBC = {
@@ -937,6 +979,7 @@ DBC = {
CAR.ELANTRA_HEV_2021: dbc_dict('hyundai_kia_generic', None),
CAR.ELANTRA_GT_I30: dbc_dict('hyundai_kia_generic', None),
CAR.GENESIS_G70: dbc_dict('hyundai_kia_generic', None),
+ CAR.GENESIS_G70_2020: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar'),
CAR.GENESIS_G80: dbc_dict('hyundai_kia_generic', None),
CAR.GENESIS_G90: dbc_dict('hyundai_kia_generic', None),
CAR.HYUNDAI_GENESIS: dbc_dict('hyundai_kia_generic', None),
@@ -960,6 +1003,7 @@ DBC = {
CAR.KONA_HEV: dbc_dict('hyundai_kia_generic', None),
CAR.SANTA_FE: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar'),
CAR.SANTA_FE_2022: dbc_dict('hyundai_kia_generic', None),
+ CAR.SANTA_FE_HEV_2022: dbc_dict('hyundai_kia_generic', None),
CAR.SONATA: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar'),
CAR.SONATA_LF: dbc_dict('hyundai_kia_generic', None), # Has 0x5XX messages, but different format
CAR.PALISADE: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar'),
diff --git a/selfdrive/car/toyota/carcontroller.py b/selfdrive/car/toyota/carcontroller.py
index daf91a49d3..72cde0e537 100644
--- a/selfdrive/car/toyota/carcontroller.py
+++ b/selfdrive/car/toyota/carcontroller.py
@@ -1,6 +1,6 @@
from cereal import car
from common.numpy_fast import clip, interp
-from selfdrive.car import apply_toyota_steer_torque_limits, create_gas_command, make_can_msg
+from selfdrive.car import apply_toyota_steer_torque_limits, create_gas_interceptor_command, make_can_msg
from selfdrive.car.toyota.toyotacan import create_steer_command, create_ui_command, \
create_accel_command, create_acc_cancel_command, \
create_fcw_command, create_lta_steer_command
@@ -123,7 +123,7 @@ class CarController():
if frame % 2 == 0 and CS.CP.enableGasInterceptor:
# send exactly zero if gas cmd is zero. Interceptor will send the max between read value and gas cmd.
# This prevents unexpected pedal range rescaling
- can_sends.append(create_gas_command(self.packer, interceptor_gas_cmd, frame // 2))
+ can_sends.append(create_gas_interceptor_command(self.packer, interceptor_gas_cmd, frame // 2))
# ui mesg is at 100Hz but we send asap if:
# - there is something to display
diff --git a/selfdrive/common/version.h b/selfdrive/common/version.h
index aa786903c4..9f00fac4f9 100644
--- a/selfdrive/common/version.h
+++ b/selfdrive/common/version.h
@@ -1 +1 @@
-#define COMMA_VERSION "0.8.12"
+#define COMMA_VERSION "0.8.11"
diff --git a/selfdrive/debug/hyundai_enable_radar_points.py b/selfdrive/debug/hyundai_enable_radar_points.py
index 5d90dc778a..204d2480c3 100755
--- a/selfdrive/debug/hyundai_enable_radar_points.py
+++ b/selfdrive/debug/hyundai_enable_radar_points.py
@@ -1,11 +1,11 @@
#!/usr/bin/env python3
"""Some Hyundai radars can be reconfigured to output (debug) radar points on bus 1.
Reconfiguration is done over UDS by reading/writing to 0x0142 using the Read/Write Data By Identifier
-endpoints (0x22 & 0x2E). This script checks your radar firmware version against a list of known
+endpoints (0x22 & 0x2E). This script checks your radar firmware version against a list of known
firmware versions. If you want to try on a new radar make sure to note the default config value
in case it's different from the other radars and you need to revert the changes.
-After changing the config the car should not show any faults when openpilot is not running.
+After changing the config the car should not show any faults when openpilot is not running.
These config changes are persistent accross car reboots. You need to run this script again
to go back to the default values.
@@ -32,7 +32,7 @@ SUPPORTED_FW_VERSIONS = {
b"DNhe SCC FHCUP 1.00 1.02 99110-L5000 \x01#\x15# ": {
"default_config": b"\x00\x00\x00\x01\x00\x00",
"tracks_enabled": b"\x00\x00\x00\x01\x00\x01",
- },
+ },
# 2020 PALISADE
b"LX2_ SCC FHCUP 1.00 1.04 99110-S8100\x19\x05\x02\x16V ": {
"default_config": b"\x00\x00\x00\x01\x00\x00",
@@ -42,7 +42,13 @@ SUPPORTED_FW_VERSIONS = {
b"TM__ SCC F-CUP 1.00 1.03 99110-S2000\x19\x050\x13' ": {
"default_config": b"\x00\x00\x00\x01\x00\x00",
"tracks_enabled": b"\x00\x00\x00\x01\x00\x01",
- }
+ },
+
+ # 2020 GENESIS G70
+ b'IK__ SCC F-CUP 1.00 1.02 96400-G9100\x18\x07\x06\x17\x12 ': {
+ "default config": b"\x00\x00\x00\x01\x00\x00",
+ "tracks_enabled": b"\x00\x00\x00\x01\x00\x01",
+ },
}
if __name__ == "__main__":
diff --git a/selfdrive/locationd/models/live_kf.py b/selfdrive/locationd/models/live_kf.py
index c67644ff1a..75415a2845 100755
--- a/selfdrive/locationd/models/live_kf.py
+++ b/selfdrive/locationd/models/live_kf.py
@@ -57,8 +57,8 @@ class LiveKalman():
0, 0, 0])
# state covariance
- initial_P_diag = np.array([10**2, 10**2, 10**2,
- 0.01**2, 0.01**2, 0.01**2,
+ initial_P_diag = np.array([1e3**2, 1e3**2, 1e3**2,
+ 0.5**2, 0.5**2, 0.5**2,
10**2, 10**2, 10**2,
1**2, 1**2, 1**2,
1**2, 1**2, 1**2,
diff --git a/selfdrive/loggerd/tests/test_encoder.py b/selfdrive/loggerd/tests/test_encoder.py
index 992e8538b6..97c142652f 100755
--- a/selfdrive/loggerd/tests/test_encoder.py
+++ b/selfdrive/loggerd/tests/test_encoder.py
@@ -102,8 +102,7 @@ class TestEncoder(unittest.TestCase):
# TODO: this ffprobe call is really slow
# check frame count
- cmd = f"ffprobe -v error -count_frames -select_streams v:0 -show_entries stream=nb_read_frames \
- -of default=nokey=1:noprint_wrappers=1 {file_path}"
+ cmd = f"ffprobe -v error -select_streams v:0 -count_packets -show_entries stream=nb_read_packets -of csv=p=0 {file_path}"
if TICI:
cmd = "LD_LIBRARY_PATH=/usr/local/lib " + cmd
diff --git a/selfdrive/loggerd/tests/test_loggerd.py b/selfdrive/loggerd/tests/test_loggerd.py
index 76756c8724..7ee97f5118 100755
--- a/selfdrive/loggerd/tests/test_loggerd.py
+++ b/selfdrive/loggerd/tests/test_loggerd.py
@@ -117,15 +117,15 @@ class TestLoggerd(unittest.TestCase):
expected_files.add("ecamera.hevc")
# give camerad time to start
- time.sleep(5)
+ time.sleep(3)
for _ in range(5):
- num_segs = random.randint(1, 10)
- length = random.randint(2, 5)
+ num_segs = random.randint(2, 5)
+ length = random.randint(1, 3)
os.environ["LOGGERD_SEGMENT_LENGTH"] = str(length)
managed_processes["loggerd"].start()
- time.sleep((num_segs + 1) * length)
+ time.sleep(num_segs*length + 1)
managed_processes["loggerd"].stop()
route_path = str(self._get_latest_log_dir()).rsplit("--", 1)[0]
@@ -177,7 +177,9 @@ class TestLoggerd(unittest.TestCase):
# sleep enough for the first poll to time out
# TOOD: fix loggerd bug dropping the msgs from the first poll
managed_processes["loggerd"].start()
- time.sleep(2)
+ for s in services:
+ while not pm.all_readers_updated(s):
+ time.sleep(0.1)
sent_msgs = defaultdict(list)
for _ in range(random.randint(2, 10) * 100):
@@ -220,9 +222,11 @@ class TestLoggerd(unittest.TestCase):
pm = messaging.PubMaster(services)
# sleep enough for the first poll to time out
- # TOOD: fix loggerd bug dropping the msgs from the first poll
+ # TODO: fix loggerd bug dropping the msgs from the first poll
managed_processes["loggerd"].start()
- time.sleep(2)
+ for s in services:
+ while not pm.all_readers_updated(s):
+ time.sleep(0.1)
sent_msgs = defaultdict(list)
for _ in range(random.randint(2, 10) * 100):
@@ -233,9 +237,8 @@ class TestLoggerd(unittest.TestCase):
m = messaging.new_message(s, random.randint(2, 10))
pm.send(s, m)
sent_msgs[s].append(m)
- time.sleep(0.01)
- time.sleep(1)
+ time.sleep(2)
managed_processes["loggerd"].stop()
lr = list(LogReader(os.path.join(self._get_latest_log_dir(), "rlog.bz2")))
diff --git a/selfdrive/manager/test/test_manager.py b/selfdrive/manager/test/test_manager.py
index 588d72aa28..6acda36a22 100755
--- a/selfdrive/manager/test/test_manager.py
+++ b/selfdrive/manager/test/test_manager.py
@@ -5,7 +5,7 @@ import time
import unittest
import selfdrive.manager.manager as manager
-from selfdrive.hardware import EON
+from selfdrive.hardware import EON, TICI, HARDWARE
from selfdrive.manager.process import DaemonProcess
from selfdrive.manager.process_config import managed_processes
@@ -37,8 +37,8 @@ class TestManager(unittest.TestCase):
# ensure all processes exit cleanly
def test_clean_exit(self):
+ HARDWARE.set_power_save(False)
manager.manager_prepare()
-
for p in ALL_PROCESSES:
managed_processes[p].start()
@@ -49,7 +49,7 @@ class TestManager(unittest.TestCase):
self.assertTrue(state.running, f"{p} not running")
exit_code = managed_processes[p].stop(retry=False)
- if (p == 'ui') or (EON and p == 'logcatd'):
+ if (TICI and p in ['ui', 'navd']) or (EON and p == 'logcatd'):
# TODO: make Qt UI exit gracefully
continue
diff --git a/selfdrive/modeld/models/dmonitoring.cc b/selfdrive/modeld/models/dmonitoring.cc
index 719a9d8a07..9d87e320af 100644
--- a/selfdrive/modeld/models/dmonitoring.cc
+++ b/selfdrive/modeld/models/dmonitoring.cc
@@ -13,11 +13,30 @@
#define MODEL_HEIGHT 640
#define FULL_W 852 // should get these numbers from camerad
+template
+static inline T *get_buffer(std::vector &buf, const size_t size) {
+ if (buf.size() < size) buf.resize(size);
+ return buf.data();
+}
+
+static inline void init_yuv_buf(std::vector &buf, const int width, int height) {
+ uint8_t *y = get_buffer(buf, width * height * 3 / 2);
+ uint8_t *u = y + width * height;
+ uint8_t *v = u + (width / 2) * (height / 2);
+
+ // needed on comma two to make the padded border black
+ // equivalent to RGB(0,0,0) in YUV space
+ memset(y, 16, width * height);
+ memset(u, 128, (width / 2) * (height / 2));
+ memset(v, 128, (width / 2) * (height / 2));
+}
+
void dmonitoring_init(DMonitoringModelState* s) {
s->is_rhd = Params().getBool("IsRHD");
for (int x = 0; x < std::size(s->tensor); ++x) {
s->tensor[x] = (x - 128.f) * 0.0078125f;
}
+ init_yuv_buf(s->resized_buf, MODEL_WIDTH, MODEL_HEIGHT);
#ifdef USE_ONNX_MODEL
s->m = new ONNXModel("../../models/dmonitoring_model.onnx", &s->output[0], OUTPUT_SIZE, USE_DSP_RUNTIME);
@@ -26,12 +45,6 @@ void dmonitoring_init(DMonitoringModelState* s) {
#endif
}
-template
-static inline T *get_buffer(std::vector &buf, const size_t size) {
- if (buf.size() < size) buf.resize(size);
- return buf.data();
-}
-
static inline auto get_yuv_buf(std::vector &buf, const int width, int height) {
uint8_t *y = get_buffer(buf, width * height * 3 / 2);
uint8_t *u = y + width * height;
diff --git a/selfdrive/modeld/runners/runmodel.h b/selfdrive/modeld/runners/runmodel.h
index 0893a4acc6..948048f5d3 100644
--- a/selfdrive/modeld/runners/runmodel.h
+++ b/selfdrive/modeld/runners/runmodel.h
@@ -1,6 +1,7 @@
#pragma once
class RunModel {
public:
+ virtual ~RunModel() {}
virtual void addRecurrent(float *state, int state_size) {}
virtual void addDesire(float *state, int state_size) {}
virtual void addTrafficConvention(float *state, int state_size) {}
diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit
index 92ae208dd0..9021aaec7a 100644
--- a/selfdrive/test/process_replay/ref_commit
+++ b/selfdrive/test/process_replay/ref_commit
@@ -1 +1 @@
-848bc88a069b182d6f50698dd785ba360915e8dc
\ No newline at end of file
+567866c06976f8f95fa7d1670b51d8723e663ea1
\ No newline at end of file
diff --git a/selfdrive/test/test_models.py b/selfdrive/test/test_models.py
index faba823a0e..a55ad35a12 100755
--- a/selfdrive/test/test_models.py
+++ b/selfdrive/test/test_models.py
@@ -7,10 +7,10 @@ from collections import defaultdict, Counter
from parameterized import parameterized_class
from cereal import log, car
+from common.params import Params
from selfdrive.car.fingerprints import all_known_cars
from selfdrive.car.car_helpers import interfaces
-from selfdrive.car.honda.values import HONDA_BOSCH
-from selfdrive.car.honda.values import CAR as HONDA
+from selfdrive.car.honda.values import HONDA_BOSCH, CAR as HONDA
from selfdrive.car.chrysler.values import CAR as CHRYSLER
from selfdrive.car.hyundai.values import CAR as HYUNDAI
from selfdrive.test.test_routes import routes, non_tested_cars
@@ -60,6 +60,9 @@ class TestCarModel(unittest.TestCase):
if lr is None:
raise Exception("Route not found. Is it uploaded?")
+ params = Params()
+ params.clear_all()
+
can_msgs = []
fingerprint = {i: dict() for i in range(3)}
for msg in lr:
@@ -68,15 +71,26 @@ class TestCarModel(unittest.TestCase):
if m.src < 128:
fingerprint[m.src][m.address] = len(m.dat)
can_msgs.append(msg)
+ elif msg.which() == "carParams":
+ if msg.carParams.openpilotLongitudinalControl:
+ params.put_bool("DisableRadar", True)
+
cls.can_msgs = sorted(can_msgs, key=lambda msg: msg.logMonoTime)
- CarInterface, CarController, CarState = interfaces[cls.car_model]
+ cls.CarInterface, cls.CarController, cls.CarState = interfaces[cls.car_model]
- cls.CP = CarInterface.get_params(cls.car_model, fingerprint, [])
+ cls.CP = cls.CarInterface.get_params(cls.car_model, fingerprint, [])
assert cls.CP
- cls.CI = CarInterface(cls.CP, CarController, CarState)
- assert cls.CI
+ def setUp(self):
+ self.CI = self.CarInterface(self.CP, self.CarController, self.CarState)
+ assert self.CI
+
+ # TODO: check safetyModel is in release panda build
+ self.safety = libpandasafety_py.libpandasafety
+ set_status = self.safety.set_safety_hooks(self.CP.safetyConfigs[0].safetyModel.raw, self.CP.safetyConfigs[0].safetyParam)
+ self.assertEqual(0, set_status, f"failed to set safetyModel {self.CP.safetyConfigs[0].safetyModel}")
+ self.safety.init_tests()
def test_car_params(self):
if self.CP.dashcamOnly:
@@ -95,11 +109,6 @@ class TestCarModel(unittest.TestCase):
elif tuning == 'indi':
self.assertTrue(len(self.CP.lateralTuning.indi.outerLoopGainV))
- # TODO: check safetyModel is in release panda build
- safety = libpandasafety_py.libpandasafety
- set_status = safety.set_safety_hooks(self.CP.safetyConfigs[0].safetyModel.raw, self.CP.safetyConfigs[0].safetyParam)
- self.assertEqual(0, set_status, f"failed to set safetyModel {self.CP.safetyConfigs[0].safetyModel}")
-
def test_car_interface(self):
# TODO: also check for checkusm and counter violations from can parser
can_invalid_cnt = 0
@@ -132,30 +141,25 @@ class TestCarModel(unittest.TestCase):
if self.CP.dashcamOnly:
self.skipTest("no need to check panda safety for dashcamOnly")
- safety = libpandasafety_py.libpandasafety
- set_status = safety.set_safety_hooks(self.CP.safetyConfigs[0].safetyModel.raw, self.CP.safetyConfigs[0].safetyParam)
- self.assertEqual(0, set_status)
-
failed_addrs = Counter()
for can in self.can_msgs:
for msg in can.can:
if msg.src >= 128:
continue
to_send = package_can_msg([msg.address, 0, msg.dat, msg.src])
- if not safety.safety_rx_hook(to_send):
+ if self.safety.safety_rx_hook(to_send) != 1:
failed_addrs[hex(msg.address)] += 1
self.assertFalse(len(failed_addrs), f"panda safety RX check failed: {failed_addrs}")
def test_panda_safety_carstate(self):
+ """
+ Assert that panda safety matches openpilot's carState
+ """
if self.CP.dashcamOnly:
self.skipTest("no need to check panda safety for dashcamOnly")
if self.car_model in ignore_carstate_check:
self.skipTest("see comments in test_models.py")
- safety = libpandasafety_py.libpandasafety
- set_status = safety.set_safety_hooks(self.CP.safetyConfigs[0].safetyModel.raw, self.CP.safetyConfigs[0].safetyParam)
- self.assertEqual(0, set_status)
-
checks = defaultdict(lambda: 0)
CC = car.CarControl.new_message()
for can in self.can_msgs:
@@ -163,14 +167,20 @@ class TestCarModel(unittest.TestCase):
if msg.src >= 128:
continue
to_send = package_can_msg([msg.address, 0, msg.dat, msg.src])
- safety.safety_rx_hook(to_send)
+ ret = self.safety.safety_rx_hook(to_send)
+ self.assertEqual(1, ret, f"safety rx failed ({ret=}): {to_send}")
CS = self.CI.update(CC, (can.as_builder().to_bytes(),))
# TODO: check steering state
# check that openpilot and panda safety agree on the car's state
- checks['gasPressed'] += CS.gasPressed != safety.get_gas_pressed_prev()
- checks['brakePressed'] += CS.brakePressed != safety.get_brake_pressed_prev()
- checks['controlsAllowed'] += not CS.cruiseState.enabled and safety.get_controls_allowed()
+ checks['gasPressed'] += CS.gasPressed != self.safety.get_gas_pressed_prev()
+ checks['brakePressed'] += CS.brakePressed != self.safety.get_brake_pressed_prev()
+ if self.CP.pcmCruise:
+ checks['controlsAllowed'] += not CS.cruiseState.enabled and self.safety.get_controls_allowed()
+
+ # TODO: extend this to all cars
+ if self.CP.carName == "honda":
+ checks['mainOn'] += CS.cruiseState.available != self.safety.get_acc_main_on()
# TODO: reduce tolerance to 0
failed_checks = {k: v for k, v in checks.items() if v > 25}
diff --git a/selfdrive/test/test_routes.py b/selfdrive/test/test_routes.py
index 7465c8c6fd..5344f8fd75 100755
--- a/selfdrive/test/test_routes.py
+++ b/selfdrive/test/test_routes.py
@@ -71,6 +71,7 @@ routes = [
TestRoute("6b301bf83f10aa90|2020-11-22--16-45-07", HYUNDAI.GENESIS_G80),
TestRoute("38bfd238edecbcd7|2018-08-29--22-02-15", HYUNDAI.SANTA_FE),
TestRoute("bf43d9df2b660eb0|2021-09-23--14-16-37", HYUNDAI.SANTA_FE_2022),
+ TestRoute("37398f32561a23ad|2021-11-18--00-11-35", HYUNDAI.SANTA_FE_HEV_2022),
TestRoute("e0e98335f3ebc58f|2021-03-07--16-38-29", HYUNDAI.KIA_CEED),
TestRoute("7653b2bce7bcfdaa|2020-03-04--15-34-32", HYUNDAI.KIA_OPTIMA),
TestRoute("c75a59efa0ecd502|2021-03-11--20-52-55", HYUNDAI.KIA_SELTOS),
@@ -97,6 +98,7 @@ routes = [
TestRoute("82e9cdd3f43bf83e|2021-05-15--02-42-51", HYUNDAI.ELANTRA_2021),
TestRoute("715ac05b594e9c59|2021-06-20--16-21-07", HYUNDAI.ELANTRA_HEV_2021),
TestRoute("7120aa90bbc3add7|2021-08-02--07-12-31", HYUNDAI.SONATA_HYBRID),
+ TestRoute("715ac05b594e9c59|2021-10-27--23-24-56", HYUNDAI.GENESIS_G70_2020),
TestRoute("00c829b1b7613dea|2021-06-24--09-10-10", TOYOTA.ALPHARD_TSS2),
TestRoute("000cf3730200c71c|2021-05-24--10-42-05", TOYOTA.AVALON),
diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc
index a7916171ef..7caa29c428 100644
--- a/selfdrive/ui/qt/offroad/settings.cc
+++ b/selfdrive/ui/qt/offroad/settings.cc
@@ -25,69 +25,88 @@
#include "selfdrive/ui/qt/util.h"
#include "selfdrive/ui/qt/qt_window.h"
-TogglesPanel::TogglesPanel(QWidget *parent) : ListWidget(parent) {
- auto params = Params();
- addItem(new ParamControl("OpenpilotEnabledToggle",
- "Enable openpilot",
- "Use the openpilot system for adaptive cruise control and lane keep driver assistance. Your attention is required at all times to use this feature. Changing this setting takes effect when the car is powered off.",
- "../assets/offroad/icon_openpilot.png",
- this));
- addItem(new ParamControl("IsLdwEnabled",
- "Enable Lane Departure Warnings",
- "Receive alerts to steer back into the lane when your vehicle drifts over a detected lane line without a turn signal activated while driving over 31mph (50kph).",
- "../assets/offroad/icon_warning.png",
- this));
- addItem(new ParamControl("IsRHD",
- "Enable Right-Hand Drive",
- "Allow openpilot to obey left-hand traffic conventions and perform driver monitoring on right driver seat.",
- "../assets/offroad/icon_openpilot_mirrored.png",
- this));
- addItem(new ParamControl("IsMetric",
- "Use Metric System",
- "Display speed in km/h instead of mph.",
- "../assets/offroad/icon_metric.png",
- this));
- addItem(new ParamControl("CommunityFeaturesToggle",
- "Enable Community Features",
- "Use features, such as community supported hardware, from the open source community that are not maintained or supported by comma.ai and have not been confirmed to meet the standard safety model. Be extra cautious when using these features",
- "../assets/offroad/icon_shell.png",
- this));
-
- addItem(new ParamControl("UploadRaw",
- "Upload Raw Logs",
- "Upload full logs and full resolution video by default while on Wi-Fi. If not enabled, individual logs can be marked for upload at useradmin.comma.ai.",
- "../assets/offroad/icon_network.png",
- this));
-
- ParamControl *record_toggle = new ParamControl("RecordFront",
- "Record and Upload Driver Camera",
- "Upload data from the driver facing camera and help improve the driver monitoring algorithm.",
- "../assets/offroad/icon_monitoring.png",
- this);
- addItem(record_toggle);
- addItem(new ParamControl("EndToEndToggle",
- "\U0001f96c Disable use of lanelines (Alpha) \U0001f96c",
- "In this mode openpilot will ignore lanelines and just drive how it thinks a human would.",
- "../assets/offroad/icon_road.png",
- this));
+TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) {
+ // param, title, desc, icon
+ std::vector> toggles{
+ {
+ "OpenpilotEnabledToggle",
+ "Enable openpilot",
+ "Use the openpilot system for adaptive cruise control and lane keep driver assistance. Your attention is required at all times to use this feature. Changing this setting takes effect when the car is powered off.",
+ "../assets/offroad/icon_openpilot.png",
+ },
+ {
+ "IsLdwEnabled",
+ "Enable Lane Departure Warnings",
+ "Receive alerts to steer back into the lane when your vehicle drifts over a detected lane line without a turn signal activated while driving over 31mph (50kph).",
+ "../assets/offroad/icon_warning.png",
+ },
+ {
+ "IsRHD",
+ "Enable Right-Hand Drive",
+ "Allow openpilot to obey left-hand traffic conventions and perform driver monitoring on right driver seat.",
+ "../assets/offroad/icon_openpilot_mirrored.png",
+ },
+ {
+ "IsMetric",
+ "Use Metric System",
+ "Display speed in km/h instead of mph.",
+ "../assets/offroad/icon_metric.png",
+ },
+ {
+ "CommunityFeaturesToggle",
+ "Enable Community Features",
+ "Use features, such as community supported hardware, from the open source community that are not maintained or supported by comma.ai and have not been confirmed to meet the standard safety model. Be extra cautious when using these features",
+ "../assets/offroad/icon_shell.png",
+ },
+ {
+ "UploadRaw",
+ "Upload Raw Logs",
+ "Upload full logs and full resolution video by default while on Wi-Fi. If not enabled, individual logs can be marked for upload at useradmin.comma.ai.",
+ "../assets/offroad/icon_network.png",
+ },
+ {
+ "RecordFront",
+ "Record and Upload Driver Camera",
+ "Upload data from the driver facing camera and help improve the driver monitoring algorithm.",
+ "../assets/offroad/icon_monitoring.png",
+ },
+ {
+ "EndToEndToggle",
+ "\U0001f96c Disable use of lanelines (Alpha) \U0001f96c",
+ "In this mode openpilot will ignore lanelines and just drive how it thinks a human would.",
+ "../assets/offroad/icon_road.png",
+ },
#ifdef ENABLE_MAPS
- addItem(new ParamControl("NavSettingTime24h",
- "Show ETA in 24h format",
- "Use 24h format instead of am/pm",
- "../assets/offroad/icon_metric.png",
- this));
+ {
+ "NavSettingTime24h",
+ "Show ETA in 24h format",
+ "Use 24h format instead of am/pm",
+ "../assets/offroad/icon_metric.png",
+ },
#endif
- if (params.getBool("DisableRadar_Allow")) {
- addItem(new ParamControl("DisableRadar",
- "openpilot Longitudinal Control",
- "openpilot will disable the car's radar and will take over control of gas and brakes. Warning: this disables AEB!",
- "../assets/offroad/icon_speed_limit.png",
- this));
+ };
+
+ Params params;
+
+ if (params.getBool("DisableRadar_Allow")) {
+ toggles.push_back({
+ "DisableRadar",
+ "openpilot Longitudinal Control",
+ "openpilot will disable the car's radar and will take over control of gas and brakes. Warning: this disables AEB!",
+ "../assets/offroad/icon_speed_limit.png",
+ });
}
- bool record_lock = params.getBool("RecordFrontLock");
- record_toggle->setEnabled(!record_lock);
+ for (auto &[param, title, desc, icon] : toggles) {
+ auto toggle = new ParamControl(param, title, desc, icon, this);
+ bool locked = params.getBool((param + "Lock").toStdString());
+ toggle->setEnabled(!locked);
+ if (!locked) {
+ connect(parent, &SettingsWindow::offroadTransition, toggle, &ParamControl::setEnabled);
+ }
+ addItem(toggle);
+ }
}
DevicePanel::DevicePanel(QWidget* parent) : ListWidget(parent) {
@@ -123,8 +142,8 @@ DevicePanel::DevicePanel(QWidget* parent) : ListWidget(parent) {
double pitch = calib.getRpyCalib()[1] * (180 / M_PI);
double yaw = calib.getRpyCalib()[2] * (180 / M_PI);
desc += QString(" Your device is pointed %1° %2 and %3° %4.")
- .arg(QString::number(std::abs(pitch), 'g', 1), pitch > 0 ? "up" : "down",
- QString::number(std::abs(yaw), 'g', 1), yaw > 0 ? "right" : "left");
+ .arg(QString::number(std::abs(pitch), 'g', 1), pitch > 0 ? "up" : "down",
+ QString::number(std::abs(yaw), 'g', 1), yaw > 0 ? "right" : "left");
}
} catch (kj::Exception) {
qInfo() << "invalid CalibrationParams";
@@ -358,7 +377,7 @@ SettingsWindow::SettingsWindow(QWidget *parent) : QFrame(parent) {
const int padding = panels.size() > 3 ? 25 : 35;
- nav_btns = new QButtonGroup();
+ nav_btns = new QButtonGroup(this);
for (auto &[name, panel] : panels) {
QPushButton *btn = new QPushButton(name);
btn->setCheckable(true);
diff --git a/selfdrive/ui/qt/offroad/settings.h b/selfdrive/ui/qt/offroad/settings.h
index f922463366..a2c7e01d8f 100644
--- a/selfdrive/ui/qt/offroad/settings.h
+++ b/selfdrive/ui/qt/offroad/settings.h
@@ -12,6 +12,28 @@
#include "selfdrive/ui/qt/widgets/controls.h"
// ********** settings window + top-level panels **********
+class SettingsWindow : public QFrame {
+ Q_OBJECT
+
+public:
+ explicit SettingsWindow(QWidget *parent = 0);
+
+protected:
+ void hideEvent(QHideEvent *event) override;
+ void showEvent(QShowEvent *event) override;
+
+signals:
+ void closeSettings();
+ void offroadTransition(bool offroad);
+ void reviewTrainingGuide();
+ void showDriverView();
+
+private:
+ QPushButton *sidebar_alert_widget;
+ QWidget *sidebar_widget;
+ QButtonGroup *nav_btns;
+ QStackedWidget *panel_widget;
+};
class DevicePanel : public ListWidget {
Q_OBJECT
@@ -25,7 +47,7 @@ signals:
class TogglesPanel : public ListWidget {
Q_OBJECT
public:
- explicit TogglesPanel(QWidget *parent = nullptr);
+ explicit TogglesPanel(SettingsWindow *parent);
};
class SoftwarePanel : public ListWidget {
@@ -47,26 +69,3 @@ private:
Params params;
QFileSystemWatcher *fs_watch;
};
-
-class SettingsWindow : public QFrame {
- Q_OBJECT
-
-public:
- explicit SettingsWindow(QWidget *parent = 0);
-
-protected:
- void hideEvent(QHideEvent *event) override;
- void showEvent(QShowEvent *event) override;
-
-signals:
- void closeSettings();
- void offroadTransition(bool offroad);
- void reviewTrainingGuide();
- void showDriverView();
-
-private:
- QPushButton *sidebar_alert_widget;
- QWidget *sidebar_widget;
- QButtonGroup *nav_btns;
- QStackedWidget *panel_widget;
-};
diff --git a/selfdrive/ui/qt/offroad/wifiManager.cc b/selfdrive/ui/qt/offroad/wifiManager.cc
index e798949a89..0970173929 100644
--- a/selfdrive/ui/qt/offroad/wifiManager.cc
+++ b/selfdrive/ui/qt/offroad/wifiManager.cc
@@ -9,7 +9,7 @@
#include "selfdrive/ui/qt/util.h"
template
-T get_response(QDBusMessage response) {
+T get_response(const QDBusMessage &response) {
QVariant first = response.arguments().at(0);
QDBusVariant dbvFirst = first.value();
QVariant vFirst = dbvFirst.variant();
diff --git a/selfdrive/ui/replay/logreader.cc b/selfdrive/ui/replay/logreader.cc
index 10be8a19c7..7e7a943f88 100644
--- a/selfdrive/ui/replay/logreader.cc
+++ b/selfdrive/ui/replay/logreader.cc
@@ -36,13 +36,12 @@ LogReader::LogReader(bool local_cache, int chunk_size, int retries, size_t memor
}
LogReader::~LogReader() {
-#ifdef HAS_MEMORY_RESOURCE
- delete mbr_;
- ::operator delete(pool_buffer_);
-#else
for (Event *e : events) {
delete e;
}
+#ifdef HAS_MEMORY_RESOURCE
+ delete mbr_;
+ ::operator delete(pool_buffer_);
#endif
}
diff --git a/selfdrive/ui/replay/tests/test_replay.cc b/selfdrive/ui/replay/tests/test_replay.cc
index 4b776e7403..f2a2171c82 100644
--- a/selfdrive/ui/replay/tests/test_replay.cc
+++ b/selfdrive/ui/replay/tests/test_replay.cc
@@ -57,7 +57,7 @@ TEST_CASE("FileReader") {
}
TEST_CASE("Segment") {
- auto flags = GENERATE(REPLAY_FLAG_NONE, REPLAY_FLAG_QCAMERA);
+ auto flags = GENERATE(REPLAY_FLAG_DCAM | REPLAY_FLAG_ECAM, REPLAY_FLAG_QCAMERA);
Route demo_route(DEMO_ROUTE);
REQUIRE(demo_route.load());
REQUIRE(demo_route.segments().size() == 11);
@@ -68,21 +68,32 @@ TEST_CASE("Segment") {
REQUIRE(segment.isLoaded() == true);
REQUIRE(segment.log != nullptr);
REQUIRE(segment.frames[RoadCam] != nullptr);
- REQUIRE(segment.frames[DriverCam] == nullptr);
- REQUIRE(segment.frames[WideRoadCam] == nullptr);
+ if (flags & REPLAY_FLAG_DCAM) {
+ REQUIRE(segment.frames[DriverCam] != nullptr);
+ }
+ if (flags & REPLAY_FLAG_ECAM) {
+ REQUIRE(segment.frames[WideRoadCam] != nullptr);
+ }
- // LogReader & FrameReader
+ // test LogReader & FrameReader
REQUIRE(segment.log->events.size() > 0);
REQUIRE(std::is_sorted(segment.log->events.begin(), segment.log->events.end(), Event::lessThan()));
- auto &fr = segment.frames[RoadCam];
- REQUIRE(fr->getFrameCount() == 1200);
- std::unique_ptr rgb_buf = std::make_unique(fr->getRGBSize());
- std::unique_ptr yuv_buf = std::make_unique(fr->getYUVSize());
- // sequence get 50 frames
- for (int i = 0; i < 50; ++i) {
- REQUIRE(fr->get(i, rgb_buf.get(), yuv_buf.get()));
+ for (auto cam : ALL_CAMERAS) {
+ auto &fr = segment.frames[cam];
+ if (!fr) continue;
+
+ if (cam == RoadCam || cam == WideRoadCam) {
+ REQUIRE(fr->getFrameCount() == 1200);
+ }
+ std::unique_ptr rgb_buf = std::make_unique(fr->getRGBSize());
+ std::unique_ptr yuv_buf = std::make_unique(fr->getYUVSize());
+ // sequence get 50 frames
+ for (int i = 0; i < 50; ++i) {
+ REQUIRE(fr->get(i, rgb_buf.get(), yuv_buf.get()));
+ }
}
+
loop.quit();
});
loop.exec();
@@ -134,7 +145,7 @@ void TestReplay::test_seek() {
stream_thread_ = new QThread(this);
QEventLoop loop;
std::thread thread = std::thread([&]() {
- for (int i = 0; i < 100; ++i) {
+ for (int i = 0; i < 50; ++i) {
testSeekTo(random_int(0, 3 * 60));
}
loop.quit();
diff --git a/selfdrive/ui/ui.h b/selfdrive/ui/ui.h
index 46cbae63fb..fab68d3818 100644
--- a/selfdrive/ui/ui.h
+++ b/selfdrive/ui/ui.h
@@ -188,7 +188,7 @@ private:
// auto brightness
const float accel_samples = 5*UI_FREQ;
- bool awake;
+ bool awake = false;
int awake_timeout = 0;
float accel_prev = 0;
float gyro_prev = 0;
diff --git a/tools/README.md b/tools/README.md
index 22e83c8b2f..81bff69e1d 100644
--- a/tools/README.md
+++ b/tools/README.md
@@ -1,6 +1,11 @@
openpilot tools
============
+CTF
+============
+
+Learn about the openpilot ecosystem and tools by playing our [CTF](/tools/CTF.md).
+
SSH
============
diff --git a/update_requirements.sh b/update_requirements.sh
index 50c4c8204f..be7d53f98b 100755
--- a/update_requirements.sh
+++ b/update_requirements.sh
@@ -33,7 +33,7 @@ pip install pipenv==2021.5.29
echo "pip packages install ..."
if [ -d "./xx" ]; then
- PIPENV_PIPFILE=./xx/Pipfile pipenv install --system --dev --deploy
+ export PIPENV_PIPFILE=./xx/Pipfile
pipenv install --system --dev --deploy
RUN=""
else