From c2d13e529219422b942cbedcc3a496e2c936dd9b Mon Sep 17 00:00:00 2001 From: royjr Date: Thu, 30 Mar 2023 17:27:05 -0400 Subject: [PATCH 01/24] ui: experimental -> alpha OP long toggle (#27725) * swap locations * remove experimental from toggle name * revert * alpha * revert that --------- Co-authored-by: Adeeb Shihadeh --- selfdrive/ui/qt/offroad/settings.cc | 8 ++++---- selfdrive/ui/translations/main_de.ts | 24 ++++++++++++------------ selfdrive/ui/translations/main_ja.ts | 24 ++++++++++++------------ selfdrive/ui/translations/main_ko.ts | 24 ++++++++++++------------ selfdrive/ui/translations/main_pt-BR.ts | 24 ++++++++++++------------ selfdrive/ui/translations/main_zh-CHS.ts | 24 ++++++++++++------------ selfdrive/ui/translations/main_zh-CHT.ts | 24 ++++++++++++------------ 7 files changed, 76 insertions(+), 76 deletions(-) diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index c22484167c..fd14ed15e2 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -43,10 +43,10 @@ TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) { }, { "ExperimentalLongitudinalEnabled", - tr("Experimental openpilot Longitudinal Control"), - QString("%1
%2") - .arg(tr("WARNING: openpilot longitudinal control is experimental for this car and will disable Automatic Emergency Braking (AEB).")) - .arg(tr("On this car, openpilot defaults to the car's built-in ACC instead of openpilot's longitudinal control. Enable this to switch to openpilot longitudinal control. Enabling Experimental mode is recommended when using experimental openpilot longitudinal control.")), + tr("openpilot Longitudinal Control (Alpha)"), + QString("%1

%2") + .arg(tr("WARNING: openpilot longitudinal control is in alpha for this car and will disable Automatic Emergency Braking (AEB).")) + .arg(tr("On this car, openpilot defaults to the car's built-in ACC instead of openpilot's longitudinal control. Enable this to switch to openpilot longitudinal control. Enabling Experimental mode is recommended when enabling openpilot longitudinal control alpha.")), "../assets/offroad/icon_speed_limit.png", }, { diff --git a/selfdrive/ui/translations/main_de.ts b/selfdrive/ui/translations/main_de.ts index 5f3511d3cc..2e4e833e07 100644 --- a/selfdrive/ui/translations/main_de.ts +++ b/selfdrive/ui/translations/main_de.ts @@ -992,22 +992,10 @@ This may take up to a minute. Experimental Mode Experimenteller Modus - - Experimental openpilot Longitudinal Control - Experimenteller Openpilot Tempomat - - - WARNING: openpilot longitudinal control is experimental for this car and will disable Automatic Emergency Braking (AEB). - WARNUNG: Der Openpilot Tempomat ist für dieses Auto experimentell und deaktiviert den Notbremsassistenten. - Disengage on Accelerator Pedal Bei Gasbetätigung ausschalten - - On this car, openpilot defaults to the car's built-in ACC instead of openpilot's longitudinal control. Enable this to switch to openpilot longitudinal control. Enabling Experimental mode is recommended when using experimental openpilot longitudinal control. - Bei diesem auto wird standardmäßig der im Auto eingebaute adaptive Tempomat anstelle des Openpilot Tempomats benutzt. Aktiviere diesen Schalter, um zum Openpilot Tempomaten zu wechseln. Es ist empfohlen den Experimentellen Modus bei Nutzung des Openpilot Tempomats zu aktivieren. - openpilot defaults to driving in <b>chill mode</b>. Experimental mode enables <b>alpha-level features</b> that aren't ready for chill mode. Experimental features are listed below: Openpilot fährt standardmäßig im <b>entspannten Modus</b>. Der Experimentelle Modus aktiviert<b>Alpha-level Funktionen</b>, die noch nicht für den entspannten Modus bereit sind. Die experimentellen Funktionen sind die Folgenden: @@ -1044,6 +1032,18 @@ This may take up to a minute. Enable experimental longitudinal control to allow Experimental mode. Aktiviere den experimentellen Openpilot Tempomaten für experimentelle Funktionen. + + openpilot Longitudinal Control (Alpha) + + + + WARNING: openpilot longitudinal control is in alpha for this car and will disable Automatic Emergency Braking (AEB). + + + + On this car, openpilot defaults to the car's built-in ACC instead of openpilot's longitudinal control. Enable this to switch to openpilot longitudinal control. Enabling Experimental mode is recommended when enabling openpilot longitudinal control alpha. + + Updater diff --git a/selfdrive/ui/translations/main_ja.ts b/selfdrive/ui/translations/main_ja.ts index 1e0223606b..06435d3b41 100644 --- a/selfdrive/ui/translations/main_ja.ts +++ b/selfdrive/ui/translations/main_ja.ts @@ -962,10 +962,6 @@ This may take up to a minute. Upload data from the driver facing camera and help improve the driver monitoring algorithm. 車内カメラの映像をアップロードし、ドライバー監視システムのアルゴリズムの向上に役立てます。 - - Experimental openpilot Longitudinal Control - 実験段階のopenpilotによるアクセル制御 - Disengage on Accelerator Pedal アクセルを踏むと openpilot を中断 @@ -994,14 +990,6 @@ This may take up to a minute. Experimental Mode 実験モード - - WARNING: openpilot longitudinal control is experimental for this car and will disable Automatic Emergency Braking (AEB). - 警告: この車種でのopenpilotによるアクセル制御は実験段階であり、衝突被害軽減ブレーキ(AEB)を無効化します。 - - - On this car, openpilot defaults to the car's built-in ACC instead of openpilot's longitudinal control. Enable this to switch to openpilot longitudinal control. Enabling Experimental mode is recommended when using experimental openpilot longitudinal control. - openpilotはこの車の場合、車に内蔵されているACCを標準で利用します。この機能を有効にすることで実験段階のopenpilotによるアクセル制御を利用できます。実験モードと合わせて利用することをお勧めします。 - openpilot defaults to driving in <b>chill mode</b>. Experimental mode enables <b>alpha-level features</b> that aren't ready for chill mode. Experimental features are listed below: openpilotは標準ではゆっくりとくつろげる運転を提供します。この実験モードを有効にすると、以下のくつろげる段階ではない開発中の機能を利用する事ができます。 @@ -1038,6 +1026,18 @@ This may take up to a minute. Enable experimental longitudinal control to allow Experimental mode. 実験段階のopenpilotによるアクセル制御を有効にしてください。 + + openpilot Longitudinal Control (Alpha) + + + + WARNING: openpilot longitudinal control is in alpha for this car and will disable Automatic Emergency Braking (AEB). + + + + On this car, openpilot defaults to the car's built-in ACC instead of openpilot's longitudinal control. Enable this to switch to openpilot longitudinal control. Enabling Experimental mode is recommended when enabling openpilot longitudinal control alpha. + + Updater diff --git a/selfdrive/ui/translations/main_ko.ts b/selfdrive/ui/translations/main_ko.ts index be11f2efde..675798e377 100644 --- a/selfdrive/ui/translations/main_ko.ts +++ b/selfdrive/ui/translations/main_ko.ts @@ -963,10 +963,6 @@ This may take up to a minute. Upload data from the driver facing camera and help improve the driver monitoring algorithm. 운전자 카메라에서 데이터를 업로드하고 운전자 모니터링 알고리즘을 개선합니다. - - Experimental openpilot Longitudinal Control - openpilot 롱컨트롤 (실험적) - Disengage on Accelerator Pedal 가속페달 조작시 해제 @@ -995,14 +991,6 @@ This may take up to a minute. Experimental Mode 실험적 모드 - - WARNING: openpilot longitudinal control is experimental for this car and will disable Automatic Emergency Braking (AEB). - 경고: openpilot 롱컨트롤은 실험적인 기능으로 차량의 자동긴급제동(AEB)를 비활성화합니다. - - - On this car, openpilot defaults to the car's built-in ACC instead of openpilot's longitudinal control. Enable this to switch to openpilot longitudinal control. Enabling Experimental mode is recommended when using experimental openpilot longitudinal control. - 이 차량은 openpilot 롱컨트롤 대신 차량의 내장 ACC로 기본 설정됩니다. openpilot 롱컨트롤을 사용하려면 이 옵션을 활성화하세요. 실험적 openpilot 롱컨트롤을 사용하는 경우 실험적 모드를 활성화 하세요. - openpilot defaults to driving in <b>chill mode</b>. Experimental mode enables <b>alpha-level features</b> that aren't ready for chill mode. Experimental features are listed below: openpilot은 기본적으로 <b>안정적 모드</b>로 주행합니다. 실험적 모드는 안정적 모드에 준비되지 않은 <b>알파 수준 기능</b>을 활성화 합니다. 실험적 모드의 특징은 아래에 나열되어 있습니다 @@ -1039,6 +1027,18 @@ This may take up to a minute. Enable experimental longitudinal control to allow Experimental mode. 실험적 롱컨트롤을 사용하려면 실험적 모드를 활성화 하세요. + + openpilot Longitudinal Control (Alpha) + + + + WARNING: openpilot longitudinal control is in alpha for this car and will disable Automatic Emergency Braking (AEB). + + + + On this car, openpilot defaults to the car's built-in ACC instead of openpilot's longitudinal control. Enable this to switch to openpilot longitudinal control. Enabling Experimental mode is recommended when enabling openpilot longitudinal control alpha. + + Updater diff --git a/selfdrive/ui/translations/main_pt-BR.ts b/selfdrive/ui/translations/main_pt-BR.ts index 8dc3a9830d..f1caaa9068 100644 --- a/selfdrive/ui/translations/main_pt-BR.ts +++ b/selfdrive/ui/translations/main_pt-BR.ts @@ -967,10 +967,6 @@ Isso pode levar até um minuto. Upload data from the driver facing camera and help improve the driver monitoring algorithm. Upload dados da câmera voltada para o motorista e ajude a melhorar o algoritmo de monitoramentor. - - Experimental openpilot Longitudinal Control - Controle longitudinal experimental openpilot - Disengage on Accelerator Pedal Desacionar com Pedal do Acelerador @@ -999,14 +995,6 @@ Isso pode levar até um minuto. Experimental Mode Modo Experimental - - WARNING: openpilot longitudinal control is experimental for this car and will disable Automatic Emergency Braking (AEB). - ATENÇÃO: o controle longitudinal do openpilot é experimental para este carro e desativará a Frenagem Automática de Emergência (AEB). - - - On this car, openpilot defaults to the car's built-in ACC instead of openpilot's longitudinal control. Enable this to switch to openpilot longitudinal control. Enabling Experimental mode is recommended when using experimental openpilot longitudinal control. - Neste carro o penpilot por padrão utiliza o ACC nativo do veículo ao invés de controlar longitudinalmente. Ative isto para mudar para o controle longitudinal do openpilot. Ativar o Modo Experimental é recomendado quando em uso do controle longitudinal experimental do openpilot. - openpilot defaults to driving in <b>chill mode</b>. Experimental mode enables <b>alpha-level features</b> that aren't ready for chill mode. Experimental features are listed below: openpilot por padrão funciona em <b>modo chill</b>. modo Experimental ativa <b>recursos de nível-alfa</b> que não estão prontos para o modo chill. Recursos experimentais estão listados abaixo: @@ -1043,6 +1031,18 @@ Isso pode levar até um minuto. Enable experimental longitudinal control to allow Experimental mode. Ative o controle longitudinal experimental para permitir o modo Experimental. + + openpilot Longitudinal Control (Alpha) + + + + WARNING: openpilot longitudinal control is in alpha for this car and will disable Automatic Emergency Braking (AEB). + + + + On this car, openpilot defaults to the car's built-in ACC instead of openpilot's longitudinal control. Enable this to switch to openpilot longitudinal control. Enabling Experimental mode is recommended when enabling openpilot longitudinal control alpha. + + Updater diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts index cfc055ac98..7cacc72f1c 100644 --- a/selfdrive/ui/translations/main_zh-CHS.ts +++ b/selfdrive/ui/translations/main_zh-CHS.ts @@ -960,10 +960,6 @@ This may take up to a minute. Upload data from the driver facing camera and help improve the driver monitoring algorithm. 上传驾驶员摄像头的数据,帮助改进驾驶员监控算法。 - - Experimental openpilot Longitudinal Control - 试验性的openpilot纵向控制 - Disengage on Accelerator Pedal 踩油门时取消控制 @@ -992,14 +988,6 @@ This may take up to a minute. Experimental Mode 测试模式 - - WARNING: openpilot longitudinal control is experimental for this car and will disable Automatic Emergency Braking (AEB). - 警告: 此车辆的openpilot纵向控制是试验性功能,且将禁用AEB自动刹车功能。 - - - On this car, openpilot defaults to the car's built-in ACC instead of openpilot's longitudinal control. Enable this to switch to openpilot longitudinal control. Enabling Experimental mode is recommended when using experimental openpilot longitudinal control. - 针对此车辆,openpilot默认使用车辆自带的ACC,而非openpilot的纵向控制。启用此选项将切换到openpilot纵向控制。当使用试验性的openpilot纵向控制时,建议同时启用试验模式。 - openpilot defaults to driving in <b>chill mode</b>. Experimental mode enables <b>alpha-level features</b> that aren't ready for chill mode. Experimental features are listed below: openpilot 默认 <b>轻松模式</b>驾驶车辆。试验模式启用一些轻松模式之外的 <b>试验性功能</b>。试验性功能包括: @@ -1036,6 +1024,18 @@ This may take up to a minute. Enable experimental longitudinal control to allow Experimental mode. 启用试验性的纵向控制,以便允许使用试验模式。 + + openpilot Longitudinal Control (Alpha) + + + + WARNING: openpilot longitudinal control is in alpha for this car and will disable Automatic Emergency Braking (AEB). + + + + On this car, openpilot defaults to the car's built-in ACC instead of openpilot's longitudinal control. Enable this to switch to openpilot longitudinal control. Enabling Experimental mode is recommended when enabling openpilot longitudinal control alpha. + + Updater diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts index 83db0b7301..e559ca88a6 100644 --- a/selfdrive/ui/translations/main_zh-CHT.ts +++ b/selfdrive/ui/translations/main_zh-CHT.ts @@ -962,10 +962,6 @@ This may take up to a minute. Upload data from the driver facing camera and help improve the driver monitoring algorithm. 上傳駕駛監控的錄像來協助我們提升駕駛監控的準確率。 - - Experimental openpilot Longitudinal Control - 使用 openpilot 縱向控制(實驗) - Disengage on Accelerator Pedal 油門取消控車 @@ -994,14 +990,6 @@ This may take up to a minute. Experimental Mode 實驗模式 - - WARNING: openpilot longitudinal control is experimental for this car and will disable Automatic Emergency Braking (AEB). - 警告:openpilot 縱向控制在這輛車上仍屬實驗性質,啟用後會喪失自動緊急煞車 (AEB) 功能。 - - - On this car, openpilot defaults to the car's built-in ACC instead of openpilot's longitudinal control. Enable this to switch to openpilot longitudinal control. Enabling Experimental mode is recommended when using experimental openpilot longitudinal control. - 在本車輛中,openpilot預設將使用原車內建的ACC系統,而非openpilot縱向控制。開啟此開關來啟用openpilot縱向控制,使用此選項時建議一併啟用實驗模式。 - openpilot defaults to driving in <b>chill mode</b>. Experimental mode enables <b>alpha-level features</b> that aren't ready for chill mode. Experimental features are listed below: openpilot 預設以 <b>輕鬆模式</b> 駕駛。 實驗模式啟用了尚未準備好進入輕鬆模式的 <b>alpha 級功能</b>。實驗功能如下: @@ -1038,6 +1026,18 @@ This may take up to a minute. Enable experimental longitudinal control to allow Experimental mode. 啟用實驗性縱向控制以使用實驗模式。 + + openpilot Longitudinal Control (Alpha) + + + + WARNING: openpilot longitudinal control is in alpha for this car and will disable Automatic Emergency Braking (AEB). + + + + On this car, openpilot defaults to the car's built-in ACC instead of openpilot's longitudinal control. Enable this to switch to openpilot longitudinal control. Enabling Experimental mode is recommended when enabling openpilot longitudinal control alpha. + + Updater From 2c13bfac7498adb17d526c5472228f4bf4b09780 Mon Sep 17 00:00:00 2001 From: Lee Jong Mun <43285072+crwusiz@users.noreply.github.com> Date: Fri, 31 Mar 2023 09:34:39 +0900 Subject: [PATCH 02/24] Multilang: kor translation update (#27756) --- selfdrive/ui/translations/main_ko.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/selfdrive/ui/translations/main_ko.ts b/selfdrive/ui/translations/main_ko.ts index 675798e377..b55a56a061 100644 --- a/selfdrive/ui/translations/main_ko.ts +++ b/selfdrive/ui/translations/main_ko.ts @@ -1029,15 +1029,15 @@ This may take up to a minute. openpilot Longitudinal Control (Alpha) - + openpilot 롱컨트롤 (알파) WARNING: openpilot longitudinal control is in alpha for this car and will disable Automatic Emergency Braking (AEB). - + 경고: openpilot 롱컨트롤은 알파 기능으로 차량의 자동긴급제동(AEB)를 비활성화합니다. On this car, openpilot defaults to the car's built-in ACC instead of openpilot's longitudinal control. Enable this to switch to openpilot longitudinal control. Enabling Experimental mode is recommended when enabling openpilot longitudinal control alpha. - + 이 차량은 openpilot 롱컨트롤 대신 차량의 내장 ACC로 기본 설정됩니다. openpilot 롱컨트롤으로 전환하려면 이 기능을 활성화하세요. openpilot 롱컨트롤 알파를 활성화하는경우 실험적 모드 활성화를 권장합니다. From 08be9eed0820ecedcec63a92f32bc5b1077713a2 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Thu, 30 Mar 2023 19:36:03 -0700 Subject: [PATCH 03/24] sensord: remove hardcoded irq from test (#27759) * sensord: remove hardcoded irq from test * fix linter --------- Co-authored-by: Comma Device --- system/sensord/tests/test_sensord.py | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/system/sensord/tests/test_sensord.py b/system/sensord/tests/test_sensord.py index c6fe33129a..21b67271d6 100755 --- a/system/sensord/tests/test_sensord.py +++ b/system/sensord/tests/test_sensord.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 import os +import glob import time import unittest import numpy as np @@ -7,7 +8,7 @@ from collections import namedtuple, defaultdict import cereal.messaging as messaging from cereal import log -from system.hardware import TICI, HARDWARE +from system.hardware import TICI from selfdrive.manager.process_config import managed_processes BMX = { @@ -70,7 +71,6 @@ ALL_SENSORS = { } } -LSM_IRQ = 336 def get_irq_count(irq: int): with open(f"/sys/kernel/irq/{irq}/per_cpu_count") as f: @@ -101,9 +101,6 @@ class TestSensord(unittest.TestCase): if not TICI: raise unittest.SkipTest - # make sure gpiochip0 is readable - HARDWARE.initialize_hardware() - # enable LSM self test os.environ["LSM_SELF_TEST"] = "1" @@ -114,6 +111,15 @@ class TestSensord(unittest.TestCase): time.sleep(3) cls.sample_secs = 10 cls.events = read_sensor_events(cls.sample_secs) + + # determine sensord's irq + cls.sensord_irq = None + for fn in glob.glob('/sys/kernel/irq/*/actions'): + with open(fn) as f: + if "sensord" in f.read(): + cls.sensord_irq = int(fn.split('/')[-2]) + break + assert cls.sensord_irq is not None finally: # teardown won't run if this doesn't succeed managed_processes["sensord"].stop() @@ -121,8 +127,6 @@ class TestSensord(unittest.TestCase): @classmethod def tearDownClass(cls): managed_processes["sensord"].stop() - if "LSM_SELF_TEST" in os.environ: - del os.environ['LSM_SELF_TEST'] def tearDown(self): managed_processes["sensord"].stop() @@ -250,9 +254,9 @@ class TestSensord(unittest.TestCase): time.sleep(3) # read /proc/interrupts to verify interrupts are received - state_one = get_irq_count(LSM_IRQ) + state_one = get_irq_count(self.sensord_irq) time.sleep(1) - state_two = get_irq_count(LSM_IRQ) + state_two = get_irq_count(self.sensord_irq) error_msg = f"no interrupts received after sensord start!\n{state_one} {state_two}" assert state_one != state_two, error_msg @@ -261,9 +265,9 @@ class TestSensord(unittest.TestCase): time.sleep(1) # read /proc/interrupts to verify no more interrupts are received - state_one = get_irq_count(LSM_IRQ) + state_one = get_irq_count(self.sensord_irq) time.sleep(1) - state_two = get_irq_count(LSM_IRQ) + state_two = get_irq_count(self.sensord_irq) assert state_one == state_two, "Interrupts received after sensord stop!" From 909ad5e285cdd8dfe68f76e0ae67eda20fcf782d Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 31 Mar 2023 00:10:41 -0700 Subject: [PATCH 04/24] bump panda (#27761) --- panda | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda b/panda index 12b9b65985..7933635b54 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 12b9b65985edf7207a1dfd48de0b714192e6e55d +Subproject commit 7933635b54b68eda3f8a906d5e2c3ca30dbed279 From 652fc0e90419d505bec80bac12617676a3591854 Mon Sep 17 00:00:00 2001 From: routine88 Date: Thu, 30 Mar 2023 21:34:35 -1000 Subject: [PATCH 05/24] Added fingerprint for 2023 Hyundai Elantra Hybrid (#27758) * Update values.py * Update values.py * Update selfdrive/car/hyundai/values.py * Update selfdrive/car/hyundai/values.py --------- Co-authored-by: Shane Smiskol --- selfdrive/car/hyundai/values.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index dcc3a0fc0f..7fcc5b9140 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -1485,25 +1485,29 @@ FW_VERSIONS = { b'\xf1\x00CN7HMFC AT USA LHD 1.00 1.05 99210-AA000 210930', b'\xf1\000CN7HMFC AT USA LHD 1.00 1.03 99210-AA000 200819', b'\xf1\x00CN7HMFC AT USA LHD 1.00 1.07 99210-AA000 220426', + b'\xf1\x00CN7HMFC AT USA LHD 1.00 1.08 99210-AA000 220728', ], (Ecu.fwdRadar, 0x7d0, None): [ - b'\xf1\000CNhe SCC FHCUP 1.00 1.01 99110-BY000 ', + b'\xf1\x00CNhe SCC FHCUP 1.00 1.01 99110-BY000 ', b'\xf1\x8799110BY000\xf1\x00CNhe SCC FHCUP 1.00 1.01 99110-BY000 ', ], (Ecu.eps, 0x7d4, None): [ b'\xf1\x00CN7 MDPS C 1.00 1.03 56310BY0500 4CNHC103', b'\xf1\x8756310/BY050\xf1\x00CN7 MDPS C 1.00 1.03 56310/BY050 4CNHC103', b'\xf1\x8756310/BY050\xf1\000CN7 MDPS C 1.00 1.02 56310/BY050 4CNHC102', + b'\xf1\x00CN7 MDPS C 1.00 1.04 56310BY050\x00 4CNHC104', ], (Ecu.transmission, 0x7e1, None): [ b'\xf1\0006U3L0_C2\000\0006U3K3051\000\000HCN0G16NS0\xb9?A\xaa', b'\xf1\0006U3L0_C2\000\0006U3K3051\000\000HCN0G16NS0\000\000\000\000', b'\xf1\x816U3K3051\000\000\xf1\0006U3L0_C2\000\0006U3K3051\000\000HCN0G16NS0\xb9?A\xaa', b'\xf1\x816U3K3051\x00\x00\xf1\x006U3L0_C2\x00\x006U3K3051\x00\x00HCN0G16NS0\x00\x00\x00\x00', + b'\xf1\x006U3L0_C2\x00\x006U3K9051\x00\x00HCN0G16NS1\x00\x00\x00\x00', ], (Ecu.engine, 0x7e0, None): [ b'\xf1\x816H6G5051\x00\x00\x00\x00\x00\x00\x00\x00', b'\xf1\x816H6G6051\x00\x00\x00\x00\x00\x00\x00\x00', + b'\xf1\x816H6G8051\x00\x00\x00\x00\x00\x00\x00\x00', ] }, CAR.KONA_HEV: { From 852f67dc8818abe011aa7ad4f2e425fc1d9f81e8 Mon Sep 17 00:00:00 2001 From: AlexandreSato <66435071+AlexandreSato@users.noreply.github.com> Date: Fri, 31 Mar 2023 15:29:08 -0300 Subject: [PATCH 06/24] Multilang: update pt-BR translations (#27767) --- selfdrive/ui/translations/main_pt-BR.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/selfdrive/ui/translations/main_pt-BR.ts b/selfdrive/ui/translations/main_pt-BR.ts index f1caaa9068..34fbc8abf0 100644 --- a/selfdrive/ui/translations/main_pt-BR.ts +++ b/selfdrive/ui/translations/main_pt-BR.ts @@ -1033,15 +1033,15 @@ Isso pode levar até um minuto. openpilot Longitudinal Control (Alpha) - + Controle Longitudinal openpilot (Alpha) WARNING: openpilot longitudinal control is in alpha for this car and will disable Automatic Emergency Braking (AEB). - + AVISO: o controle longitudinal openpilot está em alfa para este carro e desativará a Frenagem Automática de Emergência (AEB). On this car, openpilot defaults to the car's built-in ACC instead of openpilot's longitudinal control. Enable this to switch to openpilot longitudinal control. Enabling Experimental mode is recommended when enabling openpilot longitudinal control alpha. - + Neste carro, o openpilot tem como padrão o ACC embutido do carro em vez do controle longitudinal do openpilot. Habilite isso para alternar para o controle longitudinal openpilot. Recomenda-se ativar o modo Experimental ao ativar o alfa de controle longitudinal openpilot. From ced90c163ed292f41a450810035ae32438fe81fc Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Fri, 31 Mar 2023 20:32:27 +0200 Subject: [PATCH 07/24] cabana: show min and max values in chart tooltip (#27744) --- tools/cabana/chartswidget.cc | 20 +++++++++++++------- tools/cabana/chartswidget.h | 2 ++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/tools/cabana/chartswidget.cc b/tools/cabana/chartswidget.cc index 09ee9f1cff..2c9a01b752 100644 --- a/tools/cabana/chartswidget.cc +++ b/tools/cabana/chartswidget.cc @@ -606,16 +606,20 @@ void ChartView::updateAxisY() { auto first = std::lower_bound(s.vals.begin(), s.vals.end(), axis_x->min(), xLessThan); auto last = std::lower_bound(first, s.vals.end(), axis_x->max(), xLessThan); + s.min = std::numeric_limits::max(); + s.max = std::numeric_limits::lowest(); if (can->liveStreaming()) { for (auto it = first; it != last; ++it) { - if (it->y() < min) min = it->y(); - if (it->y() > max) max = it->y(); + if (it->y() < s.min) s.min = it->y(); + if (it->y() > s.max) s.max = it->y(); } } else { auto [min_y, max_y] = s.segment_tree.minmax(std::distance(s.vals.begin(), first), std::distance(s.vals.begin(), last)); - min = std::min(min, min_y); - max = std::max(max, max_y); + s.min = min_y; + s.max = max_y; } + min = std::min(min, s.min); + max = std::max(max, s.max); } if (min == std::numeric_limits::max()) min = 0; if (max == std::numeric_limits::lowest()) max = 0; @@ -764,16 +768,18 @@ void ChartView::mouseMoveEvent(QMouseEvent *ev) { s.track_pt = chart()->mapToPosition(*it); x = std::max(x, s.track_pt.x()); } - text_list.push_back(QString("%2: %3") + text_list.push_back(QString("%2: %3 (%4 - %5)") .arg(s.series->color().name(), s.sig->name, - s.track_pt.isNull() ? "--" : QString::number(value))); + s.track_pt.isNull() ? "--" : QString::number(value), + QString::number(s.min), QString::number(s.max))); + } if (x < 0) { x = ev->pos().x(); } text_list.push_front(QString::number(chart()->mapToValue({x, 0}).x(), 'f', 3)); QPointF tooltip_pt(x + 12, plot_area.top() - 20); - QToolTip::showText(mapToGlobal(tooltip_pt.toPoint()), text_list.join("
"), this, plot_area.toRect()); + QToolTip::showText(mapToGlobal(tooltip_pt.toPoint()), "

" + text_list.join("
"), this, plot_area.toRect()); scene()->invalidate({}, QGraphicsScene::ForegroundLayer); } else { QToolTip::hideText(); diff --git a/tools/cabana/chartswidget.h b/tools/cabana/chartswidget.h index 7f757f0211..592e063163 100644 --- a/tools/cabana/chartswidget.h +++ b/tools/cabana/chartswidget.h @@ -46,6 +46,8 @@ public: uint64_t last_value_mono_time = 0; QPointF track_pt{}; SegmentTree segment_tree; + double min = 0; + double max = 0; }; signals: From 63f888fa3a31dcf06ff2a2f098e2930c45050ea6 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Sat, 1 Apr 2023 02:44:21 +0800 Subject: [PATCH 08/24] cabana: fix sparkline overlapping issue (#27766) * fix sparkline overlapping issue * cleanup --- tools/cabana/detailwidget.cc | 1 - tools/cabana/detailwidget.h | 1 - tools/cabana/signalview.cc | 48 +++++++++++++++++++++++++----------- tools/cabana/signalview.h | 3 ++- 4 files changed, 35 insertions(+), 18 deletions(-) diff --git a/tools/cabana/detailwidget.cc b/tools/cabana/detailwidget.cc index ab723fa0e2..543946b19a 100644 --- a/tools/cabana/detailwidget.cc +++ b/tools/cabana/detailwidget.cc @@ -48,7 +48,6 @@ DetailWidget::DetailWidget(ChartsWidget *charts, QWidget *parent) : charts(chart // msg widget splitter = new QSplitter(Qt::Vertical, this); - splitter->setAutoFillBackground(true); splitter->addWidget(binary_view = new BinaryView(this)); splitter->addWidget(signal_view = new SignalView(charts, this)); binary_view->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); diff --git a/tools/cabana/detailwidget.h b/tools/cabana/detailwidget.h index 2794d41b99..b7cfed376c 100644 --- a/tools/cabana/detailwidget.h +++ b/tools/cabana/detailwidget.h @@ -30,7 +30,6 @@ public: DetailWidget(ChartsWidget *charts, QWidget *parent); void setMessage(const MessageId &message_id); void refresh(); - QSize minimumSizeHint() const override { return binary_view->minimumSizeHint(); } private: void showTabBarContextMenu(const QPoint &pt); diff --git a/tools/cabana/signalview.cc b/tools/cabana/signalview.cc index e3c19faa13..4eb1456b1e 100644 --- a/tools/cabana/signalview.cc +++ b/tools/cabana/signalview.cc @@ -168,6 +168,8 @@ QVariant SignalModel::data(const QModelIndex &index, int role) const { if (item->type == Item::Signed) return item->sig->is_signed ? Qt::Checked : Qt::Unchecked; } else if (role == Qt::DecorationRole && index.column() == 0 && item->type == Item::ExtraInfo) { return utils::icon(item->parent->extra_expanded ? "chevron-compact-down" : "chevron-compact-up"); + } else if (role == Qt::ToolTipRole && item->type == Item::Sig) { + return (index.column() == 0) ? item->sig->name : item->sig_val; } } return {}; @@ -323,11 +325,25 @@ QSize SignalItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QMo int spacing = option.widget->style()->pixelMetric(QStyle::PM_TreeViewIndentation) + color_label_width + 8; it = width_cache.insert(text, option.fontMetrics.width(text) + spacing); } - width = std::min(width, it.value()); + width = std::min(option.widget->size().width() / 3.0, it.value()); } return {width, QApplication::fontMetrics().height()}; } +bool SignalItemDelegate::helpEvent(QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &index) { + if (event && event->type() == QEvent::ToolTip && index.isValid()) { + auto item = (SignalModel::Item *)index.internalPointer(); + if (item->type == SignalModel::Item::Sig && index.column() == 1) { + QRect rc = option.rect.adjusted(0, 0, -option.rect.width() * 0.4, 0); + if (rc.contains(event->pos())) { + event->setAccepted(false); + return false; + } + } + } + return QStyledItemDelegate::helpEvent(event, view, option, index); +} + void SignalItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { int h_margin = option.widget->style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; int v_margin = option.widget->style()->pixelMetric(QStyle::PM_FocusFrameVMargin); @@ -363,25 +379,30 @@ void SignalItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op painter->fillRect(option.rect, option.palette.highlight()); } - drawSparkline(painter, option, index); + int adjust_right = ((SignalView *)parent())->tree->indexWidget(index)->sizeHint().width() + 2 * h_margin; + QRect r = option.rect.adjusted(h_margin, v_margin, -adjust_right, -v_margin); // draw signal value - int right_offset = ((SignalView *)parent())->tree->indexWidget(index)->sizeHint().width() + 2 * h_margin; - QRect rc = option.rect.adjusted(0, 0, -right_offset, 0); - auto text = painter->fontMetrics().elidedText(index.data(Qt::DisplayRole).toString(), Qt::ElideRight, rc.width()); + QRect value_rect = r.adjusted(r.width() * 0.6 + h_margin, 0, 0, 0); + auto text = painter->fontMetrics().elidedText(index.data(Qt::DisplayRole).toString(), Qt::ElideRight, value_rect.width()); painter->setPen(option.palette.color(option.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text)); - painter->drawText(rc, Qt::AlignRight | Qt::AlignVCenter, text); + painter->drawText(value_rect, Qt::AlignRight | Qt::AlignVCenter, text); + + QRect sparkline_rect = r.adjusted(0, 0, -r.width() * 0.4 - h_margin, 0); + drawSparkline(painter, sparkline_rect, index); } else { QStyledItemDelegate::paint(painter, option, index); } } -void SignalItemDelegate::drawSparkline(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { +void SignalItemDelegate::drawSparkline(QPainter *painter, const QRect &rect, const QModelIndex &index) const { static std::vector points; const auto &msg_id = ((SignalView *)parent())->msg_id; const auto &msgs = can->events().at(msg_id); + uint64_t ts = (can->lastMessage(msg_id).ts + can->routeStartTime()) * 1e9; auto first = std::lower_bound(msgs.cbegin(), msgs.cend(), CanEvent{.mono_time = (uint64_t)std::max(ts - settings.sparkline_range * 1e9, 0)}); auto last = std::upper_bound(first, msgs.cend(), CanEvent{.mono_time = ts}); + if (first != last) { double min = std::numeric_limits::max(); double max = std::numeric_limits::lowest(); @@ -398,16 +419,13 @@ void SignalItemDelegate::drawSparkline(QPainter *painter, const QStyleOptionView max += 1; } - int h_margin = option.widget->style()->pixelMetric(QStyle::PM_FocusFrameHMargin); - int v_margin = std::max(option.widget->style()->pixelMetric(QStyle::PM_FocusFrameVMargin) + 2, 4); - const double xscale = (option.rect.width() - 175.0 - h_margin * 2) / settings.sparkline_range; - const double yscale = (option.rect.height() - v_margin * 2) / (max - min); - const int left = option.rect.left(); - const int top = option.rect.top() + v_margin; + const double xscale = rect.width() / (double)settings.sparkline_range; + const double yscale = rect.height() / (max - min); for (auto &pt : points) { - pt.rx() = left + pt.x() * xscale; - pt.ry() = top + std::abs(pt.y() - max) * yscale; + pt.rx() = rect.left() + pt.x() * xscale; + pt.ry() = rect.top() + std::abs(pt.y() - max) * yscale; } + painter->setPen(getColor(sig)); painter->drawPolyline(points.data(), points.size()); if ((points.back().x() - points.front().x()) / points.size() > 10) { diff --git a/tools/cabana/signalview.h b/tools/cabana/signalview.h index 50ba4e06b8..8bc9477888 100644 --- a/tools/cabana/signalview.h +++ b/tools/cabana/signalview.h @@ -83,7 +83,8 @@ public: void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override; - void drawSparkline(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + bool helpEvent(QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &index) override; + void drawSparkline(QPainter *painter, const QRect &rect, const QModelIndex &index) const; QValidator *name_validator, *double_validator; QFont small_font; const int color_label_width = 18; From a1d01220e787b160f2be153e02c172c938a491e5 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 31 Mar 2023 12:15:59 -0700 Subject: [PATCH 09/24] bump panda (#27768) --- panda | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda b/panda index 7933635b54..09fee3e7ea 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 7933635b54b68eda3f8a906d5e2c3ca30dbed279 +Subproject commit 09fee3e7ead96a6a9613430c81bb2d3e095aa0fe From 15a4b60ee6e78d16646db1535c5840cc4fd56932 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Sat, 1 Apr 2023 03:48:31 +0800 Subject: [PATCH 10/24] cabana: display signal value in all charts on mouse hover (#27749) * display all values * cleanup * cleanup * emit hoverd if tip is visible --- tools/cabana/chartswidget.cc | 119 +++++++++++++++++++++++++---------- tools/cabana/chartswidget.h | 12 ++++ 2 files changed, 97 insertions(+), 34 deletions(-) diff --git a/tools/cabana/chartswidget.cc b/tools/cabana/chartswidget.cc index 2c9a01b752..4ae83c05d7 100644 --- a/tools/cabana/chartswidget.cc +++ b/tools/cabana/chartswidget.cc @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -157,6 +158,12 @@ void ChartsWidget::zoomUndo() { } } +void ChartsWidget::showValueTip(double sec) { + for (auto c : charts) { + sec >= 0 ? c->showTip(sec) : c->hideTip(); + } +} + void ChartsWidget::updateState() { if (charts.isEmpty()) return; @@ -226,6 +233,7 @@ ChartView *ChartsWidget::createChart() { QObject::connect(chart, &ChartView::seriesRemoved, this, &ChartsWidget::seriesChanged); QObject::connect(chart, &ChartView::seriesAdded, this, &ChartsWidget::seriesChanged); QObject::connect(chart, &ChartView::axisYLabelWidthChanged, &align_timer, qOverload<>(&QTimer::start)); + QObject::connect(chart, &ChartView::hovered, this, &ChartsWidget::showValueTip); charts.push_back(chart); updateLayout(); return chart; @@ -346,7 +354,7 @@ bool ChartsWidget::event(QEvent *event) { // ChartView -ChartView::ChartView(QWidget *parent) : QChartView(nullptr, parent) { +ChartView::ChartView(QWidget *parent) : tip_label(this), QChartView(nullptr, parent) { series_type = (SeriesType)settings.chart_series_type; QChart *chart = new QChart(); chart->setBackgroundVisible(false); @@ -542,7 +550,11 @@ void ChartView::updateSeriesPoints() { double pixels_per_point = (chart()->mapToPosition(right_pt).x() - chart()->mapToPosition(*begin).x()) / num_points; if (series_type == SeriesType::Scatter) { - ((QScatterSeries *)s.series)->setMarkerSize(std::clamp(pixels_per_point / 2.0, 2.0, 8.0) * devicePixelRatioF()); + qreal size = std::clamp(pixels_per_point / 2.0, 2.0, 8.0); + if (s.series->useOpenGL()) { + size *= devicePixelRatioF(); + } + ((QScatterSeries *)s.series)->setMarkerSize(size); } else { s.series->setPointsVisible(pixels_per_point > 20); } @@ -672,8 +684,9 @@ qreal ChartView::niceNumber(qreal x, bool ceiling) { } void ChartView::leaveEvent(QEvent *event) { - clearTrackPoints(); - scene()->update(); + if (tip_label.isVisible()) { + emit hovered(-1); + } QChartView::leaveEvent(event); } @@ -745,44 +758,17 @@ void ChartView::mouseMoveEvent(QMouseEvent *ev) { if (plot_area.contains(ev->pos())) { can->seekTo(std::clamp(chart()->mapToValue(ev->pos()).x(), 0., can->totalSeconds())); } - return; } auto rubber = findChild(); bool is_zooming = rubber && rubber->isVisible(); - is_scrubbing = false; clearTrackPoints(); if (!is_zooming && plot_area.contains(ev->pos())) { - QStringList text_list; const double sec = chart()->mapToValue(ev->pos()).x(); - qreal x = -1; - for (auto &s : sigs) { - if (!s.series->isVisible()) continue; - - // use reverse iterator to find last item <= sec. - double value = 0; - auto it = std::lower_bound(s.vals.rbegin(), s.vals.rend(), sec, [](auto &p, double x) { return p.x() > x; }); - if (it != s.vals.rend() && it->x() >= axis_x->min()) { - value = it->y(); - s.track_pt = chart()->mapToPosition(*it); - x = std::max(x, s.track_pt.x()); - } - text_list.push_back(QString("%2: %3 (%4 - %5)") - .arg(s.series->color().name(), s.sig->name, - s.track_pt.isNull() ? "--" : QString::number(value), - QString::number(s.min), QString::number(s.max))); - - } - if (x < 0) { - x = ev->pos().x(); - } - text_list.push_front(QString::number(chart()->mapToValue({x, 0}).x(), 'f', 3)); - QPointF tooltip_pt(x + 12, plot_area.top() - 20); - QToolTip::showText(mapToGlobal(tooltip_pt.toPoint()), "

" + text_list.join("
"), this, plot_area.toRect()); - scene()->invalidate({}, QGraphicsScene::ForegroundLayer); - } else { - QToolTip::hideText(); + emit hovered(sec); + } else if (tip_label.isVisible()) { + emit hovered(-1); } QChartView::mouseMoveEvent(ev); @@ -797,6 +783,35 @@ void ChartView::mouseMoveEvent(QMouseEvent *ev) { } } +void ChartView::showTip(double sec) { + qreal x = chart()->mapToPosition({sec, 0}).x(); + QStringList text_list(QString::number(chart()->mapToValue({x, 0}).x(), 'f', 3)); + for (auto &s : sigs) { + if (s.series->isVisible()) { + QString value = "--"; + // use reverse iterator to find last item <= sec. + auto it = std::lower_bound(s.vals.rbegin(), s.vals.rend(), sec, [](auto &p, double x) { return p.x() > x; }); + if (it != s.vals.rend() && it->x() >= axis_x->min()) { + value = QString::number(it->y()); + s.track_pt = chart()->mapToPosition(*it); + x = std::max(x, s.track_pt.x()); + } + text_list << QString("%2: %3 (%4 - %5)") + .arg(s.series->color().name(), s.sig->name, value, QString::number(s.min), QString::number(s.max)); + } + } + QPointF tooltip_pt(x, chart()->plotArea().top()); + int plot_right = mapToGlobal(chart()->plotArea().topRight().toPoint()).x(); + tip_label.showText(mapToGlobal(tooltip_pt.toPoint()), "

" + text_list.join("
") + "

", plot_right); + scene()->update(); +} + +void ChartView::hideTip() { + clearTrackPoints(); + tip_label.hide(); + scene()->update(); +} + void ChartView::dragMoveEvent(QDragMoveEvent *event) { if (event->mimeData()->hasFormat(mime_type)) { event->setDropAction(event->source() == this ? Qt::MoveAction : Qt::CopyAction); @@ -1039,3 +1054,39 @@ QList SeriesSelector::seletedItems() { for (int i = 0; i < selected_list->count(); ++i) ret.push_back((ListItem *)selected_list->item(i)); return ret; } + +// ValueTipLabel + +ValueTipLabel::ValueTipLabel(QWidget *parent) : QLabel(parent, Qt::Tool | Qt::FramelessWindowHint) { + setForegroundRole(QPalette::ToolTipText); + setBackgroundRole(QPalette::ToolTipBase); + setPalette(QToolTip::palette()); + ensurePolished(); + setMargin(1 + style()->pixelMetric(QStyle::PM_ToolTipLabelFrameWidth, nullptr, this)); + setAttribute(Qt::WA_ShowWithoutActivating); + setTextFormat(Qt::RichText); + setVisible(false); +} + +void ValueTipLabel::showText(const QPoint &pt, const QString &text, int right_edge) { + setText(text); + if (!text.isEmpty()) { + QSize extra(1, 1); + resize(sizeHint() + extra); + QPoint tip_pos(pt.x() + 12, pt.y()); + if (tip_pos.x() + size().width() >= right_edge) { + tip_pos.rx() = pt.x() - size().width() - 12; + } + move(tip_pos); + } + setVisible(!text.isEmpty()); +} + +void ValueTipLabel::paintEvent(QPaintEvent *ev) { + QStylePainter p(this); + QStyleOptionFrame opt; + opt.init(this); + p.drawPrimitive(QStyle::PE_PanelTipLabel, opt); + p.end(); + QLabel::paintEvent(ev); +} diff --git a/tools/cabana/chartswidget.h b/tools/cabana/chartswidget.h index 592e063163..fad345ae34 100644 --- a/tools/cabana/chartswidget.h +++ b/tools/cabana/chartswidget.h @@ -25,6 +25,13 @@ enum class SeriesType { Scatter }; +class ValueTipLabel : public QLabel { +public: + ValueTipLabel(QWidget *parent = nullptr); + void showText(const QPoint &pt, const QString &sec, int right_edge); + void paintEvent(QPaintEvent *ev) override; +}; + class ChartView : public QChartView { Q_OBJECT @@ -36,6 +43,8 @@ public: void updatePlot(double cur, double min, double max); void setSeriesType(SeriesType type); void updatePlotArea(int left); + void showTip(double sec); + void hideTip(); struct SigItem { MessageId msg_id; @@ -57,6 +66,7 @@ signals: void zoomUndo(); void remove(); void axisYLabelWidthChanged(int w); + void hovered(double sec); private slots: void signalUpdated(const cabana::Signal *sig); @@ -94,6 +104,7 @@ private: QGraphicsProxyWidget *close_btn_proxy; QGraphicsProxyWidget *manage_btn_proxy; QGraphicsRectItem *background; + ValueTipLabel tip_label; QList sigs; double cur_sec = 0; const QString mime_type = "application/x-cabanachartview"; @@ -137,6 +148,7 @@ private: void setMaxChartRange(int value); void updateLayout(); void settingChanged(); + void showValueTip(double sec); bool eventFilter(QObject *obj, QEvent *event) override; ChartView *findChart(const MessageId &id, const cabana::Signal *sig); From aa3b8e5f300f992c69b4924a7c94994ce13db5c4 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Sat, 1 Apr 2023 04:58:50 +0800 Subject: [PATCH 11/24] cabana: fixed chat tool tips was displayed outside of the viewport (#27770) --- tools/cabana/chartswidget.cc | 11 ++++++++--- tools/cabana/chartswidget.h | 2 ++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/tools/cabana/chartswidget.cc b/tools/cabana/chartswidget.cc index 4ae83c05d7..845667bad7 100644 --- a/tools/cabana/chartswidget.cc +++ b/tools/cabana/chartswidget.cc @@ -71,13 +71,13 @@ ChartsWidget::ChartsWidget(QWidget *parent) : align_timer(this), QFrame(parent) charts_layout = new QGridLayout(); charts_layout->setSpacing(10); - QWidget *charts_container = new QWidget(this); + charts_container = new QWidget(this); QVBoxLayout *charts_main_layout = new QVBoxLayout(charts_container); charts_main_layout->setContentsMargins(0, 0, 0, 0); charts_main_layout->addLayout(charts_layout); charts_main_layout->addStretch(0); - QScrollArea *charts_scroll = new QScrollArea(this); + charts_scroll = new QScrollArea(this); charts_scroll->setFrameStyle(QFrame::NoFrame); charts_scroll->setWidgetResizable(true); charts_scroll->setWidget(charts_container); @@ -159,8 +159,13 @@ void ChartsWidget::zoomUndo() { } void ChartsWidget::showValueTip(double sec) { + const QRect visible_rect(-charts_container->pos(), charts_scroll->viewport()->size()); for (auto c : charts) { - sec >= 0 ? c->showTip(sec) : c->hideTip(); + if (sec >= 0 && visible_rect.contains(QRect(c->mapTo(charts_container, QPoint(0, 0)), c->size()))) { + c->showTip(sec); + } else { + c->hideTip(); + } } } diff --git a/tools/cabana/chartswidget.h b/tools/cabana/chartswidget.h index fad345ae34..98ceb02674 100644 --- a/tools/cabana/chartswidget.h +++ b/tools/cabana/chartswidget.h @@ -164,6 +164,8 @@ private: QAction *remove_all_btn; QGridLayout *charts_layout; QList charts; + QWidget *charts_container; + QScrollArea *charts_scroll; uint32_t max_chart_range = 0; bool is_zoomed = false; std::pair display_range; From e82d7a10d37cbcec54918a05f2233e20ee755ce2 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Sat, 1 Apr 2023 04:59:08 +0800 Subject: [PATCH 12/24] cabana: show min and max values in sparkline on hover (#27769) --- tools/cabana/signalview.cc | 29 +++++++++++++++++++++++++++-- tools/cabana/signalview.h | 1 + 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/tools/cabana/signalview.cc b/tools/cabana/signalview.cc index 4eb1456b1e..4f841a2866 100644 --- a/tools/cabana/signalview.cc +++ b/tools/cabana/signalview.cc @@ -344,6 +344,17 @@ bool SignalItemDelegate::helpEvent(QHelpEvent *event, QAbstractItemView *view, c return QStyledItemDelegate::helpEvent(event, view, option, index); } +void SignalItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const { + auto item = (SignalModel::Item *)index.internalPointer(); + if (editor && item->type == SignalModel::Item::Sig && index.column() == 1) { + QRect geom = option.widget->style()->subElementRect(QStyle::SE_ItemViewItemText, &option); + geom.setLeft(geom.right() - editor->sizeHint().width()); + editor->setGeometry(geom); + return; + } + QStyledItemDelegate::updateEditorGeometry(editor, option, index); +} + void SignalItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { int h_margin = option.widget->style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; int v_margin = option.widget->style()->pixelMetric(QStyle::PM_FocusFrameVMargin); @@ -375,6 +386,7 @@ void SignalItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op painter->drawText(text_rect, option.displayAlignment, text); painter->restore(); } else if (index.column() == 1 && item && item->type == SignalModel::Item::Sig) { + painter->save(); if (option.state & QStyle::State_Selected) { painter->fillRect(option.rect, option.palette.highlight()); } @@ -389,6 +401,7 @@ void SignalItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op QRect sparkline_rect = r.adjusted(0, 0, -r.width() * 0.4 - h_margin, 0); drawSparkline(painter, sparkline_rect, index); + painter->restore(); } else { QStyledItemDelegate::paint(painter, option, index); } @@ -406,7 +419,8 @@ void SignalItemDelegate::drawSparkline(QPainter *painter, const QRect &rect, con if (first != last) { double min = std::numeric_limits::max(); double max = std::numeric_limits::lowest(); - const auto sig = ((SignalModel::Item *)index.internalPointer())->sig; + const auto item = (const SignalModel::Item *)index.internalPointer(); + const auto sig = item->sig; points.clear(); for (auto it = first; it != last; ++it) { double value = get_raw_value(it->dat, it->size, *sig); @@ -435,6 +449,17 @@ void SignalItemDelegate::drawSparkline(QPainter *painter, const QRect &rect, con painter->drawEllipse(pt, 2, 2); } } + + if (item->highlight) { + QFont font; + font.setPixelSize(10); + painter->setFont(font); + painter->setPen(Qt::darkGray); + painter->drawLine(rect.topRight(), rect.bottomRight()); + QRect minmax_rect{rect.right() + 3, rect.top(), 1000, rect.height()}; + painter->drawText(minmax_rect, Qt::AlignLeft | Qt::AlignTop, QString::number(max)); + painter->drawText(minmax_rect, Qt::AlignLeft | Qt::AlignBottom, QString::number(min)); + } } } @@ -552,7 +577,6 @@ void SignalView::rowsChanged() { int h_margin = style()->pixelMetric(QStyle::PM_FocusFrameHMargin); h->setContentsMargins(0, v_margin, -h_margin, v_margin); h->setSpacing(style()->pixelMetric(QStyle::PM_ToolBarItemSpacing)); - h->addStretch(0); auto remove_btn = toolButton("x", tr("Remove signal")); auto plot_btn = toolButton("graph-up", ""); @@ -612,6 +636,7 @@ void SignalView::signalHovered(const cabana::Signal *sig) { bool highlight = children[i]->sig == sig; if (std::exchange(children[i]->highlight, highlight) != highlight) { emit model->dataChanged(model->index(i, 0), model->index(i, 0), {Qt::DecorationRole}); + emit model->dataChanged(model->index(i, 1), model->index(i, 1), {Qt::DisplayRole}); } } } diff --git a/tools/cabana/signalview.h b/tools/cabana/signalview.h index 8bc9477888..711748937a 100644 --- a/tools/cabana/signalview.h +++ b/tools/cabana/signalview.h @@ -85,6 +85,7 @@ public: QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override; bool helpEvent(QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &index) override; void drawSparkline(QPainter *painter, const QRect &rect, const QModelIndex &index) const; + void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override; QValidator *name_validator, *double_validator; QFont small_font; const int color_label_width = 18; From 1ee4f41d5a6c8643301e197063c7934eae952c11 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 31 Mar 2023 20:00:49 -0700 Subject: [PATCH 13/24] bump panda: iso-tp bugfixes (#27772) bumppanda --- panda | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda b/panda index 09fee3e7ea..a12c0a7956 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 09fee3e7ead96a6a9613430c81bb2d3e095aa0fe +Subproject commit a12c0a795678373d946b644b43d9402b72e502a9 From a0f33658f283072fe86d18b06d0c4c98728d507a Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 31 Mar 2023 20:57:32 -0700 Subject: [PATCH 14/24] IsoTpParallelQuery: extend timeouts when receiving consecutive frames (#27762) * change to rx_in_progress * bump panda * bump panda --- panda | 2 +- selfdrive/car/isotp_parallel_query.py | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/panda b/panda index a12c0a7956..8efbcf041c 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit a12c0a795678373d946b644b43d9402b72e502a9 +Subproject commit 8efbcf041c1b6da1764bb56f822609fd4bb0758f diff --git a/selfdrive/car/isotp_parallel_query.py b/selfdrive/car/isotp_parallel_query.py index 70f8b5f50d..1b115c665d 100644 --- a/selfdrive/car/isotp_parallel_query.py +++ b/selfdrive/car/isotp_parallel_query.py @@ -105,13 +105,14 @@ class IsoTpParallelQuery: for tx_addr, msg in msgs.items(): try: - dat, updated = msg.recv() + dat, rx_in_progress = msg.recv() except Exception: cloudlog.exception(f"Error processing UDS response: {tx_addr}") request_done[tx_addr] = True continue - if updated: + # Extend timeout for each consecutive ISO-TP frame to avoid timing out on long responses + if rx_in_progress: response_timeouts[tx_addr] = time.monotonic() + timeout if not dat: @@ -123,6 +124,7 @@ class IsoTpParallelQuery: if response_valid: if counter + 1 < len(self.request): + response_timeouts[tx_addr] = time.monotonic() + timeout msg.send(self.request[counter + 1]) request_counter[tx_addr] += 1 else: From 64f9b13871f83593e84becd3beeef82945f550c8 Mon Sep 17 00:00:00 2001 From: Cameron Clough Date: Sat, 1 Apr 2023 21:20:47 +0100 Subject: [PATCH 15/24] Ford: add Maverick 2023 FW (#27781) Ford Maverick 2023 Lariat Lux (added radar) VIN: 3FTTW8E31PRA18806 bd37e43731e5964b|2023-04-01--15-13-06--0 --- selfdrive/car/ford/values.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/selfdrive/car/ford/values.py b/selfdrive/car/ford/values.py index 50c7d93987..110bf59d55 100644 --- a/selfdrive/car/ford/values.py +++ b/selfdrive/car/ford/values.py @@ -84,7 +84,7 @@ CAR_INFO: Dict[str, Union[CarInfo, List[CarInfo]]] = { FordCarInfo("Lincoln Aviator Plug-in Hybrid 2021", "Co-Pilot360 Plus"), ], CAR.FOCUS_MK4: FordCarInfo("Ford Focus EU 2019", "Driver Assistance Pack"), - CAR.MAVERICK_MK1: FordCarInfo("Ford Maverick 2022", "Co-Pilot360 Assist"), + CAR.MAVERICK_MK1: FordCarInfo("Ford Maverick 2022-23", "Co-Pilot360 Assist"), } FW_QUERY_CONFIG = FwQueryConfig( @@ -217,6 +217,7 @@ FW_VERSIONS = { ], (Ecu.abs, 0x760, None): [ b'NZ6C-2D053-AG\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', + b'PZ6C-2D053-ED\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], (Ecu.fwdRadar, 0x764, None): [ b'NZ6T-14D049-AA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', @@ -228,6 +229,7 @@ FW_VERSIONS = { b'NZ6A-14C204-AAA\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'NZ6A-14C204-PA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'NZ6A-14C204-ZA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', + b'PZ6A-14C204-JC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], (Ecu.shiftByWire, 0x732, None): [ b'NZ6P-14G395-AD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', From 6bbcbab3f7705a750e90e99a8de22b191e177184 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Sun, 2 Apr 2023 06:20:47 +0800 Subject: [PATCH 16/24] cabana: fix chart tooltip issues (#27778) --- tools/cabana/chartswidget.cc | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/tools/cabana/chartswidget.cc b/tools/cabana/chartswidget.cc index 845667bad7..df6bf0c8b7 100644 --- a/tools/cabana/chartswidget.cc +++ b/tools/cabana/chartswidget.cc @@ -342,12 +342,26 @@ bool ChartsWidget::eventFilter(QObject *obj, QEvent *event) { bool ChartsWidget::event(QEvent *event) { bool back_button = false; - if (event->type() == QEvent::MouseButtonPress) { - QMouseEvent *ev = static_cast(event); - back_button = ev->button() == Qt::BackButton; - } else if (event->type() == QEvent::NativeGesture) { // MacOS emulates a back swipe on pressing the mouse back button - QNativeGestureEvent *ev = static_cast(event); - back_button = (ev->value() == 180); + switch (event->type()) { + case QEvent::MouseButtonPress: { + QMouseEvent *ev = static_cast(event); + back_button = ev->button() == Qt::BackButton; + break; + } + + case QEvent::NativeGesture: { + QNativeGestureEvent *ev = static_cast(event); + back_button = (ev->value() == 180); + break; + } + case QEvent::WindowActivate: + case QEvent::WindowDeactivate: + case QEvent::FocusIn: + case QEvent::FocusOut: + showValueTip(-1); + break; + default: + break; } if (back_button) { @@ -541,7 +555,7 @@ void ChartView::updatePlot(double cur, double min, double max) { updateAxisY(); updateSeriesPoints(); } - scene()->invalidate({}, QGraphicsScene::ForegroundLayer); + scene()->update(); } void ChartView::updateSeriesPoints() { @@ -738,7 +752,7 @@ void ChartView::mouseReleaseEvent(QMouseEvent *event) { } else if (rubber->width() > 10) { emit zoomIn(min_rounded, max_rounded); } else { - scene()->invalidate({}, QGraphicsScene::ForegroundLayer); + scene()->update(); } event->accept(); } else if (!can->liveStreaming() && event->button() == Qt::RightButton) { @@ -784,7 +798,7 @@ void ChartView::mouseMoveEvent(QMouseEvent *ev) { if (rubber_rect != rubber->geometry()) { rubber->setGeometry(rubber_rect); } - scene()->invalidate({}, QGraphicsScene::ForegroundLayer); + scene()->update(); } } @@ -1062,7 +1076,7 @@ QList SeriesSelector::seletedItems() { // ValueTipLabel -ValueTipLabel::ValueTipLabel(QWidget *parent) : QLabel(parent, Qt::Tool | Qt::FramelessWindowHint) { +ValueTipLabel::ValueTipLabel(QWidget *parent) : QLabel(parent, Qt::ToolTip | Qt::FramelessWindowHint) { setForegroundRole(QPalette::ToolTipText); setBackgroundRole(QPalette::ToolTipBase); setPalette(QToolTip::palette()); From a50fbe17c8b56acd3f61f2fa71fbaa8f9faa3a44 Mon Sep 17 00:00:00 2001 From: eFini Date: Sun, 2 Apr 2023 06:21:26 +0800 Subject: [PATCH 17/24] Cleanup: Honda interface already checks vehicle model for BSM (#27775) --- selfdrive/car/honda/carstate.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/selfdrive/car/honda/carstate.py b/selfdrive/car/honda/carstate.py index 8189800368..eea78758a8 100644 --- a/selfdrive/car/honda/carstate.py +++ b/selfdrive/car/honda/carstate.py @@ -293,7 +293,7 @@ class CarState(CarStateBase): if self.CP.carFingerprint in HONDA_BOSCH_RADARLESS: self.lkas_hud = cp_cam.vl["LKAS_HUD"] - if self.CP.enableBsm and self.CP.carFingerprint in (CAR.CRV_5G, ): + if self.CP.enableBsm: # BSM messages are on B-CAN, requires a panda forwarding B-CAN messages to CAN 0 # more info here: https://github.com/commaai/openpilot/pull/1867 ret.leftBlindspot = cp_body.vl["BSM_STATUS_LEFT"]["BSM_ALERT"] == 1 @@ -340,7 +340,7 @@ class CarState(CarStateBase): @staticmethod def get_body_can_parser(CP): - if CP.enableBsm and CP.carFingerprint == CAR.CRV_5G: + if CP.enableBsm: signals = [("BSM_ALERT", "BSM_STATUS_RIGHT"), ("BSM_ALERT", "BSM_STATUS_LEFT")] From 2ab05f96c3e535938533dd877968a7f6ae79f583 Mon Sep 17 00:00:00 2001 From: royjr Date: Sat, 1 Apr 2023 18:24:29 -0400 Subject: [PATCH 18/24] Cleanup: GM remove unnecessary variable (#27779) --- selfdrive/car/gm/interface.py | 1 - 1 file changed, 1 deletion(-) diff --git a/selfdrive/car/gm/interface.py b/selfdrive/car/gm/interface.py index 6e2797ce24..e7fc0abb1a 100755 --- a/selfdrive/car/gm/interface.py +++ b/selfdrive/car/gm/interface.py @@ -98,7 +98,6 @@ class CarInterface(CarInterfaceBase): # Tuning for experimental long ret.longitudinalTuning.kpV = [2.0, 1.5] ret.longitudinalTuning.kiV = [0.72] - ret.stopAccel = -2.0 ret.stoppingDecelRate = 2.0 # reach brake quickly after enabling ret.vEgoStopping = 0.25 ret.vEgoStarting = 0.25 From 133721aafc0f8220a993a14fcade6ee8fc05c747 Mon Sep 17 00:00:00 2001 From: eFini Date: Sun, 2 Apr 2023 06:34:55 +0800 Subject: [PATCH 19/24] Toyota: support openpilot long with a smartDSU on nodsu models (#27417) * init * fix syntax * add test route * syntax * cleanup * bool --------- Co-authored-by: Adeeb Shihadeh --- selfdrive/car/tests/routes.py | 1 + selfdrive/car/toyota/carstate.py | 12 +++++++++--- selfdrive/car/toyota/interface.py | 14 +++++++++----- selfdrive/car/toyota/values.py | 1 + 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/selfdrive/car/tests/routes.py b/selfdrive/car/tests/routes.py index 4dd19d24e3..40ed0ea047 100644 --- a/selfdrive/car/tests/routes.py +++ b/selfdrive/car/tests/routes.py @@ -185,6 +185,7 @@ routes = [ CarTestRoute("9b36accae406390e|2021-03-30--10-41-38", TOYOTA.MIRAI), CarTestRoute("cd9cff4b0b26c435|2021-05-13--15-12-39", TOYOTA.CHR), CarTestRoute("ea8fbe72b96a185c|2023-02-08--15-11-46", TOYOTA.CHR_TSS2), + CarTestRoute("ea8fbe72b96a185c|2023-02-22--09-20-34", TOYOTA.CHR_TSS2), # openpilot longitudinal, with smartDSU CarTestRoute("57858ede0369a261|2021-05-18--20-34-20", TOYOTA.CHRH), CarTestRoute("6719965b0e1d1737|2023-02-09--22-44-05", TOYOTA.CHRH_TSS2), CarTestRoute("14623aae37e549f3|2021-10-24--01-20-49", TOYOTA.PRIUS_V), diff --git a/selfdrive/car/toyota/carstate.py b/selfdrive/car/toyota/carstate.py index 050f8747a2..68adc2ee57 100644 --- a/selfdrive/car/toyota/carstate.py +++ b/selfdrive/car/toyota/carstate.py @@ -115,7 +115,8 @@ class CarState(CarStateBase): cp_acc = cp_cam if self.CP.carFingerprint in (TSS2_CAR - RADAR_ACC_CAR) else cp if self.CP.carFingerprint in (TSS2_CAR | RADAR_ACC_CAR): - self.acc_type = cp_acc.vl["ACC_CONTROL"]["ACC_TYPE"] + if not (self.CP.flags & ToyotaFlags.SMART_DSU.value): + self.acc_type = cp_acc.vl["ACC_CONTROL"]["ACC_TYPE"] ret.stockFcw = bool(cp_acc.vl["ACC_HUD"]["FCW"]) # some TSS2 cars have low speed lockout permanently set, so ignore on those cars @@ -235,12 +236,17 @@ class CarState(CarStateBase): checks.append(("BSM", 1)) if CP.carFingerprint in RADAR_ACC_CAR: + if not CP.flags & ToyotaFlags.SMART_DSU.value: + signals += [ + ("ACC_TYPE", "ACC_CONTROL"), + ] + checks += [ + ("ACC_CONTROL", 33), + ] signals += [ - ("ACC_TYPE", "ACC_CONTROL"), ("FCW", "ACC_HUD"), ] checks += [ - ("ACC_CONTROL", 33), ("ACC_HUD", 1), ] diff --git a/selfdrive/car/toyota/interface.py b/selfdrive/car/toyota/interface.py index 33a87451e9..6e8664c340 100644 --- a/selfdrive/car/toyota/interface.py +++ b/selfdrive/car/toyota/interface.py @@ -201,14 +201,18 @@ class CarInterface(CarInterfaceBase): tire_stiffness_factor=tire_stiffness_factor) ret.enableBsm = 0x3F6 in fingerprint[0] and candidate in TSS2_CAR - # Detect smartDSU, which intercepts ACC_CMD from the DSU allowing openpilot to send it - smartDsu = 0x2FF in fingerprint[0] - # In TSS2 cars the camera does long control + + # Detect smartDSU, which intercepts ACC_CMD from the DSU (or radar) allowing openpilot to send it + if 0x2FF in fingerprint[0]: + ret.flags |= ToyotaFlags.SMART_DSU.value + + # In TSS2 cars, the camera does long control found_ecus = [fw.ecu for fw in car_fw] - ret.enableDsu = len(found_ecus) > 0 and Ecu.dsu not in found_ecus and candidate not in (NO_DSU_CAR | UNSUPPORTED_DSU_CAR) and not smartDsu + ret.enableDsu = len(found_ecus) > 0 and Ecu.dsu not in found_ecus and candidate not in (NO_DSU_CAR | UNSUPPORTED_DSU_CAR) and not (ret.flags & ToyotaFlags.SMART_DSU) ret.enableGasInterceptor = 0x201 in fingerprint[0] + # if the smartDSU is detected, openpilot can send ACC_CMD (and the smartDSU will block it from the DSU) or not (the DSU is "connected") - ret.openpilotLongitudinalControl = smartDsu or ret.enableDsu or candidate in (TSS2_CAR - RADAR_ACC_CAR) + ret.openpilotLongitudinalControl = bool(ret.flags & ToyotaFlags.SMART_DSU) or ret.enableDsu or candidate in (TSS2_CAR - RADAR_ACC_CAR) ret.autoResumeSng = ret.openpilotLongitudinalControl and candidate in NO_STOP_TIMER_CAR if not ret.openpilotLongitudinalControl: diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py index f0e846cc54..8584c6b078 100644 --- a/selfdrive/car/toyota/values.py +++ b/selfdrive/car/toyota/values.py @@ -33,6 +33,7 @@ class CarControllerParams: class ToyotaFlags(IntFlag): HYBRID = 1 + SMART_DSU = 2 class CAR: From cddb7c37e6a3e267d568725f6ed70a1dd24ff3b7 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sat, 1 Apr 2023 16:05:51 -0700 Subject: [PATCH 20/24] ci: locationd cpu has increased a bit --- selfdrive/test/test_onroad.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/test/test_onroad.py b/selfdrive/test/test_onroad.py index 07a3c61bc5..81d68aa877 100755 --- a/selfdrive/test/test_onroad.py +++ b/selfdrive/test/test_onroad.py @@ -25,7 +25,7 @@ PROCS = { "./loggerd": 10.0, "./encoderd": 17.0, "./camerad": 14.5, - "./locationd": 9.1, + "./locationd": 11.0, "selfdrive.controls.plannerd": 16.5, "./_ui": 19.2, "selfdrive.locationd.paramsd": 9.0, From a0364303906380def2d686e57b3e415e1dda74d2 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Sun, 2 Apr 2023 07:29:06 +0800 Subject: [PATCH 21/24] cabana: static link to opendbc (#27409) * static link to opendbc * bump opendbc * cleanup * bump opendbc --------- Co-authored-by: Adeeb Shihadeh --- SConstruct | 3 --- opendbc | 2 +- tools/cabana/.gitignore | 4 ++-- tools/cabana/README.md | 2 +- tools/cabana/SConscript | 12 +++++------- tools/cabana/cabana | 4 ---- tools/cabana/tests/test_cabana | 4 ---- 7 files changed, 9 insertions(+), 22 deletions(-) delete mode 100755 tools/cabana/cabana delete mode 100755 tools/cabana/tests/test_cabana diff --git a/SConstruct b/SConstruct index 387d2e76f4..4ff4cf487f 100644 --- a/SConstruct +++ b/SConstruct @@ -434,9 +434,6 @@ SConscript(['selfdrive/navd/SConscript']) if arch in ['x86_64', 'Darwin'] or GetOption('extras'): SConscript(['tools/replay/SConscript']) - - opendbc = abspath([File('opendbc/can/libdbc.so')]) - Export('opendbc') SConscript(['tools/cabana/SConscript']) external_sconscript = GetOption('external_sconscript') diff --git a/opendbc b/opendbc index b7d4a6e271..9a1de83e4b 160000 --- a/opendbc +++ b/opendbc @@ -1 +1 @@ -Subproject commit b7d4a6e2718d9ec3cf436441696528bedb1d44cf +Subproject commit 9a1de83e4b0625c38c6bc677a762528b7026aa5e diff --git a/tools/cabana/.gitignore b/tools/cabana/.gitignore index c74ab7483c..c3f5ef2b69 100644 --- a/tools/cabana/.gitignore +++ b/tools/cabana/.gitignore @@ -1,7 +1,7 @@ moc_* *.moc -_cabana +cabana settings dbc/car_fingerprint_to_dbc.json -tests/_test_cabana +tests/test_cabana diff --git a/tools/cabana/README.md b/tools/cabana/README.md index db247c39c5..4faa7c61d0 100644 --- a/tools/cabana/README.md +++ b/tools/cabana/README.md @@ -8,7 +8,7 @@ Cabana is a tool developed to view raw CAN data. One use for this is creating an ```bash $ ./cabana -h -Usage: ./_cabana [options] route +Usage: ./cabana [options] route Options: -h, --help Displays this help. diff --git a/tools/cabana/SConscript b/tools/cabana/SConscript index 7d5129fc16..d6c2779ac3 100644 --- a/tools/cabana/SConscript +++ b/tools/cabana/SConscript @@ -1,6 +1,6 @@ import os Import('env', 'qt_env', 'arch', 'common', 'messaging', 'visionipc', 'replay_lib', - 'cereal', 'transformations', 'widgets', 'opendbc') + 'cereal', 'transformations', 'widgets') base_frameworks = qt_env['FRAMEWORKS'] base_libs = [common, messaging, cereal, visionipc, transformations, 'zmq', @@ -15,8 +15,9 @@ else: qt_libs = ['qt_util'] + base_libs -cabana_libs = [widgets, cereal, messaging, visionipc, replay_lib, opendbc,'avutil', 'avcodec', 'avformat', 'bz2', 'curl', 'yuv'] + qt_libs cabana_env = qt_env.Clone() +cabana_env["LIBPATH"] += ['../../opendbc/can'] +cabana_libs = [widgets, cereal, messaging, visionipc, replay_lib, 'libdbc_static', 'avutil', 'avcodec', 'avformat', 'bz2', 'curl', 'yuv'] + qt_libs opendbc_path = '-DOPENDBC_FILE_PATH=\'"%s"\'' % (cabana_env.Dir("../../opendbc").abspath) cabana_env['CXXFLAGS'] += [opendbc_path] @@ -31,13 +32,10 @@ cabana_env['QT_MOCHPREFIX'] = os.path.dirname(prev_moc_path) + '/cabana/moc_' cabana_lib = cabana_env.Library("cabana_lib", ['mainwin.cc', 'streams/livestream.cc', 'streams/abstractstream.cc', 'streams/replaystream.cc', 'binaryview.cc', 'chartswidget.cc', 'historylog.cc', 'videowidget.cc', 'signalview.cc', 'dbc/dbc.cc', 'dbc/dbcfile.cc', 'dbc/dbcmanager.cc', 'commands.cc', 'messageswidget.cc', 'route.cc', 'settings.cc', 'util.cc', 'detailwidget.cc', 'tools/findsimilarbits.cc'], LIBS=cabana_libs, FRAMEWORKS=base_frameworks) -cabana_env.Program('_cabana', ['cabana.cc', cabana_lib, assets], LIBS=cabana_libs, FRAMEWORKS=base_frameworks) - -if arch == "Darwin": - cabana_env.Execute('install_name_tool -change opendbc/can/libdbc.dylib @loader_path/../../opendbc/can/libdbc.dylib ./_cabana') +cabana_env.Program('cabana', ['cabana.cc', cabana_lib, assets], LIBS=cabana_libs, FRAMEWORKS=base_frameworks) if GetOption('test'): - cabana_env.Program('tests/_test_cabana', ['tests/test_runner.cc', 'tests/test_cabana.cc', cabana_lib], LIBS=[cabana_libs]) + cabana_env.Program('tests/test_cabana', ['tests/test_runner.cc', 'tests/test_cabana.cc', cabana_lib], LIBS=[cabana_libs]) def generate_dbc_json(target, source, env): env.Execute('tools/cabana/dbc/generate_dbc_json.py --out tools/cabana/dbc/car_fingerprint_to_dbc.json') diff --git a/tools/cabana/cabana b/tools/cabana/cabana deleted file mode 100755 index 14647b6a10..0000000000 --- a/tools/cabana/cabana +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -cd "$(dirname "$0")" -export LD_LIBRARY_PATH="../../opendbc/can:$LD_LIBRARY_PATH" -exec ./_cabana "$@" diff --git a/tools/cabana/tests/test_cabana b/tools/cabana/tests/test_cabana deleted file mode 100755 index bac242fbdd..0000000000 --- a/tools/cabana/tests/test_cabana +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -cd "$(dirname "$0")" -export LD_LIBRARY_PATH="../../../opendbc/can:$LD_LIBRARY_PATH" -exec ./_test_cabana "$1" From 0cee9d4e789d2daa1c6da85231912b53576fd00d Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Mon, 3 Apr 2023 02:34:01 +0800 Subject: [PATCH 22/24] cabana: significantly reduce CPU usage by caching chart to pixmap (#27786) * caching chart to pixmap * cleanup * fill with QPalette::Base --- tools/cabana/chartswidget.cc | 62 +++++++++++++++++++++++++----------- tools/cabana/chartswidget.h | 6 ++-- 2 files changed, 48 insertions(+), 20 deletions(-) diff --git a/tools/cabana/chartswidget.cc b/tools/cabana/chartswidget.cc index df6bf0c8b7..7fae43ceb9 100644 --- a/tools/cabana/chartswidget.cc +++ b/tools/cabana/chartswidget.cc @@ -385,19 +385,18 @@ ChartView::ChartView(QWidget *parent) : tip_label(this), QChartView(nullptr, par chart->legend()->setShowToolTips(true); chart->setMargins({0, 0, 0, 0}); - background = new QGraphicsRectItem(chart); - background->setBrush(QApplication::palette().color(QPalette::Base)); - background->setPen(Qt::NoPen); - background->setZValue(chart->zValue() - 1); - setChart(chart); createToolButtons(); - setRenderHint(QPainter::Antialiasing); // TODO: enable zoomIn/seekTo in live streaming mode. setRubberBand(can->liveStreaming() ? QChartView::NoRubberBand : QChartView::HorizontalRubberBand); setMouseTracking(true); + QObject::connect(axis_x, &QValueAxis::rangeChanged, [this]() { resetChartCache(); }); + QObject::connect(axis_y, &QValueAxis::rangeChanged, [this]() { resetChartCache(); }); + QObject::connect(axis_y, &QAbstractAxis::titleTextChanged, [this]() { resetChartCache(); }); + QObject::connect(chart, &QChart::plotAreaChanged, [this]() { resetChartCache(); }); + QObject::connect(dbc(), &DBCManager::signalRemoved, this, &ChartView::signalRemoved); QObject::connect(dbc(), &DBCManager::signalUpdated, this, &ChartView::signalUpdated); QObject::connect(dbc(), &DBCManager::msgRemoved, this, &ChartView::msgRemoved); @@ -474,6 +473,7 @@ void ChartView::removeIf(std::function predicate) { emit remove(); } else if (sigs.size() != prev_size) { updateAxisY(); + resetChartCache(); } } @@ -515,15 +515,14 @@ void ChartView::resizeEvent(QResizeEvent *event) { manage_btn_proxy->setPos(x, top); chart()->legend()->setGeometry({move_icon->sceneBoundingRect().topRight(), manage_btn_proxy->sceneBoundingRect().bottomLeft()}); if (align_to > 0) { - updatePlotArea(align_to); + updatePlotArea(align_to, true); } QChartView::resizeEvent(event); } -void ChartView::updatePlotArea(int left_pos) { - if (align_to != left_pos || rect() != background->rect()) { +void ChartView::updatePlotArea(int left_pos, bool force) { + if (align_to != left_pos || force) { align_to = left_pos; - background->setRect(rect()); qreal left, top, right, bottom; chart()->layout()->getContentsMargins(&left, &top, &right, &bottom); @@ -532,9 +531,6 @@ void ChartView::updatePlotArea(int left_pos) { int adjust_top = chart()->legend()->geometry().height() + style()->pixelMetric(QStyle::PM_LayoutTopMargin); chart()->setPlotArea(rect().adjusted(align_to + left, adjust_top + top, -x_label_size.width() / 2 - right, -x_label_size.height() - bottom)); chart()->layout()->invalidate(); - if (can->isPaused()) { - update(); - } } } @@ -546,6 +542,7 @@ void ChartView::updateTitle() { auto decoration = s.series->isVisible() ? "none" : "line-through"; s.series->setName(QString("%2 %3 %4").arg(decoration, s.sig->name, msgName(s.msg_id), s.msg_id.toString())); } + resetChartCache(); } void ChartView::updatePlot(double cur, double min, double max) { @@ -555,7 +552,7 @@ void ChartView::updatePlot(double cur, double min, double max) { updateAxisY(); updateSeriesPoints(); } - scene()->update(); + viewport()->update(); } void ChartView::updateSeriesPoints() { @@ -617,6 +614,7 @@ void ChartView::updateSeries(const cabana::Signal *sig) { } } updateAxisY(); + resetChartCache(); } // auto zoom on yaxis @@ -752,7 +750,7 @@ void ChartView::mouseReleaseEvent(QMouseEvent *event) { } else if (rubber->width() > 10) { emit zoomIn(min_rounded, max_rounded); } else { - scene()->update(); + viewport()->update(); } event->accept(); } else if (!can->liveStreaming() && event->button() == Qt::RightButton) { @@ -798,7 +796,7 @@ void ChartView::mouseMoveEvent(QMouseEvent *ev) { if (rubber_rect != rubber->geometry()) { rubber->setGeometry(rubber_rect); } - scene()->update(); + viewport()->update(); } } @@ -822,13 +820,13 @@ void ChartView::showTip(double sec) { QPointF tooltip_pt(x, chart()->plotArea().top()); int plot_right = mapToGlobal(chart()->plotArea().topRight().toPoint()).x(); tip_label.showText(mapToGlobal(tooltip_pt.toPoint()), "

" + text_list.join("
") + "

", plot_right); - scene()->update(); + viewport()->update(); } void ChartView::hideTip() { clearTrackPoints(); tip_label.hide(); - scene()->update(); + viewport()->update(); } void ChartView::dragMoveEvent(QDragMoveEvent *event) { @@ -858,6 +856,34 @@ void ChartView::dropEvent(QDropEvent *event) { } } +void ChartView::resetChartCache() { + chart_pixmap = QPixmap(); + viewport()->update(); +} + +void ChartView::paintEvent(QPaintEvent *event) { + if (!can->liveStreaming()) { + if (chart_pixmap.isNull()) { + const qreal dpr = viewport()->devicePixelRatioF(); + chart_pixmap = QPixmap(viewport()->size() * dpr); + chart_pixmap.setDevicePixelRatio(dpr); + chart_pixmap.fill(palette().color(QPalette::Base)); + QPainter p(&chart_pixmap); + p.setRenderHints(QPainter::Antialiasing); + scene()->setSceneRect(viewport()->rect()); + scene()->render(&p); + } + + QPainter painter(viewport()); + painter.setRenderHints(QPainter::Antialiasing); + painter.drawPixmap(QPoint(), chart_pixmap); + QRectF exposed_rect = mapToScene(event->region().boundingRect()).boundingRect(); + drawForeground(&painter, exposed_rect); + } else { + QChartView::paintEvent(event); + } +} + void ChartView::drawForeground(QPainter *painter, const QRectF &rect) { // draw time line qreal x = chart()->mapToPosition(QPointF{cur_sec, 0}).x(); diff --git a/tools/cabana/chartswidget.h b/tools/cabana/chartswidget.h index 98ceb02674..f4cc681ff0 100644 --- a/tools/cabana/chartswidget.h +++ b/tools/cabana/chartswidget.h @@ -42,7 +42,7 @@ public: void updateSeries(const cabana::Signal *sig = nullptr); void updatePlot(double cur, double min, double max); void setSeriesType(SeriesType type); - void updatePlotArea(int left); + void updatePlotArea(int left, bool force = false); void showTip(double sec); void hideTip(); @@ -88,6 +88,8 @@ private: QSize sizeHint() const override { return {CHART_MIN_WIDTH, settings.chart_height}; } void updateAxisY(); void updateTitle(); + void resetChartCache(); + void paintEvent(QPaintEvent *event) override; void drawForeground(QPainter *painter, const QRectF &rect) override; std::tuple getNiceAxisNumbers(qreal min, qreal max, int tick_count); qreal niceNumber(qreal x, bool ceiling); @@ -103,7 +105,6 @@ private: QGraphicsPixmapItem *move_icon; QGraphicsProxyWidget *close_btn_proxy; QGraphicsProxyWidget *manage_btn_proxy; - QGraphicsRectItem *background; ValueTipLabel tip_label; QList sigs; double cur_sec = 0; @@ -111,6 +112,7 @@ private: SeriesType series_type = SeriesType::Line; bool is_scrubbing = false; bool resume_after_scrub = false; + QPixmap chart_pixmap; friend class ChartsWidget; }; From c56872265a126a0e8feda8bb21225e885ea6e941 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Mon, 3 Apr 2023 02:34:10 +0800 Subject: [PATCH 23/24] cabana: support toggle between light / dark theme (#27787) add dark theme --- tools/cabana/cabana.cc | 1 + tools/cabana/chartswidget.cc | 4 +--- tools/cabana/chartswidget.h | 1 - tools/cabana/mainwin.cc | 1 + tools/cabana/settings.cc | 9 +++++++++ tools/cabana/settings.h | 2 ++ tools/cabana/util.cc | 38 +++++++++++++++++++++++++++++++++--- tools/cabana/util.h | 1 + 8 files changed, 50 insertions(+), 7 deletions(-) diff --git a/tools/cabana/cabana.cc b/tools/cabana/cabana.cc index 5c182f435f..329b6070ae 100644 --- a/tools/cabana/cabana.cc +++ b/tools/cabana/cabana.cc @@ -15,6 +15,7 @@ int main(int argc, char *argv[]) { QApplication app(argc, argv); app.setApplicationDisplayName("Cabana"); app.setWindowIcon(QIcon(":cabana-icon.png")); + utils::setTheme(settings.theme); QCommandLineParser cmd_parser; cmd_parser.addHelpOption(); diff --git a/tools/cabana/chartswidget.cc b/tools/cabana/chartswidget.cc index 7fae43ceb9..c2ef7c17c1 100644 --- a/tools/cabana/chartswidget.cc +++ b/tools/cabana/chartswidget.cc @@ -85,8 +85,6 @@ ChartsWidget::ChartsWidget(QWidget *parent) : align_timer(this), QFrame(parent) main_layout->addWidget(charts_scroll); // init settings - use_dark_theme = QApplication::palette().color(QPalette::WindowText).value() > - QApplication::palette().color(QPalette::Background).value(); column_count = std::clamp(settings.chart_column_count, 1, MAX_COLUMN_COUNT); max_chart_range = std::clamp(settings.chart_range, 1, settings.max_cached_minutes * 60); display_range = {0, max_chart_range}; @@ -231,7 +229,7 @@ ChartView *ChartsWidget::createChart() { chart->setFixedHeight(settings.chart_height); chart->setMinimumWidth(CHART_MIN_WIDTH); chart->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - chart->chart()->setTheme(use_dark_theme ? QChart::QChart::ChartThemeDark : QChart::ChartThemeLight); + chart->chart()->setTheme(settings.theme == 2 ? QChart::QChart::ChartThemeDark : QChart::ChartThemeLight); QObject::connect(chart, &ChartView::remove, [=]() { removeChart(chart); }); QObject::connect(chart, &ChartView::zoomIn, this, &ChartsWidget::zoomIn); QObject::connect(chart, &ChartView::zoomUndo, this, &ChartsWidget::zoomUndo); diff --git a/tools/cabana/chartswidget.h b/tools/cabana/chartswidget.h index f4cc681ff0..a88b3185af 100644 --- a/tools/cabana/chartswidget.h +++ b/tools/cabana/chartswidget.h @@ -173,7 +173,6 @@ private: std::pair display_range; std::pair zoomed_range; QStack> zoom_stack; - bool use_dark_theme = false; QAction *columns_action; int column_count = 1; int current_column_count = 0; diff --git a/tools/cabana/mainwin.cc b/tools/cabana/mainwin.cc index c979a20f16..892dfdb91f 100644 --- a/tools/cabana/mainwin.cc +++ b/tools/cabana/mainwin.cc @@ -541,6 +541,7 @@ void MainWindow::updateDownloadProgress(uint64_t cur, uint64_t total, bool succe void MainWindow::updateStatus() { status_label->setText(tr("Cached Minutes:%1 FPS:%2").arg(settings.max_cached_minutes).arg(settings.fps)); + utils::setTheme(settings.theme); } void MainWindow::dockCharts(bool dock) { diff --git a/tools/cabana/settings.cc b/tools/cabana/settings.cc index 9e829708b1..a18b8a9ad6 100644 --- a/tools/cabana/settings.cc +++ b/tools/cabana/settings.cc @@ -27,6 +27,7 @@ void Settings::save() { s.setValue("recent_files", recent_files); s.setValue("message_header_state", message_header_state); s.setValue("chart_series_type", chart_series_type); + s.setValue("theme", theme); s.setValue("sparkline_range", sparkline_range); } @@ -45,6 +46,7 @@ void Settings::load() { recent_files = s.value("recent_files").toStringList(); message_header_state = s.value("message_header_state").toByteArray(); chart_series_type = s.value("chart_series_type", 0).toInt(); + theme = s.value("theme", 0).toInt(); sparkline_range = s.value("sparkline_range", 15).toInt(); } @@ -54,6 +56,12 @@ SettingsDlg::SettingsDlg(QWidget *parent) : QDialog(parent) { setWindowTitle(tr("Settings")); QFormLayout *form_layout = new QFormLayout(this); + theme = new QComboBox(this); + theme->setToolTip(tr("You may need to restart cabana after changes theme")); + theme->addItems({tr("Automatic"), tr("Light"), tr("Dark")}); + theme->setCurrentIndex(settings.theme); + form_layout->addRow(tr("Color Theme"), theme); + fps = new QSpinBox(this); fps->setRange(10, 100); fps->setSingleStep(10); @@ -87,6 +95,7 @@ SettingsDlg::SettingsDlg(QWidget *parent) : QDialog(parent) { void SettingsDlg::save() { settings.fps = fps->value(); + settings.theme = theme->currentIndex(); settings.max_cached_minutes = cached_minutes->value(); settings.chart_series_type = chart_series_type->currentIndex(); settings.chart_height = chart_height->value(); diff --git a/tools/cabana/settings.h b/tools/cabana/settings.h index a8b6d189a5..8076cbf36d 100644 --- a/tools/cabana/settings.h +++ b/tools/cabana/settings.h @@ -19,6 +19,7 @@ public: int chart_column_count = 1; int chart_range = 3 * 60; // 3 minutes int chart_series_type = 0; + int theme = 0; int sparkline_range = 15; // 15 seconds QString last_dir; QString last_route_dir; @@ -42,6 +43,7 @@ public: QSpinBox *cached_minutes; QSpinBox *chart_height; QComboBox *chart_series_type; + QComboBox *theme; }; extern Settings settings; diff --git a/tools/cabana/util.cc b/tools/cabana/util.cc index e5a9749103..8a25b11cbf 100644 --- a/tools/cabana/util.cc +++ b/tools/cabana/util.cc @@ -8,6 +8,7 @@ #include #include "selfdrive/ui/qt/util.h" +#include "tools/cabana/settings.h" static QColor blend(QColor a, QColor b) { return QColor((a.red() + b.red()) / 2, (a.green() + b.green()) / 2, (a.blue() + b.blue()) / 2, (a.alpha() + b.alpha()) / 2); @@ -145,8 +146,7 @@ QValidator::State NameValidator::validate(QString &input, int &pos) const { namespace utils { QPixmap icon(const QString &id) { - static bool dark_theme = QApplication::palette().color(QPalette::WindowText).value() > - QApplication::palette().color(QPalette::Background).value(); + bool dark_theme = settings.theme == 2; QPixmap pm; QString key = "bootstrap_" % id % (dark_theme ? "1" : "0"); if (!QPixmapCache::find(key, &pm)) { @@ -154,12 +154,44 @@ QPixmap icon(const QString &id) { if (dark_theme) { QPainter p(&pm); p.setCompositionMode(QPainter::CompositionMode_SourceIn); - p.fillRect(pm.rect(), Qt::lightGray); + p.fillRect(pm.rect(), Qt::white); } QPixmapCache::insert(key, pm); } return pm; } + +void setTheme(int theme) { + auto style = QApplication::style(); + if (!style) return; + + static int prev_theme = 0; + if (theme != prev_theme) { + prev_theme = theme; + if (theme == 2) { + // modify palette to dark + QPalette darkPalette; + darkPalette.setColor(QPalette::Window, QColor(53, 53, 53)); + darkPalette.setColor(QPalette::WindowText, Qt::white); + darkPalette.setColor(QPalette::Base, QColor(25, 25, 25)); + darkPalette.setColor(QPalette::AlternateBase, QColor(53, 53, 53)); + darkPalette.setColor(QPalette::ToolTipBase, Qt::white); + darkPalette.setColor(QPalette::ToolTipText, QColor(41, 41, 41)); + darkPalette.setColor(QPalette::Text, Qt::white); + darkPalette.setColor(QPalette::Button, QColor(53, 53, 53)); + darkPalette.setColor(QPalette::ButtonText, Qt::white); + darkPalette.setColor(QPalette::BrightText, Qt::red); + darkPalette.setColor(QPalette::Link, QColor(42, 130, 218)); + darkPalette.setColor(QPalette::Highlight, QColor(42, 130, 218)); + darkPalette.setColor(QPalette::HighlightedText, Qt::black); + qApp->setPalette(darkPalette); + } else { + qApp->setPalette(style->standardPalette()); + } + style->polish(qApp); + } +} + } // namespace utils QToolButton *toolButton(const QString &icon, const QString &tooltip) { diff --git a/tools/cabana/util.h b/tools/cabana/util.h index e90a838af8..e0fe4ad036 100644 --- a/tools/cabana/util.h +++ b/tools/cabana/util.h @@ -98,6 +98,7 @@ public: namespace utils { QPixmap icon(const QString &id); +void setTheme(int theme); inline QString formatSeconds(int seconds) { return QDateTime::fromTime_t(seconds).toString(seconds > 60 * 60 ? "hh:mm:ss" : "mm:ss"); } From d16ee6ecc8f38c90da4798f0eeacbfd0c3118de4 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sun, 2 Apr 2023 12:59:13 -0700 Subject: [PATCH 24/24] boardd: log voltage and current from panda (#27789) * boardd: log voltage and current from panda * bump cereal --- cereal | 2 +- selfdrive/boardd/boardd.cc | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/cereal b/cereal index d70d215de6..5827c4e17e 160000 --- a/cereal +++ b/cereal @@ -1 +1 @@ -Subproject commit d70d215de6c584f671272d2de2f46a4f778e9f14 +Subproject commit 5827c4e17ef0c6bb3de24f987ca2f5e0fb3f464b diff --git a/selfdrive/boardd/boardd.cc b/selfdrive/boardd/boardd.cc index 8f045c2a69..ec8be95f94 100644 --- a/selfdrive/boardd/boardd.cc +++ b/selfdrive/boardd/boardd.cc @@ -363,6 +363,8 @@ std::optional send_panda_states(PubMaster *pm, const std::vector } auto ps = pss[i]; + ps.setVoltage(health.voltage_pkt); + ps.setCurrent(health.current_pkt); ps.setUptime(health.uptime_pkt); ps.setSafetyTxBlocked(health.safety_tx_blocked_pkt); ps.setSafetyRxInvalid(health.safety_rx_invalid_pkt);