From 8d9f99b835aeb0d317337d1f87a961e75f8d6468 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Sat, 18 Feb 2023 21:48:13 -0800 Subject: [PATCH 001/102] cabana: add space to help message (#27384) add space --- tools/cabana/mainwin.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/cabana/mainwin.cc b/tools/cabana/mainwin.cc index 07d37df4e4..2cba29bf5e 100644 --- a/tools/cabana/mainwin.cc +++ b/tools/cabana/mainwin.cc @@ -176,7 +176,7 @@ void MainWindow::createStatusBar() { progress_bar->setTextVisible(true); progress_bar->setFixedSize({230, 16}); progress_bar->setVisible(false); - statusBar()->addWidget(new QLabel(tr("For Help,Press F1"))); + statusBar()->addWidget(new QLabel(tr("For Help, Press F1"))); statusBar()->addPermanentWidget(progress_bar); } From 8e3cb0fb2075cc0e21f0362dad467cd992291c3a Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Mon, 20 Feb 2023 07:14:13 +0800 Subject: [PATCH 002/102] cabana: add qrc resource file (#27386) * add qrc resource file * remove export --- selfdrive/ui/SConscript | 1 - tools/cabana/SConscript | 10 ++++++++-- tools/cabana/assets/.gitignore | 1 + tools/cabana/assets/assets.qrc | 5 +++++ 4 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 tools/cabana/assets/.gitignore create mode 100644 tools/cabana/assets/assets.qrc diff --git a/selfdrive/ui/SConscript b/selfdrive/ui/SConscript index 0f28f5ccc3..a8c8463bd7 100644 --- a/selfdrive/ui/SConscript +++ b/selfdrive/ui/SConscript @@ -42,7 +42,6 @@ assets_src = "#selfdrive/assets/assets.qrc" qt_env.Command(assets, assets_src, f"rcc $SOURCES -o $TARGET") qt_env.Depends(assets, Glob('#selfdrive/assets/*', exclude=[assets, assets_src, "#selfdrive/assets/assets.o"])) asset_obj = qt_env.Object("assets", assets) -Export('asset_obj') # build soundd qt_env.Program("soundd/_soundd", ["soundd/main.cc", "soundd/sound.cc"], LIBS=qt_libs) diff --git a/tools/cabana/SConscript b/tools/cabana/SConscript index 166b3d5548..ddd6208c07 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', 'asset_obj') + 'cereal', 'transformations', 'widgets', 'opendbc') base_frameworks = qt_env['FRAMEWORKS'] base_libs = [common, messaging, cereal, visionipc, transformations, 'zmq', @@ -20,11 +20,17 @@ cabana_env = qt_env.Clone() opendbc_path = '-DOPENDBC_FILE_PATH=\'"%s"\'' % (cabana_env.Dir("../../opendbc").abspath) cabana_env['CXXFLAGS'] += [opendbc_path] +# build assets +assets = "assets/assets.cc" +assets_src = "assets/assets.qrc" +cabana_env.Command(assets, assets_src, f"rcc $SOURCES -o $TARGET") +cabana_env.Depends(assets, Glob('/assets/*', exclude=[assets, assets_src, "assets/assets.o"])) + prev_moc_path = cabana_env['QT_MOCHPREFIX'] 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', 'signaledit.cc', '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, asset_obj], 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') diff --git a/tools/cabana/assets/.gitignore b/tools/cabana/assets/.gitignore new file mode 100644 index 0000000000..283034ca8b --- /dev/null +++ b/tools/cabana/assets/.gitignore @@ -0,0 +1 @@ +*.cc diff --git a/tools/cabana/assets/assets.qrc b/tools/cabana/assets/assets.qrc new file mode 100644 index 0000000000..b42f2a82b1 --- /dev/null +++ b/tools/cabana/assets/assets.qrc @@ -0,0 +1,5 @@ + + + ../../../third_party/bootstrap/bootstrap-icons.svg + + From c7cc36d9ee22aea2e07aab61d51f0f949b64bcf5 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Mon, 20 Feb 2023 13:15:59 -0800 Subject: [PATCH 003/102] cabana: add window icon (#27109) * add logos * most zoomed in * add alt * slightly zoomed more * add images * add draft images * best image * not working * 96px icon image to reduce compiled size * remove from selfdrive assets * fixes --- tools/cabana/assets/assets.qrc | 1 + tools/cabana/assets/cabana-icon.png | Bin 0 -> 18008 bytes tools/cabana/cabana.cc | 1 + 3 files changed, 2 insertions(+) create mode 100644 tools/cabana/assets/cabana-icon.png diff --git a/tools/cabana/assets/assets.qrc b/tools/cabana/assets/assets.qrc index b42f2a82b1..6a8e5a3414 100644 --- a/tools/cabana/assets/assets.qrc +++ b/tools/cabana/assets/assets.qrc @@ -1,5 +1,6 @@ ../../../third_party/bootstrap/bootstrap-icons.svg + cabana-icon.png diff --git a/tools/cabana/assets/cabana-icon.png b/tools/cabana/assets/cabana-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..86add806fd1cabcd145ceef74a3995bc609d34fb GIT binary patch literal 18008 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 literal 0 HcmV?d00001 diff --git a/tools/cabana/cabana.cc b/tools/cabana/cabana.cc index e028e383c2..5c182f435f 100644 --- a/tools/cabana/cabana.cc +++ b/tools/cabana/cabana.cc @@ -14,6 +14,7 @@ int main(int argc, char *argv[]) { initApp(argc, argv); QApplication app(argc, argv); app.setApplicationDisplayName("Cabana"); + app.setWindowIcon(QIcon(":cabana-icon.png")); QCommandLineParser cmd_parser; cmd_parser.addHelpOption(); From a20f07144beb26e4ade7b3c5dc6e4be40ff5a12d Mon Sep 17 00:00:00 2001 From: Jason Wen <47793918+sunnyhaibin@users.noreply.github.com> Date: Mon, 20 Feb 2023 16:19:17 -0500 Subject: [PATCH 004/102] Hyundai CAN-FD: common PT bus function cleanup (#27397) * Hyundai CAN-FD: common PT bus function cleanup * use CP * Update selfdrive/car/hyundai/hyundaicanfd.py --------- Co-authored-by: Shane Smiskol --- selfdrive/car/hyundai/interface.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/selfdrive/car/hyundai/interface.py b/selfdrive/car/hyundai/interface.py index 2a909b6e2e..1dd91ac888 100644 --- a/selfdrive/car/hyundai/interface.py +++ b/selfdrive/car/hyundai/interface.py @@ -2,6 +2,7 @@ from cereal import car from panda import Panda from common.conversions import Conversions as CV +from selfdrive.car.hyundai.hyundaicanfd import get_e_can_bus from selfdrive.car.hyundai.values import HyundaiFlags, CAR, DBC, CANFD_CAR, CAMERA_SCC_CAR, CANFD_RADAR_SCC_CAR, EV_CAR, HYBRID_CAR, LEGACY_SAFETY_MODE_CAR, Buttons from selfdrive.car.hyundai.radar_interface import RADAR_START_ADDR from selfdrive.car import STD_CARGO_KG, create_button_event, scale_tire_stiffness, get_safety_config @@ -247,8 +248,7 @@ class CarInterface(CarInterfaceBase): # *** feature detection *** if candidate in CANFD_CAR: - bus = 5 if ret.flags & HyundaiFlags.CANFD_HDA2 else 4 - ret.enableBsm = 0x1e5 in fingerprint[bus] + ret.enableBsm = 0x1e5 in fingerprint[get_e_can_bus(ret)] else: ret.enableBsm = 0x58b in fingerprint[0] From 4918daaf5d8578c467f9626afc0ae0d6dafd9422 Mon Sep 17 00:00:00 2001 From: Matt Crum Date: Mon, 20 Feb 2023 15:25:46 -0600 Subject: [PATCH 005/102] Added FW for 2023 Hyundai Santa Cruz Limited (#27395) * Update values.py Added additional firmware version for Santa Cruz 1st Gen forward camera Updated CAR.SANTA_CRUZ_1ST_GEN's information to include 2023 models * Update values.py added fwdRadar firmware version * Update CARS.md Updated to include 2023 Hyundai Santa Cruz --- docs/CARS.md | 2 +- selfdrive/car/hyundai/values.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/CARS.md b/docs/CARS.md index 8860299360..5a29a63f45 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -79,7 +79,7 @@ A supported vehicle is one that just works when you install a comma three. All s |Hyundai|Kona Electric 2022|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai O|| |Hyundai|Kona Hybrid 2020|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai I|| |Hyundai|Palisade 2020-22|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai H|| -|Hyundai|Santa Cruz 2021-22[5](#footnotes)|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai N|| +|Hyundai|Santa Cruz 2021-23[5](#footnotes)|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai N|| |Hyundai|Santa Fe 2019-20|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai D|| |Hyundai|Santa Fe 2021-22|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai L|| |Hyundai|Santa Fe Hybrid 2022|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai L|| diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index d0a4e4dd1a..7a16b47a4d 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -191,7 +191,7 @@ CAR_INFO: Dict[str, Optional[Union[HyundaiCarInfo, List[HyundaiCarInfo]]]] = { HyundaiCarInfo("Hyundai Tucson 2023", "All", harness=Harness.hyundai_n), ], CAR.TUCSON_HYBRID_4TH_GEN: HyundaiCarInfo("Hyundai Tucson Hybrid 2022", "All", harness=Harness.hyundai_n), - CAR.SANTA_CRUZ_1ST_GEN: HyundaiCarInfo("Hyundai Santa Cruz 2021-22", harness=Harness.hyundai_n), + CAR.SANTA_CRUZ_1ST_GEN: HyundaiCarInfo("Hyundai Santa Cruz 2021-23", harness=Harness.hyundai_n), # Kia CAR.KIA_FORTE: HyundaiCarInfo("Kia Forte 2019-21", harness=Harness.hyundai_g), @@ -1597,9 +1597,11 @@ FW_VERSIONS = { CAR.SANTA_CRUZ_1ST_GEN: { (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00NX4 FR_CMR AT USA LHD 1.00 1.00 99211-CW000 14M', + b'\xf1\x00NX4 FR_CMR AT USA LHD 1.00 1.00 99211-CW010 14X', ], (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00NX4__ 1.00 1.00 99110-K5000 ', + b'\xf1\x00NX4__ 1.01 1.00 99110-K5000 ', ], }, CAR.KIA_SPORTAGE_5TH_GEN: { From 927289cda8cd8465c1161e64026d7839cc4fc938 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Mon, 20 Feb 2023 13:25:52 -0800 Subject: [PATCH 006/102] increase fetch depth for release submodule check --- release/check-submodules.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/check-submodules.sh b/release/check-submodules.sh index bc85a43c57..2585db6bd7 100755 --- a/release/check-submodules.sh +++ b/release/check-submodules.sh @@ -1,7 +1,7 @@ #!/bin/bash while read hash submodule ref; do - git -C $submodule fetch --depth 200 origin master + git -C $submodule fetch --depth 300 origin master git -C $submodule branch -r --contains $hash | grep "origin/master" if [ "$?" -eq 0 ]; then echo "$submodule ok" From 55da5175aea1a4d206001f2c51d66f4cdf6799c2 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Mon, 20 Feb 2023 13:29:37 -0800 Subject: [PATCH 007/102] HKG: update Santa Cruz model years (#27401) 2021 Santa Cruz doesn't exist --- docs/CARS.md | 2 +- selfdrive/car/hyundai/values.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/CARS.md b/docs/CARS.md index 5a29a63f45..1b2ec8a2c8 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -79,7 +79,7 @@ A supported vehicle is one that just works when you install a comma three. All s |Hyundai|Kona Electric 2022|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai O|| |Hyundai|Kona Hybrid 2020|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai I|| |Hyundai|Palisade 2020-22|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai H|| -|Hyundai|Santa Cruz 2021-23[5](#footnotes)|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai N|| +|Hyundai|Santa Cruz 2022-23[5](#footnotes)|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai N|| |Hyundai|Santa Fe 2019-20|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai D|| |Hyundai|Santa Fe 2021-22|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai L|| |Hyundai|Santa Fe Hybrid 2022|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai L|| diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index 7a16b47a4d..49645fb0b1 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -191,7 +191,7 @@ CAR_INFO: Dict[str, Optional[Union[HyundaiCarInfo, List[HyundaiCarInfo]]]] = { HyundaiCarInfo("Hyundai Tucson 2023", "All", harness=Harness.hyundai_n), ], CAR.TUCSON_HYBRID_4TH_GEN: HyundaiCarInfo("Hyundai Tucson Hybrid 2022", "All", harness=Harness.hyundai_n), - CAR.SANTA_CRUZ_1ST_GEN: HyundaiCarInfo("Hyundai Santa Cruz 2021-23", harness=Harness.hyundai_n), + CAR.SANTA_CRUZ_1ST_GEN: HyundaiCarInfo("Hyundai Santa Cruz 2022-23", harness=Harness.hyundai_n), # Kia CAR.KIA_FORTE: HyundaiCarInfo("Kia Forte 2019-21", harness=Harness.hyundai_g), From 1f89afd1401176641443090fde6ca7a787c890a9 Mon Sep 17 00:00:00 2001 From: ntegan1 Date: Mon, 20 Feb 2023 16:31:30 -0500 Subject: [PATCH 008/102] cabana: missing includes (#27390) --- tools/cabana/dbcmanager.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/cabana/dbcmanager.h b/tools/cabana/dbcmanager.h index b438b3e1c2..267157b31a 100644 --- a/tools/cabana/dbcmanager.h +++ b/tools/cabana/dbcmanager.h @@ -2,6 +2,8 @@ #include #include +#include +#include #include struct MessageId { From bd469d7c54a0cf32b0d038e1d2e72b737071eb94 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Mon, 20 Feb 2023 13:32:52 -0800 Subject: [PATCH 009/102] bump panda --- panda | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda b/panda index 0d2ee00921..d2c2d5f926 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 0d2ee009218009173f26c73a16aefa12dd169de8 +Subproject commit d2c2d5f926537a132a253277998ef350fe866d27 From 10ed70d95293375a36d57d103b7173dc637e861a Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Tue, 21 Feb 2023 05:52:16 +0800 Subject: [PATCH 010/102] cabana: show command's text in statusbar (#27398) --- tools/cabana/commands.cc | 24 +++++++++++++----------- tools/cabana/commands.h | 4 ++-- tools/cabana/mainwin.cc | 22 ++++++++++++++++++++++ tools/cabana/mainwin.h | 3 +++ 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/tools/cabana/commands.cc b/tools/cabana/commands.cc index e03d6d1b11..70700b33b9 100644 --- a/tools/cabana/commands.cc +++ b/tools/cabana/commands.cc @@ -4,24 +4,26 @@ // EditMsgCommand -EditMsgCommand::EditMsgCommand(const MessageId &id, const QString &title, int size, QUndoCommand *parent) - : id(id), new_title(title), new_size(size), QUndoCommand(parent) { +EditMsgCommand::EditMsgCommand(const MessageId &id, const QString &name, int size, QUndoCommand *parent) + : id(id), new_name(name), new_size(size), QUndoCommand(parent) { if (auto msg = dbc()->msg(id)) { - old_title = msg->name; + old_name = msg->name; old_size = msg->size; + setText(QObject::tr("edit message %1:%2").arg(name).arg(id.address)); + } else { + setText(QObject::tr("new message %1:%2").arg(name).arg(id.address)); } - setText(QObject::tr("Edit message %1:%2").arg(id.address).arg(title)); } void EditMsgCommand::undo() { - if (old_title.isEmpty()) + if (old_name.isEmpty()) dbc()->removeMsg(id); else - dbc()->updateMsg(id, old_title, old_size); + dbc()->updateMsg(id, old_name, old_size); } void EditMsgCommand::redo() { - dbc()->updateMsg(id, new_title, new_size); + dbc()->updateMsg(id, new_name, new_size); } // RemoveMsgCommand @@ -29,7 +31,7 @@ void EditMsgCommand::redo() { RemoveMsgCommand::RemoveMsgCommand(const MessageId &id, QUndoCommand *parent) : id(id), QUndoCommand(parent) { if (auto msg = dbc()->msg(id)) { message = *msg; - setText(QObject::tr("Remove message %1:%2").arg(id.address).arg(message.name)); + setText(QObject::tr("remove message %1:%2").arg(message.name).arg(id.address)); } } @@ -50,7 +52,7 @@ void RemoveMsgCommand::redo() { AddSigCommand::AddSigCommand(const MessageId &id, const Signal &sig, QUndoCommand *parent) : id(id), signal(sig), QUndoCommand(parent) { - setText(QObject::tr("Add signal %1 to %2").arg(sig.name).arg(id.address)); + setText(QObject::tr("add signal %1 to %2:%3").arg(sig.name).arg(msgName(id)).arg(id.address)); } void AddSigCommand::undo() { dbc()->removeSignal(id, signal.name); } @@ -60,7 +62,7 @@ void AddSigCommand::redo() { dbc()->addSignal(id, signal); } RemoveSigCommand::RemoveSigCommand(const MessageId &id, const Signal *sig, QUndoCommand *parent) : id(id), signal(*sig), QUndoCommand(parent) { - setText(QObject::tr("Remove signal %1 from %2").arg(signal.name).arg(id.address)); + setText(QObject::tr("remove signal %1 from %2:%3").arg(signal.name).arg(msgName(id)).arg(id.address)); } void RemoveSigCommand::undo() { dbc()->addSignal(id, signal); } @@ -70,7 +72,7 @@ void RemoveSigCommand::redo() { dbc()->removeSignal(id, signal.name); } EditSignalCommand::EditSignalCommand(const MessageId &id, const Signal *sig, const Signal &new_sig, QUndoCommand *parent) : id(id), old_signal(*sig), new_signal(new_sig), QUndoCommand(parent) { - setText(QObject::tr("Edit signal %1").arg(old_signal.name)); + setText(QObject::tr("edit signal %1 in %2:%3").arg(old_signal.name).arg(msgName(id)).arg(id.address)); } void EditSignalCommand::undo() { dbc()->updateSignal(id, new_signal.name, old_signal); } diff --git a/tools/cabana/commands.h b/tools/cabana/commands.h index 57df664974..3565211eb9 100644 --- a/tools/cabana/commands.h +++ b/tools/cabana/commands.h @@ -9,13 +9,13 @@ using namespace dbcmanager; class EditMsgCommand : public QUndoCommand { public: - EditMsgCommand(const MessageId &id, const QString &title, int size, QUndoCommand *parent = nullptr); + EditMsgCommand(const MessageId &id, const QString &name, int size, QUndoCommand *parent = nullptr); void undo() override; void redo() override; private: const MessageId id; - QString old_title, new_title; + QString old_name, new_name; int old_size = 0, new_size = 0; }; diff --git a/tools/cabana/mainwin.cc b/tools/cabana/mainwin.cc index 2cba29bf5e..47ad3a4a6d 100644 --- a/tools/cabana/mainwin.cc +++ b/tools/cabana/mainwin.cc @@ -65,6 +65,7 @@ MainWindow::MainWindow() : QMainWindow() { QObject::connect(can, &AbstractStream::streamStarted, this, &MainWindow::loadDBCFromFingerprint); QObject::connect(dbc(), &DBCManager::DBCFileChanged, this, &MainWindow::DBCFileChanged); QObject::connect(UndoStack::instance(), &QUndoStack::cleanChanged, this, &MainWindow::undoStackCleanChanged); + QObject::connect(UndoStack::instance(), &QUndoStack::indexChanged, this, &MainWindow::undoStackIndexChanged); } void MainWindow::createActions() { @@ -186,7 +187,28 @@ void MainWindow::createShortcuts() { // TODO: add more shortcuts here. } +void MainWindow::undoStackIndexChanged(int index) { + int count = UndoStack::instance()->count(); + if (count >= 0) { + QString command_text; + if (index == count) { + command_text = (count == prev_undostack_count ? "Redo " : "") + UndoStack::instance()->text(index - 1); + } else if (index < prev_undostack_index) { + command_text = tr("Undo %1").arg(UndoStack::instance()->text(index)); + } else if (index > prev_undostack_index) { + command_text = tr("Redo %1").arg(UndoStack::instance()->text(index - 1)); + } + statusBar()->showMessage(command_text, 2000); + } + prev_undostack_index = index; + prev_undostack_count = count; +} + void MainWindow::undoStackCleanChanged(bool clean) { + if (clean) { + prev_undostack_index = 0; + prev_undostack_count = 0; + } setWindowModified(!clean); } diff --git a/tools/cabana/mainwin.h b/tools/cabana/mainwin.h index e7a39adab7..85d221a231 100644 --- a/tools/cabana/mainwin.h +++ b/tools/cabana/mainwin.h @@ -54,6 +54,7 @@ protected: void setOption(); void findSimilarBits(); void undoStackCleanChanged(bool clean); + void undoStackIndexChanged(int index); void onlineHelp(); VideoWidget *video_widget = nullptr; @@ -70,6 +71,8 @@ protected: enum { MAX_RECENT_FILES = 15 }; QAction *recent_files_acts[MAX_RECENT_FILES] = {}; QMenu *open_recent_menu = nullptr; + int prev_undostack_index = 0; + int prev_undostack_count = 0; friend class OnlineHelp; }; From ba3d3bd940d1796c863b80a7d27291c9c6249440 Mon Sep 17 00:00:00 2001 From: Chris Hart Date: Mon, 20 Feb 2023 14:03:42 -0800 Subject: [PATCH 011/102] SANTA_FE_2022: add missing transmission FW (#27369) * Added new fingerprints for updated SANTAFE_2022 * Update values.py fixed missing comma that was breaking build * Revert "Update values.py" This reverts commit 58837eadd4cfb57ec56a45592c21b251e6c52957. * Revert "Added new fingerprints for updated SANTAFE_2022" This reverts commit 3bec6e0196e9fcac83a34f79b7b860f2e24aa763. * add FW, remove radar FW from long query --------- Co-authored-by: Chris Hart Co-authored-by: Shane Smiskol --- selfdrive/car/hyundai/values.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index 49645fb0b1..4b7a295246 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -751,7 +751,6 @@ FW_VERSIONS = { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00TM__ SCC F-CUP 1.00 1.00 99110-S1500 ', b'\xf1\x8799110S1500\xf1\x00TM__ SCC F-CUP 1.00 1.00 99110-S1500 ', - b'\xf1\x8799110S1500\xf1\x00TM__ SCC FHCUP 1.00 1.00 99110-S1500 ', b'\xf1\x00TM__ SCC FHCUP 1.00 1.00 99110-S1500 ', ], (Ecu.abs, 0x7d1, None): [ @@ -785,6 +784,7 @@ FW_VERSIONS = { b'\xf1\x00TMA MFC AT USA LHD 1.00 1.01 99211-S2500 210205', ], (Ecu.transmission, 0x7e1, None): [ + b'\xf1\x00T02601BL T02900A1 VTMPT25XXX900NSA\xf3\xf4Uj', b'\xf1\x87SDMXCA9087684GN1VfvgUUeVwwgwwwwwffffU?\xfb\xff\x97\x88\x7f\xff+\xa4\xf1\x89HT6WAD00A1\xf1\x82STM4G25NH1\x00\x00\x00\x00\x00\x00', b'\xf1\x00T02601BL T02730A1 VTMPT25XXX730NS2\xa6\x06\x88\xf7', b'\xf1\x87SDMXCA8653204GN1EVugEUuWwwwwww\x87wwwwwv/\xfb\xff\xa8\x88\x9f\xff\xa5\x9c\xf1\x89HT6WAD00A1\xf1\x82STM4G25NH1\x00\x00\x00\x00\x00\x00', From 1bd15f00a70b72caa99e7be87571595adb5ea074 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Mon, 20 Feb 2023 14:07:22 -0800 Subject: [PATCH 012/102] Toyota: expand C-HR Hybrid model years (#27402) we probably support 2021 too --- docs/CARS.md | 2 +- selfdrive/car/toyota/values.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/CARS.md b/docs/CARS.md index 1b2ec8a2c8..59eece1e4b 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -179,7 +179,7 @@ A supported vehicle is one that just works when you install a comma three. All s |Toyota|C-HR 2017-20|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|| |Toyota|C-HR 2021|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|| |Toyota|C-HR Hybrid 2017-19|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|| -|Toyota|C-HR Hybrid 2022|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|| +|Toyota|C-HR Hybrid 2021-22|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|| |Toyota|Camry 2018-20|All|Stock|0 mph[6](#footnotes)|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|| |Toyota|Camry 2021-22|All|openpilot|0 mph[6](#footnotes)|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|| |Toyota|Camry Hybrid 2018-20|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|| diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py index b6a556438d..8e118293ee 100644 --- a/selfdrive/car/toyota/values.py +++ b/selfdrive/car/toyota/values.py @@ -120,7 +120,7 @@ CAR_INFO: Dict[str, Union[ToyotaCarInfo, List[ToyotaCarInfo]]] = { CAR.CHR: ToyotaCarInfo("Toyota C-HR 2017-20"), CAR.CHR_TSS2: ToyotaCarInfo("Toyota C-HR 2021"), CAR.CHRH: ToyotaCarInfo("Toyota C-HR Hybrid 2017-19"), - CAR.CHRH_TSS2: ToyotaCarInfo("Toyota C-HR Hybrid 2022"), + CAR.CHRH_TSS2: ToyotaCarInfo("Toyota C-HR Hybrid 2021-22"), CAR.COROLLA: ToyotaCarInfo("Toyota Corolla 2017-19"), CAR.COROLLA_TSS2: [ ToyotaCarInfo("Toyota Corolla 2020-22", video_link="https://www.youtube.com/watch?v=_66pXk0CBYA"), From e1051e5e5c52267407cca864f984fee2328c2cce Mon Sep 17 00:00:00 2001 From: kaischiefer-srd <106266385+kaischiefer-srd@users.noreply.github.com> Date: Mon, 20 Feb 2023 17:11:46 -0500 Subject: [PATCH 013/102] Toyota: add engine FW for 2021 NX300 (#27326) added engine fw for our 2021 NX300 F sport --- selfdrive/car/toyota/values.py | 1 + 1 file changed, 1 insertion(+) diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py index 8e118293ee..0fcabe163c 100644 --- a/selfdrive/car/toyota/values.py +++ b/selfdrive/car/toyota/values.py @@ -1726,6 +1726,7 @@ FW_VERSIONS = { (Ecu.engine, 0x700, None): [ b'\x018966378B2100\x00\x00\x00\x00', b'\x018966378B3000\x00\x00\x00\x00', + b'\x018966378B4100\x00\x00\x00\x00', b'\x018966378G3000\x00\x00\x00\x00', b'\x018966378B2000\x00\x00\x00\x00', ], From 4efd246bac004f3b6f1f7d733e6e285b3fdc8322 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Tue, 21 Feb 2023 06:16:30 +0800 Subject: [PATCH 014/102] cabana: improve UI & fix bugs (#27387) * improve ui * keep splitter size after msg changed * no leading spaces allowed in msg filter and signal filter * draw color byte AlignCenter * always set as current index * reduce chart flickers while resizing * dispaly more info in tooltip for signal * narrow combobox * use   * typo * private sigs,fix bugs * merge #27383 * no expanding after undo/redo * gray color in tooltip * clear current_msg_id before reset model * dont call setmeesage if id is the same * fix bugs * cleanup * dont fetch logs if invisible * add new CenterWidget, make sure msg_id is always valid * cache icons * cleanup paint byte color * merge #27385 implement sizeHint * cleanup code * fillrect if alpha>0 --- tools/cabana/binaryview.cc | 90 +++++++++--------- tools/cabana/binaryview.h | 4 +- tools/cabana/chartswidget.cc | 29 +++--- tools/cabana/chartswidget.h | 2 +- tools/cabana/commands.cc | 4 +- tools/cabana/dbcmanager.cc | 53 ++++++----- tools/cabana/dbcmanager.h | 6 +- tools/cabana/detailwidget.cc | 122 +++++++++++++------------ tools/cabana/detailwidget.h | 27 +++--- tools/cabana/historylog.cc | 76 ++++++++------- tools/cabana/historylog.h | 17 ++-- tools/cabana/mainwin.cc | 10 +- tools/cabana/mainwin.h | 2 +- tools/cabana/messageswidget.cc | 28 +++--- tools/cabana/messageswidget.h | 3 - tools/cabana/signaledit.cc | 83 ++++++++--------- tools/cabana/signaledit.h | 6 +- tools/cabana/streams/abstractstream.cc | 10 +- tools/cabana/tests/test_cabana.cc | 14 +-- tools/cabana/util.cc | 49 +++++----- tools/cabana/util.h | 4 + tools/cabana/videowidget.cc | 4 +- 22 files changed, 344 insertions(+), 299 deletions(-) diff --git a/tools/cabana/binaryview.cc b/tools/cabana/binaryview.cc index 5ea5ea2d99..d9b00f6882 100644 --- a/tools/cabana/binaryview.cc +++ b/tools/cabana/binaryview.cc @@ -32,7 +32,6 @@ BinaryView::BinaryView(QWidget *parent) : QTableView(parent) { verticalHeader()->setSectionResizeMode(QHeaderView::Fixed); verticalHeader()->setDefaultSectionSize(CELL_HEIGHT); horizontalHeader()->hide(); - setFrameShape(QFrame::NoFrame); setShowGrid(false); setMouseTracking(true); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); @@ -44,17 +43,17 @@ BinaryView::BinaryView(QWidget *parent) : QTableView(parent) { setWhatsThis(R"( Binary View
- Shortcuts:
+ Shortcuts
Delete Signal: - x , - Backspace , - Delete
- Change endianness: e
- Change singedness: s
+  x , +  Backspace , +  Delete 
+ Change endianness:  e 
+ Change singedness:  s 
Open chart: - c , - p , - g
+  c , +  p , +  g  )"); } @@ -108,14 +107,14 @@ void BinaryView::addShortcuts() { QObject::connect(shortcut_plot_c, &QShortcut::activated, shortcut_plot, &QShortcut::activated); QObject::connect(shortcut_plot, &QShortcut::activated, [=]{ if (hovered_sig != nullptr) { - emit showChart(*model->msg_id, hovered_sig, true, false); + emit showChart(model->msg_id, hovered_sig, true, false); } }); } QSize BinaryView::minimumSizeHint() const { - return {(horizontalHeader()->minimumSectionSize() + 1) * 9 + VERTICAL_HEADER_WIDTH, - CELL_HEIGHT * std::min(model->rowCount(), 10)}; + return {(horizontalHeader()->minimumSectionSize() + 1) * 9 + VERTICAL_HEADER_WIDTH + 2, + CELL_HEIGHT * std::min(model->rowCount(), 10) + 2}; } void BinaryView::highlight(const Signal *sig) { @@ -127,6 +126,16 @@ void BinaryView::highlight(const Signal *sig) { emit model->dataChanged(index, index, {Qt::DisplayRole}); } } + + if (sig && underMouse()) { + QString tooltip = tr(R"(%1
+ Size:%2 LE:%3 SGD:%4 + )").arg(sig->name).arg(sig->size).arg(sig->is_little_endian ? "Y" : "N").arg(sig->is_signed ? "Y" : "N"); + QToolTip::showText(QCursor::pos(), tooltip, this, rect()); + } else { + QToolTip::showText(QCursor::pos(), "", this, rect()); + } + hovered_sig = sig; emit signalHovered(hovered_sig); } @@ -169,7 +178,6 @@ void BinaryView::highlightPosition(const QPoint &pos) { auto item = (BinaryViewModel::Item *)index.internalPointer(); const Signal *sig = item->sigs.isEmpty() ? nullptr : item->sigs.back(); highlight(sig); - QToolTip::showText(pos, sig ? sig->name : "", this, rect()); } } @@ -210,8 +218,6 @@ void BinaryView::setMessage(const MessageId &message_id) { } void BinaryView::refresh() { - if (!model->msg_id) return; - clearSelection(); anchor_index = QModelIndex(); resize_sig = nullptr; @@ -245,26 +251,26 @@ std::tuple BinaryView::getSelection(QModelIndex index) { void BinaryViewModel::refresh() { beginResetModel(); items.clear(); - if (auto dbc_msg = dbc()->msg(*msg_id)) { + if (auto dbc_msg = dbc()->msg(msg_id)) { row_count = dbc_msg->size; items.resize(row_count * column_count); - for (auto &sig : dbc_msg->sigs) { - auto [start, end] = getSignalRange(&sig); + for (auto sig : dbc_msg->getSignals()) { + auto [start, end] = getSignalRange(sig); for (int j = start; j <= end; ++j) { - int bit_index = sig.is_little_endian ? bigEndianBitIndex(j) : j; + int bit_index = sig->is_little_endian ? bigEndianBitIndex(j) : j; int idx = column_count * (bit_index / 8) + bit_index % 8; if (idx >= items.size()) { - qWarning() << "signal " << sig.name << "out of bounds.start_bit:" << sig.start_bit << "size:" << sig.size; + qWarning() << "signal " << sig->name << "out of bounds.start_bit:" << sig->start_bit << "size:" << sig->size; break; } - if (j == start) sig.is_little_endian ? items[idx].is_lsb = true : items[idx].is_msb = true; - if (j == end) sig.is_little_endian ? items[idx].is_msb = true : items[idx].is_lsb = true; - items[idx].bg_color = getColor(&sig); - items[idx].sigs.push_back(&sig); + if (j == start) sig->is_little_endian ? items[idx].is_lsb = true : items[idx].is_msb = true; + if (j == end) sig->is_little_endian ? items[idx].is_msb = true : items[idx].is_lsb = true; + items[idx].bg_color = getColor(sig); + items[idx].sigs.push_back(sig); } } } else { - row_count = can->lastMessage(*msg_id).dat.size(); + row_count = can->lastMessage(msg_id).dat.size(); items.resize(row_count * column_count); } endResetModel(); @@ -273,7 +279,7 @@ void BinaryViewModel::refresh() { void BinaryViewModel::updateState() { auto prev_items = items; - const auto &last_msg = can->lastMessage(*msg_id); + const auto &last_msg = can->lastMessage(msg_id); const auto &binary = last_msg.dat; // data size may changed. @@ -283,33 +289,29 @@ void BinaryViewModel::updateState() { items.resize(row_count * column_count); endInsertRows(); } + + double max_f = 255.0; + double factor = 0.25; + double scaler = max_f / log2(1.0 + factor); char hex[3] = {'\0'}; for (int i = 0; i < binary.size(); ++i) { for (int j = 0; j < 8; ++j) { - items[i * column_count + j].val = ((binary[i] >> (7 - j)) & 1) != 0 ? '1' : '0'; - + auto &item = items[i * column_count + j]; + item.val = ((binary[i] >> (7 - j)) & 1) != 0 ? '1' : '0'; // Bit update frequency based highlighting - bool has_signal = items[i * column_count + j].sigs.size() > 0; - double offset = has_signal ? 50 : 0; - - double min_f = last_msg.bit_change_counts[i][7 - j] == 0 ? offset : offset + 25; - double max_f = 255.0; - - double factor = 0.25; - double scaler = max_f / log2(1.0 + factor); - - double alpha = std::clamp(offset + log2(1.0 + factor * (double)last_msg.bit_change_counts[i][7 - j] / (double)last_msg.count) * scaler, min_f, max_f); - items[i * column_count + j].bg_color.setAlpha(alpha); + double offset = !item.sigs.empty() ? 50 : 0; + auto n = last_msg.bit_change_counts[i][7 - j]; + double min_f = n == 0 ? offset : offset + 25; + double alpha = std::clamp(offset + log2(1.0 + factor * (double)n / (double)last_msg.count) * scaler, min_f, max_f); + item.bg_color.setAlpha(alpha); } hex[0] = toHex(binary[i] >> 4); hex[1] = toHex(binary[i] & 0xf); items[i * column_count + 8].val = hex; items[i * column_count + 8].bg_color = last_msg.colors[i]; } - for (int i = binary.size(); i < row_count; ++i) { - for (int j = 0; j < column_count; ++j) { - items[i * column_count + j].val = "-"; - } + for (int i = binary.size() * column_count; i < items.size(); ++i) { + items[i].val = "-"; } for (int i = 0; i < items.size(); ++i) { diff --git a/tools/cabana/binaryview.h b/tools/cabana/binaryview.h index 1d6d5d0b07..681ac1fbf3 100644 --- a/tools/cabana/binaryview.h +++ b/tools/cabana/binaryview.h @@ -1,7 +1,5 @@ #pragma once -#include - #include #include #include @@ -50,7 +48,7 @@ public: }; std::vector items; - std::optional msg_id; + MessageId msg_id; int row_count = 0; const int column_count = 9; }; diff --git a/tools/cabana/chartswidget.cc b/tools/cabana/chartswidget.cc index 8515ffcfe7..e315f82398 100644 --- a/tools/cabana/chartswidget.cc +++ b/tools/cabana/chartswidget.cc @@ -11,15 +11,16 @@ #include #include #include -#include #include #include const int MAX_COLUMN_COUNT = 4; // ChartsWidget -ChartsWidget::ChartsWidget(QWidget *parent) : QWidget(parent) { +ChartsWidget::ChartsWidget(QWidget *parent) : QFrame(parent) { + setFrameStyle(QFrame::StyledPanel | QFrame::Plain); QVBoxLayout *main_layout = new QVBoxLayout(this); + main_layout->setContentsMargins(0, 0, 0, 0); // toolbar QToolBar *toolbar = new QToolBar(tr("Charts"), this); @@ -43,6 +44,7 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QWidget(parent) { range_lb_action = toolbar->addWidget(range_lb = new QLabel(this)); range_slider = new QSlider(Qt::Horizontal, this); + range_slider->setMaximumWidth(200); range_slider->setToolTip(tr("Set the chart range")); range_slider->setRange(1, settings.max_cached_minutes * 60); range_slider->setSingleStep(1); @@ -67,6 +69,7 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QWidget(parent) { charts_main_layout->addStretch(0); QScrollArea *charts_scroll = new QScrollArea(this); + charts_scroll->setFrameStyle(QFrame::NoFrame); charts_scroll->setWidgetResizable(true); charts_scroll->setWidget(charts_container); charts_scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); @@ -329,18 +332,12 @@ ChartView::ChartView(QWidget *parent) : QChartView(nullptr, parent) { move_icon = new QGraphicsPixmapItem(utils::icon("grip-horizontal"), chart); move_icon->setToolTip(tr("Drag and drop to combine charts")); - QToolButton *remove_btn = new QToolButton(); - remove_btn->setIcon(utils::icon("x")); - remove_btn->setAutoRaise(true); - remove_btn->setToolTip(tr("Remove Chart")); + QToolButton *remove_btn = toolButton("x", tr("Remove Chart")); close_btn_proxy = new QGraphicsProxyWidget(chart); close_btn_proxy->setWidget(remove_btn); close_btn_proxy->setZValue(chart->zValue() + 11); - QToolButton *manage_btn = new QToolButton(); - manage_btn->setToolButtonStyle(Qt::ToolButtonIconOnly); - manage_btn->setIcon(utils::icon("list")); - manage_btn->setAutoRaise(true); + QToolButton *manage_btn = toolButton("list", ""); QMenu *menu = new QMenu(this); line_series_action = menu->addAction(tr("Line"), [this]() { setSeriesType(QAbstractSeries::SeriesTypeLine); }); line_series_action->setCheckable(true); @@ -434,12 +431,12 @@ void ChartView::manageSeries() { } void ChartView::resizeEvent(QResizeEvent *event) { - QChartView::resizeEvent(event); updatePlotArea(align_to); int x = event->size().width() - close_btn_proxy->size().width() - 11; close_btn_proxy->setPos(x, 8); manage_btn_proxy->setPos(x - manage_btn_proxy->size().width() - 5, 8); move_icon->setPos(11, 8); + QChartView::resizeEvent(event); } void ChartView::updatePlotArea(int left) { @@ -448,7 +445,7 @@ void ChartView::updatePlotArea(int left) { align_to = left; background->setRect(r); chart()->legend()->setGeometry(QRect(r.left(), r.top(), r.width(), 45)); - chart()->setPlotArea(QRect(align_to, r.top() + 45, r.width() - align_to - 22, r.height() - 80)); + chart()->setPlotArea(QRect(align_to, r.top() + 45, r.width() - align_to - 36, r.height() - 80)); chart()->layout()->invalidate(); } } @@ -570,7 +567,7 @@ void ChartView::updateAxisY() { QFontMetrics fm(axis_y->labelsFont()); int n = qMax(int(-qFloor(std::log10((max_y - min_y) / (tick_count - 1)))), 0) + 1; - y_label_width = qMax(fm.width(QString::number(min_y, 'f', n)), fm.width(QString::number(max_y, 'f', n))) + 20; // left margin 20 + y_label_width = qMax(fm.width(QString::number(min_y, 'f', n)), fm.width(QString::number(max_y, 'f', n))) + 15; // left margin 15 emit axisYLabelWidthChanged(y_label_width); } } @@ -887,10 +884,10 @@ void SeriesSelector::updateAvailableList(int index) { available_list->clear(); MessageId msg_id = msgs_combo->itemData(index).value(); auto selected_items = seletedItems(); - for (auto &s : dbc()->msg(msg_id)->sigs) { - bool is_selected = std::any_of(selected_items.begin(), selected_items.end(), [=, sig=&s](auto it) { return it->msg_id == msg_id && it->sig == sig; }); + for (auto s : dbc()->msg(msg_id)->getSignals()) { + bool is_selected = std::any_of(selected_items.begin(), selected_items.end(), [=, sig=s](auto it) { return it->msg_id == msg_id && it->sig == sig; }); if (!is_selected) { - addItemToList(available_list, msg_id, &s); + addItemToList(available_list, msg_id, s); } } } diff --git a/tools/cabana/chartswidget.h b/tools/cabana/chartswidget.h index 7089b4eaee..a1dcf32513 100644 --- a/tools/cabana/chartswidget.h +++ b/tools/cabana/chartswidget.h @@ -92,7 +92,7 @@ private: friend class ChartsWidget; }; -class ChartsWidget : public QWidget { +class ChartsWidget : public QFrame { Q_OBJECT public: diff --git a/tools/cabana/commands.cc b/tools/cabana/commands.cc index 70700b33b9..9b9724aada 100644 --- a/tools/cabana/commands.cc +++ b/tools/cabana/commands.cc @@ -38,8 +38,8 @@ RemoveMsgCommand::RemoveMsgCommand(const MessageId &id, QUndoCommand *parent) : void RemoveMsgCommand::undo() { if (!message.name.isEmpty()) { dbc()->updateMsg(id, message.name, message.size); - for (auto &s : message.sigs) - dbc()->addSignal(id, s); + for (auto s : message.getSignals()) + dbc()->addSignal(id, *s); } } diff --git a/tools/cabana/dbcmanager.cc b/tools/cabana/dbcmanager.cc index ae3a65a99b..32113c2f22 100644 --- a/tools/cabana/dbcmanager.cc +++ b/tools/cabana/dbcmanager.cc @@ -10,10 +10,6 @@ namespace dbcmanager { -void sortSignalsByAddress(QList &sigs) { - std::sort(sigs.begin(), sigs.end(), [](auto &a, auto &b) { return a.start_bit < b.start_bit; }); -} - bool DBCManager::open(const QString &dbc_file_name, QString *error) { QString opendbc_file_path = QString("%1/%2.dbc").arg(OPENDBC_FILE_PATH, dbc_file_name); QFile file(opendbc_file_path); @@ -83,27 +79,27 @@ QString DBCManager::generateDBC() { QString dbc_string, signal_comment, val_desc; for (auto &[address, m] : msgs) { dbc_string += QString("BO_ %1 %2: %3 XXX\n").arg(address).arg(m.name).arg(m.size); - for (auto &sig : m.sigs) { + for (auto sig : m.getSignals()) { dbc_string += QString(" SG_ %1 : %2|%3@%4%5 (%6,%7) [%8|%9] \"%10\" XXX\n") - .arg(sig.name) - .arg(sig.start_bit) - .arg(sig.size) - .arg(sig.is_little_endian ? '1' : '0') - .arg(sig.is_signed ? '-' : '+') - .arg(sig.factor, 0, 'g', std::numeric_limits::digits10) - .arg(sig.offset, 0, 'g', std::numeric_limits::digits10) - .arg(sig.min) - .arg(sig.max) - .arg(sig.unit); - if (!sig.comment.isEmpty()) { - signal_comment += QString("CM_ SG_ %1 %2 \"%3\";\n").arg(address).arg(sig.name).arg(sig.comment); + .arg(sig->name) + .arg(sig->start_bit) + .arg(sig->size) + .arg(sig->is_little_endian ? '1' : '0') + .arg(sig->is_signed ? '-' : '+') + .arg(sig->factor, 0, 'g', std::numeric_limits::digits10) + .arg(sig->offset, 0, 'g', std::numeric_limits::digits10) + .arg(sig->min) + .arg(sig->max) + .arg(sig->unit); + if (!sig->comment.isEmpty()) { + signal_comment += QString("CM_ SG_ %1 %2 \"%3\";\n").arg(address).arg(sig->name).arg(sig->comment); } - if (!sig.val_desc.isEmpty()) { - QString text; - for (auto &[val, desc] : sig.val_desc) { - text += QString("%1 \"%2\"").arg(val, desc); + if (!sig->val_desc.isEmpty()) { + QStringList text; + for (auto &[val, desc] : sig->val_desc) { + text << QString("%1 \"%2\"").arg(val, desc); } - val_desc += QString("VAL_ %1 %2 %3;\n").arg(address).arg(sig.name).arg(text); + val_desc += QString("VAL_ %1 %2 %3;\n").arg(address).arg(sig->name).arg(text.join(" ")); } } dbc_string += "\n"; @@ -127,7 +123,6 @@ void DBCManager::addSignal(const MessageId &id, const Signal &sig) { if (auto m = const_cast(msg(id.address))) { m->sigs.push_back(sig); auto s = &m->sigs.last(); - sortSignalsByAddress(m->sigs); emit signalAdded(id.address, s); } } @@ -136,7 +131,6 @@ void DBCManager::updateSignal(const MessageId &id, const QString &sig_name, cons if (auto m = const_cast(msg(id))) { if (auto s = (Signal *)m->sig(sig_name)) { *s = sig; - sortSignalsByAddress(m->sigs); emit signalUpdated(s); } } @@ -157,6 +151,16 @@ DBCManager *dbc() { return &dbc_manager; } +// Msg + +std::vector Msg::getSignals() const { + std::vector ret; + ret.reserve(sigs.size()); + for (auto &sig : sigs) ret.push_back(&sig); + std::sort(ret.begin(), ret.end(), [](auto l, auto r) { return l->start_bit < r->start_bit; }); + return ret; +} + // helper functions static QVector BIG_ENDIAN_START_BITS = []() { @@ -246,7 +250,6 @@ bool dbcmanager::DBCManager::open(const QString &name, const QString &content, Q sig.offset = s.offset; sig.is_little_endian = s.is_little_endian; } - sortSignalsByAddress(m.sigs); } parseExtraInfo(content); name_ = name; diff --git a/tools/cabana/dbcmanager.h b/tools/cabana/dbcmanager.h index 267157b31a..d877347796 100644 --- a/tools/cabana/dbcmanager.h +++ b/tools/cabana/dbcmanager.h @@ -52,12 +52,16 @@ struct Signal { struct Msg { QString name; uint32_t size; - QList sigs; + std::vector getSignals() const; const Signal *sig(const QString &sig_name) const { auto it = std::find_if(sigs.begin(), sigs.end(), [&](auto &s) { return s.name == sig_name; }); return it != sigs.end() ? &(*it) : nullptr; } + +private: + QList sigs; + friend class DBCManager; }; class DBCManager : public QObject { diff --git a/tools/cabana/detailwidget.cc b/tools/cabana/detailwidget.cc index 882ea932c6..01fbccf7db 100644 --- a/tools/cabana/detailwidget.cc +++ b/tools/cabana/detailwidget.cc @@ -3,15 +3,13 @@ #include #include #include -#include #include "tools/cabana/commands.h" // DetailWidget DetailWidget::DetailWidget(ChartsWidget *charts, QWidget *parent) : charts(charts), QWidget(parent) { - QWidget *main_widget = new QWidget(this); - QVBoxLayout *main_layout = new QVBoxLayout(main_widget); + QVBoxLayout *main_layout = new QVBoxLayout(this); main_layout->setContentsMargins(0, 0, 0, 0); // tabbar @@ -23,22 +21,22 @@ DetailWidget::DetailWidget(ChartsWidget *charts, QWidget *parent) : charts(chart main_layout->addWidget(tabbar); // message title - QToolBar *toolbar = new QToolBar(this); - toolbar->setIconSize({16, 16}); - toolbar->addWidget(new QLabel("time:")); + QHBoxLayout *title_layout = new QHBoxLayout(); + title_layout->setContentsMargins(0, 6, 0, 0); time_label = new QLabel(this); - time_label->setStyleSheet("font-weight:bold"); - toolbar->addWidget(time_label); + time_label->setToolTip(tr("Current time")); + time_label->setStyleSheet("QLabel{font-weight:bold;}"); + title_layout->addWidget(time_label); name_label = new ElidedLabel(this); - name_label->setContentsMargins(5, 0, 5, 0); - name_label->setStyleSheet("font-weight:bold;"); + name_label->setStyleSheet("QLabel{font-weight:bold;}"); name_label->setAlignment(Qt::AlignCenter); name_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - toolbar->addWidget(name_label); - toolbar->addAction(utils::icon("pencil"), "", this, &DetailWidget::editMsg)->setToolTip(tr("Edit Message")); - remove_msg_act = toolbar->addAction(utils::icon("x-lg"), "", this, &DetailWidget::removeMsg); - remove_msg_act->setToolTip(tr("Remove Message")); - main_layout->addWidget(toolbar); + title_layout->addWidget(name_label); + auto edit_btn = toolButton("pencil", tr("Edit Message")); + title_layout->addWidget(edit_btn); + remove_btn = toolButton("x-lg", tr("Remove Message")); + title_layout->addWidget(remove_btn); + main_layout->addLayout(title_layout); // warning warning_widget = new QWidget(this); @@ -59,19 +57,18 @@ DetailWidget::DetailWidget(ChartsWidget *charts, QWidget *parent) : charts(chart splitter->setStretchFactor(1, 1); tab_widget = new QTabWidget(this); + tab_widget->setStyleSheet("QTabWidget::pane {border: none; margin-bottom: -2px;}"); tab_widget->setTabPosition(QTabWidget::South); tab_widget->addTab(splitter, utils::icon("file-earmark-ruled"), "&Msg"); tab_widget->addTab(history_log = new LogsWidget(this), utils::icon("stopwatch"), "&Logs"); main_layout->addWidget(tab_widget); - stacked_layout = new QStackedLayout(this); - stacked_layout->addWidget(new WelcomeWidget(this)); - stacked_layout->addWidget(main_widget); - + QObject::connect(edit_btn, &QToolButton::clicked, this, &DetailWidget::editMsg); + QObject::connect(remove_btn, &QToolButton::clicked, this, &DetailWidget::removeMsg); QObject::connect(binary_view, &BinaryView::resizeSignal, signal_view->model, &SignalModel::resizeSignal); QObject::connect(binary_view, &BinaryView::addSignal, signal_view->model, &SignalModel::addSignal); QObject::connect(binary_view, &BinaryView::signalHovered, signal_view, &SignalView::signalHovered); - QObject::connect(binary_view, &BinaryView::signalClicked, signal_view, &SignalView::expandSignal); + QObject::connect(binary_view, &BinaryView::signalClicked, [this](const Signal *s) { signal_view->selectSignal(s, true); }); QObject::connect(binary_view, &BinaryView::editSignal, signal_view->model, &SignalModel::saveSignal); QObject::connect(binary_view, &BinaryView::removeSignal, signal_view->model, &SignalModel::removeSignal); QObject::connect(binary_view, &BinaryView::showChart, charts, &ChartsWidget::showChart); @@ -87,9 +84,7 @@ DetailWidget::DetailWidget(ChartsWidget *charts, QWidget *parent) : charts(chart setMessage(tabbar->tabData(index).value()); } }); - QObject::connect(tabbar, &QTabBar::tabCloseRequested, [this](int index) { - tabbar->removeTab(index); - }); + QObject::connect(tabbar, &QTabBar::tabCloseRequested, tabbar, &QTabBar::removeTab); QObject::connect(charts, &ChartsWidget::seriesChanged, signal_view, &SignalView::updateChartState); } @@ -108,18 +103,8 @@ void DetailWidget::showTabBarContextMenu(const QPoint &pt) { } } -void DetailWidget::removeAll() { - msg_id = std::nullopt; - tabbar->blockSignals(true); - while (tabbar->count() > 0) { - tabbar->removeTab(0); - } - tabbar->blockSignals(false); - stacked_layout->setCurrentIndex(0); -} - void DetailWidget::setMessage(const MessageId &message_id) { - msg_id = message_id; + if (std::exchange(msg_id, message_id) == message_id) return; tabbar->blockSignals(true); int index = tabbar->count() - 1; @@ -135,25 +120,18 @@ void DetailWidget::setMessage(const MessageId &message_id) { tabbar->blockSignals(false); setUpdatesEnabled(false); - - signal_view->setMessage(*msg_id); - binary_view->setMessage(*msg_id); - history_log->setMessage(*msg_id); - - stacked_layout->setCurrentIndex(1); + signal_view->setMessage(msg_id); + binary_view->setMessage(msg_id); + history_log->setMessage(msg_id); refresh(); - splitter->setSizes({1, 2}); - setUpdatesEnabled(true); } void DetailWidget::refresh() { - if (!msg_id) return; - QStringList warnings; - auto msg = dbc()->msg(*msg_id); + auto msg = dbc()->msg(msg_id); if (msg) { - if (msg->size != can->lastMessage(*msg_id).dat.size()) { + if (msg->size != can->lastMessage(msg_id).dat.size()) { warnings.push_back(tr("Message size (%1) is incorrect.").arg(msg->size)); } for (auto s : binary_view->getOverlappingSignals()) { @@ -162,8 +140,8 @@ void DetailWidget::refresh() { } else { warnings.push_back(tr("Drag-Select in binary view to create new signal.")); } - remove_msg_act->setEnabled(msg != nullptr); - name_label->setText(msgName(*msg_id)); + remove_btn->setEnabled(msg != nullptr); + name_label->setText(msgName(msg_id)); if (!warnings.isEmpty()) { warning_label->setText(warnings.join('\n')); @@ -174,7 +152,7 @@ void DetailWidget::refresh() { void DetailWidget::updateState(const QHash *msgs) { time_label->setText(QString::number(can->currentSec(), 'f', 3)); - if (!msg_id || (msgs && !msgs->contains(*msg_id))) + if ((msgs && !msgs->contains(msg_id))) return; if (tab_widget->currentIndex() == 0) @@ -184,17 +162,16 @@ void DetailWidget::updateState(const QHash *msgs) { } void DetailWidget::editMsg() { - MessageId id = *msg_id; - auto msg = dbc()->msg(id); - int size = msg ? msg->size : can->lastMessage(id).dat.size(); - EditMessageDialog dlg(id, msgName(id), size, this); + auto msg = dbc()->msg(msg_id); + int size = msg ? msg->size : can->lastMessage(msg_id).dat.size(); + EditMessageDialog dlg(msg_id, msgName(msg_id), size, this); if (dlg.exec()) { - UndoStack::push(new EditMsgCommand(*msg_id, dlg.name_edit->text(), dlg.size_spin->value())); + UndoStack::push(new EditMsgCommand(msg_id, dlg.name_edit->text(), dlg.size_spin->value())); } } void DetailWidget::removeMsg() { - UndoStack::push(new RemoveMsgCommand(*msg_id)); + UndoStack::push(new RemoveMsgCommand(msg_id)); } // EditMessageDialog @@ -240,10 +217,34 @@ void EditMessageDialog::validateName(const QString &text) { btn_box->button(QDialogButtonBox::Ok)->setEnabled(valid); } -// WelcomeWidget +// CenterWidget -WelcomeWidget::WelcomeWidget(QWidget *parent) : QWidget(parent) { +CenterWidget::CenterWidget(ChartsWidget *charts, QWidget *parent) : charts(charts), QWidget(parent) { QVBoxLayout *main_layout = new QVBoxLayout(this); + main_layout->setContentsMargins(0, 0, 0, 0); + main_layout->addWidget(welcome_widget = createWelcomeWidget()); +} + +void CenterWidget::setMessage(const MessageId &msg_id) { + if (!detail_widget) { + delete welcome_widget; + welcome_widget = nullptr; + layout()->addWidget(detail_widget = new DetailWidget(charts, this)); + } + detail_widget->setMessage(msg_id); +} + +void CenterWidget::clear() { + delete detail_widget; + detail_widget = nullptr; + if (!welcome_widget) { + layout()->addWidget(welcome_widget = createWelcomeWidget()); + } +} + +QWidget *CenterWidget::createWelcomeWidget() { + QWidget *w = new QWidget(this); + QVBoxLayout *main_layout = new QVBoxLayout(w); main_layout->addStretch(0); QLabel *logo = new QLabel("CABANA"); logo->setAlignment(Qt::AlignCenter); @@ -268,7 +269,8 @@ WelcomeWidget::WelcomeWidget(QWidget *parent) : QWidget(parent) { main_layout->addLayout(newShortcutRow("WhatsThis", "Shift+F1")); main_layout->addStretch(0); - setStyleSheet("QLabel{color:darkGray;}"); - setBackgroundRole(QPalette::Base); - setAutoFillBackground(true); + w->setStyleSheet("QLabel{color:darkGray;}"); + w->setBackgroundRole(QPalette::Base); + w->setAutoFillBackground(true); + return w; } diff --git a/tools/cabana/detailwidget.h b/tools/cabana/detailwidget.h index b3e353d539..0bfd8a74af 100644 --- a/tools/cabana/detailwidget.h +++ b/tools/cabana/detailwidget.h @@ -2,9 +2,7 @@ #include #include -#include #include -#include #include "selfdrive/ui/qt/widgets/controls.h" #include "tools/cabana/binaryview.h" @@ -24,11 +22,6 @@ public: QSpinBox *size_spin; }; -class WelcomeWidget : public QWidget { -public: - WelcomeWidget(QWidget *parent); -}; - class DetailWidget : public QWidget { Q_OBJECT @@ -36,7 +29,6 @@ public: DetailWidget(ChartsWidget *charts, QWidget *parent); void setMessage(const MessageId &message_id); void refresh(); - void removeAll(); QSize minimumSizeHint() const override { return binary_view->minimumSizeHint(); } private: @@ -45,17 +37,30 @@ private: void removeMsg(); void updateState(const QHash * msgs = nullptr); - std::optional msg_id; + MessageId msg_id; QLabel *time_label, *warning_icon, *warning_label; ElidedLabel *name_label; QWidget *warning_widget; QTabBar *tabbar; QTabWidget *tab_widget; - QAction *remove_msg_act; + QToolButton *remove_btn; LogsWidget *history_log; BinaryView *binary_view; SignalView *signal_view; ChartsWidget *charts; QSplitter *splitter; - QStackedLayout *stacked_layout; +}; + +class CenterWidget : public QWidget { + Q_OBJECT +public: + CenterWidget(ChartsWidget* charts, QWidget *parent); + void setMessage(const MessageId &msg_id); + void clear(); + +private: + QWidget *createWelcomeWidget(); + DetailWidget *detail_widget = nullptr; + QWidget *welcome_widget = nullptr; + ChartsWidget *charts; }; diff --git a/tools/cabana/historylog.cc b/tools/cabana/historylog.cc index a1c671b68d..abf0b53af8 100644 --- a/tools/cabana/historylog.cc +++ b/tools/cabana/historylog.cc @@ -5,8 +5,6 @@ #include #include "tools/cabana/commands.h" -#include "tools/cabana/util.h" - // HistoryLogModel QVariant HistoryLogModel::data(const QModelIndex &index, int role) const { @@ -27,17 +25,19 @@ void HistoryLogModel::setMessage(const MessageId &message_id) { msg_id = message_id; } -void HistoryLogModel::refresh() { +void HistoryLogModel::refresh(bool fetch_message) { beginResetModel(); sigs.clear(); - if (auto dbc_msg = dbc()->msg(*msg_id)) { - sigs = dbc_msg->sigs; + if (auto dbc_msg = dbc()->msg(msg_id)) { + sigs = dbc_msg->getSignals(); } last_fetch_time = 0; has_more_data = true; messages.clear(); hex_colors.clear(); - updateState(); + if (fetch_message) { + updateState(); + } endResetModel(); } @@ -48,9 +48,9 @@ QVariant HistoryLogModel::headerData(int section, Qt::Orientation orientation, i if (section == 0) { return "Time"; } - return show_signals ? sigs[section - 1].name : "Data"; + return show_signals ? sigs[section - 1]->name : "Data"; } else if (role == Qt::BackgroundRole && section > 0 && show_signals) { - return QBrush(getColor(&sigs[section - 1])); + return QBrush(getColor(sigs[section - 1])); } } return {}; @@ -79,17 +79,15 @@ void HistoryLogModel::setFilter(int sig_idx, const QString &value, std::function } void HistoryLogModel::updateState() { - if (msg_id) { - uint64_t current_time = (can->lastMessage(*msg_id).ts + can->routeStartTime()) * 1e9 + 1; - auto new_msgs = dynamic_mode ? fetchData(current_time, last_fetch_time) : fetchData(0); - if (!new_msgs.empty()) { - beginInsertRows({}, 0, new_msgs.size() - 1); - messages.insert(messages.begin(), std::move_iterator(new_msgs.begin()), std::move_iterator(new_msgs.end())); - endInsertRows(); - } - has_more_data = new_msgs.size() >= batch_size; - last_fetch_time = current_time; + uint64_t current_time = (can->lastMessage(msg_id).ts + can->routeStartTime()) * 1e9 + 1; + auto new_msgs = dynamic_mode ? fetchData(current_time, last_fetch_time) : fetchData(0); + if (!new_msgs.empty()) { + beginInsertRows({}, 0, new_msgs.size() - 1); + messages.insert(messages.begin(), std::move_iterator(new_msgs.begin()), std::move_iterator(new_msgs.end())); + endInsertRows(); } + has_more_data = new_msgs.size() >= batch_size; + last_fetch_time = current_time; } void HistoryLogModel::fetchMore(const QModelIndex &parent) { @@ -111,10 +109,10 @@ std::deque HistoryLogModel::fetchData(InputIt first, I for (auto it = first; it != last && (*it)->mono_time > min_time; ++it) { if ((*it)->which == cereal::Event::Which::CAN) { for (const auto &c : (*it)->event.getCan()) { - if (msg_id->address == c.getAddress() && msg_id->source == c.getSrc()) { + if (msg_id.address == c.getAddress() && msg_id.source == c.getSrc()) { const auto dat = c.getDat(); for (int i = 0; i < sigs.size(); ++i) { - values[i] = get_raw_value((uint8_t *)dat.begin(), dat.size(), sigs[i]); + values[i] = get_raw_value((uint8_t *)dat.begin(), dat.size(), *sigs[i]); } if (!filter_cmp || filter_cmp(values[filter_sig_idx], filter_value)) { auto &m = msgs.emplace_back(); @@ -136,7 +134,7 @@ template std::deque HistoryLogModel::fetchData<>(std:: std::deque HistoryLogModel::fetchData(uint64_t from_time, uint64_t min_time) { auto events = can->events(); - const auto freq = can->lastMessage(*msg_id).freq; + const auto freq = can->lastMessage(msg_id).freq; const bool update_colors = !display_signals_mode || sigs.empty(); if (dynamic_mode) { @@ -189,7 +187,8 @@ void HeaderView::paintSection(QPainter *painter, const QRect &rect, int logicalI // LogsWidget -LogsWidget::LogsWidget(QWidget *parent) : QWidget(parent) { +LogsWidget::LogsWidget(QWidget *parent) : QFrame(parent) { + setFrameStyle(QFrame::StyledPanel | QFrame::Plain); QVBoxLayout *main_layout = new QVBoxLayout(this); main_layout->setContentsMargins(0, 0, 0, 0); main_layout->setSpacing(0); @@ -209,7 +208,8 @@ LogsWidget::LogsWidget(QWidget *parent) : QWidget(parent) { h->addStretch(0); h->addWidget(dynamic_mode = new QCheckBox(tr("Dynamic")), 0, Qt::AlignRight); - display_type_cb->addItems({"Signal Value", "Hex Value"}); + display_type_cb->addItems({"Signal", "Hex"}); + display_type_cb->setToolTip(tr("Display signal value or raw hex value")); comp_box->addItems({">", "=", "!=", "<"}); value_edit->setClearButtonEnabled(true); value_edit->setValidator(new QDoubleValidator(-500000, 500000, 6, this)); @@ -219,10 +219,10 @@ LogsWidget::LogsWidget(QWidget *parent) : QWidget(parent) { main_layout->addWidget(toolbar); QFrame *line = new QFrame(this); line->setFrameStyle(QFrame::HLine | QFrame::Sunken); - main_layout->addWidget(line);; - + main_layout->addWidget(line); main_layout->addWidget(logs = new QTableView(this)); logs->setModel(model = new HistoryLogModel(this)); + delegate = new MessageBytesDelegate(this); logs->setItemDelegateForColumn(1, new MessageBytesDelegate(this)); logs->setHorizontalHeader(new HeaderView(Qt::Horizontal, this)); logs->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft | (Qt::Alignment)Qt::TextWordWrap); @@ -230,7 +230,10 @@ LogsWidget::LogsWidget(QWidget *parent) : QWidget(parent) { logs->verticalHeader()->setVisible(false); logs->setFrameShape(QFrame::NoFrame); - QObject::connect(display_type_cb, SIGNAL(activated(int)), model, SLOT(setDisplayType(int))); + QObject::connect(display_type_cb, qOverload(&QComboBox::activated), [this](int index) { + logs->setItemDelegateForColumn(1, index == 1 ? delegate : nullptr); + model->setDisplayType(index); + }); QObject::connect(dynamic_mode, &QCheckBox::stateChanged, model, &HistoryLogModel::setDynamicMode); QObject::connect(signals_cb, SIGNAL(activated(int)), this, SLOT(setFilter())); QObject::connect(comp_box, SIGNAL(activated(int)), this, SLOT(setFilter())); @@ -247,17 +250,16 @@ void LogsWidget::setMessage(const MessageId &message_id) { } void LogsWidget::refresh() { - if (!model->msg_id) return; - model->setFilter(0, "", nullptr); - model->refresh(); + model->refresh(isVisible()); bool has_signal = model->sigs.size(); if (has_signal) { signals_cb->clear(); - for (auto &s : model->sigs) { - signals_cb->addItem(s.name); + for (auto s : model->sigs) { + signals_cb->addItem(s->name); } } + logs->setItemDelegateForColumn(1, !has_signal || display_type_cb->currentIndex() == 1 ? delegate : nullptr); value_edit->clear(); comp_box->setCurrentIndex(0); filters_widget->setVisible(has_signal); @@ -276,3 +278,15 @@ void LogsWidget::setFilter() { model->setFilter(signals_cb->currentIndex(), value_edit->text(), cmp); model->refresh(); } + +void LogsWidget::updateState() { + if (isVisible() && dynamic_mode->isChecked()) { + model->updateState(); + } +} + +void LogsWidget::showEvent(QShowEvent *event) { + if (dynamic_mode->isChecked() || model->canFetchMore({}) && model->rowCount() == 0) { + model->refresh(); + } +} diff --git a/tools/cabana/historylog.h b/tools/cabana/historylog.h index a1b7bc0098..206d53bc8d 100644 --- a/tools/cabana/historylog.h +++ b/tools/cabana/historylog.h @@ -1,8 +1,6 @@ #pragma once #include -#include - #include #include #include @@ -11,6 +9,8 @@ #include "tools/cabana/dbcmanager.h" #include "tools/cabana/streams/abstractstream.h" +#include "tools/cabana/util.h" + using namespace dbcmanager; class HeaderView : public QHeaderView { @@ -36,7 +36,7 @@ public: int columnCount(const QModelIndex &parent = QModelIndex()) const override { return display_signals_mode && !sigs.empty() ? sigs.size() + 1 : 2; } - void refresh(); + void refresh(bool fetch_message = true); public slots: void setDisplayType(int type); @@ -55,7 +55,7 @@ public: std::deque fetchData(InputIt first, InputIt last, uint64_t min_time); std::deque fetchData(uint64_t from_time, uint64_t min_time = 0); - std::optional msg_id; + MessageId msg_id; ChangeTracker hex_colors; bool has_more_data = true; const int batch_size = 50; @@ -64,19 +64,19 @@ public: uint64_t last_fetch_time = 0; std::function filter_cmp = nullptr; std::deque messages; - QList sigs; + std::vector sigs; bool dynamic_mode = true; bool display_signals_mode = true; }; -class LogsWidget : public QWidget { +class LogsWidget : public QFrame { Q_OBJECT public: LogsWidget(QWidget *parent); void setMessage(const MessageId &message_id); - void updateState() {if (dynamic_mode->isChecked()) model->updateState(); } - void showEvent(QShowEvent *event) override { if (dynamic_mode->isChecked()) model->refresh(); } + void updateState(); + void showEvent(QShowEvent *event) override; private slots: void setFilter(); @@ -90,4 +90,5 @@ private: QComboBox *signals_cb, *comp_box, *display_type_cb; QLineEdit *value_edit; QWidget *filters_widget; + MessageBytesDelegate *delegate; }; diff --git a/tools/cabana/mainwin.cc b/tools/cabana/mainwin.cc index 47ad3a4a6d..bc090b2cc0 100644 --- a/tools/cabana/mainwin.cc +++ b/tools/cabana/mainwin.cc @@ -27,8 +27,8 @@ void qLogMessageHandler(QtMsgType type, const QMessageLogContext &context, const MainWindow::MainWindow() : QMainWindow() { createDockWindows(); - detail_widget = new DetailWidget(charts_widget, this); - setCentralWidget(detail_widget); + center_widget = new CenterWidget(charts_widget, this); + setCentralWidget(center_widget); createActions(); createStatusBar(); createShortcuts(); @@ -60,7 +60,7 @@ MainWindow::MainWindow() : QMainWindow() { QObject::connect(this, &MainWindow::showMessage, statusBar(), &QStatusBar::showMessage); QObject::connect(this, &MainWindow::updateProgressBar, this, &MainWindow::updateDownloadProgress); - QObject::connect(messages_widget, &MessagesWidget::msgSelectionChanged, detail_widget, &DetailWidget::setMessage); + QObject::connect(messages_widget, &MessagesWidget::msgSelectionChanged, center_widget, &CenterWidget::setMessage); QObject::connect(charts_widget, &ChartsWidget::dock, this, &MainWindow::dockCharts); QObject::connect(can, &AbstractStream::streamStarted, this, &MainWindow::loadDBCFromFingerprint); QObject::connect(dbc(), &DBCManager::DBCFileChanged, this, &MainWindow::DBCFileChanged); @@ -175,7 +175,7 @@ void MainWindow::createStatusBar() { progress_bar = new QProgressBar(); progress_bar->setRange(0, 100); progress_bar->setTextVisible(true); - progress_bar->setFixedSize({230, 16}); + progress_bar->setFixedSize({300, 16}); progress_bar->setVisible(false); statusBar()->addWidget(new QLabel(tr("For Help, Press F1"))); statusBar()->addPermanentWidget(progress_bar); @@ -220,7 +220,7 @@ void MainWindow::DBCFileChanged() { void MainWindow::openRoute() { OpenRouteDialog dlg(this); if (dlg.exec()) { - detail_widget->removeAll(); + center_widget->clear(); charts_widget->removeAll(); statusBar()->showMessage(tr("Route %1 loaded").arg(can->routeName()), 2000); } else if (dlg.failedToLoad()) { diff --git a/tools/cabana/mainwin.h b/tools/cabana/mainwin.h index 85d221a231..dd53b1f213 100644 --- a/tools/cabana/mainwin.h +++ b/tools/cabana/mainwin.h @@ -60,7 +60,7 @@ protected: VideoWidget *video_widget = nullptr; QDockWidget *video_dock; MessagesWidget *messages_widget; - DetailWidget *detail_widget; + CenterWidget *center_widget; ChartsWidget *charts_widget; QWidget *floating_window = nullptr; QVBoxLayout *charts_layout; diff --git a/tools/cabana/messageswidget.cc b/tools/cabana/messageswidget.cc index 42ac22865c..c880c61058 100644 --- a/tools/cabana/messageswidget.cc +++ b/tools/cabana/messageswidget.cc @@ -1,17 +1,17 @@ #include "tools/cabana/messageswidget.h" -#include -#include #include -#include #include #include MessagesWidget::MessagesWidget(QWidget *parent) : QWidget(parent) { QVBoxLayout *main_layout = new QVBoxLayout(this); + main_layout->setContentsMargins(0 ,0, 0, 0); // message filter filter = new QLineEdit(this); + QRegularExpression re("\\S+"); + filter->setValidator(new QRegularExpressionValidator(re, this)); filter->setClearButtonEnabled(true); filter->setPlaceholderText(tr("filter messages")); main_layout->addWidget(filter); @@ -44,11 +44,16 @@ MessagesWidget::MessagesWidget(QWidget *parent) : QWidget(parent) { QObject::connect(dbc(), &DBCManager::DBCFileChanged, model, &MessageListModel::sortMessages); QObject::connect(dbc(), &DBCManager::msgUpdated, model, &MessageListModel::sortMessages); QObject::connect(dbc(), &DBCManager::msgRemoved, model, &MessageListModel::sortMessages); - QObject::connect(model, &MessageListModel::modelReset, [this]() { selectMessage(*current_msg_id); }); + QObject::connect(model, &MessageListModel::modelReset, [this]() { + if (current_msg_id) { + selectMessage(*current_msg_id); + } + }); QObject::connect(table_widget->selectionModel(), &QItemSelectionModel::currentChanged, [=](const QModelIndex ¤t, const QModelIndex &previous) { if (current.isValid() && current.row() < model->msgs.size()) { - if (model->msgs[current.row()] != *current_msg_id) { - current_msg_id = model->msgs[current.row()]; + auto &id = model->msgs[current.row()]; + if (!current_msg_id || id != *current_msg_id) { + current_msg_id = id; emit msgSelectionChanged(*current_msg_id); } } @@ -67,10 +72,10 @@ MessagesWidget::MessagesWidget(QWidget *parent) : QWidget(parent) { setWhatsThis(tr(R"( Message View
- Byte color:
+ Byte color
constant changing
increasing
- decreasing
+ decreasing )")); } @@ -91,9 +96,10 @@ void MessagesWidget::updateSuppressedButtons() { } void MessagesWidget::reset() { + current_msg_id = std::nullopt; + table_widget->selectionModel()->clear(); model->reset(); filter->clear(); - current_msg_id = std::nullopt; updateSuppressedButtons(); } @@ -138,8 +144,8 @@ void MessageListModel::setFilterString(const QString &string) { if (id.toString().contains(txt, cs) || msgName(id).contains(txt, cs)) return true; // Search by signal name if (const auto msg = dbc()->msg(id)) { - for (auto &signal : msg->sigs) { - if (signal.name.contains(txt, cs)) return true; + for (auto s : msg->getSignals()) { + if (s->name.contains(txt, cs)) return true; } } return false; diff --git a/tools/cabana/messageswidget.h b/tools/cabana/messageswidget.h index d88def3acb..926d131c8d 100644 --- a/tools/cabana/messageswidget.h +++ b/tools/cabana/messageswidget.h @@ -1,12 +1,9 @@ #pragma once -#include - #include #include #include #include -#include #include #include "tools/cabana/dbcmanager.h" diff --git a/tools/cabana/signaledit.cc b/tools/cabana/signaledit.cc index d5099da6f4..e862439b68 100644 --- a/tools/cabana/signaledit.cc +++ b/tools/cabana/signaledit.cc @@ -6,7 +6,6 @@ #include #include #include -#include #include #include "tools/cabana/commands.h" @@ -48,9 +47,9 @@ void SignalModel::refresh() { beginResetModel(); root.reset(new SignalModel::Item); if (auto msg = dbc()->msg(msg_id)) { - for (auto &s : msg->sigs) { - if (filter_str.isEmpty() || s.name.contains(filter_str, Qt::CaseInsensitive)) { - insertItem(root.get(), root->children.size(), &s); + for (auto s : msg->getSignals()) { + if (filter_str.isEmpty() || s->name.contains(filter_str, Qt::CaseInsensitive)) { + insertItem(root.get(), root->children.size(), s); } } } @@ -58,7 +57,7 @@ void SignalModel::refresh() { } void SignalModel::updateState(const QHash *msgs) { - if (!msgs || (msgs->contains(msg_id))) { + if (!msgs || msgs->contains(msg_id)) { auto &dat = can->lastMessage(msg_id).dat; int row = 0; for (auto item : root->children) { @@ -93,9 +92,8 @@ Qt::ItemFlags SignalModel::flags(const QModelIndex &index) const { } int SignalModel::signalRow(const Signal *sig) const { - auto &children = root->children; - for (int i = 0; i < children.size(); ++i) { - if (children[i]->sig == sig) return i; + for (int i = 0; i < root->children.size(); ++i) { + if (root->children[i]->sig == sig) return i; } return -1; } @@ -129,11 +127,11 @@ QVariant SignalModel::data(const QModelIndex &index, int role) const { case Item::Min: return item->sig->min; case Item::Max: return item->sig->max; case Item::Desc: { - QString val_desc; + QStringList val_desc; for (auto &[val, desc] : item->sig->val_desc) { - val_desc += QString("%1 \"%2\"").arg(val, desc); + val_desc << QString("%1 \"%2\"").arg(val, desc); } - return val_desc; + return val_desc.join(" "); } default: break; } @@ -280,16 +278,24 @@ void SignalModel::handleSignalRemoved(const Signal *sig) { // SignalItemDelegate -SignalItemDelegate::SignalItemDelegate(QObject *parent) { +SignalItemDelegate::SignalItemDelegate(QObject *parent) : QStyledItemDelegate(parent) { name_validator = new NameValidator(this); double_validator = new QDoubleValidator(this); double_validator->setLocale(QLocale::C); // Match locale of QString::toDouble() instead of system small_font.setPointSize(8); } +QSize SignalItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { + QSize size = QStyledItemDelegate::sizeHint(option, index); + if (!index.parent().isValid() && index.column() == 0) { + size.rwidth() = std::min(((QWidget*)parent())->size().width() / 2, size.width() + color_label_width + 8); + } + return size; +} + void SignalItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { auto item = (SignalModel::Item *)index.internalPointer(); - if (item && !index.parent().isValid() && index.column() == 0) { + if (index.column() == 0 && item && item->type == SignalModel::Item::Sig) { painter->save(); painter->setRenderHint(QPainter::Antialiasing); if (option.state & QStyle::State_Selected) { @@ -298,7 +304,7 @@ void SignalItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op // color label auto bg_color = getColor(item->sig); - QRect rc{option.rect.left(), option.rect.top(), 18, option.rect.height()}; + QRect rc{option.rect.left(), option.rect.top(), color_label_width, option.rect.height()}; painter->setPen(Qt::NoPen); painter->setBrush(item->highlight ? bg_color.darker(125) : bg_color); painter->drawRoundedRect(rc.adjusted(0, 2, 0, -2), 3, 3); @@ -345,22 +351,22 @@ QWidget *SignalItemDelegate::createEditor(QWidget *parent, const QStyleOptionVie // SignalView -SignalView::SignalView(ChartsWidget *charts, QWidget *parent) : charts(charts), QWidget(parent) { +SignalView::SignalView(ChartsWidget *charts, QWidget *parent) : charts(charts), QFrame(parent) { + setFrameStyle(QFrame::StyledPanel | QFrame::Plain); // title bar QWidget *title_bar = new QWidget(this); title_bar->setAutoFillBackground(true); QHBoxLayout *hl = new QHBoxLayout(title_bar); hl->addWidget(signal_count_lb = new QLabel()); filter_edit = new QLineEdit(this); + QRegularExpression re("\\S+"); + filter_edit->setValidator(new QRegularExpressionValidator(re, this)); filter_edit->setClearButtonEnabled(true); - filter_edit->setPlaceholderText(tr("filter signals by name")); + filter_edit->setPlaceholderText(tr("filter signals")); hl->addWidget(filter_edit); hl->addStretch(1); - auto collapse_btn = new QToolButton(); - collapse_btn->setIcon(utils::icon("dash-square")); + auto collapse_btn = toolButton("dash-square", tr("Collapse All")); collapse_btn->setIconSize({12, 12}); - collapse_btn->setAutoRaise(true); - collapse_btn->setToolTip(tr("Collapse All")); hl->addWidget(collapse_btn); // tree view @@ -371,7 +377,8 @@ SignalView::SignalView(ChartsWidget *charts, QWidget *parent) : charts(charts), tree->setHeaderHidden(true); tree->setMouseTracking(true); tree->setExpandsOnDoubleClick(false); - tree->header()->setSectionResizeMode(QHeaderView::Stretch); + tree->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); + tree->header()->setStretchLastSection(true); tree->setMinimumHeight(300); tree->setStyleSheet("QSpinBox{background-color:white;border:none;} QLineEdit{background-color:white;}"); @@ -389,7 +396,7 @@ SignalView::SignalView(ChartsWidget *charts, QWidget *parent) : charts(charts), QObject::connect(model, &QAbstractItemModel::modelReset, this, &SignalView::rowsChanged); QObject::connect(model, &QAbstractItemModel::rowsInserted, this, &SignalView::rowsChanged); QObject::connect(model, &QAbstractItemModel::rowsRemoved, this, &SignalView::rowsChanged); - QObject::connect(dbc(), &DBCManager::signalAdded, [this](uint32_t address, const Signal *sig) { expandSignal(sig); }); + QObject::connect(dbc(), &DBCManager::signalAdded, [this](uint32_t address, const Signal *sig) { selectSignal(sig); }); setWhatsThis(tr(R"( Signal view
@@ -404,16 +411,6 @@ void SignalView::setMessage(const MessageId &id) { } void SignalView::rowsChanged() { - auto create_btn = [](const QString &id, const QString &tooltip) { - auto btn = new QToolButton(); - btn->setIcon(utils::icon(id)); - btn->setToolTip(tooltip); - btn->setAutoRaise(true); - return btn; - }; - - signal_count_lb->setText(tr("Signals: %1").arg(model->rowCount())); - for (int i = 0; i < model->rowCount(); ++i) { auto index = model->index(i, 1); if (!tree->indexWidget(index)) { @@ -422,8 +419,8 @@ void SignalView::rowsChanged() { h->setContentsMargins(0, 2, 0, 2); h->addStretch(1); - auto remove_btn = create_btn("x", tr("Remove signal")); - auto plot_btn = create_btn("graph-up", ""); + auto remove_btn = toolButton("x", tr("Remove signal")); + auto plot_btn = toolButton("graph-up", ""); plot_btn->setCheckable(true); h->addWidget(plot_btn); h->addWidget(remove_btn); @@ -436,6 +433,7 @@ void SignalView::rowsChanged() { }); } } + signal_count_lb->setText(tr("Signals: %1").arg(model->rowCount())); updateChartState(); } @@ -449,23 +447,26 @@ void SignalView::rowClicked(const QModelIndex &index) { } } -void SignalView::expandSignal(const Signal *sig) { +void SignalView::selectSignal(const Signal *sig, bool expand) { if (int row = model->signalRow(sig); row != -1) { auto idx = model->index(row, 0); - bool expand = !tree->isExpanded(idx); - tree->setExpanded(idx, expand); + if (expand) { + tree->setExpanded(idx, !tree->isExpanded(idx)); + } tree->scrollTo(idx, QAbstractItemView::PositionAtTop); - if (expand) tree->setCurrentIndex(idx); + tree->setCurrentIndex(idx); } } void SignalView::updateChartState() { int i = 0; for (auto item : model->root->children) { - auto plot_btn = tree->indexWidget(model->index(i, 1))->findChildren()[0]; bool chart_opened = charts->hasSignal(msg_id, item->sig); - plot_btn->setChecked(chart_opened); - plot_btn->setToolTip(chart_opened ? tr("Close Plot") : tr("Show Plot\nSHIFT click to add to previous opened plot")); + auto buttons = tree->indexWidget(model->index(i, 1))->findChildren(); + if (buttons.size() > 0) { + buttons[0]->setChecked(chart_opened); + buttons[0]->setToolTip(chart_opened ? tr("Close Plot") : tr("Show Plot\nSHIFT click to add to previous opened plot")); + } ++i; } } diff --git a/tools/cabana/signaledit.h b/tools/cabana/signaledit.h index efdc653584..3cb193b62f 100644 --- a/tools/cabana/signaledit.h +++ b/tools/cabana/signaledit.h @@ -80,12 +80,14 @@ class SignalItemDelegate : public QStyledItemDelegate { public: SignalItemDelegate(QObject *parent); 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; QValidator *name_validator, *double_validator; QFont small_font; + const int color_label_width = 18; }; -class SignalView : public QWidget { +class SignalView : public QFrame { Q_OBJECT public: @@ -93,7 +95,7 @@ public: void setMessage(const MessageId &id); void signalHovered(const Signal *sig); void updateChartState(); - void expandSignal(const Signal *sig); + void selectSignal(const Signal *sig, bool expand = false); void rowClicked(const QModelIndex &index); SignalModel *model = nullptr; diff --git a/tools/cabana/streams/abstractstream.cc b/tools/cabana/streams/abstractstream.cc index 8fdfbd5c1b..3e631d3709 100644 --- a/tools/cabana/streams/abstractstream.cc +++ b/tools/cabana/streams/abstractstream.cc @@ -31,10 +31,12 @@ bool AbstractStream::updateEvent(const Event *event) { data.dat = QByteArray((char *)c.getDat().begin(), c.getDat().size()); data.count = ++counters[id]; data.freq = data.count / std::max(1.0, current_sec); - change_trackers[id].compute(data.dat, data.ts, data.freq); - data.colors = change_trackers[id].colors; - data.last_change_t = change_trackers[id].last_change_t; - data.bit_change_counts = change_trackers[id].bit_change_counts; + + auto &tracker = change_trackers[id]; + tracker.compute(data.dat, data.ts, data.freq); + data.colors = tracker.colors; + data.last_change_t = tracker.last_change_t; + data.bit_change_counts = tracker.bit_change_counts; } double ts = millis_since_boot(); diff --git a/tools/cabana/tests/test_cabana.cc b/tools/cabana/tests/test_cabana.cc index 9a8ab710bc..6f9f2d016b 100644 --- a/tools/cabana/tests/test_cabana.cc +++ b/tools/cabana/tests/test_cabana.cc @@ -23,9 +23,11 @@ TEST_CASE("DBCManager::generateDBC") { auto &new_m = new_msgs.at(address); REQUIRE(m.name == new_m.name); REQUIRE(m.size == new_m.size); - REQUIRE(m.sigs.size() == new_m.sigs.size()); - for (int i = 0; i < m.sigs.size(); ++i) { - REQUIRE(m.sigs[i] == new_m.sigs[i]); + REQUIRE(m.getSignals().size() == new_m.getSignals().size()); + auto sigs = m.getSignals(); + auto new_sigs = new_m.getSignals(); + for (int i = 0; i < sigs.size(); ++i) { + REQUIRE(*sigs[i] == *new_sigs[i]); } } } @@ -44,9 +46,9 @@ TEST_CASE("Parse can messages") { for (const auto &c : e->event.getCan()) { const auto msg = dbc.msg(c.getAddress()); if (c.getSrc() == 0 && msg) { - for (auto &sig : msg->sigs) { - double val = get_raw_value((uint8_t *)c.getDat().begin(), c.getDat().size(), sig); - values_1[{c.getAddress(), sig.name}].push_back(val); + for (auto sig : msg->getSignals()) { + double val = get_raw_value((uint8_t *)c.getDat().begin(), c.getDat().size(), *sig); + values_1[{c.getAddress(), sig->name}].push_back(val); } } } diff --git a/tools/cabana/util.cc b/tools/cabana/util.cc index 6415cc8e16..4f79f9a3ac 100644 --- a/tools/cabana/util.cc +++ b/tools/cabana/util.cc @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -73,32 +74,23 @@ MessageBytesDelegate::MessageBytesDelegate(QObject *parent) : QStyledItemDelegat } void MessageBytesDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { - QStyleOptionViewItemV4 opt = option; - initStyleOption(&opt, index); - - auto byte_list = opt.text.split(" "); - if (byte_list.size() <= 1) { - QStyledItemDelegate::paint(painter, option, index); - return; - } - auto color_role = option.state & QStyle::State_Selected ? QPalette::HighlightedText: QPalette::Text; painter->setPen(option.palette.color(color_role)); painter->setFont(fixed_font); - QRect space = painter->boundingRect(opt.rect, opt.displayAlignment, " "); - QRect pos = painter->boundingRect(opt.rect, opt.displayAlignment, "00"); - pos.moveLeft(pos.x() + space.width()); - - int m = space.width() / 2; + int space = painter->boundingRect(option.rect, option.displayAlignment, " ").width(); + QRect pos = painter->boundingRect(option.rect, option.displayAlignment, "00").adjusted(0, 0, 2, 0); + pos.moveLeft(pos.x() + space); + int m = space / 2; const QMargins margins(m, m, m, m); auto colors = index.data(Qt::UserRole).value>(); + auto byte_list = index.data(Qt::DisplayRole).toString().split(" "); for (int i = 0; i < byte_list.size(); ++i) { - if (i < colors.size()) { + if (i < colors.size() && colors[i].alpha() > 0) { painter->fillRect(pos.marginsAdded(margins), colors[i]); } - painter->drawText(pos, opt.displayAlignment, byte_list[i]); - pos.moveLeft(pos.right() + space.width()); + painter->drawText(pos, Qt::AlignCenter, byte_list[i]); + pos.moveLeft(pos.right() + space); } } @@ -124,12 +116,25 @@ namespace utils { QPixmap icon(const QString &id) { static bool dark_theme = QApplication::style()->standardPalette().color(QPalette::WindowText).value() > QApplication::style()->standardPalette().color(QPalette::Background).value(); - QPixmap pm = bootstrapPixmap(id); - if (dark_theme) { - QPainter p(&pm); - p.setCompositionMode(QPainter::CompositionMode_SourceIn); - p.fillRect(pm.rect(), Qt::lightGray); + QPixmap pm; + QString key = "bootstrap_" % id % (dark_theme ? "1" : "0"); + if (!QPixmapCache::find(key, &pm)) { + pm = bootstrapPixmap(id); + if (dark_theme) { + QPainter p(&pm); + p.setCompositionMode(QPainter::CompositionMode_SourceIn); + p.fillRect(pm.rect(), Qt::lightGray); + } + QPixmapCache::insert(key, pm); } return pm; } } // namespace utils + +QToolButton *toolButton(const QString &icon, const QString &tooltip) { + auto btn = new QToolButton(); + btn->setIcon(utils::icon(icon)); + btn->setToolTip(tooltip); + btn->setAutoRaise(true); + return btn; +}; diff --git a/tools/cabana/util.h b/tools/cabana/util.h index 2717451061..b72ddfcaa0 100644 --- a/tools/cabana/util.h +++ b/tools/cabana/util.h @@ -6,7 +6,9 @@ #include #include #include +#include #include +#include #include #include "tools/cabana/dbcmanager.h" @@ -52,3 +54,5 @@ public: namespace utils { QPixmap icon(const QString &id); } + +QToolButton *toolButton(const QString &icon, const QString &tooltip); diff --git a/tools/cabana/videowidget.cc b/tools/cabana/videowidget.cc index 2b5374d85f..536ae7ba97 100644 --- a/tools/cabana/videowidget.cc +++ b/tools/cabana/videowidget.cc @@ -28,9 +28,9 @@ inline QString formatTime(int seconds) { VideoWidget::VideoWidget(QWidget *parent) : QWidget(parent) { QVBoxLayout *main_layout = new QVBoxLayout(this); + main_layout->setContentsMargins(0, 0, 0, 0); QFrame *frame = new QFrame(this); - frame->setFrameShape(QFrame::StyledPanel); - frame->setFrameShadow(QFrame::Sunken); + frame->setFrameStyle(QFrame::StyledPanel | QFrame::Plain); main_layout->addWidget(frame); QVBoxLayout *frame_layout = new QVBoxLayout(frame); From 500b1b4a5c7e5a1402325092a92774805b95b324 Mon Sep 17 00:00:00 2001 From: Webomcar <124065911+Webomcar@users.noreply.github.com> Date: Tue, 21 Feb 2023 00:23:42 +0100 Subject: [PATCH 015/102] Add missing FW for Toyota C-HR Hybrid 2020 (#27366) * Update values.py * Verified C-HR 2020 is TSS-P --------- Co-authored-by: Shane Smiskol --- docs/CARS.md | 2 +- selfdrive/car/toyota/values.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/CARS.md b/docs/CARS.md index 59eece1e4b..3bc918f784 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -178,7 +178,7 @@ A supported vehicle is one that just works when you install a comma three. All s |Toyota|Avalon Hybrid 2022|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|| |Toyota|C-HR 2017-20|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|| |Toyota|C-HR 2021|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|| -|Toyota|C-HR Hybrid 2017-19|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|| +|Toyota|C-HR Hybrid 2017-20|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|| |Toyota|C-HR Hybrid 2021-22|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|| |Toyota|Camry 2018-20|All|Stock|0 mph[6](#footnotes)|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|| |Toyota|Camry 2021-22|All|openpilot|0 mph[6](#footnotes)|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|| diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py index 0fcabe163c..0639d46ec0 100644 --- a/selfdrive/car/toyota/values.py +++ b/selfdrive/car/toyota/values.py @@ -119,7 +119,7 @@ CAR_INFO: Dict[str, Union[ToyotaCarInfo, List[ToyotaCarInfo]]] = { CAR.CAMRYH_TSS2: ToyotaCarInfo("Toyota Camry Hybrid 2021-23"), CAR.CHR: ToyotaCarInfo("Toyota C-HR 2017-20"), CAR.CHR_TSS2: ToyotaCarInfo("Toyota C-HR 2021"), - CAR.CHRH: ToyotaCarInfo("Toyota C-HR Hybrid 2017-19"), + CAR.CHRH: ToyotaCarInfo("Toyota C-HR Hybrid 2017-20"), CAR.CHRH_TSS2: ToyotaCarInfo("Toyota C-HR Hybrid 2021-22"), CAR.COROLLA: ToyotaCarInfo("Toyota Corolla 2017-19"), CAR.COROLLA_TSS2: [ @@ -712,6 +712,7 @@ FW_VERSIONS = { b'8646FF404000 ', b'8646FF406000 ', b'8646FF407000 ', + b'8646FF407100 ', ], }, CAR.CHRH_TSS2: { From c3ba2a025ba96684cd0371ae46b3847589b5c773 Mon Sep 17 00:00:00 2001 From: Eric Brown Date: Mon, 20 Feb 2023 16:28:32 -0700 Subject: [PATCH 016/102] GM: detect unplugged or missing radar (#27245) * Add flashed Volt fingerprint * Add another fingerprint * Detect radar header message * dashcamOnly if ASCM vehicle with radar unavailable May be able to change this in the future to OP long off with experimental long available * no submodule update * Revert minEnableSpeed * combine into one fingerprint * Don't use GM radar DBC Co-authored-by: Shane Smiskol * unused * add new FP * update docs * use_off_car_defaults use_off_car_defaults * update docs --------- Co-authored-by: Shane Smiskol --- selfdrive/car/gm/interface.py | 9 ++++++--- selfdrive/car/gm/values.py | 4 ++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/selfdrive/car/gm/interface.py b/selfdrive/car/gm/interface.py index c28274011e..032a49e761 100755 --- a/selfdrive/car/gm/interface.py +++ b/selfdrive/car/gm/interface.py @@ -6,7 +6,8 @@ from panda import Panda from common.numpy_fast import interp from common.conversions import Conversions as CV from selfdrive.car import STD_CARGO_KG, create_button_event, scale_tire_stiffness, get_safety_config -from selfdrive.car.gm.values import CAR, CruiseButtons, CarControllerParams, EV_CAR, CAMERA_ACC_CAR +from selfdrive.car.gm.radar_interface import RADAR_HEADER_MSG +from selfdrive.car.gm.values import CAR, CruiseButtons, CarControllerParams, EV_CAR, CAMERA_ACC_CAR, CanBus from selfdrive.car.interfaces import CarInterfaceBase, TorqueFromLateralAccelCallbackType, FRICTION_THRESHOLD from selfdrive.controls.lib.drive_helpers import apply_center_deadzone @@ -87,6 +88,7 @@ class CarInterface(CarInterfaceBase): ret.carName = "gm" ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.gm)] ret.autoResumeSng = False + use_off_car_defaults = len(fingerprint[0]) == 0 # Pick sensible carParams during offline doc generation/CI jobs if candidate in EV_CAR: ret.transmissionType = TransmissionType.direct @@ -125,7 +127,7 @@ class CarInterface(CarInterfaceBase): else: # ASCM, OBD-II harness ret.openpilotLongitudinalControl = True ret.networkLocation = NetworkLocation.gateway - ret.radarUnavailable = False + ret.radarUnavailable = RADAR_HEADER_MSG not in fingerprint[CanBus.OBSTACLE] and not use_off_car_defaults ret.pcmCruise = False # stock non-adaptive cruise control is kept off # supports stop and go, but initial engage must (conservatively) be above 18mph ret.minEnableSpeed = 18 * CV.MPH_TO_MS @@ -138,7 +140,8 @@ class CarInterface(CarInterfaceBase): # These cars have been put into dashcam only due to both a lack of users and test coverage. # These cars likely still work fine. Once a user confirms each car works and a test route is # added to selfdrive/car/tests/routes.py, we can remove it from this list. - ret.dashcamOnly = candidate in {CAR.CADILLAC_ATS, CAR.HOLDEN_ASTRA, CAR.MALIBU, CAR.BUICK_REGAL, CAR.EQUINOX} + ret.dashcamOnly = candidate in {CAR.CADILLAC_ATS, CAR.HOLDEN_ASTRA, CAR.MALIBU, CAR.BUICK_REGAL, CAR.EQUINOX} or \ + (ret.networkLocation == NetworkLocation.gateway and ret.radarUnavailable) # Start with a baseline tuning for all GM vehicles. Override tuning as needed in each model section below. ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] diff --git a/selfdrive/car/gm/values.py b/selfdrive/car/gm/values.py index 207af6bb05..c4791738b8 100644 --- a/selfdrive/car/gm/values.py +++ b/selfdrive/car/gm/values.py @@ -151,6 +151,10 @@ FINGERPRINTS = { # Volt Premier w/ ACC 2018 { 170: 8, 171: 8, 189: 7, 190: 6, 193: 8, 197: 8, 199: 4, 201: 8, 209: 7, 211: 2, 241: 6, 288: 5, 298: 8, 304: 1, 308: 4, 309: 8, 311: 8, 313: 8, 320: 3, 328: 1, 352: 5, 381: 6, 384: 4, 386: 8, 388: 8, 389: 2, 390: 7, 417: 7, 419: 1, 426: 7, 451: 8, 452: 8, 453: 6, 454: 8, 456: 8, 479: 3, 481: 7, 485: 8, 489: 8, 493: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 508: 8, 528: 4, 532: 6, 546: 7, 550: 8, 554: 3, 558: 8, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 566: 5, 567: 3, 568: 1, 573: 1, 577: 8, 578: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 3, 707: 8, 711: 6, 715: 8, 717: 5, 761: 7, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 869: 4, 880: 6, 961: 8, 967: 4, 969: 8, 977: 8, 979: 7, 988: 6, 989: 8, 995: 7, 1001: 8, 1005: 6, 1009: 8, 1017: 8, 1019: 2, 1020: 8, 1033: 7, 1034: 7, 1105: 6, 1187: 4, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1227: 4, 1233: 8, 1249: 8, 1257: 6, 1265: 8, 1267: 1, 1273: 3, 1275: 3, 1280: 4, 1296: 4, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 1417: 8, 1516: 8, 1601: 8, 1618: 8, 1905: 7, 1906: 7, 1907: 7, 1910: 7, 1912: 7, 1922: 7, 1927: 7, 1930: 7, 2016: 8, 2018: 8, 2020: 8, 2024: 8, 2028: 8 + }, + # Volt Premier 2018 w/ flashed firmware, no radar + { + 170: 8, 171: 8, 189: 7, 190: 6, 192: 5, 193: 8, 197: 8, 199: 4, 201: 6, 209: 7, 211: 2, 241: 6, 288: 5, 289: 1, 290: 1, 298: 2, 304: 1, 308: 4, 309: 8, 311: 8, 313: 8, 320: 3, 328: 1, 352: 5, 368: 8, 381: 2, 384: 8, 386: 5, 388: 8, 389: 2, 390: 7, 417: 7, 419: 1, 426: 7, 451: 8, 452: 8, 453: 6, 454: 8, 456: 8, 458: 8, 479: 3, 481: 7, 485: 8, 489: 5, 493: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 3, 508: 8, 512: 3, 528: 4, 530: 8, 532: 6, 537: 5, 539: 8, 542: 7, 546: 7, 550: 8, 554: 3, 558: 8, 560: 6, 562: 4, 563: 5, 564: 5, 565: 5, 566: 5, 567: 3, 568: 1, 573: 1, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 3, 707: 8, 711: 6, 761: 7, 810: 8, 821: 4, 823: 7, 832: 8, 840: 5, 842: 5, 844: 8, 853: 8, 866: 4, 961: 8, 967: 4, 969: 8, 977: 8, 979: 7, 988: 6, 989: 8, 995: 7, 1001: 5, 1003: 5, 1005: 6, 1009: 8, 1017: 8, 1019: 2, 1020: 8, 1033: 7, 1034: 7, 1105: 6, 1187: 4, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1227: 4, 1233: 8, 1249: 8, 1257: 6, 1265: 8, 1267: 1, 1273: 3, 1275: 3, 1280: 4, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 1417: 8, 1905: 7, 1906: 7, 1907: 7, 1910: 7, 1912: 7, 1922: 7, 1927: 7 }], CAR.BUICK_REGAL : [ # Regal TourX Essence w/ ACC 2018 From 14d44e444418e1b6bd23afe5a371db886e8273e2 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Mon, 20 Feb 2023 15:33:15 -0800 Subject: [PATCH 017/102] GM: remove redundant CarController class variable (#27280) * clean up * fix check * only set ts_nanos on update --- selfdrive/car/gm/carcontroller.py | 9 +++------ selfdrive/car/gm/carstate.py | 3 ++- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/selfdrive/car/gm/carcontroller.py b/selfdrive/car/gm/carcontroller.py index 73085d30b0..42eaf7e88a 100644 --- a/selfdrive/car/gm/carcontroller.py +++ b/selfdrive/car/gm/carcontroller.py @@ -30,7 +30,6 @@ class CarController: self.cancel_counter = 0 self.lka_steering_cmd_counter = 0 - self.sent_lka_steering_cmd = False self.lka_icon_status_last = (False, False) self.params = CarControllerParams(self.CP) @@ -59,19 +58,17 @@ class CarController: # - until we're in sync with camera so counters align when relay closes, preventing a fault. # openpilot can subtly drift, so this is activated throughout a drive to stay synced out_of_sync = self.lka_steering_cmd_counter % 4 != (CS.cam_lka_steering_cmd_counter + 1) % 4 - if not self.sent_lka_steering_cmd or out_of_sync: + if CS.loopback_lka_steering_cmd_ts_nanos == 0 or out_of_sync: steer_step = self.params.STEER_STEP - if CS.loopback_lka_steering_cmd_updated: - self.lka_steering_cmd_counter += 1 - self.sent_lka_steering_cmd = True + self.lka_steering_cmd_counter += 1 if CS.loopback_lka_steering_cmd_updated else 0 # Avoid GM EPS faults when transmitting messages too close together: skip this transmit if we # received the ASCMLKASteeringCmd loopback confirmation too recently last_lka_steer_msg_ms = (now_nanos - CS.loopback_lka_steering_cmd_ts_nanos) * 1e-6 if (self.frame - self.last_steer_frame) >= steer_step and last_lka_steer_msg_ms > MIN_STEER_MSG_INTERVAL_MS: # Initialize ASCMLKASteeringCmd counter using the camera until we get a msg on the bus - if not self.sent_lka_steering_cmd: + if CS.loopback_lka_steering_cmd_ts_nanos == 0: self.lka_steering_cmd_counter = CS.pt_lka_steering_cmd_counter + 1 if CC.latActive: diff --git a/selfdrive/car/gm/carstate.py b/selfdrive/car/gm/carstate.py index 3c7d35f2dc..2f9c952876 100644 --- a/selfdrive/car/gm/carstate.py +++ b/selfdrive/car/gm/carstate.py @@ -37,7 +37,8 @@ class CarState(CarStateBase): # Variables used for avoiding LKAS faults self.loopback_lka_steering_cmd_updated = len(loopback_cp.vl_all["ASCMLKASteeringCmd"]["RollingCounter"]) > 0 - self.loopback_lka_steering_cmd_ts_nanos = loopback_cp.ts_nanos["ASCMLKASteeringCmd"]["RollingCounter"] + if self.loopback_lka_steering_cmd_updated: + self.loopback_lka_steering_cmd_ts_nanos = loopback_cp.ts_nanos["ASCMLKASteeringCmd"]["RollingCounter"] if self.CP.networkLocation == NetworkLocation.fwdCamera: self.pt_lka_steering_cmd_counter = pt_cp.vl["ASCMLKASteeringCmd"]["RollingCounter"] self.cam_lka_steering_cmd_counter = cam_cp.vl["ASCMLKASteeringCmd"]["RollingCounter"] From 79749a306c7621e047d1a57fae40493b40c25954 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Mon, 20 Feb 2023 16:12:11 -0800 Subject: [PATCH 018/102] GM: add longitudinal delay to Escalade (#27406) * add delay to escalade too * order --- selfdrive/car/gm/interface.py | 1 + 1 file changed, 1 insertion(+) diff --git a/selfdrive/car/gm/interface.py b/selfdrive/car/gm/interface.py index 032a49e761..44ece1d415 100755 --- a/selfdrive/car/gm/interface.py +++ b/selfdrive/car/gm/interface.py @@ -207,6 +207,7 @@ class CarInterface(CarInterfaceBase): ret.wheelbase = 2.95 # 116 inches in meters ret.steerRatio = 17.3 ret.centerToFront = ret.wheelbase * 0.5 + ret.longitudinalActuatorDelayUpperBound = 0.5 # large delay to initially start braking CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) elif candidate == CAR.ESCALADE_ESV: From dff054d4dfb6c08a471315778dadf6c0dc24207d Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Mon, 20 Feb 2023 16:13:01 -0800 Subject: [PATCH 019/102] Ford: filter steering pressed (#27123) * ford steering pressed filter * raise to 1.0 * Update ref_commit --- selfdrive/car/ford/carstate.py | 2 +- selfdrive/car/ford/values.py | 2 +- selfdrive/test/process_replay/ref_commit | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/selfdrive/car/ford/carstate.py b/selfdrive/car/ford/carstate.py index f97225e9f2..21af1062f3 100644 --- a/selfdrive/car/ford/carstate.py +++ b/selfdrive/car/ford/carstate.py @@ -37,7 +37,7 @@ class CarState(CarStateBase): # steering wheel ret.steeringAngleDeg = cp.vl["SteeringPinion_Data"]["StePinComp_An_Est"] ret.steeringTorque = cp.vl["EPAS_INFO"]["SteeringColumnTorque"] - ret.steeringPressed = abs(ret.steeringTorque) > CarControllerParams.STEER_DRIVER_ALLOWANCE + ret.steeringPressed = self.update_steering_pressed(abs(ret.steeringTorque) > CarControllerParams.STEER_DRIVER_ALLOWANCE, 5) ret.steerFaultTemporary = cp.vl["EPAS_INFO"]["EPAS_Failure"] == 1 ret.steerFaultPermanent = cp.vl["EPAS_INFO"]["EPAS_Failure"] in (2, 3) # ret.espDisabled = False # TODO: find traction control signal diff --git a/selfdrive/car/ford/values.py b/selfdrive/car/ford/values.py index 951cd09ba0..6be93269c4 100644 --- a/selfdrive/car/ford/values.py +++ b/selfdrive/car/ford/values.py @@ -24,7 +24,7 @@ class CarControllerParams: BUTTONS_STEP = 10 / 2 CURVATURE_MAX = 0.02 # Max curvature for steering command, m^-1 - STEER_DRIVER_ALLOWANCE = 0.8 # Driver intervention threshold, Nm + STEER_DRIVER_ALLOWANCE = 1.0 # Driver intervention threshold, Nm # Curvature rate limits # TODO: unify field names used by curvature and angle control cars diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index e9016cc27c..c158382fe8 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -70753c5f491de7432ff22f4ef560820ce9919b2e +f7ff7e7d37c276c31d8d44c73a0091b5996650b1 From ea419c5764739555673d5545f16cff7c05f9e6c0 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Mon, 20 Feb 2023 16:29:17 -0800 Subject: [PATCH 020/102] add 'remount device' to permanent calibration invalid alert (#27407) --- selfdrive/controls/lib/events.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/controls/lib/events.py b/selfdrive/controls/lib/events.py index a85e48649f..4e664d8cf0 100644 --- a/selfdrive/controls/lib/events.py +++ b/selfdrive/controls/lib/events.py @@ -292,7 +292,7 @@ def calibration_invalid_alert(CP: car.CarParams, CS: car.CarState, sm: messaging rpy = sm['liveCalibration'].rpyCalib yaw = math.degrees(rpy[2] if len(rpy) == 3 else math.nan) pitch = math.degrees(rpy[1] if len(rpy) == 3 else math.nan) - angles = f"Pitch: {pitch:.1f}°, Yaw: {yaw:.1f}°" + angles = f"Remount Device (Pitch: {pitch:.1f}°, Yaw: {yaw:.1f}°)" return NormalPermanentAlert("Calibration Invalid", angles) From 3c66106539e5aad272c967009e23e4ff8508157c Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Mon, 20 Feb 2023 18:02:52 -0800 Subject: [PATCH 021/102] Chrysler Pacifica Hybrid 2017: add missing CAN FP (#27408) add missing 840: 8 --- selfdrive/car/chrysler/values.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/car/chrysler/values.py b/selfdrive/car/chrysler/values.py index 16ebb4fa11..2a5daf440c 100644 --- a/selfdrive/car/chrysler/values.py +++ b/selfdrive/car/chrysler/values.py @@ -93,7 +93,7 @@ CAR_INFO: Dict[str, Optional[Union[ChryslerCarInfo, List[ChryslerCarInfo]]]] = { FINGERPRINTS = { CAR.PACIFICA_2017_HYBRID: [{ - 168: 8, 257: 5, 258: 8, 264: 8, 268: 8, 270: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 291: 8, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 515: 7, 516: 7, 517: 7, 518: 7, 520: 8, 528: 8, 532: 8, 542: 8, 544: 8, 557: 8, 559: 8, 560: 4, 564: 4, 571: 3, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 653: 8, 654: 8, 655: 8, 658: 6, 660: 8, 669: 3, 671: 8, 672: 8, 678: 8, 680: 8, 701: 8, 704: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 729: 5, 736: 8, 737: 8, 746: 5, 760: 8, 764: 8, 766: 8, 770: 8, 773: 8, 779: 8, 782: 8, 784: 8, 788:3, 792: 8, 799: 8, 800: 8, 804: 8, 808: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 878: 8, 882: 8, 897: 8, 908: 8, 924: 3, 926: 3, 929: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 956: 8, 958: 8, 959: 8, 969: 4, 974: 5, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1082: 8, 1083: 8, 1098: 8, 1100: 8, 1216: 8, 1218: 8, 1220: 8, 1225: 8, 1235: 8, 1242: 8, 1246: 8, 1250: 8, 1284: 8, 1537: 8, 1538: 8, 1562: 8, 1568: 8, 1856: 8, 1858: 8, 1860: 8, 1865: 8, 1875: 8, 1882: 8, 1886: 8, 1890: 8, 1892: 8, 2016: 8, 2024: 8 + 168: 8, 257: 5, 258: 8, 264: 8, 268: 8, 270: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 291: 8, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 515: 7, 516: 7, 517: 7, 518: 7, 520: 8, 528: 8, 532: 8, 542: 8, 544: 8, 557: 8, 559: 8, 560: 4, 564: 4, 571: 3, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 653: 8, 654: 8, 655: 8, 658: 6, 660: 8, 669: 3, 671: 8, 672: 8, 678: 8, 680: 8, 701: 8, 704: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 729: 5, 736: 8, 737: 8, 746: 5, 760: 8, 764: 8, 766: 8, 770: 8, 773: 8, 779: 8, 782: 8, 784: 8, 788: 3, 792: 8, 799: 8, 800: 8, 804: 8, 808: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 840: 8, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 878: 8, 882: 8, 897: 8, 908: 8, 924: 3, 926: 3, 929: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 956: 8, 958: 8, 959: 8, 969: 4, 974: 5, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1082: 8, 1083: 8, 1098: 8, 1100: 8, 1216: 8, 1218: 8, 1220: 8, 1225: 8, 1235: 8, 1242: 8, 1246: 8, 1250: 8, 1284: 8, 1537: 8, 1538: 8, 1562: 8, 1568: 8, 1856: 8, 1858: 8, 1860: 8, 1865: 8, 1875: 8, 1882: 8, 1886: 8, 1890: 8, 1892: 8, 2016: 8, 2024: 8 }], CAR.PACIFICA_2018: [{ 55: 8, 257: 5, 258: 8, 264: 8, 268: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 416: 7, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 516: 7, 517: 7, 520: 8, 524: 8, 526: 6, 528: 8, 532: 8, 542: 8, 544: 8, 557: 8, 559: 8, 560: 4, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 656: 4, 658: 6, 660: 8, 669: 3, 671: 8, 672: 8, 678: 8, 680: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 729: 5, 736: 8, 746: 5, 752: 2, 760: 8, 764: 8, 766: 8, 770: 8, 773: 8, 779: 8, 784: 8, 792: 8, 799: 8, 800: 8, 804: 8, 808: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 882: 8, 897: 8, 924: 8, 926: 3, 937: 8, 947: 8, 948: 8, 969: 4, 974: 5, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1098: 8, 1100: 8, 1537: 8, 1538: 8, 1562: 8 From 2008332bd42528ae56d937a2ec0e9a1dd244b2ea Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 21 Feb 2023 15:27:48 -0800 Subject: [PATCH 022/102] GM: revert custom Bolt torque tune (#27403) * Revert "GM: cleanup torque feedforward function (#27347)" This reverts commit 8c099dd4e5adf040f7f454714cf729725bee7f91. * Revert "Chevrolet Bolt: Non-linear torque tune (#27344)" This reverts commit e49748d571d06a65a4361dde1f2f63c7294da13a. * update refs --- selfdrive/car/gm/interface.py | 43 +-------------------- selfdrive/car/interfaces.py | 4 +- selfdrive/controls/lib/latcontrol_torque.py | 4 +- 3 files changed, 6 insertions(+), 45 deletions(-) diff --git a/selfdrive/car/gm/interface.py b/selfdrive/car/gm/interface.py index 44ece1d415..7e6e71c642 100755 --- a/selfdrive/car/gm/interface.py +++ b/selfdrive/car/gm/interface.py @@ -3,13 +3,11 @@ from cereal import car from math import fabs from panda import Panda -from common.numpy_fast import interp from common.conversions import Conversions as CV from selfdrive.car import STD_CARGO_KG, create_button_event, scale_tire_stiffness, get_safety_config from selfdrive.car.gm.radar_interface import RADAR_HEADER_MSG from selfdrive.car.gm.values import CAR, CruiseButtons, CarControllerParams, EV_CAR, CAMERA_ACC_CAR, CanBus -from selfdrive.car.interfaces import CarInterfaceBase, TorqueFromLateralAccelCallbackType, FRICTION_THRESHOLD -from selfdrive.controls.lib.drive_helpers import apply_center_deadzone +from selfdrive.car.interfaces import CarInterfaceBase ButtonType = car.CarState.ButtonEvent.Type EventName = car.CarEvent.EventName @@ -46,43 +44,6 @@ class CarInterface(CarInterfaceBase): else: return CarInterfaceBase.get_steer_feedforward_default - @staticmethod - def torque_from_lateral_accel_bolt(lateral_accel_value, torque_params, lateral_accel_error, lateral_accel_deadzone, vego, friction_compensation): - friction_interp = interp( - apply_center_deadzone(lateral_accel_error, lateral_accel_deadzone), - [-FRICTION_THRESHOLD, FRICTION_THRESHOLD], - [-torque_params.friction, torque_params.friction] - ) - friction = friction_interp if friction_compensation else 0.0 - steer_torque = lateral_accel_value / torque_params.latAccelFactor - - # TODO: - # 1. Learn the correction factors from data - # 2. Generalize the logic to other GM torque control platforms - steer_break_pts = [-1.0, -0.9, -0.75, -0.5, 0.0, 0.5, 0.75, 0.9, 1.0] - steer_lataccel_factors = [1.5, 1.15, 1.02, 1.0, 1.0, 1.0, 1.02, 1.15, 1.5] - steer_correction_factor = interp( - steer_torque, - steer_break_pts, - steer_lataccel_factors - ) - - vego_break_pts = [0.0, 10.0, 15.0, 20.0, 100.0] - vego_lataccel_factors = [1.5, 1.5, 1.25, 1.0, 1.0] - vego_correction_factor = interp( - vego, - vego_break_pts, - vego_lataccel_factors, - ) - - return (steer_torque + friction) / (steer_correction_factor * vego_correction_factor) - - def torque_from_lateral_accel(self) -> TorqueFromLateralAccelCallbackType: - if self.CP.carFingerprint == CAR.BOLT_EUV: - return self.torque_from_lateral_accel_bolt - else: - return self.torque_from_lateral_accel_linear - @staticmethod def _get_params(ret, candidate, fingerprint, car_fw, experimental_long): ret.carName = "gm" @@ -227,7 +188,7 @@ class CarInterface(CarInterfaceBase): ret.steerRatio = 16.8 ret.centerToFront = ret.wheelbase * 0.4 tire_stiffness_factor = 1.0 - ret.steerActuatorDelay = 0.12 + ret.steerActuatorDelay = 0.2 CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) elif candidate == CAR.SILVERADO: diff --git a/selfdrive/car/interfaces.py b/selfdrive/car/interfaces.py index f1e2081d05..249818369c 100644 --- a/selfdrive/car/interfaces.py +++ b/selfdrive/car/interfaces.py @@ -18,7 +18,7 @@ from selfdrive.controls.lib.vehicle_model import VehicleModel ButtonType = car.CarState.ButtonEvent.Type GearShifter = car.CarState.GearShifter EventName = car.CarEvent.EventName -TorqueFromLateralAccelCallbackType = Callable[[float, car.CarParams.LateralTorqueTuning, float, float, float, bool], float] +TorqueFromLateralAccelCallbackType = Callable[[float, car.CarParams.LateralTorqueTuning, float, float, bool], float] MAX_CTRL_SPEED = (V_CRUISE_MAX + 4) * CV.KPH_TO_MS ACCEL_MAX = 2.0 @@ -131,7 +131,7 @@ class CarInterfaceBase(ABC): return self.get_steer_feedforward_default @staticmethod - def torque_from_lateral_accel_linear(lateral_accel_value, torque_params, lateral_accel_error, lateral_accel_deadzone, vego, friction_compensation): + def torque_from_lateral_accel_linear(lateral_accel_value, torque_params, lateral_accel_error, lateral_accel_deadzone, friction_compensation): # The default is a linear relationship between torque and lateral acceleration (accounting for road roll and steering friction) friction_interp = interp( apply_center_deadzone(lateral_accel_error, lateral_accel_deadzone), diff --git a/selfdrive/controls/lib/latcontrol_torque.py b/selfdrive/controls/lib/latcontrol_torque.py index 9129693e5a..2f56094379 100644 --- a/selfdrive/controls/lib/latcontrol_torque.py +++ b/selfdrive/controls/lib/latcontrol_torque.py @@ -64,10 +64,10 @@ class LatControlTorque(LatControl): error = setpoint - measurement gravity_adjusted_lateral_accel = desired_lateral_accel - params.roll * ACCELERATION_DUE_TO_GRAVITY pid_log.error = self.torque_from_lateral_accel(error, self.torque_params, error, - lateral_accel_deadzone, CS.vEgo, friction_compensation=False) + lateral_accel_deadzone, friction_compensation=False) ff = self.torque_from_lateral_accel(gravity_adjusted_lateral_accel, self.torque_params, desired_lateral_accel - actual_lateral_accel, - lateral_accel_deadzone, CS.vEgo, friction_compensation=True) + lateral_accel_deadzone, friction_compensation=True) freeze_integrator = steer_limited or CS.steeringPressed or CS.vEgo < 5 output_torque = self.pid.update(pid_log.error, From 1504c10760627406ce26478bcb98957c64deafac Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 21 Feb 2023 15:48:10 -0800 Subject: [PATCH 023/102] GM: revert steering limits update (#27413) * Revert " GM: update steering limits (#27331)" This reverts commit 1cdf80003dcaea79375cf398ec65849424f2f44b. * update refs * bump panda --- panda | 2 +- selfdrive/car/gm/values.py | 4 ++-- selfdrive/test/process_replay/ref_commit | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/panda b/panda index d2c2d5f926..9fe24bd368 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit d2c2d5f926537a132a253277998ef350fe866d27 +Subproject commit 9fe24bd3683377146b04c68ab94d0935f0bd9d78 diff --git a/selfdrive/car/gm/values.py b/selfdrive/car/gm/values.py index c4791738b8..2ac418b629 100644 --- a/selfdrive/car/gm/values.py +++ b/selfdrive/car/gm/values.py @@ -14,8 +14,8 @@ class CarControllerParams: STEER_STEP = 3 # Active control frames per command (~33hz) INACTIVE_STEER_STEP = 10 # Inactive control frames per command (10hz) STEER_DELTA_UP = 10 # Delta rates require review due to observed EPS weakness - STEER_DELTA_DOWN = 15 - STEER_DRIVER_ALLOWANCE = 65 + STEER_DELTA_DOWN = 25 + STEER_DRIVER_ALLOWANCE = 50 STEER_DRIVER_MULTIPLIER = 4 STEER_DRIVER_FACTOR = 100 NEAR_STOP_BRAKE_PHASE = 0.5 # m/s diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index c158382fe8..07fe22b022 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -f7ff7e7d37c276c31d8d44c73a0091b5996650b1 +4ad02871365f4cbd83c6b4c4f8ad6bb73015a626 \ No newline at end of file From f381b694013ef662c5d7638fe7b706315ce9547d Mon Sep 17 00:00:00 2001 From: huifan0114 <108561744+huifan0114@users.noreply.github.com> Date: Wed, 22 Feb 2023 11:14:19 +0800 Subject: [PATCH 024/102] =?UTF-8?q?=C5=A0koda:=20add=20missing=20FW=20vers?= =?UTF-8?q?ions=20for=202019=20Kodiaq=20(#27410)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update values.py * remove duplicate --------- Co-authored-by: Shane Smiskol --- selfdrive/car/volkswagen/values.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py index cd30bef73b..158a178b03 100755 --- a/selfdrive/car/volkswagen/values.py +++ b/selfdrive/car/volkswagen/values.py @@ -1050,6 +1050,7 @@ FW_VERSIONS = { b'\xf1\x8704E906027DD\xf1\x893123', b'\xf1\x8704L906026DE\xf1\x895418', b'\xf1\x875NA907115E \xf1\x890003', + b'\xf1\x875NA907115E \xf1\x890005', ], (Ecu.transmission, 0x7e1, None): [ b'\xf1\x870D9300043 \xf1\x895202', @@ -1058,8 +1059,8 @@ FW_VERSIONS = { b'\xf1\x870DL300013G \xf1\x892119', ], (Ecu.srs, 0x715, None): [ - b'\xf1\x873Q0959655BJ\xf1\x890703\xf1\x82\0161213001211001205212111052100', - b'\xf1\x873Q0959655CN\xf1\x890720\xf1\x82\0161213001211001205212112052100', + b'\xf1\x873Q0959655BJ\xf1\x890703\xf1\x82\x0e1213001211001205212111052100', + b'\xf1\x873Q0959655CN\xf1\x890720\xf1\x82\x0e1213001211001205212112052100', b'\xf1\x873Q0959655CQ\xf1\x890720\xf1\x82\x0e1213111211001205212112052111', ], (Ecu.eps, 0x712, None): [ From 72539fa177a4e3f320daf3257038ef3f2e4893ac Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 21 Feb 2023 21:34:02 -0800 Subject: [PATCH 025/102] AGNOS system reset: handle ABL reset (#27418) * AGNOS system reset: handle ABL reset * no more tapping * eta --- selfdrive/ui/qt/setup/reset.cc | 49 ++++++++++++++++-------- selfdrive/ui/qt/setup/reset.h | 11 +++++- selfdrive/ui/translations/main_de.ts | 21 +++++----- selfdrive/ui/translations/main_ja.ts | 21 +++++----- selfdrive/ui/translations/main_ko.ts | 21 +++++----- selfdrive/ui/translations/main_pt-BR.ts | 21 +++++----- selfdrive/ui/translations/main_zh-CHS.ts | 21 +++++----- selfdrive/ui/translations/main_zh-CHT.ts | 21 +++++----- 8 files changed, 107 insertions(+), 79 deletions(-) diff --git a/selfdrive/ui/qt/setup/reset.cc b/selfdrive/ui/qt/setup/reset.cc index 582217c1d7..ccf9bf8053 100644 --- a/selfdrive/ui/qt/setup/reset.cc +++ b/selfdrive/ui/qt/setup/reset.cc @@ -11,14 +11,11 @@ #define NVME "/dev/nvme0n1" #define USERDATA "/dev/disk/by-partlabel/userdata" -void Reset::doReset() { - // best effort to wipe nvme and sd card +void Reset::doErase() { + // best effort to wipe nvme std::system("sudo umount " NVME); std::system("yes | sudo mkfs.ext4 " NVME); - // we handle two cases here - // * user-prompted factory reset - // * recovering from a corrupt userdata by formatting int rm = std::system("sudo rm -rf /data/*"); std::system("sudo umount " USERDATA); int fmt = std::system("yes | sudo mkfs.ext4 " USERDATA); @@ -30,22 +27,26 @@ void Reset::doReset() { rebootBtn->show(); } +void Reset::startReset() { + body->setText(tr("Resetting device...\nThis may take up to a minute.")); + rejectBtn->hide(); + rebootBtn->hide(); + confirmBtn->hide(); +#ifdef __aarch64__ + QTimer::singleShot(100, this, &Reset::doErase); +#endif +} + void Reset::confirm() { const QString confirm_txt = tr("Are you sure you want to reset your device?"); if (body->text() != confirm_txt) { body->setText(confirm_txt); } else { - body->setText(tr("Resetting device...")); - rejectBtn->hide(); - rebootBtn->hide(); - confirmBtn->hide(); -#ifdef __aarch64__ - QTimer::singleShot(100, this, &Reset::doReset); -#endif + startReset(); } } -Reset::Reset(bool recover, QWidget *parent) : QWidget(parent) { +Reset::Reset(ResetMode mode, QWidget *parent) : QWidget(parent) { QVBoxLayout *main_layout = new QVBoxLayout(this); main_layout->setContentsMargins(45, 220, 45, 45); main_layout->setSpacing(0); @@ -56,7 +57,7 @@ Reset::Reset(bool recover, QWidget *parent) : QWidget(parent) { main_layout->addSpacing(60); - body = new QLabel(tr("System reset triggered. Press confirm to erase all content and settings. Press cancel to resume boot.")); + body = new QLabel(tr("Press confirm to erase all content and settings. Press cancel to resume boot.")); body->setWordWrap(true); body->setStyleSheet("font-size: 80px; font-weight: light;"); main_layout->addWidget(body, 1, Qt::AlignTop | Qt::AlignLeft); @@ -82,10 +83,16 @@ Reset::Reset(bool recover, QWidget *parent) : QWidget(parent) { blayout->addWidget(confirmBtn); QObject::connect(confirmBtn, &QPushButton::clicked, this, &Reset::confirm); + bool recover = mode == ResetMode::RECOVER; rejectBtn->setVisible(!recover); rebootBtn->setVisible(recover); if (recover) { - body->setText(tr("Unable to mount data partition. Press confirm to reset your device.")); + body->setText(tr("Unable to mount data partition. Partition may be corrupted. Press confirm to erase and reset your device.")); + } + + // automatically start if we're just finishing up an ABL reset + if (mode == ResetMode::FORMAT) { + startReset(); } setStyleSheet(R"( @@ -108,9 +115,17 @@ Reset::Reset(bool recover, QWidget *parent) : QWidget(parent) { } int main(int argc, char *argv[]) { - bool recover = argc > 1 && strcmp(argv[1], "--recover") == 0; + ResetMode mode = ResetMode::USER_RESET; + if (argc > 1) { + if (strcmp(argv[1], "--recover") == 0) { + mode = ResetMode::RECOVER; + } else if (strcmp(argv[1], "--format") == 0) { + mode = ResetMode::FORMAT; + } + } + QApplication a(argc, argv); - Reset reset(recover); + Reset reset(mode); setMainWindow(&reset); return a.exec(); } diff --git a/selfdrive/ui/qt/setup/reset.h b/selfdrive/ui/qt/setup/reset.h index 3a4994077c..04a191d829 100644 --- a/selfdrive/ui/qt/setup/reset.h +++ b/selfdrive/ui/qt/setup/reset.h @@ -2,18 +2,25 @@ #include #include +enum ResetMode { + USER_RESET, // user initiated a factory reset from openpilot + RECOVER, // userdata is corrupt for some reason, give a chance to recover + FORMAT, // finish up an ABL factory reset +}; + class Reset : public QWidget { Q_OBJECT public: - explicit Reset(bool recover = false, QWidget *parent = 0); + explicit Reset(ResetMode mode, QWidget *parent = 0); private: QLabel *body; QPushButton *rejectBtn; QPushButton *rebootBtn; QPushButton *confirmBtn; - void doReset(); + void doErase(); + void startReset(); private slots: void confirm(); diff --git a/selfdrive/ui/translations/main_de.ts b/selfdrive/ui/translations/main_de.ts index b40812af7c..77670ede3b 100644 --- a/selfdrive/ui/translations/main_de.ts +++ b/selfdrive/ui/translations/main_de.ts @@ -576,18 +576,10 @@ location set Are you sure you want to reset your device? Bist du sicher, dass du das Gerät auf Werkseinstellungen zurücksetzen möchtest?
- - Resetting device... - Gerät wird zurückgesetzt... - System Reset System auf Werkseinstellungen zurücksetzen - - System reset triggered. Press confirm to erase all content and settings. Press cancel to resume boot. - Zurücksetzen auf Werkseinstellungen wurde ausgewählt. Drücke Annehmen, um alle Inhalte und Einstellungen zu löschen. Drücke Abbrechen, um mit dem Starten des Gerätes fortzufahren. - Cancel Abbrechen @@ -601,8 +593,17 @@ location set Bestätigen - Unable to mount data partition. Press confirm to reset your device. - Datenpartition kann nicht geöffnet werden. Drücke Annehmen, um dein Gerät auf Werkseinstellungen zurückzusetzen. + Unable to mount data partition. Partition may be corrupted. Press confirm to erase and reset your device. + + + + Press confirm to erase all content and settings. Press cancel to resume boot. + + + + Resetting device... +This may take up to a minute. + diff --git a/selfdrive/ui/translations/main_ja.ts b/selfdrive/ui/translations/main_ja.ts index ed08a52df5..856beee7bc 100644 --- a/selfdrive/ui/translations/main_ja.ts +++ b/selfdrive/ui/translations/main_ja.ts @@ -574,18 +574,10 @@ location set Are you sure you want to reset your device? 初期化してもよろしいですか?
- - Resetting device... - デバイスが初期化されます... - System Reset システムを初期化 - - System reset triggered. Press confirm to erase all content and settings. Press cancel to resume boot. - システムの初期化をリクエストしました。「確認」ボタンを押すとデバイスが初期化されます。「キャンセル」ボタンを押すと起動を続行します。 - Cancel キャンセル @@ -599,8 +591,17 @@ location set 確認 - Unable to mount data partition. Press confirm to reset your device. - 「data」パーティションをマウントできません。「確認」ボタンを押すとデバイスが初期化されます。 + Unable to mount data partition. Partition may be corrupted. Press confirm to erase and reset your device. + + + + Press confirm to erase all content and settings. Press cancel to resume boot. + + + + Resetting device... +This may take up to a minute. + diff --git a/selfdrive/ui/translations/main_ko.ts b/selfdrive/ui/translations/main_ko.ts index 7b742a5048..ee5bb4fd36 100644 --- a/selfdrive/ui/translations/main_ko.ts +++ b/selfdrive/ui/translations/main_ko.ts @@ -574,18 +574,10 @@ location set Are you sure you want to reset your device? 장치를 초기화 하시겠습니까? - - Resetting device... - 장치 초기화중... - System Reset 장치 초기화 - - System reset triggered. Press confirm to erase all content and settings. Press cancel to resume boot. - 장치를 초기화 합니다. 확인버튼을 누르면 모든 내용과 설정이 초기화됩니다. 부팅을 재개하려면 취소를 누르세요. - Cancel 취소 @@ -599,8 +591,17 @@ location set 확인 - Unable to mount data partition. Press confirm to reset your device. - 데이터 파티션을 마운트할 수 없습니다. 확인 버튼을 눌러 장치를 리셋합니다. + Unable to mount data partition. Partition may be corrupted. Press confirm to erase and reset your device. + + + + Press confirm to erase all content and settings. Press cancel to resume boot. + + + + Resetting device... +This may take up to a minute. + diff --git a/selfdrive/ui/translations/main_pt-BR.ts b/selfdrive/ui/translations/main_pt-BR.ts index a25c51de3c..156b6f16c1 100644 --- a/selfdrive/ui/translations/main_pt-BR.ts +++ b/selfdrive/ui/translations/main_pt-BR.ts @@ -578,18 +578,10 @@ trabalho definido Are you sure you want to reset your device? Tem certeza que quer resetar seu dispositivo? - - Resetting device... - Resetando dispositivo... - System Reset Resetar Sistema - - System reset triggered. Press confirm to erase all content and settings. Press cancel to resume boot. - Solicitado reset do sistema. Confirme para apagar todo conteúdo e configurações. Aperte cancelar para continuar boot. - Cancel Cancelar @@ -603,8 +595,17 @@ trabalho definido Confirmar - Unable to mount data partition. Press confirm to reset your device. - Não foi possível montar a partição de dados. Pressione confirmar para resetar seu dispositivo. + Unable to mount data partition. Partition may be corrupted. Press confirm to erase and reset your device. + + + + Press confirm to erase all content and settings. Press cancel to resume boot. + + + + Resetting device... +This may take up to a minute. + diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts index 68c1bb766f..f295a72938 100644 --- a/selfdrive/ui/translations/main_zh-CHS.ts +++ b/selfdrive/ui/translations/main_zh-CHS.ts @@ -572,18 +572,10 @@ location set Are you sure you want to reset your device? 您确定要重置您的设备吗? - - Resetting device... - 正在重置设备…… - System Reset 恢复出厂设置 - - System reset triggered. Press confirm to erase all content and settings. Press cancel to resume boot. - 已触发系统重置:确认以删除所有内容和设置。取消以正常启动设备。 - Cancel 取消 @@ -597,8 +589,17 @@ location set 确认 - Unable to mount data partition. Press confirm to reset your device. - 无法挂载数据分区。 确认以重置您的设备。 + Unable to mount data partition. Partition may be corrupted. Press confirm to erase and reset your device. + + + + Press confirm to erase all content and settings. Press cancel to resume boot. + + + + Resetting device... +This may take up to a minute. + diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts index 71315e118f..b7636c18c5 100644 --- a/selfdrive/ui/translations/main_zh-CHT.ts +++ b/selfdrive/ui/translations/main_zh-CHT.ts @@ -574,18 +574,10 @@ location set Are you sure you want to reset your device? 您確定要重置你的設備嗎? - - Resetting device... - 重置設備中… - System Reset 系統重置 - - System reset triggered. Press confirm to erase all content and settings. Press cancel to resume boot. - 系統重置已觸發。請按確認刪除所有內容和設置。按取消恢復啟動。 - Cancel 取消 @@ -599,8 +591,17 @@ location set 確認 - Unable to mount data partition. Press confirm to reset your device. - 無法掛載數據分區。請按確認重置您的設備。 + Unable to mount data partition. Partition may be corrupted. Press confirm to erase and reset your device. + + + + Press confirm to erase all content and settings. Press cancel to resume boot. + + + + Resetting device... +This may take up to a minute. + From 58cd96536b852949f65309fea37684a6fa16668e Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Thu, 23 Feb 2023 03:44:53 +0800 Subject: [PATCH 026/102] cabana: small improvements to SignalView (#27419) --- tools/cabana/signaledit.cc | 34 ++++++++++++++++++++++++---------- tools/cabana/signaledit.h | 2 +- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/tools/cabana/signaledit.cc b/tools/cabana/signaledit.cc index e862439b68..c614ecb247 100644 --- a/tools/cabana/signaledit.cc +++ b/tools/cabana/signaledit.cc @@ -61,16 +61,26 @@ void SignalModel::updateState(const QHash *msgs) { auto &dat = can->lastMessage(msg_id).dat; int row = 0; for (auto item : root->children) { - double value = get_raw_value((uint8_t *)dat.begin(), dat.size(), *item->sig); - item->sig_val = QString::number(value); - emit dataChanged(index(row, 1), index(row, 1), {Qt::DisplayRole}); + QString value = QString::number(get_raw_value((uint8_t *)dat.begin(), dat.size(), *item->sig)); + if (value != item->sig_val) { + item->sig_val = value; + emit dataChanged(index(row, 1), index(row, 1), {Qt::DisplayRole}); + } ++row; } } } +SignalModel::Item *SignalModel::getItem(const QModelIndex &index) const { + SignalModel::Item *item = nullptr; + if (index.isValid()) { + item = (SignalModel::Item *)index.internalPointer(); + } + return item ? item : root.get(); +} + int SignalModel::rowCount(const QModelIndex &parent) const { - if (parent.column() > 0) return 0; + if (parent.isValid() && parent.column() > 0) return 0; auto parent_item = getItem(parent); int row_count = parent_item->children.size(); @@ -99,14 +109,19 @@ int SignalModel::signalRow(const Signal *sig) const { } QModelIndex SignalModel::index(int row, int column, const QModelIndex &parent) const { - if (!hasIndex(row, column, parent)) return {}; - return createIndex(row, column, getItem(parent)->children[row]); + if (parent.isValid() && parent.column() != 0) return {}; + + auto parent_item = getItem(parent); + if (parent_item && row < parent_item->children.size()) { + return createIndex(row, column, parent_item->children[row]); + } + return {}; } QModelIndex SignalModel::parent(const QModelIndex &index) const { if (!index.isValid()) return {}; Item *parent_item = getItem(index)->parent; - return parent_item == root.get() ? QModelIndex() : createIndex(parent_item->row(), 0, parent_item); + return !parent_item || parent_item == root.get() ? QModelIndex() : createIndex(parent_item->row(), 0, parent_item); } QVariant SignalModel::data(const QModelIndex &index, int role) const { @@ -287,8 +302,8 @@ SignalItemDelegate::SignalItemDelegate(QObject *parent) : QStyledItemDelegate(pa QSize SignalItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { QSize size = QStyledItemDelegate::sizeHint(option, index); - if (!index.parent().isValid() && index.column() == 0) { - size.rwidth() = std::min(((QWidget*)parent())->size().width() / 2, size.width() + color_label_width + 8); + if (index.column() == 0 && !index.parent().isValid()) { + size.rwidth() = std::min(option.widget->size().width() / 2, size.width() + color_label_width + 8); } return size; } @@ -355,7 +370,6 @@ SignalView::SignalView(ChartsWidget *charts, QWidget *parent) : charts(charts), setFrameStyle(QFrame::StyledPanel | QFrame::Plain); // title bar QWidget *title_bar = new QWidget(this); - title_bar->setAutoFillBackground(true); QHBoxLayout *hl = new QHBoxLayout(title_bar); hl->addWidget(signal_count_lb = new QLabel()); filter_edit = new QLineEdit(this); diff --git a/tools/cabana/signaledit.h b/tools/cabana/signaledit.h index 3cb193b62f..73a107f5c9 100644 --- a/tools/cabana/signaledit.h +++ b/tools/cabana/signaledit.h @@ -42,7 +42,7 @@ public: bool saveSignal(const Signal *origin_s, Signal &s); void resizeSignal(const Signal *sig, int start_bit, int size); void removeSignal(const Signal *sig); - inline Item *getItem(const QModelIndex &index) const { return index.isValid() ? (Item *)index.internalPointer() : root.get(); } + Item *getItem(const QModelIndex &index) const; int signalRow(const Signal *sig) const; void showExtraInfo(const QModelIndex &index); From e0a6074d00df9fafaa2b6d5e2d0fa01b154cce2f Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Thu, 23 Feb 2023 03:45:05 +0800 Subject: [PATCH 027/102] cabana: remove setUpdatesEnabled and setLabelFormat after updateAxisY (#27421) --- tools/cabana/chartswidget.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tools/cabana/chartswidget.cc b/tools/cabana/chartswidget.cc index e315f82398..8a3a59d989 100644 --- a/tools/cabana/chartswidget.cc +++ b/tools/cabana/chartswidget.cc @@ -154,12 +154,10 @@ void ChartsWidget::updateState() { can->seekTo(zoomed_range.first); } - charts_layout->parentWidget()->setUpdatesEnabled(false); const auto &range = is_zoomed ? zoomed_range : display_range; for (auto c : charts) { c->updatePlot(cur_sec, range.first, range.second); } - charts_layout->parentWidget()->setUpdatesEnabled(true); } void ChartsWidget::setMaxChartRange(int value) { @@ -213,7 +211,6 @@ ChartView *ChartsWidget::createChart() { } void ChartsWidget::showChart(const MessageId &id, const Signal *sig, bool show, bool merge) { - setUpdatesEnabled(false); ChartView *chart = findChart(id, sig); if (show && !chart) { chart = merge && charts.size() > 0 ? charts.back() : createChart(); @@ -223,7 +220,6 @@ void ChartsWidget::showChart(const MessageId &id, const Signal *sig, bool show, chart->removeIf([&](auto &s) { return s.msg_id == id && s.sig == sig; }); } updateToolBar(); - setUpdatesEnabled(true); } void ChartsWidget::setColumnCount(int n) { @@ -568,6 +564,7 @@ void ChartView::updateAxisY() { QFontMetrics fm(axis_y->labelsFont()); int n = qMax(int(-qFloor(std::log10((max_y - min_y) / (tick_count - 1)))), 0) + 1; y_label_width = qMax(fm.width(QString::number(min_y, 'f', n)), fm.width(QString::number(max_y, 'f', n))) + 15; // left margin 15 + axis_y->setLabelFormat(QString("%.%1f").arg(n)); emit axisYLabelWidthChanged(y_label_width); } } From f2982340f8aed49559713f573b751e6095e51504 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Wed, 22 Feb 2023 14:09:16 -0800 Subject: [PATCH 028/102] Ford: adjust curvature rate limits (#27423) * Update values.py * Update values.py * make consistent * Update ref_commit --- selfdrive/car/ford/values.py | 5 +++-- selfdrive/test/process_replay/ref_commit | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/selfdrive/car/ford/values.py b/selfdrive/car/ford/values.py index 6be93269c4..1c8917446a 100644 --- a/selfdrive/car/ford/values.py +++ b/selfdrive/car/ford/values.py @@ -28,8 +28,9 @@ class CarControllerParams: # Curvature rate limits # TODO: unify field names used by curvature and angle control cars - ANGLE_RATE_LIMIT_UP = AngleRateLimit(speed_bp=[5, 15, 25], angle_v=[0.005, 0.00056, 0.0002]) - ANGLE_RATE_LIMIT_DOWN = AngleRateLimit(speed_bp=[5, 15, 25], angle_v=[0.008, 0.00089, 0.00032]) + # ~2 m/s^3 up, -3 m/s^3 down + ANGLE_RATE_LIMIT_UP = AngleRateLimit(speed_bp=[5, 15, 25], angle_v=[0.004, 0.00044, 0.0002]) + ANGLE_RATE_LIMIT_DOWN = AngleRateLimit(speed_bp=[5, 15, 25], angle_v=[0.006, 0.00066, 0.00024]) ACCEL_MAX = 2.0 # m/s^s max acceleration ACCEL_MIN = -3.5 # m/s^s max deceleration diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index 07fe22b022..1d807d75cd 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -4ad02871365f4cbd83c6b4c4f8ad6bb73015a626 \ No newline at end of file +5f45771d28c8e7112d474edcdd991689c6440acf From 6b4ac801e7ecb1addf74c9018958469741b609a3 Mon Sep 17 00:00:00 2001 From: Kurt Nistelberger Date: Wed, 22 Feb 2023 14:11:04 -0800 Subject: [PATCH 029/102] laikad: use new cache param (#27404) * add backward compatibility * rename laikad cache file * rm and update --------- Co-authored-by: Kurt Nistelberger Co-authored-by: Adeeb Shihadeh --- common/params.cc | 2 +- selfdrive/locationd/laikad.py | 2 +- selfdrive/loggerd/tests/test_loggerd.py | 8 ++++---- tools/gpstest/rpc_server.py | 2 +- tools/gpstest/test_laikad.py | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/common/params.cc b/common/params.cc index 5e3361a70f..2ba4f7e8ab 100644 --- a/common/params.cc +++ b/common/params.cc @@ -138,7 +138,7 @@ std::unordered_map keys = { {"IsReleaseBranch", CLEAR_ON_MANAGER_START}, {"IsUpdateAvailable", CLEAR_ON_MANAGER_START}, {"JoystickDebugMode", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF}, - {"LaikadEphemeris", PERSISTENT | DONT_LOG}, + {"LaikadEphemerisV2", PERSISTENT | DONT_LOG}, {"LanguageSetting", PERSISTENT}, {"LastAthenaPingTime", CLEAR_ON_MANAGER_START}, {"LastGPSPosition", PERSISTENT}, diff --git a/selfdrive/locationd/laikad.py b/selfdrive/locationd/laikad.py index e85cd0ad42..2eb1e94526 100755 --- a/selfdrive/locationd/laikad.py +++ b/selfdrive/locationd/laikad.py @@ -28,7 +28,7 @@ from selfdrive.locationd.models.gnss_kf import States as GStates from system.swaglog import cloudlog MAX_TIME_GAP = 10 -EPHEMERIS_CACHE = 'LaikadEphemeris' +EPHEMERIS_CACHE = 'LaikadEphemerisV2' DOWNLOADS_CACHE_FOLDER = "/tmp/comma_download_cache/" CACHE_VERSION = 0.2 POS_FIX_RESIDUAL_THRESHOLD = 100.0 diff --git a/selfdrive/loggerd/tests/test_loggerd.py b/selfdrive/loggerd/tests/test_loggerd.py index 9c3565d130..857dc5c4e9 100755 --- a/selfdrive/loggerd/tests/test_loggerd.py +++ b/selfdrive/loggerd/tests/test_loggerd.py @@ -86,7 +86,7 @@ class TestLoggerd(unittest.TestCase): params.clear_all() for k, _, v in fake_params: params.put(k, v) - params.put("LaikadEphemeris", "abc") + params.put("LaikadEphemerisV2", "abc") lr = list(LogReader(str(self._gen_bootlog()))) initData = lr[0].initData @@ -103,14 +103,14 @@ class TestLoggerd(unittest.TestCase): # check params logged_params = {entry.key: entry.value for entry in initData.params.entries} - expected_params = set(k for k, _, __ in fake_params) | {'LaikadEphemeris'} + expected_params = set(k for k, _, __ in fake_params) | {'LaikadEphemerisV2'} assert set(logged_params.keys()) == expected_params, set(logged_params.keys()) ^ expected_params - assert logged_params['LaikadEphemeris'] == b'', f"DONT_LOG param value was logged: {repr(logged_params['LaikadEphemeris'])}" + assert logged_params['LaikadEphemerisV2'] == b'', f"DONT_LOG param value was logged: {repr(logged_params['LaikadEphemerisV2'])}" for param_key, initData_key, v in fake_params: self.assertEqual(getattr(initData, initData_key), v) self.assertEqual(logged_params[param_key].decode(), v) - params.put("LaikadEphemeris", "") + params.put("LaikadEphemerisV2", "") def test_rotation(self): os.environ["LOGGERD_TEST"] = "1" diff --git a/tools/gpstest/rpc_server.py b/tools/gpstest/rpc_server.py index b35c66d02d..a368566982 100644 --- a/tools/gpstest/rpc_server.py +++ b/tools/gpstest/rpc_server.py @@ -17,7 +17,7 @@ ALT_DELTA = 30 MATCH_NUM = 10 REPORT_STATS = 10 -EPHEM_CACHE = "/data/params/d/LaikadEphemeris" +EPHEM_CACHE = "/data/params/d/LaikadEphemerisV2" DOWNLOAD_CACHE = "/tmp/comma_download_cache" SERVER_LOG_FILE = "/tmp/fuzzy_server.log" diff --git a/tools/gpstest/test_laikad.py b/tools/gpstest/test_laikad.py index 613ac991b1..410a9c70d3 100644 --- a/tools/gpstest/test_laikad.py +++ b/tools/gpstest/test_laikad.py @@ -39,7 +39,7 @@ class TestLaikad(unittest.TestCase): def setUp(self): # ensure laikad cold start - Params().remove("LaikadEphemeris") + Params().remove("LaikadEphemerisV2") os.environ["LAIKAD_NO_INTERNET"] = "1" managed_processes['laikad'].start() From 9d64fb2d1abeb35d0b716b9e54169d473222ab21 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 22 Feb 2023 14:11:29 -0800 Subject: [PATCH 030/102] improved fan malfunction detection (#27405) --- selfdrive/controls/controlsd.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index 2c359ec32a..f49b58212a 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -280,8 +280,9 @@ class Controls: # Alert if fan isn't spinning for 5 seconds if self.sm['peripheralState'].pandaType != log.PandaState.PandaType.unknown: - if self.sm['peripheralState'].fanSpeedRpm == 0 and self.sm['deviceState'].fanSpeedPercentDesired > 50: - if (self.sm.frame - self.last_functional_fan_frame) * DT_CTRL > 5.0: + if self.sm['peripheralState'].fanSpeedRpm < 500 and self.sm['deviceState'].fanSpeedPercentDesired > 50: + # allow enough time for the fan controller in the panda to recover from stalls + if (self.sm.frame - self.last_functional_fan_frame) * DT_CTRL > 15.0: self.events.add(EventName.fanMalfunction) else: self.last_functional_fan_frame = self.sm.frame From b00eb57bb735a8c533a28a22ee3aed534afd4a7c Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Wed, 22 Feb 2023 15:59:07 -0800 Subject: [PATCH 031/102] Ford: adjust curvature rate limits (#27427) * fix up * Update ref_commit --- selfdrive/car/ford/values.py | 4 ++-- selfdrive/test/process_replay/ref_commit | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/selfdrive/car/ford/values.py b/selfdrive/car/ford/values.py index 1c8917446a..3bc56eb9dd 100644 --- a/selfdrive/car/ford/values.py +++ b/selfdrive/car/ford/values.py @@ -28,8 +28,8 @@ class CarControllerParams: # Curvature rate limits # TODO: unify field names used by curvature and angle control cars - # ~2 m/s^3 up, -3 m/s^3 down - ANGLE_RATE_LIMIT_UP = AngleRateLimit(speed_bp=[5, 15, 25], angle_v=[0.004, 0.00044, 0.0002]) + # ~2 m/s^3 up, ~-3 m/s^3 down + ANGLE_RATE_LIMIT_UP = AngleRateLimit(speed_bp=[5, 15, 25], angle_v=[0.004, 0.00044, 0.00016]) ANGLE_RATE_LIMIT_DOWN = AngleRateLimit(speed_bp=[5, 15, 25], angle_v=[0.006, 0.00066, 0.00024]) ACCEL_MAX = 2.0 # m/s^s max acceleration diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index 1d807d75cd..5e7a5c8c0a 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -5f45771d28c8e7112d474edcdd991689c6440acf +a38b267bd2d44945dcd664b2a84e6cd0a6163f91 From 90db46e7756e2eb6d61b1ff23f7cb4a7b356abb9 Mon Sep 17 00:00:00 2001 From: Cameron Clough Date: Wed, 22 Feb 2023 17:26:37 -0800 Subject: [PATCH 032/102] setup: write installer URL to tmpfile (#27426) * setup: write installer URL to tmpfile * missed ptr type --- selfdrive/ui/qt/setup/setup.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/selfdrive/ui/qt/setup/setup.cc b/selfdrive/ui/qt/setup/setup.cc index 392be68a12..409d79796c 100644 --- a/selfdrive/ui/qt/setup/setup.cc +++ b/selfdrive/ui/qt/setup/setup.cc @@ -59,6 +59,11 @@ void Setup::download(QString url) { curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &res_status); if (ret == CURLE_OK && res_status == 200 && is_elf(tmpfile)) { rename(tmpfile, "/tmp/installer"); + + FILE *fp_url = fopen("/tmp/installer_url", "w"); + fprintf(fp_url, "%s", url.toStdString().c_str()); + fclose(fp_url); + emit finished(true); } else { emit finished(false); From c1be6d945bb2efd6564f80f153c0ff71c59a3505 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Thu, 23 Feb 2023 12:44:33 +0800 Subject: [PATCH 033/102] cabana: dispaly current FPS & cached minitues on statusbar (#27430) dispaly current FPS & cached minitues on statusbar --- tools/cabana/mainwin.cc | 17 +++++++++++++++++ tools/cabana/mainwin.h | 2 ++ 2 files changed, 19 insertions(+) diff --git a/tools/cabana/mainwin.cc b/tools/cabana/mainwin.cc index bc090b2cc0..25e40e15aa 100644 --- a/tools/cabana/mainwin.cc +++ b/tools/cabana/mainwin.cc @@ -63,9 +63,11 @@ MainWindow::MainWindow() : QMainWindow() { QObject::connect(messages_widget, &MessagesWidget::msgSelectionChanged, center_widget, &CenterWidget::setMessage); QObject::connect(charts_widget, &ChartsWidget::dock, this, &MainWindow::dockCharts); QObject::connect(can, &AbstractStream::streamStarted, this, &MainWindow::loadDBCFromFingerprint); + QObject::connect(can, &AbstractStream::eventsMerged, this, &MainWindow::updateStatus); QObject::connect(dbc(), &DBCManager::DBCFileChanged, this, &MainWindow::DBCFileChanged); QObject::connect(UndoStack::instance(), &QUndoStack::cleanChanged, this, &MainWindow::undoStackCleanChanged); QObject::connect(UndoStack::instance(), &QUndoStack::indexChanged, this, &MainWindow::undoStackIndexChanged); + QObject::connect(&settings, &Settings::changed, this, &MainWindow::updateStatus); } void MainWindow::createActions() { @@ -179,6 +181,9 @@ void MainWindow::createStatusBar() { progress_bar->setVisible(false); statusBar()->addWidget(new QLabel(tr("For Help, Press F1"))); statusBar()->addPermanentWidget(progress_bar); + + statusBar()->addPermanentWidget(status_label = new QLabel(this)); + updateStatus(); } void MainWindow::createShortcuts() { @@ -403,6 +408,18 @@ void MainWindow::updateDownloadProgress(uint64_t cur, uint64_t total, bool succe } } +void MainWindow::updateStatus() { + float cached_minutes = 0; + if (!can->liveStreaming()) { + if (auto events = can->events(); !events->empty()) { + cached_minutes = (events->back()->mono_time - events->front()->mono_time) / (1e9 * 60); + } + } else { + settings.max_cached_minutes = settings.max_cached_minutes; + } + status_label->setText(tr("Cached Minutes:%1 FPS:%2").arg(cached_minutes, 0, 'f', 1).arg(settings.fps)); +} + void MainWindow::dockCharts(bool dock) { if (dock && floating_window) { floating_window->removeEventFilter(charts_widget); diff --git a/tools/cabana/mainwin.h b/tools/cabana/mainwin.h index dd53b1f213..2aeb20aea8 100644 --- a/tools/cabana/mainwin.h +++ b/tools/cabana/mainwin.h @@ -56,6 +56,7 @@ protected: void undoStackCleanChanged(bool clean); void undoStackIndexChanged(int index); void onlineHelp(); + void updateStatus(); VideoWidget *video_widget = nullptr; QDockWidget *video_dock; @@ -65,6 +66,7 @@ protected: QWidget *floating_window = nullptr; QVBoxLayout *charts_layout; QProgressBar *progress_bar; + QLabel *status_label; QJsonDocument fingerprint_to_dbc; QSplitter *video_splitter;; QString current_file = ""; From 7b43a69089fa862c492eb4d4d1706b19662ff8b4 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 22 Feb 2023 21:04:40 -0800 Subject: [PATCH 034/102] Update RELEASES.md --- RELEASES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index 0ea4241a35..f71810784a 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -2,7 +2,7 @@ Version 0.9.2 (2023-03-XX) ======================== * Draw MPC path instead of model predicted path, this is a more accurate representation of what the car will do. -Version 0.9.1 (2023-02-23) +Version 0.9.1 (2023-02-28) ======================== * New driving model * 30% improved height estimation resulting in better driving performance for tall cars From 4e0a3aa0d51c3abd96774bb12a6e28943082fa81 Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Thu, 23 Feb 2023 19:44:53 +0100 Subject: [PATCH 035/102] cabana: show bus in own column (#27434) --- tools/cabana/messageswidget.cc | 33 +++++++++++++++++++++++---------- tools/cabana/messageswidget.h | 2 +- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/tools/cabana/messageswidget.cc b/tools/cabana/messageswidget.cc index c880c61058..cda3069ad9 100644 --- a/tools/cabana/messageswidget.cc +++ b/tools/cabana/messageswidget.cc @@ -20,11 +20,15 @@ MessagesWidget::MessagesWidget(QWidget *parent) : QWidget(parent) { table_widget = new QTableView(this); model = new MessageListModel(this); table_widget->setModel(model); - table_widget->setItemDelegateForColumn(4, new MessageBytesDelegate(table_widget)); + table_widget->setItemDelegateForColumn(5, new MessageBytesDelegate(table_widget)); table_widget->setSelectionBehavior(QAbstractItemView::SelectRows); table_widget->setSelectionMode(QAbstractItemView::SingleSelection); table_widget->setSortingEnabled(true); table_widget->sortByColumn(0, Qt::AscendingOrder); + table_widget->setColumnWidth(0, 150); + table_widget->setColumnWidth(1, 50); + table_widget->setColumnWidth(2, 50); + table_widget->setColumnWidth(3, 50); table_widget->horizontalHeader()->setStretchLastSection(true); table_widget->verticalHeader()->hide(); main_layout->addWidget(table_widget); @@ -108,7 +112,7 @@ void MessagesWidget::reset() { QVariant MessageListModel::headerData(int section, Qt::Orientation orientation, int role) const { if (orientation == Qt::Horizontal && role == Qt::DisplayRole) - return (QString[]){"Name", "ID", "Freq", "Count", "Bytes"}[section]; + return (QString[]){"Name", "Bus", "ID", "Freq", "Count", "Bytes"}[section]; return {}; } @@ -119,12 +123,13 @@ QVariant MessageListModel::data(const QModelIndex &index, int role) const { if (role == Qt::DisplayRole) { switch (index.column()) { case 0: return msgName(id); - case 1: return id.toString(); // TODO: put source and address in separate columns - case 2: return can_data.freq; - case 3: return can_data.count; - case 4: return toHex(can_data.dat); + case 1: return id.source; + case 2: return QString::number(id.address, 16);; + case 3: return can_data.freq; + case 4: return can_data.count; + case 5: return toHex(can_data.dat); } - } else if (role == Qt::UserRole && index.column() == 4) { + } else if (role == Qt::UserRole && index.column() == 5) { QVector colors = can_data.colors; if (!suppressed_bytes.empty()) { for (int i = 0; i < colors.size(); i++) { @@ -171,15 +176,23 @@ void MessageListModel::sortMessages() { }); } else if (sort_column == 1) { std::sort(msgs.begin(), msgs.end(), [this](auto &l, auto &r) { - return sort_order == Qt::AscendingOrder ? l < r : l > r; + auto ll = std::pair{l.source, l}; + auto rr = std::pair{r.source, r}; + return sort_order == Qt::AscendingOrder ? ll < rr : ll > rr; }); } else if (sort_column == 2) { + std::sort(msgs.begin(), msgs.end(), [this](auto &l, auto &r) { + auto ll = std::pair{l.address, l}; + auto rr = std::pair{r.address, r}; + return sort_order == Qt::AscendingOrder ? ll < rr : ll > rr; + }); + } else if (sort_column == 3) { std::sort(msgs.begin(), msgs.end(), [this](auto &l, auto &r) { auto ll = std::pair{can->lastMessage(l).freq, l}; auto rr = std::pair{can->lastMessage(r).freq, r}; return sort_order == Qt::AscendingOrder ? ll < rr : ll > rr; }); - } else if (sort_column == 3) { + } else if (sort_column == 4) { std::sort(msgs.begin(), msgs.end(), [this](auto &l, auto &r) { auto ll = std::pair{can->lastMessage(l).count, l}; auto rr = std::pair{can->lastMessage(r).count, r}; @@ -200,7 +213,7 @@ void MessageListModel::msgsReceived(const QHash *new_msgs) { } for (int i = 0; i < msgs.size(); ++i) { if (new_msgs->contains(msgs[i])) { - for (int col = 2; col < columnCount(); ++col) + for (int col = 3; col < columnCount(); ++col) emit dataChanged(index(i, col), index(i, col), {Qt::DisplayRole}); } } diff --git a/tools/cabana/messageswidget.h b/tools/cabana/messageswidget.h index 926d131c8d..ed9e241b0c 100644 --- a/tools/cabana/messageswidget.h +++ b/tools/cabana/messageswidget.h @@ -16,7 +16,7 @@ Q_OBJECT public: MessageListModel(QObject *parent) : QAbstractTableModel(parent) {} QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override { return 5; } + int columnCount(const QModelIndex &parent = QModelIndex()) const override { return 6; } QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; int rowCount(const QModelIndex &parent = QModelIndex()) const override { return msgs.size(); } void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) override; From a5644faa3f1095c2aa36b12e534fbba1b2ac921d Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Thu, 23 Feb 2023 19:45:13 +0100 Subject: [PATCH 036/102] cabana: show units (#27433) * show units on chart y axis * show in signal list * show in historyview * use clear() --- tools/cabana/chartswidget.cc | 12 +++++++++++- tools/cabana/historylog.cc | 10 +++++++++- tools/cabana/signaledit.cc | 3 +++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/tools/cabana/chartswidget.cc b/tools/cabana/chartswidget.cc index 8a3a59d989..7f07490abd 100644 --- a/tools/cabana/chartswidget.cc +++ b/tools/cabana/chartswidget.cc @@ -542,9 +542,16 @@ void ChartView::updateAxisY() { double min = std::numeric_limits::max(); double max = std::numeric_limits::lowest(); + QString unit = sigs[0].sig->unit; + for (auto &s : sigs) { if (!s.series->isVisible()) continue; + // Only show unit when all signals have the same unit + if (unit != s.sig->unit) { + unit.clear(); + } + auto first = std::lower_bound(s.vals.begin(), s.vals.end(), axis_x->min(), [](auto &p, double x) { return p.x() < x; }); auto last = std::lower_bound(first, s.vals.end(), axis_x->max(), [](auto &p, double x) { return p.x() < x; }); for (auto it = first; it != last; ++it) { @@ -552,6 +559,8 @@ void ChartView::updateAxisY() { if (it->y() > max) max = it->y(); } } + axis_y->setTitleText(unit); + if (min == std::numeric_limits::max()) min = 0; if (max == std::numeric_limits::lowest()) max = 0; @@ -563,7 +572,8 @@ void ChartView::updateAxisY() { QFontMetrics fm(axis_y->labelsFont()); int n = qMax(int(-qFloor(std::log10((max_y - min_y) / (tick_count - 1)))), 0) + 1; - y_label_width = qMax(fm.width(QString::number(min_y, 'f', n)), fm.width(QString::number(max_y, 'f', n))) + 15; // left margin 15 + int title_spacing = axis_y->titleText().isEmpty() ? 0 : 20; + y_label_width = title_spacing + qMax(fm.width(QString::number(min_y, 'f', n)), fm.width(QString::number(max_y, 'f', n))) + 15; // left margin 15 axis_y->setLabelFormat(QString("%.%1f").arg(n)); emit axisYLabelWidthChanged(y_label_width); } diff --git a/tools/cabana/historylog.cc b/tools/cabana/historylog.cc index abf0b53af8..deee2f1724 100644 --- a/tools/cabana/historylog.cc +++ b/tools/cabana/historylog.cc @@ -48,7 +48,15 @@ QVariant HistoryLogModel::headerData(int section, Qt::Orientation orientation, i if (section == 0) { return "Time"; } - return show_signals ? sigs[section - 1]->name : "Data"; + if (show_signals) { + QString name = sigs[section - 1]->name; + if (!sigs[section - 1]->unit.isEmpty()) { + name += QString(" (%1)").arg(sigs[section - 1]->unit); + } + return name; + } else { + return "Data"; + } } else if (role == Qt::BackgroundRole && section > 0 && show_signals) { return QBrush(getColor(sigs[section - 1])); } diff --git a/tools/cabana/signaledit.cc b/tools/cabana/signaledit.cc index c614ecb247..5fcfc116c1 100644 --- a/tools/cabana/signaledit.cc +++ b/tools/cabana/signaledit.cc @@ -62,6 +62,9 @@ void SignalModel::updateState(const QHash *msgs) { int row = 0; for (auto item : root->children) { QString value = QString::number(get_raw_value((uint8_t *)dat.begin(), dat.size(), *item->sig)); + if (!item->sig->unit.isEmpty()){ + value += " " + item->sig->unit; + } if (value != item->sig_val) { item->sig_val = value; emit dataChanged(index(row, 1), index(row, 1), {Qt::DisplayRole}); From dc4ebeb29c569c2b3bc9c687778b6e4ed754d329 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Fri, 24 Feb 2023 02:45:59 +0800 Subject: [PATCH 037/102] cabana: added a new series type to chart: step line (#27422) * add step line series * create buttons in createToolButtons * add inline function clearTrackPoints * do not show tooltip if series is invisible * use QActionGroup --- tools/cabana/chartswidget.cc | 151 +++++++++++++++++++++-------------- tools/cabana/chartswidget.h | 19 +++-- tools/cabana/settings.cc | 2 +- 3 files changed, 106 insertions(+), 66 deletions(-) diff --git a/tools/cabana/chartswidget.cc b/tools/cabana/chartswidget.cc index 7f07490abd..d895191d86 100644 --- a/tools/cabana/chartswidget.cc +++ b/tools/cabana/chartswidget.cc @@ -1,5 +1,6 @@ #include "tools/cabana/chartswidget.h" +#include #include #include #include @@ -183,7 +184,7 @@ void ChartsWidget::settingChanged() { range_slider->setRange(1, settings.max_cached_minutes * 60); for (auto c : charts) { c->setFixedHeight(settings.chart_height); - c->setSeriesType(settings.chart_series_type == 0 ? QAbstractSeries::SeriesTypeLine : QAbstractSeries::SeriesTypeScatter); + c->setSeriesType((SeriesType)settings.chart_series_type); } } @@ -309,7 +310,7 @@ bool ChartsWidget::eventFilter(QObject *obj, QEvent *event) { // ChartView ChartView::ChartView(QWidget *parent) : QChartView(nullptr, parent) { - series_type = settings.chart_series_type == 0 ? QAbstractSeries::SeriesTypeLine : QAbstractSeries::SeriesTypeScatter; + series_type = (SeriesType)settings.chart_series_type; QChart *chart = new QChart(); chart->setBackgroundVisible(false); axis_x = new QValueAxis(this); @@ -325,31 +326,9 @@ ChartView::ChartView(QWidget *parent) : QChartView(nullptr, parent) { background->setPen(Qt::NoPen); background->setZValue(chart->zValue() - 1); - move_icon = new QGraphicsPixmapItem(utils::icon("grip-horizontal"), chart); - move_icon->setToolTip(tr("Drag and drop to combine charts")); - - QToolButton *remove_btn = toolButton("x", tr("Remove Chart")); - close_btn_proxy = new QGraphicsProxyWidget(chart); - close_btn_proxy->setWidget(remove_btn); - close_btn_proxy->setZValue(chart->zValue() + 11); - - QToolButton *manage_btn = toolButton("list", ""); - QMenu *menu = new QMenu(this); - line_series_action = menu->addAction(tr("Line"), [this]() { setSeriesType(QAbstractSeries::SeriesTypeLine); }); - line_series_action->setCheckable(true); - line_series_action->setChecked(series_type == QAbstractSeries::SeriesTypeLine); - scatter_series_action = menu->addAction(tr("Scatter"), [this]() { setSeriesType(QAbstractSeries::SeriesTypeScatter); }); - scatter_series_action->setCheckable(true); - scatter_series_action->setChecked(series_type == QAbstractSeries::SeriesTypeScatter); - menu->addSeparator(); - menu->addAction(tr("Manage series"), this, &ChartView::manageSeries); - manage_btn->setMenu(menu); - manage_btn->setPopupMode(QToolButton::InstantPopup); - manage_btn_proxy = new QGraphicsProxyWidget(chart); - manage_btn_proxy->setWidget(manage_btn); - manage_btn_proxy->setZValue(chart->zValue() + 11); - setChart(chart); + + createToolButtons(); setRenderHint(QPainter::Antialiasing); // TODO: enable zoomIn/seekTo in live streaming mode. setRubberBand(can->liveStreaming() ? QChartView::NoRubberBand : QChartView::HorizontalRubberBand); @@ -358,7 +337,43 @@ ChartView::ChartView(QWidget *parent) : QChartView(nullptr, parent) { QObject::connect(dbc(), &DBCManager::signalUpdated, this, &ChartView::signalUpdated); QObject::connect(dbc(), &DBCManager::msgRemoved, this, &ChartView::msgRemoved); QObject::connect(dbc(), &DBCManager::msgUpdated, this, &ChartView::msgUpdated); +} + +void ChartView::createToolButtons() { + move_icon = new QGraphicsPixmapItem(utils::icon("grip-horizontal"), chart()); + move_icon->setToolTip(tr("Drag and drop to combine charts")); + + QToolButton *remove_btn = toolButton("x", tr("Remove Chart")); + close_btn_proxy = new QGraphicsProxyWidget(chart()); + close_btn_proxy->setWidget(remove_btn); + close_btn_proxy->setZValue(chart()->zValue() + 11); + + // series types + QMenu *menu = new QMenu(this); + auto change_series_group = new QActionGroup(menu); + change_series_group->setExclusive(true); + QStringList types{tr("line"), tr("Step Line"), tr("Scatter")}; + for (int i = 0; i < types.size(); ++i) { + QAction *act = new QAction(types[i], change_series_group); + act->setData(i); + act->setCheckable(true); + act->setChecked(i == (int)series_type); + menu->addAction(act); + } + menu->addSeparator(); + menu->addAction(tr("Manage series"), this, &ChartView::manageSeries); + + QToolButton *manage_btn = toolButton("list", ""); + manage_btn->setMenu(menu); + manage_btn->setPopupMode(QToolButton::InstantPopup); + manage_btn_proxy = new QGraphicsProxyWidget(chart()); + manage_btn_proxy->setWidget(manage_btn); + manage_btn_proxy->setZValue(chart()->zValue() + 11); + QObject::connect(remove_btn, &QToolButton::clicked, this, &ChartView::remove); + QObject::connect(change_series_group, &QActionGroup::triggered, [this](QAction *action) { + setSeriesType((SeriesType)action->data().toInt()); + }); } void ChartView::addSeries(const MessageId &msg_id, const Signal *sig) { @@ -476,7 +491,7 @@ void ChartView::updateSeriesPoints() { int num_points = std::max(end - begin, 1); int pixels_per_point = width() / num_points; - if (series_type == QAbstractSeries::SeriesTypeScatter) { + if (series_type == SeriesType::Scatter) { ((QScatterSeries *)s.series)->setMarkerSize(std::clamp(pixels_per_point / 3, 2, 8)); } else { s.series->setPointsVisible(pixels_per_point > 20); @@ -490,7 +505,9 @@ void ChartView::updateSeries(const Signal *sig, const std::vector *even if (!sig || s.sig == sig) { if (clear) { s.vals.clear(); + s.step_vals.clear(); s.vals.reserve(settings.max_cached_minutes * 60 * 100); // [n]seconds * 100hz + s.step_vals.reserve(settings.max_cached_minutes * 60 * 100 * 2); s.last_value_mono_time = 0; } s.series->setColor(getColor(s.sig)); @@ -498,6 +515,7 @@ void ChartView::updateSeries(const Signal *sig, const std::vector *even struct Chunk { std::vector::const_iterator first, second; QVector vals; + QVector step_vals; }; // split into one minitue chunks QVector chunks; @@ -510,6 +528,7 @@ void ChartView::updateSeries(const Signal *sig, const std::vector *even QtConcurrent::blockingMap(chunks, [&](Chunk &chunk) { chunk.vals.reserve(60 * 100); // 100 hz + chunk.step_vals.reserve(60 * 100 * 2); // 100 hz double route_start_time = can->routeStartTime(); for (auto it = chunk.first; it != chunk.second; ++it) { if ((*it)->which == cereal::Event::Which::CAN) { @@ -519,6 +538,10 @@ void ChartView::updateSeries(const Signal *sig, const std::vector *even double value = get_raw_value((uint8_t *)dat.begin(), dat.size(), *s.sig); double ts = ((*it)->mono_time / (double)1e9) - route_start_time; // seconds chunk.vals.push_back({ts, value}); + if (!chunk.step_vals.empty()) { + chunk.step_vals.push_back({ts, chunk.step_vals.back().y()}); + } + chunk.step_vals.push_back({ts,value}); } } } @@ -526,11 +549,12 @@ void ChartView::updateSeries(const Signal *sig, const std::vector *even }); for (auto &c : chunks) { s.vals.append(c.vals); + s.step_vals.append(c.step_vals); } if (events->size()) { s.last_value_mono_time = events->back()->mono_time; } - s.series->replace(s.vals); + s.series->replace(series_type == SeriesType::StepLine ? s.step_vals : s.vals); } } updateAxisY(); @@ -607,7 +631,7 @@ qreal ChartView::niceNumber(qreal x, bool ceiling) { } void ChartView::leaveEvent(QEvent *event) { - track_pts.clear(); + clearTrackPoints(); scene()->update(); QChartView::leaveEvent(event); } @@ -663,26 +687,31 @@ void ChartView::mouseMoveEvent(QMouseEvent *ev) { auto rubber = findChild(); bool is_zooming = rubber && rubber->isVisible(); const auto plot_area = chart()->plotArea(); - track_pts.clear(); + clearTrackPoints(); + if (!is_zooming && plot_area.contains(ev->pos())) { - track_pts.resize(sigs.size()); QStringList text_list; const double sec = chart()->mapToValue(ev->pos()).x(); - for (int i = 0; i < sigs.size(); ++i) { - QString value = "--"; + qreal x = -1; + for (auto &s : sigs) { + if (!s.series->isVisible()) continue; + // use reverse iterator to find last item <= sec. - auto it = std::lower_bound(sigs[i].vals.rbegin(), sigs[i].vals.rend(), sec, [](auto &p, double x) { return p.x() > x; }); - if (it != sigs[i].vals.rend() && it->x() >= axis_x->min()) { - value = QString::number(it->y()); - track_pts[i] = chart()->mapToPosition(*it); + 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()) { + s.track_pt = chart()->mapToPosition(*it); + x = std::max(x, s.track_pt.x()); } - text_list.push_back(QString("%2: %3").arg(sigs[i].series->color().name(), sigs[i].sig->name, value)); + text_list.push_back(QString("%2: %3") + .arg(s.series->color().name(), s.sig->name, + s.track_pt.isNull() ? "--" : QString::number(s.track_pt.y()))); } - auto max = std::max_element(track_pts.begin(), track_pts.end(), [](auto &a, auto &b) { return a.x() < b.x(); }); - auto pt = (max == track_pts.end()) ? ev->pos() : *max; - text_list.push_front(QString::number(chart()->mapToValue(pt).x(), 'f', 3)); - QPointF tooltip_pt(pt.x() + 12, plot_area.top() - 20); - QToolTip::showText(mapToGlobal(tooltip_pt.toPoint()), pt.isNull() ? "" : text_list.join("
"), this, plot_area.toRect()); + 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(); @@ -727,6 +756,7 @@ void ChartView::dropEvent(QDropEvent *event) { } void ChartView::drawForeground(QPainter *painter, const QRectF &rect) { + // draw time line qreal x = chart()->mapToPosition(QPointF{cur_sec, 0}).x(); x = std::clamp(x, chart()->plotArea().left(), chart()->plotArea().right()); qreal y1 = chart()->plotArea().top() - 2; @@ -734,18 +764,20 @@ void ChartView::drawForeground(QPainter *painter, const QRectF &rect) { painter->setPen(QPen(chart()->titleBrush().color(), 2)); painter->drawLine(QPointF{x, y1}, QPointF{x, y2}); - auto max = std::max_element(track_pts.begin(), track_pts.end(), [](auto &a, auto &b) { return a.x() < b.x(); }); - if (max != track_pts.end() && !max->isNull()) { - painter->setPen(QPen(Qt::darkGray, 1, Qt::DashLine)); - painter->drawLine(QPointF{max->x(), y1}, QPointF{max->x(), y2}); - painter->setPen(Qt::NoPen); - for (int i = 0; i < track_pts.size(); ++i) { - if (!track_pts[i].isNull() && i < sigs.size()) { - painter->setBrush(sigs[i].series->color().darker(125)); - painter->drawEllipse(track_pts[i], 5.5, 5.5); - } + // draw track points + painter->setPen(Qt::NoPen); + qreal track_line_x = -1; + for (auto &s : sigs) { + if (!s.track_pt.isNull() && s.series->isVisible()) { + painter->setBrush(s.series->color().darker(125)); + painter->drawEllipse(s.track_pt, 5.5, 5.5); + track_line_x = std::max(track_line_x, s.track_pt.x()); } } + if (track_line_x > 0) { + painter->setPen(QPen(Qt::darkGray, 1, Qt::DashLine)); + painter->drawLine(QPointF{track_line_x, y1}, QPointF{track_line_x, y2}); + } // paint points. OpenGL mode lacks certain features (such as showing points) painter->setPen(Qt::NoPen); @@ -761,11 +793,14 @@ void ChartView::drawForeground(QPainter *painter, const QRectF &rect) { } } -QXYSeries *ChartView::createSeries(QAbstractSeries::SeriesType type, QColor color) { +QXYSeries *ChartView::createSeries(SeriesType type, QColor color) { QXYSeries *series = nullptr; - if (type == QAbstractSeries::SeriesTypeLine) { + if (type == SeriesType::Line) { series = new QLineSeries(this); chart()->legend()->setMarkerShape(QLegend::MarkerShapeRectangle); + } else if (type == SeriesType::StepLine) { + series = new QLineSeries(this); + chart()->legend()->setMarkerShape(QLegend::MarkerShapeFromSeries); } else { series = new QScatterSeries(this); chart()->legend()->setMarkerShape(QLegend::MarkerShapeCircle); @@ -786,9 +821,7 @@ QXYSeries *ChartView::createSeries(QAbstractSeries::SeriesType type, QColor colo return series; } -void ChartView::setSeriesType(QAbstractSeries::SeriesType type) { - line_series_action->setChecked(type == QAbstractSeries::SeriesTypeLine); - scatter_series_action->setChecked(type == QAbstractSeries::SeriesTypeScatter); +void ChartView::setSeriesType(SeriesType type) { if (type != series_type) { series_type = type; for (auto &s : sigs) { @@ -797,7 +830,7 @@ void ChartView::setSeriesType(QAbstractSeries::SeriesType type) { } for (auto &s : sigs) { auto series = createSeries(series_type, getColor(s.sig)); - series->replace(s.vals); + series->replace(series_type == SeriesType::StepLine ? s.step_vals : s.vals); s.series = series; } updateSeriesPoints(); diff --git a/tools/cabana/chartswidget.h b/tools/cabana/chartswidget.h index a1dcf32513..76943c1fe9 100644 --- a/tools/cabana/chartswidget.h +++ b/tools/cabana/chartswidget.h @@ -20,6 +20,12 @@ using namespace QtCharts; const int CHART_MIN_WIDTH = 300; +enum class SeriesType { + Line = 0, + StepLine, + Scatter +}; + class ChartView : public QChartView { Q_OBJECT @@ -29,7 +35,7 @@ public: bool hasSeries(const MessageId &msg_id, const Signal *sig) const; void updateSeries(const Signal *sig = nullptr, const std::vector *events = nullptr, bool clear = true); void updatePlot(double cur, double min, double max); - void setSeriesType(QAbstractSeries::SeriesType type); + void setSeriesType(SeriesType type); void updatePlotArea(int left); struct SigItem { @@ -37,7 +43,9 @@ public: const Signal *sig = nullptr; QXYSeries *series = nullptr; QVector vals; + QVector step_vals; uint64_t last_value_mono_time = 0; + QPointF track_pt{}; }; signals: @@ -57,6 +65,7 @@ private slots: void signalRemoved(const Signal *sig) { removeIf([=](auto &s) { return s.sig == sig; }); } private: + void createToolButtons(); void mousePressEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *ev) override; @@ -70,15 +79,15 @@ private: void drawForeground(QPainter *painter, const QRectF &rect) override; std::tuple getNiceAxisNumbers(qreal min, qreal max, int tick_count); qreal niceNumber(qreal x, bool ceiling); - QXYSeries *createSeries(QAbstractSeries::SeriesType type, QColor color); + QXYSeries *createSeries(SeriesType type, QColor color); void updateSeriesPoints(); void removeIf(std::function predicate); + inline void clearTrackPoints() { for (auto &s : sigs) s.track_pt = {}; } int y_label_width = 0; int align_to = 0; QValueAxis *axis_x; QValueAxis *axis_y; - QVector track_pts; QGraphicsPixmapItem *move_icon; QGraphicsProxyWidget *close_btn_proxy; QGraphicsProxyWidget *manage_btn_proxy; @@ -86,9 +95,7 @@ private: QList sigs; double cur_sec = 0; const QString mime_type = "application/x-cabanachartview"; - QAbstractSeries::SeriesType series_type = QAbstractSeries::SeriesTypeLine; - QAction *line_series_action; - QAction *scatter_series_action; + SeriesType series_type = SeriesType::Line; friend class ChartsWidget; }; diff --git a/tools/cabana/settings.cc b/tools/cabana/settings.cc index 6cbd16cabf..23f001efff 100644 --- a/tools/cabana/settings.cc +++ b/tools/cabana/settings.cc @@ -65,7 +65,7 @@ SettingsDlg::SettingsDlg(QWidget *parent) : QDialog(parent) { form_layout->addRow(tr("Max Cached Minutes"), cached_minutes); chart_series_type = new QComboBox(this); - chart_series_type->addItems({tr("Line"), tr("Scatter")}); + chart_series_type->addItems({tr("Line"), tr("Step Line"), tr("Scatter")}); chart_series_type->setCurrentIndex(settings.chart_series_type); form_layout->addRow(tr("Chart Default Series Type"), chart_series_type); From 7a3b3e8b567ea476088e6f3d7344c7220e35e398 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Thu, 23 Feb 2023 15:01:10 -0800 Subject: [PATCH 038/102] better main off alert (#27442) --- selfdrive/controls/lib/events.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/selfdrive/controls/lib/events.py b/selfdrive/controls/lib/events.py index 4e664d8cf0..e4ddfb5326 100644 --- a/selfdrive/controls/lib/events.py +++ b/selfdrive/controls/lib/events.py @@ -317,9 +317,9 @@ def modeld_lagging_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubM def wrong_car_mode_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: - text = "Cruise Mode Disabled" + text = "Enable Adaptive Cruise to Engage" if CP.carName == "honda": - text = "Main Switch Off" + text = "Enable Main Switch to Engage" return NoEntryAlert(text) From d5688ae49fd8652bf500ec145f2f3aa711c6bbf3 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Thu, 23 Feb 2023 16:18:32 -0800 Subject: [PATCH 039/102] Angle control: fix limiting bug (#27428) * fix steer up bug * Update ref_commit --- selfdrive/car/__init__.py | 2 +- selfdrive/test/process_replay/ref_commit | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/selfdrive/car/__init__.py b/selfdrive/car/__init__.py index c056f7ca3d..a90f023ed1 100644 --- a/selfdrive/car/__init__.py +++ b/selfdrive/car/__init__.py @@ -115,7 +115,7 @@ def apply_toyota_steer_torque_limits(apply_torque, apply_torque_last, motor_torq def apply_std_steer_angle_limits(apply_angle, apply_angle_last, v_ego, LIMITS): # pick angle rate limits based on wind up/down - steer_up = apply_angle_last * apply_angle > 0. and abs(apply_angle) > abs(apply_angle_last) + steer_up = apply_angle_last * apply_angle >= 0. and abs(apply_angle) > abs(apply_angle_last) rate_limits = LIMITS.ANGLE_RATE_LIMIT_UP if steer_up else LIMITS.ANGLE_RATE_LIMIT_DOWN angle_rate_lim = interp(v_ego, rate_limits.speed_bp, rate_limits.angle_v) diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index 5e7a5c8c0a..9991154b9a 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -a38b267bd2d44945dcd664b2a84e6cd0a6163f91 +772f30de36fc7f8421dabb779cc02f45eb83d7bb From 79e6910106de6ae25127613728332e8b743d962a Mon Sep 17 00:00:00 2001 From: Cameron Clough Date: Thu, 23 Feb 2023 19:45:48 -0800 Subject: [PATCH 040/102] setup: detailed error messages (#27429) * setup: specific error state for non-executable file * Result -> DownloadResult * complete -> finished * rename widgets to be more consistent * fix typos * fix setCurrentIndex This appears to have different behaviour on device than on PC (off by one) * load fonts * copy Co-authored-by: Adeeb Shihadeh * Revert "load fonts" This reverts commit e8756598ed99aea39ef5721453e97920a494051c. * font family * undo * less widgets more better * font size --------- Co-authored-by: Adeeb Shihadeh --- selfdrive/ui/qt/setup/setup.cc | 41 ++++++++++++++++-------- selfdrive/ui/qt/setup/setup.h | 5 +-- selfdrive/ui/translations/main_de.ts | 8 +++++ selfdrive/ui/translations/main_ja.ts | 8 +++++ selfdrive/ui/translations/main_ko.ts | 8 +++++ selfdrive/ui/translations/main_pt-BR.ts | 8 +++++ selfdrive/ui/translations/main_zh-CHS.ts | 8 +++++ selfdrive/ui/translations/main_zh-CHT.ts | 8 +++++ 8 files changed, 78 insertions(+), 16 deletions(-) diff --git a/selfdrive/ui/qt/setup/setup.cc b/selfdrive/ui/qt/setup/setup.cc index 409d79796c..3de6255521 100644 --- a/selfdrive/ui/qt/setup/setup.cc +++ b/selfdrive/ui/qt/setup/setup.cc @@ -34,7 +34,7 @@ bool is_elf(char *fname) { void Setup::download(QString url) { CURL *curl = curl_easy_init(); if (!curl) { - emit finished(false); + emit finished(url, tr("Something went wrong. Reboot the device.")); return; } @@ -57,16 +57,19 @@ void Setup::download(QString url) { int ret = curl_easy_perform(curl); long res_status = 0; curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &res_status); - if (ret == CURLE_OK && res_status == 200 && is_elf(tmpfile)) { + + if (ret != CURLE_OK || res_status != 200) { + emit finished(url, tr("Ensure the entered URL is valid, and the device’s internet connection is good.")); + } else if (!is_elf(tmpfile)) { + emit finished(url, tr("No custom software found at this URL.")); + } else { rename(tmpfile, "/tmp/installer"); FILE *fp_url = fopen("/tmp/installer_url", "w"); fprintf(fp_url, "%s", url.toStdString().c_str()); fclose(fp_url); - emit finished(true); - } else { - emit finished(false); + emit finished(url); } curl_slist_free_all(list); @@ -239,10 +242,10 @@ QWidget * Setup::downloading() { return widget; } -QWidget * Setup::download_failed() { +QWidget * Setup::download_failed(QLabel *url, QLabel *body) { QWidget *widget = new QWidget(); QVBoxLayout *main_layout = new QVBoxLayout(widget); - main_layout->setContentsMargins(55, 225, 55, 55); + main_layout->setContentsMargins(55, 185, 55, 55); main_layout->setSpacing(0); QLabel *title = new QLabel(tr("Download Failed")); @@ -251,7 +254,13 @@ QWidget * Setup::download_failed() { main_layout->addSpacing(67); - QLabel *body = new QLabel(tr("Ensure the entered URL is valid, and the device’s internet connection is good.")); + url->setWordWrap(true); + url->setAlignment(Qt::AlignTop | Qt::AlignLeft); + url->setStyleSheet("font-family: \"JetBrains Mono\"; font-size: 64px; font-weight: 400; margin-right: 100px;"); + main_layout->addWidget(url); + + main_layout->addSpacing(48); + body->setWordWrap(true); body->setAlignment(Qt::AlignTop | Qt::AlignLeft); body->setStyleSheet("font-size: 80px; font-weight: 300; margin-right: 100px;"); @@ -276,7 +285,7 @@ QWidget * Setup::download_failed() { restart->setProperty("primary", true); blayout->addWidget(restart); QObject::connect(restart, &QPushButton::clicked, this, [=]() { - setCurrentIndex(2); + setCurrentIndex(1); }); widget->setStyleSheet(R"( @@ -309,15 +318,19 @@ Setup::Setup(QWidget *parent) : QStackedWidget(parent) { downloading_widget = downloading(); addWidget(downloading_widget); - failed_widget = download_failed(); + QLabel *url_label = new QLabel(); + QLabel *body_label = new QLabel(); + failed_widget = download_failed(url_label, body_label); addWidget(failed_widget); - QObject::connect(this, &Setup::finished, [=](bool success) { - // hide setup on success - qDebug() << "finished" << success; - if (success) { + QObject::connect(this, &Setup::finished, [=](const QString &url, const QString &error) { + qDebug() << "finished" << url << error; + if (error.isEmpty()) { + // hide setup on success QTimer::singleShot(3000, this, &QWidget::hide); } else { + url_label->setText(url); + body_label->setText(error); setCurrentWidget(failed_widget); } }); diff --git a/selfdrive/ui/qt/setup/setup.h b/selfdrive/ui/qt/setup/setup.h index f990b5a6cb..bf5d97070d 100644 --- a/selfdrive/ui/qt/setup/setup.h +++ b/selfdrive/ui/qt/setup/setup.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -15,13 +16,13 @@ private: QWidget *getting_started(); QWidget *network_setup(); QWidget *downloading(); - QWidget *download_failed(); + QWidget *download_failed(QLabel *url, QLabel *body); QWidget *failed_widget; QWidget *downloading_widget; signals: - void finished(bool success); + void finished(const QString &url, const QString &error = ""); public slots: void nextPage(); diff --git a/selfdrive/ui/translations/main_de.ts b/selfdrive/ui/translations/main_de.ts index 77670ede3b..5f3511d3cc 100644 --- a/selfdrive/ui/translations/main_de.ts +++ b/selfdrive/ui/translations/main_de.ts @@ -703,6 +703,14 @@ This may take up to a minute. Start over Von neuem beginnen + + No custom software found at this URL. + + + + Something went wrong. Reboot the device. + +
SetupWidget diff --git a/selfdrive/ui/translations/main_ja.ts b/selfdrive/ui/translations/main_ja.ts index 856beee7bc..1e0223606b 100644 --- a/selfdrive/ui/translations/main_ja.ts +++ b/selfdrive/ui/translations/main_ja.ts @@ -701,6 +701,14 @@ This may take up to a minute. Start over 最初からやり直す + + No custom software found at this URL. + + + + Something went wrong. Reboot the device. + + SetupWidget diff --git a/selfdrive/ui/translations/main_ko.ts b/selfdrive/ui/translations/main_ko.ts index ee5bb4fd36..5470e57ce5 100644 --- a/selfdrive/ui/translations/main_ko.ts +++ b/selfdrive/ui/translations/main_ko.ts @@ -701,6 +701,14 @@ This may take up to a minute. Start over 다시 시작 + + No custom software found at this URL. + + + + Something went wrong. Reboot the device. + + SetupWidget diff --git a/selfdrive/ui/translations/main_pt-BR.ts b/selfdrive/ui/translations/main_pt-BR.ts index 156b6f16c1..5c4eab3327 100644 --- a/selfdrive/ui/translations/main_pt-BR.ts +++ b/selfdrive/ui/translations/main_pt-BR.ts @@ -705,6 +705,14 @@ This may take up to a minute. Start over Inicializar + + No custom software found at this URL. + + + + Something went wrong. Reboot the device. + + SetupWidget diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts index f295a72938..cfc055ac98 100644 --- a/selfdrive/ui/translations/main_zh-CHS.ts +++ b/selfdrive/ui/translations/main_zh-CHS.ts @@ -699,6 +699,14 @@ This may take up to a minute. Start over 重来 + + No custom software found at this URL. + + + + Something went wrong. Reboot the device. + + SetupWidget diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts index b7636c18c5..e4058ee0db 100644 --- a/selfdrive/ui/translations/main_zh-CHT.ts +++ b/selfdrive/ui/translations/main_zh-CHT.ts @@ -701,6 +701,14 @@ This may take up to a minute. Start over 重新開始 + + No custom software found at this URL. + + + + Something went wrong. Reboot the device. + + SetupWidget From f64fa07b0a42bb04d036f1280953dbbd27de41a0 Mon Sep 17 00:00:00 2001 From: Cameron Clough Date: Thu, 23 Feb 2023 19:46:06 -0800 Subject: [PATCH 041/102] setup: set download timeout (#27441) --- selfdrive/ui/qt/setup/setup.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/selfdrive/ui/qt/setup/setup.cc b/selfdrive/ui/qt/setup/setup.cc index 3de6255521..de5021c8bc 100644 --- a/selfdrive/ui/qt/setup/setup.cc +++ b/selfdrive/ui/qt/setup/setup.cc @@ -53,6 +53,7 @@ void Setup::download(QString url) { curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(curl, CURLOPT_USERAGENT, (USER_AGENT + version).c_str()); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L); int ret = curl_easy_perform(curl); long res_status = 0; From 608ac253df5295187c6c7289b5b41a983482123e Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Fri, 24 Feb 2023 12:02:46 +0800 Subject: [PATCH 042/102] cabana: right align signal values & fixed text overflow (#27444) right align the signal values --- tools/cabana/signaledit.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tools/cabana/signaledit.cc b/tools/cabana/signaledit.cc index 5fcfc116c1..d5cd4ae825 100644 --- a/tools/cabana/signaledit.cc +++ b/tools/cabana/signaledit.cc @@ -338,6 +338,15 @@ void SignalItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op text = painter->fontMetrics().elidedText(text, Qt::ElideRight, text_rect.width()); painter->drawText(text_rect, option.displayAlignment, text); painter->restore(); + } else if (index.column() == 1 && item && item->type == SignalModel::Item::Sig) { + // draw signal value + if (option.state & QStyle::State_Selected) { + painter->fillRect(option.rect, option.palette.highlight()); + } + painter->setPen((option.state & QStyle::State_Selected ? option.palette.highlightedText() : option.palette.text()).color()); + QRect rc = option.rect.adjusted(0, 0, -70, 0); + auto text = painter->fontMetrics().elidedText(index.data(Qt::DisplayRole).toString(), Qt::ElideRight, rc.width()); + painter->drawText(rc, Qt::AlignRight | Qt::AlignVCenter, text); } else { QStyledItemDelegate::paint(painter, option, index); } From c80bc583817991a47bdcb59cc9d88713b1322b88 Mon Sep 17 00:00:00 2001 From: Robbe Derks Date: Fri, 24 Feb 2023 17:01:12 +0100 Subject: [PATCH 043/102] bump panda --- panda | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda b/panda index 9fe24bd368..1923b14189 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 9fe24bd3683377146b04c68ab94d0935f0bd9d78 +Subproject commit 1923b1418933e464ff7460a3e0a05d63aad0d53b From 78116029d33ab7724daa087201f1743fd34d6a19 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Sun, 26 Feb 2023 06:27:18 +0800 Subject: [PATCH 044/102] cabana: replace hardcoded margins, colors, spacing with values from style. (#27449) replace hardcoded margins, colors, spacing improve performance of MessageBytesDelegate --- tools/cabana/binaryview.cc | 7 ++----- tools/cabana/chartswidget.cc | 21 +++++++++++--------- tools/cabana/historylog.cc | 4 +++- tools/cabana/mainwin.cc | 5 +++++ tools/cabana/messageswidget.cc | 4 +++- tools/cabana/signaledit.cc | 20 ++++++++++++------- tools/cabana/util.cc | 36 ++++++++++++++++++++++------------ tools/cabana/util.h | 9 +++++++-- 8 files changed, 68 insertions(+), 38 deletions(-) diff --git a/tools/cabana/binaryview.cc b/tools/cabana/binaryview.cc index d9b00f6882..120a85a330 100644 --- a/tools/cabana/binaryview.cc +++ b/tools/cabana/binaryview.cc @@ -293,7 +293,6 @@ void BinaryViewModel::updateState() { double max_f = 255.0; double factor = 0.25; double scaler = max_f / log2(1.0 + factor); - char hex[3] = {'\0'}; for (int i = 0; i < binary.size(); ++i) { for (int j = 0; j < 8; ++j) { auto &item = items[i * column_count + j]; @@ -305,9 +304,7 @@ void BinaryViewModel::updateState() { double alpha = std::clamp(offset + log2(1.0 + factor * (double)n / (double)last_msg.count) * scaler, min_f, max_f); item.bg_color.setAlpha(alpha); } - hex[0] = toHex(binary[i] >> 4); - hex[1] = toHex(binary[i] & 0xf); - items[i * column_count + 8].val = hex; + items[i * column_count + 8].val = toHex(binary[i]); items[i * column_count + 8].bg_color = last_msg.colors[i]; } for (int i = binary.size() * column_count; i < items.size(); ++i) { @@ -375,7 +372,7 @@ void BinaryItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op bg.setAlpha(std::max(50, bg.alpha())); } painter->fillRect(option.rect, bg); - painter->setPen(Qt::black); + painter->setPen(option.palette.color(QPalette::Text)); } } diff --git a/tools/cabana/chartswidget.cc b/tools/cabana/chartswidget.cc index d895191d86..7982a5899c 100644 --- a/tools/cabana/chartswidget.cc +++ b/tools/cabana/chartswidget.cc @@ -25,11 +25,12 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QFrame(parent) { // toolbar QToolBar *toolbar = new QToolBar(tr("Charts"), this); - toolbar->setIconSize({16, 16}); + int icon_size = style()->pixelMetric(QStyle::PM_SmallIconSize); + toolbar->setIconSize({icon_size, icon_size}); QAction *new_plot_btn = toolbar->addAction(utils::icon("file-plus"), tr("New Plot")); toolbar->addWidget(title_label = new QLabel()); - title_label->setContentsMargins(0, 0, 12, 0); + title_label->setContentsMargins(0, 0, style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing), 0); QMenu *menu = new QMenu(this); for (int i = 0; i < MAX_COLUMN_COUNT; ++i) { @@ -77,8 +78,8 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QFrame(parent) { main_layout->addWidget(charts_scroll); // init settings - use_dark_theme = QApplication::style()->standardPalette().color(QPalette::WindowText).value() > - QApplication::style()->standardPalette().color(QPalette::Background).value(); + 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}; @@ -322,7 +323,7 @@ ChartView::ChartView(QWidget *parent) : QChartView(nullptr, parent) { chart->setMargins({0, 0, 0, 0}); background = new QGraphicsRectItem(chart); - background->setBrush(Qt::white); + background->setBrush(QApplication::palette().color(QPalette::Base)); background->setPen(Qt::NoPen); background->setZValue(chart->zValue() - 1); @@ -443,10 +444,12 @@ void ChartView::manageSeries() { void ChartView::resizeEvent(QResizeEvent *event) { updatePlotArea(align_to); - int x = event->size().width() - close_btn_proxy->size().width() - 11; - close_btn_proxy->setPos(x, 8); - manage_btn_proxy->setPos(x - manage_btn_proxy->size().width() - 5, 8); - move_icon->setPos(11, 8); + int top_margin = style()->pixelMetric(QStyle::PM_LayoutTopMargin); + int spacing = style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing); + int x = event->size().width() - close_btn_proxy->size().width() - style()->pixelMetric(QStyle::PM_LayoutRightMargin); + close_btn_proxy->setPos(x, top_margin); + manage_btn_proxy->setPos(x - manage_btn_proxy->size().width() - spacing, top_margin); + move_icon->setPos(style()->pixelMetric(QStyle::PM_LayoutLeftMargin), top_margin); QChartView::resizeEvent(event); } diff --git a/tools/cabana/historylog.cc b/tools/cabana/historylog.cc index deee2f1724..57f65b97d8 100644 --- a/tools/cabana/historylog.cc +++ b/tools/cabana/historylog.cc @@ -15,8 +15,10 @@ QVariant HistoryLogModel::data(const QModelIndex &index, int role) const { return QString::number((m.mono_time / (double)1e9) - can->routeStartTime(), 'f', 2); } return show_signals ? QString::number(m.sig_values[index.column() - 1]) : toHex(m.data); - } else if (role == Qt::UserRole && index.column() == 1 && !show_signals) { + } else if (role == ColorsRole) { return QVariant::fromValue(m.colors); + } else if (role == BytesRole) { + return m.data; } return {}; } diff --git a/tools/cabana/mainwin.cc b/tools/cabana/mainwin.cc index 25e40e15aa..282a541244 100644 --- a/tools/cabana/mainwin.cc +++ b/tools/cabana/mainwin.cc @@ -58,6 +58,11 @@ MainWindow::MainWindow() : QMainWindow() { fingerprint_to_dbc = QJsonDocument::fromJson(json_file.readAll()); } + setStyleSheet(QString(R"(QMainWindow::separator { + width: %1px; /* when vertical */ + height: %1px; /* when horizontal */ + })").arg(style()->pixelMetric(QStyle::PM_SplitterWidth))); + QObject::connect(this, &MainWindow::showMessage, statusBar(), &QStatusBar::showMessage); QObject::connect(this, &MainWindow::updateProgressBar, this, &MainWindow::updateDownloadProgress); QObject::connect(messages_widget, &MessagesWidget::msgSelectionChanged, center_widget, &CenterWidget::setMessage); diff --git a/tools/cabana/messageswidget.cc b/tools/cabana/messageswidget.cc index cda3069ad9..b4a7ed7b34 100644 --- a/tools/cabana/messageswidget.cc +++ b/tools/cabana/messageswidget.cc @@ -129,7 +129,7 @@ QVariant MessageListModel::data(const QModelIndex &index, int role) const { case 4: return can_data.count; case 5: return toHex(can_data.dat); } - } else if (role == Qt::UserRole && index.column() == 5) { + } else if (role == ColorsRole) { QVector colors = can_data.colors; if (!suppressed_bytes.empty()) { for (int i = 0; i < colors.size(); i++) { @@ -139,6 +139,8 @@ QVariant MessageListModel::data(const QModelIndex &index, int role) const { } } return QVariant::fromValue(colors); + } else if (role == BytesRole) { + return can_data.dat; } return {}; } diff --git a/tools/cabana/signaledit.cc b/tools/cabana/signaledit.cc index d5cd4ae825..e425a13f82 100644 --- a/tools/cabana/signaledit.cc +++ b/tools/cabana/signaledit.cc @@ -322,19 +322,22 @@ void SignalItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op // color label auto bg_color = getColor(item->sig); - QRect rc{option.rect.left(), option.rect.top(), color_label_width, option.rect.height()}; + int h_margin = option.widget->style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; + int v_margin = option.widget->style()->pixelMetric(QStyle::PM_FocusFrameVMargin); + QRect rc{option.rect.left() + h_margin, option.rect.top(), color_label_width, option.rect.height()}; painter->setPen(Qt::NoPen); painter->setBrush(item->highlight ? bg_color.darker(125) : bg_color); - painter->drawRoundedRect(rc.adjusted(0, 2, 0, -2), 3, 3); + painter->drawRoundedRect(rc.adjusted(0, v_margin, 0, -v_margin), 3, 3); painter->setPen(item->highlight ? Qt::white : Qt::black); painter->setFont(small_font); painter->drawText(rc, Qt::AlignCenter, QString::number(item->row() + 1)); // signal name painter->setFont(option.font); - painter->setPen((option.state & QStyle::State_Selected ? option.palette.highlightedText() : option.palette.text()).color()); + painter->setPen(option.palette.color(option.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text)); QString text = index.data(Qt::DisplayRole).toString(); - QRect text_rect = option.rect.adjusted(rc.width() + 6, 0, 0, 0); + QRect text_rect = option.rect; + text_rect.setLeft(rc.right() + h_margin * 2); text = painter->fontMetrics().elidedText(text, Qt::ElideRight, text_rect.width()); painter->drawText(text_rect, option.displayAlignment, text); painter->restore(); @@ -343,7 +346,7 @@ void SignalItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op if (option.state & QStyle::State_Selected) { painter->fillRect(option.rect, option.palette.highlight()); } - painter->setPen((option.state & QStyle::State_Selected ? option.palette.highlightedText() : option.palette.text()).color()); + painter->setPen(option.palette.color(option.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text)); QRect rc = option.rect.adjusted(0, 0, -70, 0); auto text = painter->fontMetrics().elidedText(index.data(Qt::DisplayRole).toString(), Qt::ElideRight, rc.width()); painter->drawText(rc, Qt::AlignRight | Qt::AlignVCenter, text); @@ -442,8 +445,11 @@ void SignalView::rowsChanged() { if (!tree->indexWidget(index)) { QWidget *w = new QWidget(this); QHBoxLayout *h = new QHBoxLayout(w); - h->setContentsMargins(0, 2, 0, 2); - h->addStretch(1); + int v_margin = style()->pixelMetric(QStyle::PM_FocusFrameVMargin); + 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", ""); diff --git a/tools/cabana/util.cc b/tools/cabana/util.cc index 4f79f9a3ac..5e4f505d29 100644 --- a/tools/cabana/util.cc +++ b/tools/cabana/util.cc @@ -71,26 +71,26 @@ void ChangeTracker::clear() { MessageBytesDelegate::MessageBytesDelegate(QObject *parent) : QStyledItemDelegate(parent) { fixed_font = QFontDatabase::systemFont(QFontDatabase::FixedFont); + byte_width = QFontMetrics(fixed_font).width("00 "); } void MessageBytesDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { + auto colors = index.data(ColorsRole).value>(); + auto byte_list = index.data(BytesRole).toByteArray(); + + int v_margin = option.widget->style()->pixelMetric(QStyle::PM_FocusFrameVMargin); + int h_margin = option.widget->style()->pixelMetric(QStyle::PM_FocusFrameHMargin); + QRect rc{option.rect.left() + h_margin, option.rect.top() + v_margin, byte_width, option.rect.height() - 2 * v_margin}; + auto color_role = option.state & QStyle::State_Selected ? QPalette::HighlightedText: QPalette::Text; painter->setPen(option.palette.color(color_role)); painter->setFont(fixed_font); - int space = painter->boundingRect(option.rect, option.displayAlignment, " ").width(); - QRect pos = painter->boundingRect(option.rect, option.displayAlignment, "00").adjusted(0, 0, 2, 0); - pos.moveLeft(pos.x() + space); - int m = space / 2; - const QMargins margins(m, m, m, m); - - auto colors = index.data(Qt::UserRole).value>(); - auto byte_list = index.data(Qt::DisplayRole).toString().split(" "); for (int i = 0; i < byte_list.size(); ++i) { if (i < colors.size() && colors[i].alpha() > 0) { - painter->fillRect(pos.marginsAdded(margins), colors[i]); + painter->fillRect(rc, colors[i]); } - painter->drawText(pos, Qt::AlignCenter, byte_list[i]); - pos.moveLeft(pos.right() + space); + painter->drawText(rc, Qt::AlignCenter, toHex(byte_list[i])); + rc.moveLeft(rc.right() + 1); } } @@ -114,8 +114,8 @@ QValidator::State NameValidator::validate(QString &input, int &pos) const { namespace utils { QPixmap icon(const QString &id) { - static bool dark_theme = QApplication::style()->standardPalette().color(QPalette::WindowText).value() > - QApplication::style()->standardPalette().color(QPalette::Background).value(); + static bool dark_theme = QApplication::palette().color(QPalette::WindowText).value() > + QApplication::palette().color(QPalette::Background).value(); QPixmap pm; QString key = "bootstrap_" % id % (dark_theme ? "1" : "0"); if (!QPixmapCache::find(key, &pm)) { @@ -138,3 +138,13 @@ QToolButton *toolButton(const QString &icon, const QString &tooltip) { btn->setAutoRaise(true); return btn; }; + + +QString toHex(uint8_t byte) { + static std::array hex = []() { + std::array ret; + for (int i = 0; i < 256; ++i) ret[i] = QStringLiteral("%1").arg(i, 2, 16, QLatin1Char('0')).toUpper(); + return ret; + }(); + return hex[byte]; +} diff --git a/tools/cabana/util.h b/tools/cabana/util.h index b72ddfcaa0..5eb5c3c5aa 100644 --- a/tools/cabana/util.h +++ b/tools/cabana/util.h @@ -14,7 +14,6 @@ #include "tools/cabana/dbcmanager.h" using namespace dbcmanager; - class ChangeTracker { public: void compute(const QByteArray &dat, double ts, uint32_t freq); @@ -31,16 +30,22 @@ private: QByteArray prev_dat; }; +enum { + ColorsRole = Qt::UserRole + 1, + BytesRole = Qt::UserRole + 2 +}; + class MessageBytesDelegate : public QStyledItemDelegate { Q_OBJECT public: MessageBytesDelegate(QObject *parent); void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; QFont fixed_font; + int byte_width; }; inline QString toHex(const QByteArray &dat) { return dat.toHex(' ').toUpper(); } -inline char toHex(uint value) { return "0123456789ABCDEF"[value & 0xF]; } +QString toHex(uint8_t byte); QColor getColor(const dbcmanager::Signal *sig); class NameValidator : public QRegExpValidator { From 581fd62d2642629b23ac111112245a963202143f Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Sun, 26 Feb 2023 17:32:52 -0800 Subject: [PATCH 045/102] steer limits: rename common dist to meas function (#27453) * rename function * make a wrapper function (ford uses dynamic up/down limits * make two functions consistent * make torque function convert to int --- selfdrive/car/__init__.py | 38 ++++++++++++++--------- selfdrive/car/chrysler/carcontroller.py | 4 +-- selfdrive/car/gm/carcontroller.py | 4 +-- selfdrive/car/hyundai/carcontroller.py | 4 +-- selfdrive/car/mazda/carcontroller.py | 6 ++-- selfdrive/car/subaru/carcontroller.py | 4 +-- selfdrive/car/toyota/carcontroller.py | 4 +-- selfdrive/car/volkswagen/carcontroller.py | 4 +-- 8 files changed, 38 insertions(+), 30 deletions(-) diff --git a/selfdrive/car/__init__.py b/selfdrive/car/__init__.py index a90f023ed1..58cde85817 100644 --- a/selfdrive/car/__init__.py +++ b/selfdrive/car/__init__.py @@ -73,7 +73,7 @@ def dbc_dict(pt_dbc, radar_dbc, chassis_dbc=None, body_dbc=None) -> Dict[str, st return {'pt': pt_dbc, 'radar': radar_dbc, 'chassis': chassis_dbc, 'body': body_dbc} -def apply_std_steer_torque_limits(apply_torque, apply_torque_last, driver_torque, LIMITS): +def apply_driver_steer_torque_limits(apply_torque, apply_torque_last, driver_torque, LIMITS): # limits due to driver torque driver_max_torque = LIMITS.STEER_MAX + (LIMITS.STEER_DRIVER_ALLOWANCE + driver_torque * LIMITS.STEER_DRIVER_FACTOR) * LIMITS.STEER_DRIVER_MULTIPLIER @@ -93,24 +93,32 @@ def apply_std_steer_torque_limits(apply_torque, apply_torque_last, driver_torque return int(round(float(apply_torque))) -def apply_toyota_steer_torque_limits(apply_torque, apply_torque_last, motor_torque, LIMITS): - # limits due to comparison of commanded torque VS motor reported torque - max_lim = min(max(motor_torque + LIMITS.STEER_ERROR_MAX, LIMITS.STEER_ERROR_MAX), LIMITS.STEER_MAX) - min_lim = max(min(motor_torque - LIMITS.STEER_ERROR_MAX, -LIMITS.STEER_ERROR_MAX), -LIMITS.STEER_MAX) +def apply_dist_to_meas_limits(val, val_last, val_meas, + STEER_DELTA_UP, STEER_DELTA_DOWN, + STEER_ERROR_MAX, STEER_MAX): + # limits due to comparison of commanded val VS measured val (torque/angle/curvature) + max_lim = min(max(val_meas + STEER_ERROR_MAX, STEER_ERROR_MAX), STEER_MAX) + min_lim = max(min(val_meas - STEER_ERROR_MAX, -STEER_ERROR_MAX), -STEER_MAX) - apply_torque = clip(apply_torque, min_lim, max_lim) + val = clip(val, min_lim, max_lim) - # slow rate if steer torque increases in magnitude - if apply_torque_last > 0: - apply_torque = clip(apply_torque, - max(apply_torque_last - LIMITS.STEER_DELTA_DOWN, -LIMITS.STEER_DELTA_UP), - apply_torque_last + LIMITS.STEER_DELTA_UP) + # slow rate if val increases in magnitude + if val_last > 0: + val = clip(val, + max(val_last - STEER_DELTA_DOWN, -STEER_DELTA_UP), + val_last + STEER_DELTA_UP) else: - apply_torque = clip(apply_torque, - apply_torque_last - LIMITS.STEER_DELTA_UP, - min(apply_torque_last + LIMITS.STEER_DELTA_DOWN, LIMITS.STEER_DELTA_UP)) + val = clip(val, + val_last - STEER_DELTA_UP, + min(val_last + STEER_DELTA_DOWN, STEER_DELTA_UP)) - return int(round(float(apply_torque))) + return float(val) + + +def apply_meas_steer_torque_limits(apply_torque, apply_torque_last, motor_torque, LIMITS): + return int(round(apply_dist_to_meas_limits(apply_torque, apply_torque_last, motor_torque, + LIMITS.STEER_DELTA_UP, LIMITS.STEER_DELTA_DOWN, + LIMITS.STEER_ERROR_MAX, LIMITS.STEER_MAX))) def apply_std_steer_angle_limits(apply_angle, apply_angle_last, v_ego, LIMITS): diff --git a/selfdrive/car/chrysler/carcontroller.py b/selfdrive/car/chrysler/carcontroller.py index 20a44bce21..b418179e0e 100644 --- a/selfdrive/car/chrysler/carcontroller.py +++ b/selfdrive/car/chrysler/carcontroller.py @@ -1,6 +1,6 @@ from opendbc.can.packer import CANPacker from common.realtime import DT_CTRL -from selfdrive.car import apply_toyota_steer_torque_limits +from selfdrive.car import apply_meas_steer_torque_limits from selfdrive.car.chrysler.chryslercan import create_lkas_hud, create_lkas_command, create_cruise_buttons from selfdrive.car.chrysler.values import RAM_CARS, CarControllerParams, ChryslerFlags @@ -67,7 +67,7 @@ class CarController: # steer torque new_steer = int(round(CC.actuators.steer * self.params.STEER_MAX)) - apply_steer = apply_toyota_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorqueEps, self.params) + apply_steer = apply_meas_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorqueEps, self.params) if not lkas_active or not lkas_control_bit: apply_steer = 0 self.apply_steer_last = apply_steer diff --git a/selfdrive/car/gm/carcontroller.py b/selfdrive/car/gm/carcontroller.py index 42eaf7e88a..2a996c0ff6 100644 --- a/selfdrive/car/gm/carcontroller.py +++ b/selfdrive/car/gm/carcontroller.py @@ -3,7 +3,7 @@ from common.conversions import Conversions as CV from common.numpy_fast import interp from common.realtime import DT_CTRL from opendbc.can.packer import CANPacker -from selfdrive.car import apply_std_steer_torque_limits +from selfdrive.car import apply_driver_steer_torque_limits from selfdrive.car.gm import gmcan from selfdrive.car.gm.values import DBC, CanBus, CarControllerParams, CruiseButtons @@ -73,7 +73,7 @@ class CarController: if CC.latActive: new_steer = int(round(actuators.steer * self.params.STEER_MAX)) - apply_steer = apply_std_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque, self.params) + apply_steer = apply_driver_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque, self.params) else: apply_steer = 0 diff --git a/selfdrive/car/hyundai/carcontroller.py b/selfdrive/car/hyundai/carcontroller.py index 1e6f78af20..2572038492 100644 --- a/selfdrive/car/hyundai/carcontroller.py +++ b/selfdrive/car/hyundai/carcontroller.py @@ -3,7 +3,7 @@ from common.conversions import Conversions as CV from common.numpy_fast import clip from common.realtime import DT_CTRL from opendbc.can.packer import CANPacker -from selfdrive.car import apply_std_steer_torque_limits +from selfdrive.car import apply_driver_steer_torque_limits from selfdrive.car.hyundai import hyundaicanfd, hyundaican from selfdrive.car.hyundai.values import HyundaiFlags, Buttons, CarControllerParams, CANFD_CAR, CAR @@ -60,7 +60,7 @@ class CarController: # steering torque new_steer = int(round(actuators.steer * self.params.STEER_MAX)) - apply_steer = apply_std_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque, self.params) + apply_steer = apply_driver_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque, self.params) if not CC.latActive: apply_steer = 0 diff --git a/selfdrive/car/mazda/carcontroller.py b/selfdrive/car/mazda/carcontroller.py index 524a02a370..cb401a8abd 100644 --- a/selfdrive/car/mazda/carcontroller.py +++ b/selfdrive/car/mazda/carcontroller.py @@ -1,6 +1,6 @@ from cereal import car from opendbc.can.packer import CANPacker -from selfdrive.car import apply_std_steer_torque_limits +from selfdrive.car import apply_driver_steer_torque_limits from selfdrive.car.mazda import mazdacan from selfdrive.car.mazda.values import CarControllerParams, Buttons @@ -23,8 +23,8 @@ class CarController: if CC.latActive: # calculate steer and also set limits due to driver torque new_steer = int(round(CC.actuators.steer * CarControllerParams.STEER_MAX)) - apply_steer = apply_std_steer_torque_limits(new_steer, self.apply_steer_last, - CS.out.steeringTorque, CarControllerParams) + apply_steer = apply_driver_steer_torque_limits(new_steer, self.apply_steer_last, + CS.out.steeringTorque, CarControllerParams) if CC.cruiseControl.cancel: # If brake is pressed, let us wait >70ms before trying to disable crz to avoid diff --git a/selfdrive/car/subaru/carcontroller.py b/selfdrive/car/subaru/carcontroller.py index 24d85877d7..a6dbf4a39e 100644 --- a/selfdrive/car/subaru/carcontroller.py +++ b/selfdrive/car/subaru/carcontroller.py @@ -1,5 +1,5 @@ from opendbc.can.packer import CANPacker -from selfdrive.car import apply_std_steer_torque_limits +from selfdrive.car import apply_driver_steer_torque_limits from selfdrive.car.subaru import subarucan from selfdrive.car.subaru.values import DBC, GLOBAL_GEN2, PREGLOBAL_CARS, CarControllerParams @@ -34,7 +34,7 @@ class CarController: # limits due to driver torque new_steer = int(round(apply_steer)) - apply_steer = apply_std_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque, self.p) + apply_steer = apply_driver_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque, self.p) if not CC.latActive: apply_steer = 0 diff --git a/selfdrive/car/toyota/carcontroller.py b/selfdrive/car/toyota/carcontroller.py index 2e0d7009c8..8004ea9dca 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_interceptor_command, make_can_msg +from selfdrive.car import apply_meas_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 @@ -60,7 +60,7 @@ class CarController: # steer torque new_steer = int(round(actuators.steer * CarControllerParams.STEER_MAX)) - apply_steer = apply_toyota_steer_torque_limits(new_steer, self.last_steer, CS.out.steeringTorqueEps, self.torque_rate_limits) + apply_steer = apply_meas_steer_torque_limits(new_steer, self.last_steer, CS.out.steeringTorqueEps, self.torque_rate_limits) # Count up to MAX_STEER_RATE_FRAMES, at which point we need to cut torque to avoid a steering fault if lat_active and abs(CS.out.steeringRateDeg) >= MAX_STEER_RATE: diff --git a/selfdrive/car/volkswagen/carcontroller.py b/selfdrive/car/volkswagen/carcontroller.py index 5d00b5a52f..c17b632450 100644 --- a/selfdrive/car/volkswagen/carcontroller.py +++ b/selfdrive/car/volkswagen/carcontroller.py @@ -3,7 +3,7 @@ from opendbc.can.packer import CANPacker from common.numpy_fast import clip from common.conversions import Conversions as CV from common.realtime import DT_CTRL -from selfdrive.car import apply_std_steer_torque_limits +from selfdrive.car import apply_driver_steer_torque_limits from selfdrive.car.volkswagen import mqbcan, pqcan from selfdrive.car.volkswagen.values import CANBUS, PQ_CARS, CarControllerParams @@ -44,7 +44,7 @@ class CarController: if CC.latActive: new_steer = int(round(actuators.steer * self.CCP.STEER_MAX)) - apply_steer = apply_std_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque, self.CCP) + apply_steer = apply_driver_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque, self.CCP) if apply_steer == 0: hcaEnabled = False self.hcaEnabledFrameCount = 0 From c995acda7c502bc14fff431ba4832faa9dbaec18 Mon Sep 17 00:00:00 2001 From: ZwX1616 Date: Tue, 28 Feb 2023 03:01:55 +0800 Subject: [PATCH 046/102] driverview: use static icon (#27448) * fix alpha * prerender --- selfdrive/assets/img_driver_face.png | Bin 19875 -> 3769 bytes selfdrive/assets/img_driver_face_static.png | Bin 0 -> 4908 bytes selfdrive/ui/qt/offroad/driverview.cc | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 selfdrive/assets/img_driver_face_static.png diff --git a/selfdrive/assets/img_driver_face.png b/selfdrive/assets/img_driver_face.png index 03765a0376dc33e72f88fb68d0f3879bffff90ff..e2d943e537fb1cc489dbcfbb3dcfeb57258fb4b0 100644 GIT binary patch literal 3769 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 PNjdt3OOnnd7;OIrwou~J literal 19875 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 ami>RG56lgMCO}*O0000vK&AGLy2(^ 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 Us`>2_d Date: Mon, 27 Feb 2023 13:49:06 -0800 Subject: [PATCH 047/102] Update check-submodules.sh --- release/check-submodules.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/check-submodules.sh b/release/check-submodules.sh index 2585db6bd7..5f4e307e49 100755 --- a/release/check-submodules.sh +++ b/release/check-submodules.sh @@ -1,7 +1,7 @@ #!/bin/bash while read hash submodule ref; do - git -C $submodule fetch --depth 300 origin master + git -C $submodule fetch --depth 1000 origin master git -C $submodule branch -r --contains $hash | grep "origin/master" if [ "$?" -eq 0 ]; then echo "$submodule ok" From dc39a87543d61eb5d24ee5f27b661474f7f16598 Mon Sep 17 00:00:00 2001 From: Lee Jong Mun <43285072+crwusiz@users.noreply.github.com> Date: Tue, 28 Feb 2023 08:50:32 +0900 Subject: [PATCH 048/102] Multilang: kor translation update (#27445) --- selfdrive/ui/translations/main_ko.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/selfdrive/ui/translations/main_ko.ts b/selfdrive/ui/translations/main_ko.ts index 5470e57ce5..be11f2efde 100644 --- a/selfdrive/ui/translations/main_ko.ts +++ b/selfdrive/ui/translations/main_ko.ts @@ -403,7 +403,7 @@ location set Waiting for GPS - GPS를 기다리는 중 + GPS 수신중 입니다 @@ -592,16 +592,17 @@ location set Unable to mount data partition. Partition may be corrupted. Press confirm to erase and reset your device. - + 데이터 파티션을 마운트할 수 없습니다. 파티션이 손상되었을 수 있습니다. 장치를 초기화하려면 확인을 누르세요. Press confirm to erase all content and settings. Press cancel to resume boot. - + 모든 콘텐츠와 설정을 지우려면 확인을 누르세요. 부팅을 재개하려면 취소를 누르세요. Resetting device... This may take up to a minute. - + 장치 초기화 중... +최대 1분이 소요될 수 있습니다. @@ -702,12 +703,12 @@ This may take up to a minute. 다시 시작 - No custom software found at this URL. - + Something went wrong. Reboot the device. + 문제가 발생했습니다. 장치를 재부팅하세요. - Something went wrong. Reboot the device. - + No custom software found at this URL. + 이 URL에서 커스텀 소프트웨어를 찾을 수 없습니다. From ce3e9d5649d930ea0daae2d2a1587cc6e69c158b Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Tue, 28 Feb 2023 07:51:23 +0800 Subject: [PATCH 049/102] cabana: fix gaps in step line between chunks (#27447) --- tools/cabana/chartswidget.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/cabana/chartswidget.cc b/tools/cabana/chartswidget.cc index 7982a5899c..42f8e4e06a 100644 --- a/tools/cabana/chartswidget.cc +++ b/tools/cabana/chartswidget.cc @@ -552,7 +552,12 @@ void ChartView::updateSeries(const Signal *sig, const std::vector *even }); for (auto &c : chunks) { s.vals.append(c.vals); - s.step_vals.append(c.step_vals); + if (!c.step_vals.empty()) { + if (!s.step_vals.empty()) { + s.step_vals.append({c.step_vals.first().x(), s.step_vals.back().y()}); + } + s.step_vals.append(c.step_vals); + } } if (events->size()) { s.last_value_mono_time = events->back()->mono_time; From 8d317ef51ce3518e6bd3bb1a97567f8686ca8c8d Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Wed, 1 Mar 2023 07:50:30 +0800 Subject: [PATCH 050/102] cabana: press F11 to toggle fullscreen (#27455) --- tools/cabana/mainwin.cc | 15 +++++++++++++++ tools/cabana/mainwin.h | 1 + 2 files changed, 16 insertions(+) diff --git a/tools/cabana/mainwin.cc b/tools/cabana/mainwin.cc index 282a541244..abcb4948a9 100644 --- a/tools/cabana/mainwin.cc +++ b/tools/cabana/mainwin.cc @@ -194,6 +194,8 @@ void MainWindow::createStatusBar() { void MainWindow::createShortcuts() { auto shortcut = new QShortcut(QKeySequence(Qt::Key_Space), this, nullptr, nullptr, Qt::ApplicationShortcut); QObject::connect(shortcut, &QShortcut::activated, []() { can->pause(!can->isPaused()); }); + shortcut = new QShortcut(QKeySequence(QKeySequence::FullScreen), this, nullptr, nullptr, Qt::ApplicationShortcut); + QObject::connect(shortcut, &QShortcut::activated, this, &MainWindow::toggleFullScreen); // TODO: add more shortcuts here. } @@ -482,6 +484,19 @@ void MainWindow::onlineHelp() { } } +void MainWindow::toggleFullScreen() { + if (isFullScreen()) { + menuBar()->show(); + statusBar()->show(); + showNormal(); + showMaximized(); + } else { + menuBar()->hide(); + statusBar()->hide(); + showFullScreen(); + } +} + // HelpOverlay HelpOverlay::HelpOverlay(MainWindow *parent) : QWidget(parent) { setAttribute(Qt::WA_NoSystemBackground, true); diff --git a/tools/cabana/mainwin.h b/tools/cabana/mainwin.h index 2aeb20aea8..1c21d69370 100644 --- a/tools/cabana/mainwin.h +++ b/tools/cabana/mainwin.h @@ -56,6 +56,7 @@ protected: void undoStackCleanChanged(bool clean); void undoStackIndexChanged(int index); void onlineHelp(); + void toggleFullScreen(); void updateStatus(); VideoWidget *video_widget = nullptr; From b6881220426ac231215bbf4476f6fedd11e3e540 Mon Sep 17 00:00:00 2001 From: Kurt Nistelberger Date: Tue, 28 Feb 2023 21:40:54 -0800 Subject: [PATCH 051/102] laikad: reduce min satellite number (#27440) * bump laika * update laikad tests * update refs * bump laika * update refs --------- Co-authored-by: Kurt Nistelberger --- laika_repo | 2 +- selfdrive/locationd/laikad.py | 20 +++++++++++++------- selfdrive/locationd/test/test_laikad.py | 10 +++++----- selfdrive/test/process_replay/ref_commit | 2 +- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/laika_repo b/laika_repo index 278b44ba8c..b740b71c82 160000 --- a/laika_repo +++ b/laika_repo @@ -1 +1 @@ -Subproject commit 278b44ba8c2dec28adc5b30cce13dabc195f15fc +Subproject commit b740b71c82a748e3520b1599487d9a7aaf728670 diff --git a/selfdrive/locationd/laikad.py b/selfdrive/locationd/laikad.py index 2eb1e94526..10c5e1b7e5 100755 --- a/selfdrive/locationd/laikad.py +++ b/selfdrive/locationd/laikad.py @@ -97,19 +97,25 @@ class Laikad: def get_lsq_fix(self, t, measurements): if self.last_fix_t is None or abs(self.last_fix_t - t) > 0: - min_measurements = 7 if any(p.constellation_id == ConstellationId.GLONASS for p in measurements) else 6 - position_solution, pr_residuals = calc_pos_fix(measurements, self.posfix_functions, min_measurements=min_measurements) + min_measurements = 5 if any(p.constellation_id == ConstellationId.GLONASS for p in measurements) else 4 + position_solution, pr_residuals, pos_std = calc_pos_fix(measurements, self.posfix_functions, min_measurements=min_measurements) if len(position_solution) < 3: return None position_estimate = position_solution[:3] - #TODO median abs residual is decent estimate of std, can be improved with measurements stds and/or DOP - position_std = np.median(np.abs(pr_residuals)) * np.ones(3) - velocity_solution, prr_residuals = calc_vel_fix(measurements, position_estimate, self.velfix_function, min_measurements=min_measurements) + + position_std_residual = np.median(np.abs(pr_residuals)) + position_std = np.median(np.abs(pos_std))/10 + position_std = max(position_std_residual, position_std) * np.ones(3) + + velocity_solution, prr_residuals, vel_std = calc_vel_fix(measurements, position_estimate, self.velfix_function, min_measurements=min_measurements) if len(velocity_solution) < 3: return None - velocity_estimate = velocity_solution[:3] - velocity_std = np.median(np.abs(prr_residuals)) * np.ones(3) + + velocity_std_residual = np.median(np.abs(prr_residuals)) + velocity_std = np.median(np.abs(vel_std))/10 + velocity_std = max(velocity_std, velocity_std_residual) * np.ones(3) + return position_estimate, position_std, velocity_estimate, velocity_std def is_good_report(self, gnss_msg): diff --git a/selfdrive/locationd/test/test_laikad.py b/selfdrive/locationd/test/test_laikad.py index d89f521228..10ac7790b6 100755 --- a/selfdrive/locationd/test/test_laikad.py +++ b/selfdrive/locationd/test/test_laikad.py @@ -160,7 +160,7 @@ class TestLaikad(unittest.TestCase): laikad = Laikad(auto_update=True, valid_ephem_types=EphemerisType.ULTRA_RAPID_ORBIT) correct_msgs = verify_messages(self.logs, laikad) - correct_msgs_expected = 554 + correct_msgs_expected = 559 self.assertEqual(correct_msgs_expected, len(correct_msgs)) self.assertEqual(correct_msgs_expected, len([m for m in correct_msgs if m.gnssMeasurements.positionECEF.valid])) @@ -180,7 +180,7 @@ class TestLaikad(unittest.TestCase): laikad = Laikad(auto_update=True, valid_ephem_types=EphemerisType.NAV) # Disable fetch_orbits to test NAV only correct_msgs = verify_messages(self.logs, laikad) - correct_msgs_expected = 554 + correct_msgs_expected = 559 self.assertEqual(correct_msgs_expected, len(correct_msgs)) self.assertEqual(correct_msgs_expected, len([m for m in correct_msgs if m.gnssMeasurements.positionECEF.valid])) @@ -195,8 +195,8 @@ class TestLaikad(unittest.TestCase): downloader_mock.side_effect = DownloadFailed laikad = Laikad(auto_update=False) correct_msgs = verify_messages(self.logs, laikad) - self.assertEqual(0, len(correct_msgs)) - self.assertEqual(0, len([m for m in correct_msgs if m.gnssMeasurements.positionECEF.valid])) + self.assertEqual(255, len(correct_msgs)) + self.assertEqual(255, len([m for m in correct_msgs if m.gnssMeasurements.positionECEF.valid])) def test_laika_get_orbits(self): laikad = Laikad(auto_update=False) @@ -282,7 +282,7 @@ class TestLaikad(unittest.TestCase): gm = msg.gnssMeasurements if len(gm.correctedMeasurements) != 0 and gm.positionECEF.valid: cnt += 1 - self.assertEqual(cnt, 554) + self.assertEqual(cnt, 559) def dict_has_values(self, dct): self.assertGreater(len(dct), 0) diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index 9991154b9a..b44c9c2f46 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -772f30de36fc7f8421dabb779cc02f45eb83d7bb +dfa8e947c4ef76a9d89974a434e94a078e1ccc6a \ No newline at end of file From 85a37d276c105494b97eee03aa6bb31a212f2f92 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Wed, 1 Mar 2023 15:41:28 +0800 Subject: [PATCH 052/102] cabana: recalc y-axis label width after unit change (#27466) recalc width --- tools/cabana/chartswidget.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/cabana/chartswidget.cc b/tools/cabana/chartswidget.cc index 42f8e4e06a..2c27fbd8b9 100644 --- a/tools/cabana/chartswidget.cc +++ b/tools/cabana/chartswidget.cc @@ -591,11 +591,14 @@ void ChartView::updateAxisY() { if (it->y() > max) max = it->y(); } } - axis_y->setTitleText(unit); - if (min == std::numeric_limits::max()) min = 0; if (max == std::numeric_limits::lowest()) max = 0; + if (axis_y->titleText() != unit) { + axis_y->setTitleText(unit); + y_label_width = 0;// recalc width + } + double delta = std::abs(max - min) < 1e-3 ? 1 : (max - min) * 0.05; auto [min_y, max_y, tick_count] = getNiceAxisNumbers(min - delta, max + delta, axis_y->tickCount()); if (min_y != axis_y->min() || max_y != axis_y->max() || y_label_width == 0) { From d6abf1d5725e1de58d6f3dc23a238aa4bf65b642 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 1 Mar 2023 13:38:49 -0800 Subject: [PATCH 053/102] No disengage on gas by default (#27472) --- selfdrive/manager/manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/manager/manager.py b/selfdrive/manager/manager.py index 865966d6c5..963d94066b 100755 --- a/selfdrive/manager/manager.py +++ b/selfdrive/manager/manager.py @@ -36,7 +36,7 @@ def manager_init() -> None: default_params: List[Tuple[str, Union[str, bytes]]] = [ ("CompletedTrainingVersion", "0"), - ("DisengageOnAccelerator", "1"), + ("DisengageOnAccelerator", "0"), ("GsmMetered", "1"), ("HasAcceptedTerms", "0"), ("LanguageSetting", "main_en"), From 9ce26b201104afd24fb20baeba22320473afc09d Mon Sep 17 00:00:00 2001 From: Iamz Date: Thu, 2 Mar 2023 06:35:28 +0700 Subject: [PATCH 054/102] Add missing Thai translations and remove obsolete messages. (#27469) Update Thai translations --- selfdrive/ui/translations/main_th.ts | 54 +++++++++++----------------- 1 file changed, 20 insertions(+), 34 deletions(-) diff --git a/selfdrive/ui/translations/main_th.ts b/selfdrive/ui/translations/main_th.ts index ce394ecb97..45f91f1cdb 100644 --- a/selfdrive/ui/translations/main_th.ts +++ b/selfdrive/ui/translations/main_th.ts @@ -311,18 +311,6 @@ Installing... กำลังติดตั้ง... - - Receiving objects: - กำลังรับข้อมูล: - - - Resolving deltas: - การแก้ไขเดลต้า: - - - Updating files: - กำลังอัปเดตไฟล์: - MapETA @@ -586,18 +574,10 @@ location set Are you sure you want to reset your device? คุณแน่ใจหรือไม่ว่าต้องการรีเซ็ตอุปกรณ์? - - Resetting device... - กำลังรีเซ็ตอุปกรณ์... - System Reset รีเซ็ตระบบ - - System reset triggered. Press confirm to erase all content and settings. Press cancel to resume boot. - มีการสั่งรีเซ็ตระบบ กดยืนยันเพื่อลบข้อมูลและการตั้งค่าทั้งหมด กดยกเลิกเพื่อบูตเข้าระบบตามปกติ - Cancel ยกเลิก @@ -611,8 +591,18 @@ location set ยืนยัน - Unable to mount data partition. Press confirm to reset your device. - ไม่สามารถเมานต์พาร์ติชั่นข้อมูล กดยืนยันเพื่อรีเซ็ตอุปกรณ์ของคุณ + Resetting device... +This may take up to a minute. + กำลังรีเซ็ตอุปกรณ์... +อาจใช้เวลาถึงหนึ่งนาที + + + Press confirm to erase all content and settings. Press cancel to resume boot. + กดยืนยันเพื่อลบข้อมูลและการตั้งค่าทั้งหมด กดยกเลิกเพื่อบูตต่อ + + + Unable to mount data partition. Partition may be corrupted. Press confirm to erase and reset your device. + ไม่สามารถเมานต์พาร์ติชั่นข้อมูลได้ พาร์ติชั่นอาจเสียหาย กดยืนยันเพื่อลบและรีเซ็ตอุปกรณ์ของคุณ @@ -684,18 +674,6 @@ location set Waiting for internet กำลังรอสัญญาณอินเตอร์เน็ต - - Choose Software to Install - เลือกซอฟต์แวร์ที่จะติดตั้ง - - - Dashcam - กล้องติดรถยนต์ - - - Custom Software - ซอฟต์แวร์ที่กำหนดเอง - Enter URL ป้อน URL @@ -724,6 +702,14 @@ location set Start over เริ่มต้นใหม่ + + Something went wrong. Reboot the device. + มีบางอย่างผิดพลาด รีบูตอุปกรณ์ + + + No custom software found at this URL. + ไม่พบซอฟต์แวร์ที่กำหนดเองที่ URL นี้ + SetupWidget From be42193a618c9133d9a3a3bd4ac33dd19f0209f5 Mon Sep 17 00:00:00 2001 From: koffee-bean <125648286+koffee-bean@users.noreply.github.com> Date: Wed, 1 Mar 2023 16:39:38 -0700 Subject: [PATCH 055/102] Hyundai: add missing 2022 Ioniq 5 fwdCamera version (#27471) Co-authored-by: srivastavasid91@gmail.com --- selfdrive/car/hyundai/values.py | 1 + 1 file changed, 1 insertion(+) diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index 4b7a295246..d81c98fbcd 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -1566,6 +1566,7 @@ FW_VERSIONS = { b'\xf1\x00NE1 MFC AT EUR RHD 1.00 1.01 99211-GI010 211007', b'\xf1\x00NE1 MFC AT USA LHD 1.00 1.01 99211-GI010 211007', b'\xf1\x00NE1 MFC AT EUR RHD 1.00 1.02 99211-GI010 211206', + b'\xf1\x00NE1 MFC AT USA LHD 1.00 1.03 99211-GI010 220401', ], }, CAR.TUCSON_4TH_GEN: { From 7f10c736ab0e1f027738b5f64ca75308435a3ade Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Wed, 1 Mar 2023 15:57:11 -0800 Subject: [PATCH 056/102] test_fw_query_on_routes.py: don't print FW for logging --- selfdrive/debug/test_fw_query_on_routes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/debug/test_fw_query_on_routes.py b/selfdrive/debug/test_fw_query_on_routes.py index ba7d96dba0..dc6688324f 100755 --- a/selfdrive/debug/test_fw_query_on_routes.py +++ b/selfdrive/debug/test_fw_query_on_routes.py @@ -74,7 +74,7 @@ if __name__ == "__main__": elif msg.which() == "carParams": CP = msg.carParams - car_fw = CP.carFw + car_fw = [fw for fw in CP.carFw if not fw.logging] if len(car_fw) == 0: print("no fw") break From d50d8de63787a09b57c294c54b6f88a1236ec2bc Mon Sep 17 00:00:00 2001 From: javenzy <85425378+javenzy@users.noreply.github.com> Date: Thu, 2 Mar 2023 08:00:08 +0800 Subject: [PATCH 057/102] Add China HONDA ACCORD HYBRID 2018 finger (#27462) * Add China HONDA ACCORD HYBRID 2018 finger Add finger to support China HONDA ACCORD HYBRID 2018,use ACCORDH model. * remove FW for logging --------- Co-authored-by: Shane Smiskol --- selfdrive/car/honda/values.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/selfdrive/car/honda/values.py b/selfdrive/car/honda/values.py index c085c3fe80..0737bea147 100644 --- a/selfdrive/car/honda/values.py +++ b/selfdrive/car/honda/values.py @@ -368,10 +368,12 @@ FW_VERSIONS = { b'57114-TWA-A050\x00\x00', b'57114-TWA-A530\x00\x00', b'57114-TWA-B520\x00\x00', + b'57114-TWB-H030\x00\x00', ], (Ecu.srs, 0x18da53f1, None): [ b'77959-TWA-A440\x00\x00', b'77959-TWA-L420\x00\x00', + b'77959-TWB-H220\x00\x00', ], (Ecu.combinationMeter, 0x18da60f1, None): [ b'78109-TWA-A010\x00\x00', @@ -385,6 +387,7 @@ FW_VERSIONS = { b'78109-TWA-A230\x00\x00', b'78109-TWA-L010\x00\x00', b'78109-TWA-L210\x00\x00', + b'78109-TWA-H210\x00\x00', ], (Ecu.shiftByWire, 0x18da0bf1, None): [ b'54008-TWA-A910\x00\x00', @@ -396,16 +399,19 @@ FW_VERSIONS = { (Ecu.fwdCamera, 0x18dab5f1, None): [ b'36161-TWA-A070\x00\x00', b'36161-TWA-A330\x00\x00', + b'36161-TWB-H040\x00\x00', ], (Ecu.fwdRadar, 0x18dab0f1, None): [ b'36802-TWA-A070\x00\x00', b'36802-TWA-A080\x00\x00', b'36802-TWA-A330\x00\x00', + b'36802-TWB-H060\x00\x00', ], (Ecu.eps, 0x18da30f1, None): [ b'39990-TVA-A160\x00\x00', b'39990-TVA-A150\x00\x00', b'39990-TVA-A340\x00\x00', + b'39990-TWB-H120\x00\x00', ], }, CAR.CIVIC: { From e6240d6ba20c187183ac5a26e3135cb5cedaa4c3 Mon Sep 17 00:00:00 2001 From: Andrei Radulescu Date: Thu, 2 Mar 2023 02:01:39 +0200 Subject: [PATCH 058/102] =?UTF-8?q?VW=20MQB:=20Add=20FW=20for=202018=20?= =?UTF-8?q?=C5=A0koda=20Kodiaq=20(#27460)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Shane Smiskol --- selfdrive/car/volkswagen/values.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py index 158a178b03..b23742b50d 100755 --- a/selfdrive/car/volkswagen/values.py +++ b/selfdrive/car/volkswagen/values.py @@ -1049,6 +1049,7 @@ FW_VERSIONS = { (Ecu.engine, 0x7e0, None): [ b'\xf1\x8704E906027DD\xf1\x893123', b'\xf1\x8704L906026DE\xf1\x895418', + b'\xf1\x8704L906026HT\xf1\x893617', b'\xf1\x875NA907115E \xf1\x890003', b'\xf1\x875NA907115E \xf1\x890005', ], @@ -1060,17 +1061,20 @@ FW_VERSIONS = { ], (Ecu.srs, 0x715, None): [ b'\xf1\x873Q0959655BJ\xf1\x890703\xf1\x82\x0e1213001211001205212111052100', + b'\xf1\x873Q0959655BK\xf1\x890703\xf1\x82\x0e1213001211001244212111442100', b'\xf1\x873Q0959655CN\xf1\x890720\xf1\x82\x0e1213001211001205212112052100', b'\xf1\x873Q0959655CQ\xf1\x890720\xf1\x82\x0e1213111211001205212112052111', ], (Ecu.eps, 0x712, None): [ b'\xf1\x875Q0909143P \xf1\x892051\xf1\x820527T6050405', b'\xf1\x875Q0909143P \xf1\x892051\xf1\x820527T6060405', + b'\xf1\x875Q0909143P \xf1\x892051\xf1\x820527T6070405', b'\xf1\x875Q0910143C \xf1\x892211\xf1\x82\x0567T600G600', ], (Ecu.fwdRadar, 0x757, None): [ b'\xf1\x872Q0907572Q \xf1\x890342', b'\xf1\x872Q0907572R \xf1\x890372', + b'\xf1\x872Q0907572AA\xf1\x890396', ], }, CAR.SKODA_OCTAVIA_MK3: { From 3fbdddb2fb7c79f0c03e5e76edb11f778608e7a5 Mon Sep 17 00:00:00 2001 From: humza2000 <111622889+humza2000@users.noreply.github.com> Date: Wed, 1 Mar 2023 16:10:00 -0800 Subject: [PATCH 059/102] Added new transmission firmware for Hyundai Sonata 2022 (#27456) * Added new transmission firmware for Hyundai Sonata 2020-2023 b'\xf1\x00T02601BL T02900A1 VDN8T25XXX900NSCF\xe4!Y', b'\xf1\x87954A02N060\x00\x00\x00\x00\x00\xf1\x81T02900A1 \xf1\x00T02601BL T02900A1 VDN8T25XXX900NSCF\xe4!Y', Dongle ID: ba75a2db7d699895 Route: ba75a2db7d699895|2023-02-27--18-07-15 * Update selfdrive/car/hyundai/values.py * we can clean these up --------- Co-authored-by: Shane Smiskol --- selfdrive/car/hyundai/values.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index d81c98fbcd..cf0143543a 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -512,7 +512,6 @@ FW_VERSIONS = { b'\xf1\x00DN8_ SCC FHCUP 1.00 1.01 99110-L1000 ', b'\xf1\x00DN89110-L0000 \xaa\xaa\xaa\xaa\xaa\xaa\xaa ', b'\xf1\x8799110L0000\xf1\x00DN8_ SCC F-CUP 1.00 1.00 99110-L0000 ', - b'\xf1\x8799110L0000\xf1\x00DN8_ SCC FHCUP 1.00 1.00 99110-L0000 ', ], (Ecu.abs, 0x7d1, None): [ b'\xf1\x00DN ESC \x07 106 \x07\x01 58910-L0100', @@ -525,7 +524,6 @@ FW_VERSIONS = { b'\xf1\x8758910-L0100\xf1\x00DN ESC \x06 104\x19\x08\x01 58910-L0100', b'\xf1\x8758910-L0100\xf1\x00DN ESC \x06 106 \x07\x01 58910-L0100', b'\xf1\x8758910-L0100\xf1\x00DN ESC \x07 104\x19\x08\x01 58910-L0100', - b'\xf1\x8758910-L0300\xf1\x00DN ESC \x03 100 \x08\x01 58910-L0300', b'\xf1\x00DN ESC \x06 106 \x07\x01 58910-L0100', ], (Ecu.engine, 0x7e0, None): [ @@ -587,6 +585,7 @@ FW_VERSIONS = { b'\xf1\x00HT6WA280BLHT6WAD10A1SDN8G25NB4\x00\x00\x00\x00\x00\x00g!l[', b'\xf1\x00T02601BL T02730A1 VDN8T25XXX730NS5\xf7_\x92\xf5', b'\xf1\x00T02601BL T02832A1 VDN8T25XXX832NS8G\x0e\xfeE', + b'\xf1\x00T02601BL T02900A1 VDN8T25XXX900NSCF\xe4!Y', b'\xf1\x87954A02N060\x00\x00\x00\x00\x00\xf1\x81T02730A1 \xf1\x00T02601BL T02730A1 VDN8T25XXX730NS5\xf7_\x92\xf5', b'\xf1\x87SAKFBA2926554GJ2VefVww\x87xwwwww\x88\x87xww\x87wTo\xfb\xffvUo\xff\x8d\x16\xf1\x81U903\x00\x00\x00\x00\x00\x00\xf1\x00bcsh8p54 U903\x00\x00\x00\x00\x00\x00SDN8T16NB0z{\xd4v', b'\xf1\x87SAKFBA3030524GJ2UVugww\x97yx\x88\x87\x88vw\x87gww\x87wto\xf9\xfffUo\xff\xa2\x0c\xf1\x81U903\x00\x00\x00\x00\x00\x00\xf1\x00bcsh8p54 U903\x00\x00\x00\x00\x00\x00SDN8T16NB0z{\xd4v', From 1483fc32dcb0e44d07909562a3d1c10a37b648b8 Mon Sep 17 00:00:00 2001 From: Jason Young <46612682+jyoung8607@users.noreply.github.com> Date: Wed, 1 Mar 2023 19:49:11 -0500 Subject: [PATCH 060/102] VW MQB: Add FW for 2023 Volkswagen Tiguan (#27475) --- selfdrive/car/volkswagen/values.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py index b23742b50d..b53820a32e 100755 --- a/selfdrive/car/volkswagen/values.py +++ b/selfdrive/car/volkswagen/values.py @@ -739,12 +739,14 @@ FW_VERSIONS = { b'\xf1\x8783A907115B \xf1\x890005', b'\xf1\x8783A907115F \xf1\x890002', b'\xf1\x8783A907115G \xf1\x890001', + b'\xf1\x8783A907115K \xf1\x890001', ], (Ecu.transmission, 0x7e1, None): [ b'\xf1\x8709G927158DT\xf1\x893698', b'\xf1\x8709G927158FM\xf1\x893757', b'\xf1\x8709G927158GC\xf1\x893821', b'\xf1\x8709G927158GD\xf1\x893820', + b'\xf1\x8709G927158GM\xf1\x893936', b'\xf1\x870D9300043 \xf1\x895202', b'\xf1\x870DL300011N \xf1\x892001', b'\xf1\x870DL300011N \xf1\x892012', @@ -775,6 +777,7 @@ FW_VERSIONS = { b'\xf1\x875QM909144B \xf1\x891081\xf1\x82\x0521A60604A1', b'\xf1\x875QM909144C \xf1\x891082\xf1\x82\x0521A60604A1', b'\xf1\x875QM909144C \xf1\x891082\xf1\x82\00521A60804A1', + b'\xf1\x875QM907144D \xf1\x891063\xf1\x82\x002SA6092SOM', ], (Ecu.fwdRadar, 0x757, None): [ b'\xf1\x872Q0907572AA\xf1\x890396', From 437ca99fcd5bddfd2f73701d48919ef4afea3ca3 Mon Sep 17 00:00:00 2001 From: Miniz199922 <124948595+Miniz199922@users.noreply.github.com> Date: Wed, 1 Mar 2023 19:56:01 -0500 Subject: [PATCH 061/102] Chrysler: Add missing FP for 2020 Jeep Grand Cherokee (#27464) Need to add fingerprint 1538: 8 for my 2020 jeep grand cherokee. Tested and working --- selfdrive/car/chrysler/values.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/car/chrysler/values.py b/selfdrive/car/chrysler/values.py index 2a5daf440c..2af5246b88 100644 --- a/selfdrive/car/chrysler/values.py +++ b/selfdrive/car/chrysler/values.py @@ -135,7 +135,7 @@ FINGERPRINTS = { }], CAR.JEEP_CHEROKEE_2019: [{ # Jeep Grand Cherokee 2019, including most 2020 models - 55: 8, 168: 8, 179: 8, 181: 8, 256: 4, 257: 5, 258: 8, 264: 8, 268: 8, 272: 6, 273: 6, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 292: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 341: 8, 344: 8, 352: 8, 362: 8, 368: 8, 376: 3, 384: 8, 388: 4, 416: 7, 448: 6, 456: 4, 464: 8, 500: 8, 501: 8, 512: 8, 514: 8, 520: 8, 530: 8, 532: 8, 544: 8, 557: 8, 559: 8, 560: 8, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 618: 8, 624: 8, 625: 8, 632: 8, 639: 8, 640: 1, 656: 4, 658: 6, 660: 8, 671: 8, 672: 8, 676: 8, 678: 8, 680: 8, 683: 8, 684: 8, 703: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 729: 5, 736: 8, 737: 8, 738: 8, 746: 5, 752: 2, 754: 8, 760: 8, 761: 8, 764: 8, 766: 8, 773: 8, 776: 8, 779: 8, 782: 8, 783: 8, 784: 8, 785: 8, 792: 8, 799: 8, 800: 8, 804: 8, 806: 2, 808: 8, 810: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 831: 6, 832: 8, 838: 2, 840: 8, 844: 5, 847: 1, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 874: 2, 882: 8, 897: 8, 906: 8, 924: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 960: 4, 968: 8, 969: 4, 970: 8, 973: 8, 974: 5, 976: 8, 977: 4, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1062: 8, 1098: 8, 1100: 8, 1216: 8, 1218: 8, 1220: 8, 1223: 8, 1225: 8, 1227: 8, 1235: 8, 1242: 8, 1250: 8, 1251: 8, 1252: 8, 1254: 8, 1264: 8, 1284: 8, 1536: 8, 1537: 8, 1543: 8, 1545: 8, 1562: 8, 1568: 8, 1570: 8, 1572: 8, 1593: 8, 1856: 8, 1858: 8, 1860: 8, 1863: 8, 1865: 8, 1867: 8, 1875: 8, 1882: 8, 1890: 8, 1891: 8, 1892: 8, 1894: 8, 1896: 8, 1904: 8, 2015: 8, 2016: 8, 2017: 8, 2024: 8, 2025: 8 + 55: 8, 168: 8, 179: 8, 181: 8, 256: 4, 257: 5, 258: 8, 264: 8, 268: 8, 272: 6, 273: 6, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 292: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 341: 8, 344: 8, 352: 8, 362: 8, 368: 8, 376: 3, 384: 8, 388: 4, 416: 7, 448: 6, 456: 4, 464: 8, 500: 8, 501: 8, 512: 8, 514: 8, 520: 8, 530: 8, 532: 8, 544: 8, 557: 8, 559: 8, 560: 8, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 618: 8, 624: 8, 625: 8, 632: 8, 639: 8, 640: 1, 656: 4, 658: 6, 660: 8, 671: 8, 672: 8, 676: 8, 678: 8, 680: 8, 683: 8, 684: 8, 703: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 729: 5, 736: 8, 737: 8, 738: 8, 746: 5, 752: 2, 754: 8, 760: 8, 761: 8, 764: 8, 766: 8, 773: 8, 776: 8, 779: 8, 782: 8, 783: 8, 784: 8, 785: 8, 792: 8, 799: 8, 800: 8, 804: 8, 806: 2, 808: 8, 810: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 831: 6, 832: 8, 838: 2, 840: 8, 844: 5, 847: 1, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 874: 2, 882: 8, 897: 8, 906: 8, 924: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 960: 4, 968: 8, 969: 4, 970: 8, 973: 8, 974: 5, 976: 8, 977: 4, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1062: 8, 1098: 8, 1100: 8, 1216: 8, 1218: 8, 1220: 8, 1223: 8, 1225: 8, 1227: 8, 1235: 8, 1242: 8, 1250: 8, 1251: 8, 1252: 8, 1254: 8, 1264: 8, 1284: 8, 1536: 8, 1537: 8, 1538: 8, 1543: 8, 1545: 8, 1562: 8, 1568: 8, 1570: 8, 1572: 8, 1593: 8, 1856: 8, 1858: 8, 1860: 8, 1863: 8, 1865: 8, 1867: 8, 1875: 8, 1882: 8, 1890: 8, 1891: 8, 1892: 8, 1894: 8, 1896: 8, 1904: 8, 2015: 8, 2016: 8, 2017: 8, 2024: 8, 2025: 8 }], } From cb2a53ae80ab3917986266290f37ef0228a6ca21 Mon Sep 17 00:00:00 2001 From: Kurt Nistelberger Date: Wed, 1 Mar 2023 19:01:08 -0800 Subject: [PATCH 062/102] laikad: fix qcom without internet (#27468) move week Co-authored-by: Kurt Nistelberger --- selfdrive/locationd/laikad.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/locationd/laikad.py b/selfdrive/locationd/laikad.py index 10c5e1b7e5..2b18dcf152 100755 --- a/selfdrive/locationd/laikad.py +++ b/selfdrive/locationd/laikad.py @@ -193,10 +193,10 @@ class Laikad: elif self.is_good_report(gnss_msg): week, tow, new_meas = self.read_report(gnss_msg) + self.gps_week = week if len(new_meas) == 0: return None - self.gps_week = week t = gnss_mono_time * 1e-9 if week > 0: self.got_first_gnss_msg = True From afc24f08d66c34ccebf3143e5062390e8529f26f Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Thu, 2 Mar 2023 13:54:07 +0800 Subject: [PATCH 063/102] cabana: fix wrong tooltip (#27480) --- tools/cabana/chartswidget.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/cabana/chartswidget.cc b/tools/cabana/chartswidget.cc index 2c27fbd8b9..bd4bf4aba9 100644 --- a/tools/cabana/chartswidget.cc +++ b/tools/cabana/chartswidget.cc @@ -708,14 +708,16 @@ void ChartView::mouseMoveEvent(QMouseEvent *ev) { 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") .arg(s.series->color().name(), s.sig->name, - s.track_pt.isNull() ? "--" : QString::number(s.track_pt.y()))); + s.track_pt.isNull() ? "--" : QString::number(value))); } if (x < 0) { x = ev->pos().x(); @@ -779,7 +781,7 @@ void ChartView::drawForeground(QPainter *painter, const QRectF &rect) { painter->setPen(Qt::NoPen); qreal track_line_x = -1; for (auto &s : sigs) { - if (!s.track_pt.isNull() && s.series->isVisible()) { + if (!s.track_pt.isNull() && s.series->isVisible()) { painter->setBrush(s.series->color().darker(125)); painter->drawEllipse(s.track_pt, 5.5, 5.5); track_line_x = std::max(track_line_x, s.track_pt.x()); From 9245335e8c0cf4c5371a1afa5a9ff5d4469f8d30 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Thu, 2 Mar 2023 16:44:58 -0800 Subject: [PATCH 064/102] Car docs: add Toyota Camry 2023 (#27483) * We support 2023 Camry * update docs --- docs/CARS.md | 2 +- selfdrive/car/toyota/values.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/CARS.md b/docs/CARS.md index 3bc918f784..20155f306b 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -181,7 +181,7 @@ A supported vehicle is one that just works when you install a comma three. All s |Toyota|C-HR Hybrid 2017-20|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|| |Toyota|C-HR Hybrid 2021-22|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|| |Toyota|Camry 2018-20|All|Stock|0 mph[6](#footnotes)|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|| -|Toyota|Camry 2021-22|All|openpilot|0 mph[6](#footnotes)|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|| +|Toyota|Camry 2021-23|All|openpilot|0 mph[6](#footnotes)|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|| |Toyota|Camry Hybrid 2018-20|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|| |Toyota|Camry Hybrid 2021-23|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|| |Toyota|Corolla 2017-19|All|openpilot available[2](#footnotes)|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|| diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py index 0639d46ec0..35e2db8b1e 100644 --- a/selfdrive/car/toyota/values.py +++ b/selfdrive/car/toyota/values.py @@ -115,7 +115,7 @@ CAR_INFO: Dict[str, Union[ToyotaCarInfo, List[ToyotaCarInfo]]] = { CAR.AVALONH_TSS2: ToyotaCarInfo("Toyota Avalon Hybrid 2022"), CAR.CAMRY: ToyotaCarInfo("Toyota Camry 2018-20", video_link="https://www.youtube.com/watch?v=fkcjviZY9CM", footnotes=[Footnote.CAMRY]), CAR.CAMRYH: ToyotaCarInfo("Toyota Camry Hybrid 2018-20", video_link="https://www.youtube.com/watch?v=Q2DYY0AWKgk"), - CAR.CAMRY_TSS2: ToyotaCarInfo("Toyota Camry 2021-22", footnotes=[Footnote.CAMRY]), + CAR.CAMRY_TSS2: ToyotaCarInfo("Toyota Camry 2021-23", footnotes=[Footnote.CAMRY]), CAR.CAMRYH_TSS2: ToyotaCarInfo("Toyota Camry Hybrid 2021-23"), CAR.CHR: ToyotaCarInfo("Toyota C-HR 2017-20"), CAR.CHR_TSS2: ToyotaCarInfo("Toyota C-HR 2021"), From 3ab8645d3af948a35ac410ad7f841ab670091e32 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Thu, 2 Mar 2023 20:11:24 -0800 Subject: [PATCH 065/102] uiPlan: add planned acceleration field (#27484) * add accel * bump cereal * Update ref_commit --------- Co-authored-by: Bruce Wayne --- cereal | 2 +- selfdrive/controls/lib/longitudinal_planner.py | 3 ++- selfdrive/controls/plannerd.py | 1 + selfdrive/test/process_replay/ref_commit | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/cereal b/cereal index b88523f05a..42f84fd85d 160000 --- a/cereal +++ b/cereal @@ -1 +1 @@ -Subproject commit b88523f05ac958f87a8f6d57c3f4bb20da55f216 +Subproject commit 42f84fd85d06c0fc85371daa2b4820fca49d763e diff --git a/selfdrive/controls/lib/longitudinal_planner.py b/selfdrive/controls/lib/longitudinal_planner.py index 2ef9051122..e959b14ee3 100755 --- a/selfdrive/controls/lib/longitudinal_planner.py +++ b/selfdrive/controls/lib/longitudinal_planner.py @@ -122,8 +122,9 @@ class LongitudinalPlanner: self.mpc.update(sm['radarState'], v_cruise, x, v, a, j) self.v_desired_trajectory_full = np.interp(T_IDXS, T_IDXS_MPC, self.mpc.v_solution) + self.a_desired_trajectory_full = np.interp(T_IDXS, T_IDXS_MPC, self.mpc.a_solution) self.v_desired_trajectory = self.v_desired_trajectory_full[:CONTROL_N] - self.a_desired_trajectory = np.interp(T_IDXS[:CONTROL_N], T_IDXS_MPC, self.mpc.a_solution) + self.a_desired_trajectory = self.a_desired_trajectory_full[:CONTROL_N] self.j_desired_trajectory = np.interp(T_IDXS[:CONTROL_N], T_IDXS_MPC[:-1], self.mpc.j_solution) # TODO counter is only needed because radar is glitchy, remove once radar is gone diff --git a/selfdrive/controls/plannerd.py b/selfdrive/controls/plannerd.py index 543274d841..d8cf9386d1 100755 --- a/selfdrive/controls/plannerd.py +++ b/selfdrive/controls/plannerd.py @@ -22,6 +22,7 @@ def publish_ui_plan(sm, pm, lateral_planner, longitudinal_planner): uiPlan.position.x = np.interp(plan_odo, model_odo, lateral_planner.lat_mpc.x_sol[:,0]).tolist() uiPlan.position.y = np.interp(plan_odo, model_odo, lateral_planner.lat_mpc.x_sol[:,1]).tolist() uiPlan.position.z = np.interp(plan_odo, model_odo, lateral_planner.path_xyz[:,2]).tolist() + uiPlan.accel = longitudinal_planner.a_desired_trajectory_full.tolist() pm.send('uiPlan', ui_send) def plannerd_thread(sm=None, pm=None): diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index b44c9c2f46..79769e14b6 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -dfa8e947c4ef76a9d89974a434e94a078e1ccc6a \ No newline at end of file +f9c7e05b836c4bff364978752e82d64b90f9d6e6 From 6c4320559a05d6af1ee7b0f4bbebda171b94e20a Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Fri, 3 Mar 2023 14:30:12 +0800 Subject: [PATCH 066/102] replay: fixed the status is always "loading" if there is no carState in events (#27481) --- tools/replay/consoleui.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/replay/consoleui.cc b/tools/replay/consoleui.cc index 5ad702590c..077861ff96 100644 --- a/tools/replay/consoleui.cc +++ b/tools/replay/consoleui.cc @@ -165,7 +165,10 @@ void ConsoleUI::updateStatus() { sm.update(0); if (status != Status::Paused) { - status = (sm.updated("carState") || sm.updated("liveParameters")) ? Status::Playing : Status::Waiting; + auto events = replay->events(); + uint64_t current_mono_time = replay->routeStartTime() + replay->currentSeconds() * 1e9; + bool playing = !events->empty() && events->back()->mono_time > current_mono_time; + status = playing ? Status::Playing : Status::Waiting; } auto [status_str, status_color] = status_text[status]; write_item(0, 0, "STATUS: ", status_str, " ", false, status_color); From a7d9085bca46e83c6b2ea6a64c4bc9d214a0e733 Mon Sep 17 00:00:00 2001 From: Saber422 <81108166+Saber422@users.noreply.github.com> Date: Sat, 4 Mar 2023 08:19:36 +0800 Subject: [PATCH 067/102] VW MQB: Add FW for 2019 Skoda Superb (#27490) * VW MQB: Add FW for 2019 Skoda Superb 'carVin': 'TMBJD9NP0K7067520', * sort alphabetically --------- Co-authored-by: Cameron Clough --- selfdrive/car/volkswagen/values.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py index b53820a32e..4eef1307be 100755 --- a/selfdrive/car/volkswagen/values.py +++ b/selfdrive/car/volkswagen/values.py @@ -1147,6 +1147,7 @@ FW_VERSIONS = { b'\xf1\x8704L906026FP\xf1\x891196', b'\xf1\x8704L906026KB\xf1\x894071', b'\xf1\x8704L906026KD\xf1\x894798', + b'\xf1\x873G0906259 \xf1\x890004', b'\xf1\x873G0906259B \xf1\x890002', b'\xf1\x873G0906264A \xf1\x890002', ], @@ -1156,12 +1157,14 @@ FW_VERSIONS = { b'\xf1\x870D9300012 \xf1\x894940', b'\xf1\x870D9300041H \xf1\x894905', b'\xf1\x870GC300043 \xf1\x892301', + b'\xf1\x870D9300043F \xf1\x895202', ], (Ecu.srs, 0x715, None): [ b'\xf1\x875Q0959655AE\xf1\x890130\xf1\x82\x12111200111121001121110012211292221111', b'\xf1\x875Q0959655AE\xf1\x890130\xf1\x82\022111200111121001121118112231292221111', b'\xf1\x875Q0959655AK\xf1\x890130\xf1\x82\022111200111121001121110012211292221111', b'\xf1\x875Q0959655BH\xf1\x890336\xf1\x82\02331310031313100313131013141319331413100', + b'\xf1\x875Q0959655CA\xf1\x890403\xf1\x82\x1331310031313100313151013141319331423100', ], (Ecu.eps, 0x712, None): [ b'\xf1\x875Q0909143K \xf1\x892033\xf1\x820514UZ070203', From f17ac166a325ae1f73778ac45af57fc1b23a1298 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harald=20Sch=C3=A4fer?= Date: Fri, 3 Mar 2023 17:48:51 -0800 Subject: [PATCH 068/102] Enable dmoji crosshairs in gray when not enabled (#27491) * try * add fade back --------- Co-authored-by: ZwX1616 --- selfdrive/ui/qt/onroad.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/selfdrive/ui/qt/onroad.cc b/selfdrive/ui/qt/onroad.cc index 98c636b0a4..dc2f1368ac 100644 --- a/selfdrive/ui/qt/onroad.cc +++ b/selfdrive/ui/qt/onroad.cc @@ -573,7 +573,10 @@ void AnnotatedCameraWidget::drawDriverState(QPainter &painter, const UIState *s) const int arc_l = 133; const float arc_t_default = 6.7; const float arc_t_extend = 12.0; - QColor arc_color = QColor::fromRgbF(0.09, 0.945, 0.26, 0.4*(1.0-dm_fade_state)*(s->engaged())); + QColor arc_color = QColor::fromRgbF(0.545 - 0.445 * s->engaged(), + 0.545 + 0.4 * s->engaged(), + 0.545 - 0.285 * s->engaged(), + 0.4 * (1.0 - dm_fade_state)); float delta_x = -scene.driver_pose_sins[1] * arc_l / 2; float delta_y = -scene.driver_pose_sins[0] * arc_l / 2; painter.setPen(QPen(arc_color, arc_t_default+arc_t_extend*fmin(1.0, scene.driver_pose_diff[1] * 5.0), Qt::SolidLine, Qt::RoundCap)); From 703f5e34ba783dba5369bf44caa95ed66a07855a Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Sat, 4 Mar 2023 02:18:03 -0800 Subject: [PATCH 069/102] bump panda (#27497) --- panda | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda b/panda index 1923b14189..e0e754de2c 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 1923b1418933e464ff7460a3e0a05d63aad0d53b +Subproject commit e0e754de2c7fdbf943dd02db203b7bb40bf3e9b5 From 2de085d39d0b9f149526828cd02cc4ccb9122d05 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Mon, 6 Mar 2023 07:55:22 +0800 Subject: [PATCH 070/102] cabana: faster copy events (#27499) --- tools/cabana/streams/livestream.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/cabana/streams/livestream.cc b/tools/cabana/streams/livestream.cc index b2fc7ea4a6..8f63d3baec 100644 --- a/tools/cabana/streams/livestream.cc +++ b/tools/cabana/streams/livestream.cc @@ -89,10 +89,11 @@ void LiveStream::removeExpiredEvents() { } const std::vector *LiveStream::events() const { - events_vector.clear(); std::lock_guard lk(lock); - events_vector.reserve(can_events.size()); - std::copy(can_events.begin(), can_events.end(), std::back_inserter(events_vector)); + if (events_vector.capacity() <= can_events.size()) { + events_vector.reserve(can_events.size() * 2); + } + events_vector.assign(can_events.begin(), can_events.end()); return &events_vector; } From c2018d6bf291e68102859eb31bb1dd68790172b1 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Mon, 6 Mar 2023 08:03:44 +0800 Subject: [PATCH 071/102] cabana: use a segment tree to solve range queries in O(log n) time complexity (#27498) --- tools/cabana/chartswidget.cc | 17 +++++++++++++---- tools/cabana/chartswidget.h | 1 + tools/cabana/util.cc | 34 ++++++++++++++++++++++++++++++++++ tools/cabana/util.h | 13 +++++++++++++ 4 files changed, 61 insertions(+), 4 deletions(-) diff --git a/tools/cabana/chartswidget.cc b/tools/cabana/chartswidget.cc index bd4bf4aba9..54966be578 100644 --- a/tools/cabana/chartswidget.cc +++ b/tools/cabana/chartswidget.cc @@ -562,6 +562,9 @@ void ChartView::updateSeries(const Signal *sig, const std::vector *even if (events->size()) { s.last_value_mono_time = events->back()->mono_time; } + if (!can->liveStreaming()) { + s.segment_tree.build(s.vals); + } s.series->replace(series_type == SeriesType::StepLine ? s.step_vals : s.vals); } } @@ -586,9 +589,15 @@ void ChartView::updateAxisY() { auto first = std::lower_bound(s.vals.begin(), s.vals.end(), axis_x->min(), [](auto &p, double x) { return p.x() < x; }); auto last = std::lower_bound(first, s.vals.end(), axis_x->max(), [](auto &p, double x) { return p.x() < x; }); - for (auto it = first; it != last; ++it) { - if (it->y() < min) min = it->y(); - if (it->y() > max) max = it->y(); + if (can->liveStreaming()) { + for (auto it = first; it != last; ++it) { + if (it->y() < min) min = it->y(); + if (it->y() > max) 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); } } if (min == std::numeric_limits::max()) min = 0; @@ -781,7 +790,7 @@ void ChartView::drawForeground(QPainter *painter, const QRectF &rect) { painter->setPen(Qt::NoPen); qreal track_line_x = -1; for (auto &s : sigs) { - if (!s.track_pt.isNull() && s.series->isVisible()) { + if (!s.track_pt.isNull() && s.series->isVisible()) { painter->setBrush(s.series->color().darker(125)); painter->drawEllipse(s.track_pt, 5.5, 5.5); track_line_x = std::max(track_line_x, s.track_pt.x()); diff --git a/tools/cabana/chartswidget.h b/tools/cabana/chartswidget.h index 76943c1fe9..c86c19a04e 100644 --- a/tools/cabana/chartswidget.h +++ b/tools/cabana/chartswidget.h @@ -46,6 +46,7 @@ public: QVector step_vals; uint64_t last_value_mono_time = 0; QPointF track_pt{}; + SegmentTree segment_tree; }; signals: diff --git a/tools/cabana/util.cc b/tools/cabana/util.cc index 5e4f505d29..1a0b9d93ef 100644 --- a/tools/cabana/util.cc +++ b/tools/cabana/util.cc @@ -67,6 +67,40 @@ void ChangeTracker::clear() { colors.clear(); } + +// SegmentTree + +void SegmentTree::build(const QVector &arr) { + size = arr.size(); + tree.resize(4 * size); // size of the tree is 4 times the size of the array + if (size > 0) { + build_tree(arr, 1, 0, size - 1); + } +} + +void SegmentTree::build_tree(const QVector &arr, int n, int left, int right) { + if (left == right) { + const double y = arr[left].y(); + tree[n] = {y, y}; + } else { + const int mid = (left + right) >> 1; + build_tree(arr, 2 * n, left, mid); + build_tree(arr, 2 * n + 1, mid + 1, right); + tree[n] = {std::min(tree[2 * n].first, tree[2 * n + 1].first), std::max(tree[2 * n].second, tree[2 * n + 1].second)}; + } +} + +std::pair SegmentTree::get_minmax(int n, int left, int right, int range_left, int range_right) const { + if (range_left > right || range_right < left) + return {std::numeric_limits::max(), std::numeric_limits::lowest()}; + if (range_left <= left && range_right >= right) + return tree[n]; + int mid = (left + right) >> 1; + auto l = get_minmax(2 * n, left, mid, range_left, range_right); + auto r = get_minmax(2 * n + 1, mid + 1, right, range_left, range_right); + return {std::min(l.first, r.first), std::max(l.second, r.second)}; +} + // MessageBytesDelegate MessageBytesDelegate::MessageBytesDelegate(QObject *parent) : QStyledItemDelegate(parent) { diff --git a/tools/cabana/util.h b/tools/cabana/util.h index 5eb5c3c5aa..cf1b5d4b20 100644 --- a/tools/cabana/util.h +++ b/tools/cabana/util.h @@ -35,6 +35,19 @@ enum { BytesRole = Qt::UserRole + 2 }; +class SegmentTree { +public: + SegmentTree() = default; + void build(const QVector &arr); + inline std::pair minmax(int left, int right) const { return get_minmax(1, 0, size - 1, left, right); } + +private: + std::pair get_minmax(int n, int left, int right, int range_left, int range_right) const; + void build_tree(const QVector &arr, int n, int left, int right); + std::vector> tree; + int size = 0; +}; + class MessageBytesDelegate : public QStyledItemDelegate { Q_OBJECT public: From fd2e03decf0a89e1c04e0a8d6aee0bf033d2ec0b Mon Sep 17 00:00:00 2001 From: Cameron Clough Date: Mon, 6 Mar 2023 02:44:56 +0000 Subject: [PATCH 072/102] Ford: add missing Explorer FW (#27502) `1493c38de09a381a|2023-03-05--21-10-07--0` VIN: `1FMSK8FH6LGB17698` --- selfdrive/car/ford/values.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/selfdrive/car/ford/values.py b/selfdrive/car/ford/values.py index 3bc56eb9dd..50c7d93987 100644 --- a/selfdrive/car/ford/values.py +++ b/selfdrive/car/ford/values.py @@ -165,6 +165,7 @@ FW_VERSIONS = { b'M1MC-14D003-AB\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], (Ecu.abs, 0x760, None): [ + b'L1MC-2D053-BA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'L1MC-2D053-BB\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'L1MC-2D053-BF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'L1MC-2D053-KB\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', @@ -178,6 +179,7 @@ FW_VERSIONS = { b'LC5T-14F397-AH\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], (Ecu.engine, 0x7E0, None): [ + b'LB5A-14C204-BUJ\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'LB5A-14C204-EAC\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'MB5A-14C204-MD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'MB5A-14C204-RC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', From e729f5b763a98f4156c1761f1511135cc32121d3 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Mon, 6 Mar 2023 15:36:39 -0800 Subject: [PATCH 073/102] Remove dashcam override param (#27509) * remove dashcam override * sort * remove ford from segments --- common/params.cc | 1 - selfdrive/controls/controlsd.py | 3 --- selfdrive/test/process_replay/process_replay.py | 3 --- selfdrive/test/process_replay/test_processes.py | 3 +-- 4 files changed, 1 insertion(+), 9 deletions(-) diff --git a/common/params.cc b/common/params.cc index 2ba4f7e8ab..e74c63bf6a 100644 --- a/common/params.cc +++ b/common/params.cc @@ -99,7 +99,6 @@ std::unordered_map keys = { {"CompletedTrainingVersion", PERSISTENT}, {"ControlsReady", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON}, {"CurrentRoute", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON}, - {"DashcamOverride", PERSISTENT}, {"DisableLogging", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON}, {"DisablePowerDown", PERSISTENT}, {"ExperimentalMode", PERSISTENT}, diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index f49b58212a..1391d6570c 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -112,9 +112,6 @@ class Controls: if not self.disengage_on_accelerator: self.CP.alternativeExperience |= ALTERNATIVE_EXPERIENCE.DISABLE_DISENGAGE_ON_GAS - if self.CP.dashcamOnly and self.params.get_bool("DashcamOverride"): - self.CP.dashcamOnly = False - # read params self.is_metric = self.params.get_bool("IsMetric") self.is_ldw_enabled = self.params.get_bool("IsLdwEnabled") diff --git a/selfdrive/test/process_replay/process_replay.py b/selfdrive/test/process_replay/process_replay.py index 7dc0b139a3..971ddb3fe2 100755 --- a/selfdrive/test/process_replay/process_replay.py +++ b/selfdrive/test/process_replay/process_replay.py @@ -449,9 +449,6 @@ def setup_env(simulation=False, CP=None, cfg=None, controlsState=None): if CP.openpilotLongitudinalControl: params.put_bool("ExperimentalLongitudinalEnabled", True) - # controlsd process configuration assume all routes are out of dashcam - params.put_bool("DashcamOverride", True) - def python_replay_process(cfg, lr, fingerprint=None): sub_sockets = [s for _, sub in cfg.pub_sub.items() for s in sub] diff --git a/selfdrive/test/process_replay/test_processes.py b/selfdrive/test/process_replay/test_processes.py index 569090f606..07117c2e7f 100755 --- a/selfdrive/test/process_replay/test_processes.py +++ b/selfdrive/test/process_replay/test_processes.py @@ -29,12 +29,12 @@ source_segments = [ ("SUBARU", "341dccd5359e3c97|2022-09-12--10-35-33--3"), # SUBARU.OUTBACK ("GM", "0c58b6a25109da2b|2021-02-23--16-35-50--11"), # GM.VOLT ("GM2", "376bf99325883932|2022-10-27--13-41-22--1"), # GM.BOLT_EUV - ("FORD", "54827bf84c38b14f|2023-01-26--21-59-07--4"), # FORD.BRONCO_SPORT_MK1 ("NISSAN", "35336926920f3571|2021-02-12--18-38-48--46"), # NISSAN.XTRAIL ("VOLKSWAGEN", "de9592456ad7d144|2021-06-29--11-00-15--6"), # VOLKSWAGEN.GOLF ("MAZDA", "bd6a637565e91581|2021-10-30--15-14-53--4"), # MAZDA.CX9_2021 # Enable when port is tested and dashcamOnly is no longer set + #("FORD", "54827bf84c38b14f|2023-01-26--21-59-07--4"), # FORD.BRONCO_SPORT_MK1 #("TESLA", "bb50caf5f0945ab1|2021-06-19--17-20-18--3"), # TESLA.AP2_MODELS #("VOLKSWAGEN2", "3cfdec54aa035f3f|2022-07-19--23-45-10--2"), # VOLKSWAGEN.PASSAT_NMS ] @@ -53,7 +53,6 @@ segments = [ ("SUBARU", "regen1E72BBDCED5|2022-09-27--15-55-31--0"), ("GM", "regen45B05A80EF6|2022-09-27--15-57-22--0"), ("GM2", "376bf99325883932|2022-10-27--13-41-22--1"), - ("FORD", "54827bf84c38b14f|2023-01-26--21-59-07--4"), ("NISSAN", "regenC19D899B46D|2022-09-27--15-59-13--0"), ("VOLKSWAGEN", "regenD8F7AC4BD0D|2022-09-27--16-41-45--0"), ("MAZDA", "regenFC3F9ECBB64|2022-09-27--16-03-09--0"), From 3892c6098085ad05878f78aef0afefac55e38306 Mon Sep 17 00:00:00 2001 From: George Hotz <72895+geohot@users.noreply.github.com> Date: Mon, 6 Mar 2023 15:50:28 -0800 Subject: [PATCH 074/102] tinygrad: bump to 0.5 (#27505) * bump tinygrad to 0.5 * update release files * ref commit + bump tinygrad * save 220 mW --------- Co-authored-by: Comma Device --- release/files_common | 9 +++++---- selfdrive/modeld/SConscript | 2 +- selfdrive/test/process_replay/model_replay_ref_commit | 2 +- system/hardware/tici/test_power_draw.py | 2 +- tinygrad_repo | 2 +- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/release/files_common b/release/files_common index 5b310d5c80..e0f989e9be 100644 --- a/release/files_common +++ b/release/files_common @@ -577,13 +577,14 @@ opendbc/tesla_can.dbc opendbc/tesla_radar.dbc opendbc/tesla_powertrain.dbc -tinygrad_repo/accel/opencl/* -tinygrad_repo/tinygrad/llops/ops_opencl.py tinygrad_repo/openpilot/compile.py tinygrad_repo/extra/onnx.py +tinygrad_repo/extra/onnx_ops.py tinygrad_repo/extra/thneed.py tinygrad_repo/extra/utils.py -tinygrad_repo/tinygrad/llops/ops_gpu.py -tinygrad_repo/tinygrad/shape/* +tinygrad_repo/tinygrad/codegen/ast.py +tinygrad_repo/tinygrad/codegen/gpu.py tinygrad_repo/tinygrad/nn/* +tinygrad_repo/tinygrad/runtime/ops_gpu.py +tinygrad_repo/tinygrad/shape/* tinygrad_repo/tinygrad/*.py diff --git a/selfdrive/modeld/SConscript b/selfdrive/modeld/SConscript index 7bbc1b3477..c7e0dc5d86 100644 --- a/selfdrive/modeld/SConscript +++ b/selfdrive/modeld/SConscript @@ -70,7 +70,7 @@ lenv.Program('_dmonitoringmodeld', [ if use_thneed and arch == "larch64" or GetOption('pc_thneed'): fn = File("models/supercombo").abspath - tinygrad_opts = ["NATIVE_EXPLOG=1", "VALIDHACKS=1", "OPTWG=1", "IMAGE=2", "GPU=1", "CLCACHE=0"] + tinygrad_opts = ["NATIVE_EXPLOG=1", "VALIDHACKS=1", "OPTLOCAL=1", "IMAGE=2", "GPU=1", "ENABLE_METHOD_CACHE=1"] if not GetOption('pc_thneed'): # use FLOAT16 on device for speed + don't cache the CL kernels for space tinygrad_opts += ["FLOAT16=1", "PYOPENCL_NO_CACHE=1"] diff --git a/selfdrive/test/process_replay/model_replay_ref_commit b/selfdrive/test/process_replay/model_replay_ref_commit index c64f522352..ad09668a46 100644 --- a/selfdrive/test/process_replay/model_replay_ref_commit +++ b/selfdrive/test/process_replay/model_replay_ref_commit @@ -1 +1 @@ -ba947edbb131a2a36ced7c490dfcf3280ad5b167 +ab64afd1abd1059c14f50c67b51e5ef89029f216 diff --git a/system/hardware/tici/test_power_draw.py b/system/hardware/tici/test_power_draw.py index 2460152998..6c3f5747e3 100755 --- a/system/hardware/tici/test_power_draw.py +++ b/system/hardware/tici/test_power_draw.py @@ -20,7 +20,7 @@ class Proc: PROCS = [ Proc('camerad', 2.15), - Proc('modeld', 1.15, atol=0.2), + Proc('modeld', 0.93, atol=0.2), Proc('dmonitoringmodeld', 0.4), Proc('encoderd', 0.23), ] diff --git a/tinygrad_repo b/tinygrad_repo index 2e1d47b166..d8dda2af3a 160000 --- a/tinygrad_repo +++ b/tinygrad_repo @@ -1 +1 @@ -Subproject commit 2e1d47b16625ff343516287cdd9e4bcb26f5c4ef +Subproject commit d8dda2af3afcef0bb772fff580cfa8b3eabf7f69 From ebd25b8a7de29542be7c6a213c578bc363999857 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Mon, 6 Mar 2023 16:13:29 -0800 Subject: [PATCH 075/102] test_power_draw: add header to output table (#27511) * test_power_draw: add header to output table * units --- poetry.lock | 30 +++++++++++-------------- pyproject.toml | 1 + system/hardware/tici/test_power_draw.py | 10 +++++---- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/poetry.lock b/poetry.lock index 91e1b5c826..ec4022c81f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -4355,6 +4355,14 @@ python-versions = "*" [package.dependencies] types-urllib3 = "<1.27" +[[package]] +name = "types-tabulate" +version = "0.9.0.1" +description = "Typing stubs for tabulate" +category = "main" +optional = false +python-versions = "*" + [[package]] name = "types-urllib3" version = "1.26.25.1" @@ -4567,7 +4575,7 @@ testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] [metadata] lock-version = "1.1" python-versions = "~3.8" -content-hash = "9e9495c896e6fd0855803aeaf46513c6c22424b86be820759a8baf27d44e73ee" +content-hash = "669485055bf8d77336509cb7a3878e06aa32431c520825948914d76b57347fde" [metadata.files] adal = [ @@ -6616,7 +6624,6 @@ onnx = [ ] onnx2torch = [ {file = "onnx2torch-1.5.4-py3-none-any.whl", hash = "sha256:fd1a0fe05072bfb9f3d86d9330299b130b41f11bd4ae634db17078974e711725"}, - {file = "onnx2torch-1.5.4.tar.gz", hash = "sha256:df837b557a63540223d85fde4a1d679fde0ca8d8bb89d5379c030b01eddc9c24"}, ] onnxoptimizer = [ {file = "onnxoptimizer-0.3.1-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:e73a5e2e3ca4db9bff54f7131768749c861677b97ee811a136fcf1a52783cf6e"}, @@ -7002,7 +7009,6 @@ pycryptodome = [ {file = "pycryptodome-3.15.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:7c9ed8aa31c146bef65d89a1b655f5f4eab5e1120f55fc297713c89c9e56ff0b"}, {file = "pycryptodome-3.15.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:5099c9ca345b2f252f0c28e96904643153bae9258647585e5e6f649bb7a1844a"}, {file = "pycryptodome-3.15.0-cp27-cp27m-manylinux2014_aarch64.whl", hash = "sha256:2ec709b0a58b539a4f9d33fb8508264c3678d7edb33a68b8906ba914f71e8c13"}, - {file = "pycryptodome-3.15.0-cp27-cp27m-musllinux_1_1_aarch64.whl", hash = "sha256:2ae53125de5b0d2c95194d957db9bb2681da8c24d0fb0fe3b056de2bcaf5d837"}, {file = "pycryptodome-3.15.0-cp27-cp27m-win32.whl", hash = "sha256:fd2184aae6ee2a944aaa49113e6f5787cdc5e4db1eb8edb1aea914bd75f33a0c"}, {file = "pycryptodome-3.15.0-cp27-cp27m-win_amd64.whl", hash = "sha256:7e3a8f6ee405b3bd1c4da371b93c31f7027944b2bcce0697022801db93120d83"}, {file = "pycryptodome-3.15.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:b9c5b1a1977491533dfd31e01550ee36ae0249d78aae7f632590db833a5012b8"}, @@ -7010,14 +7016,12 @@ pycryptodome = [ {file = "pycryptodome-3.15.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:2aa55aae81f935a08d5a3c2042eb81741a43e044bd8a81ea7239448ad751f763"}, {file = "pycryptodome-3.15.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:c3640deff4197fa064295aaac10ab49a0d55ef3d6a54ae1499c40d646655c89f"}, {file = "pycryptodome-3.15.0-cp27-cp27mu-manylinux2014_aarch64.whl", hash = "sha256:045d75527241d17e6ef13636d845a12e54660aa82e823b3b3341bcf5af03fa79"}, - {file = "pycryptodome-3.15.0-cp27-cp27mu-musllinux_1_1_aarch64.whl", hash = "sha256:eb6fce570869e70cc8ebe68eaa1c26bed56d40ad0f93431ee61d400525433c54"}, {file = "pycryptodome-3.15.0-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9ee40e2168f1348ae476676a2e938ca80a2f57b14a249d8fe0d3cdf803e5a676"}, {file = "pycryptodome-3.15.0-cp35-abi3-manylinux1_i686.whl", hash = "sha256:4c3ccad74eeb7b001f3538643c4225eac398c77d617ebb3e57571a897943c667"}, {file = "pycryptodome-3.15.0-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:1b22bcd9ec55e9c74927f6b1f69843cb256fb5a465088ce62837f793d9ffea88"}, {file = "pycryptodome-3.15.0-cp35-abi3-manylinux2010_i686.whl", hash = "sha256:57f565acd2f0cf6fb3e1ba553d0cb1f33405ec1f9c5ded9b9a0a5320f2c0bd3d"}, {file = "pycryptodome-3.15.0-cp35-abi3-manylinux2010_x86_64.whl", hash = "sha256:4b52cb18b0ad46087caeb37a15e08040f3b4c2d444d58371b6f5d786d95534c2"}, {file = "pycryptodome-3.15.0-cp35-abi3-manylinux2014_aarch64.whl", hash = "sha256:092a26e78b73f2530b8bd6b3898e7453ab2f36e42fd85097d705d6aba2ec3e5e"}, - {file = "pycryptodome-3.15.0-cp35-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:50ca7e587b8e541eb6c192acf92449d95377d1f88908c0a32ac5ac2703ebe28b"}, {file = "pycryptodome-3.15.0-cp35-abi3-win32.whl", hash = "sha256:e244ab85c422260de91cda6379e8e986405b4f13dc97d2876497178707f87fc1"}, {file = "pycryptodome-3.15.0-cp35-abi3-win_amd64.whl", hash = "sha256:c77126899c4b9c9827ddf50565e93955cb3996813c18900c16b2ea0474e130e9"}, {file = "pycryptodome-3.15.0-pp27-pypy_73-macosx_10_9_x86_64.whl", hash = "sha256:9eaadc058106344a566dc51d3d3a758ab07f8edde013712bc8d22032a86b264f"}, @@ -7659,18 +7663,6 @@ setproctitle = [ {file = "setproctitle-1.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7f2719a398e1a2c01c2a63bf30377a34d0b6ef61946ab9cf4d550733af8f1ef1"}, {file = "setproctitle-1.3.2-cp310-cp310-win32.whl", hash = "sha256:e425be62524dc0c593985da794ee73eb8a17abb10fe692ee43bb39e201d7a099"}, {file = "setproctitle-1.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:e85e50b9c67854f89635a86247412f3ad66b132a4d8534ac017547197c88f27d"}, - {file = "setproctitle-1.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2a97d51c17d438cf5be284775a322d57b7ca9505bb7e118c28b1824ecaf8aeaa"}, - {file = "setproctitle-1.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:587c7d6780109fbd8a627758063d08ab0421377c0853780e5c356873cdf0f077"}, - {file = "setproctitle-1.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7d17c8bd073cbf8d141993db45145a70b307385b69171d6b54bcf23e5d644de"}, - {file = "setproctitle-1.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e932089c35a396dc31a5a1fc49889dd559548d14cb2237adae260382a090382e"}, - {file = "setproctitle-1.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e4f8f12258a8739c565292a551c3db62cca4ed4f6b6126664e2381acb4931bf"}, - {file = "setproctitle-1.3.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:570d255fd99c7f14d8f91363c3ea96bd54f8742275796bca67e1414aeca7d8c3"}, - {file = "setproctitle-1.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a8e0881568c5e6beff91ef73c0ec8ac2a9d3ecc9edd6bd83c31ca34f770910c4"}, - {file = "setproctitle-1.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4bba3be4c1fabf170595b71f3af46c6d482fbe7d9e0563999b49999a31876f77"}, - {file = "setproctitle-1.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:37ece938110cab2bb3957e3910af8152ca15f2b6efdf4f2612e3f6b7e5459b80"}, - {file = "setproctitle-1.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db684d6bbb735a80bcbc3737856385b55d53f8a44ce9b46e9a5682c5133a9bf7"}, - {file = "setproctitle-1.3.2-cp311-cp311-win32.whl", hash = "sha256:ca58cd260ea02759238d994cfae844fc8b1e206c684beb8f38877dcab8451dfc"}, - {file = "setproctitle-1.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:88486e6cce2a18a033013d17b30a594f1c5cb42520c49c19e6ade40b864bb7ff"}, {file = "setproctitle-1.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:92c626edc66169a1b09e9541b9c0c9f10488447d8a2b1d87c8f0672e771bc927"}, {file = "setproctitle-1.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:710e16fa3bade3b026907e4a5e841124983620046166f355bbb84be364bf2a02"}, {file = "setproctitle-1.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1f29b75e86260b0ab59adb12661ef9f113d2f93a59951373eb6d68a852b13e83"}, @@ -8066,6 +8058,10 @@ types-requests = [ {file = "types-requests-2.28.11.2.tar.gz", hash = "sha256:fdcd7bd148139fb8eef72cf4a41ac7273872cad9e6ada14b11ff5dfdeee60ed3"}, {file = "types_requests-2.28.11.2-py3-none-any.whl", hash = "sha256:14941f8023a80b16441b3b46caffcbfce5265fd14555844d6029697824b5a2ef"}, ] +types-tabulate = [ + {file = "types-tabulate-0.9.0.1.tar.gz", hash = "sha256:e486292c279f19247865bdabe802419740a0e74b53444e7f7a8009e08129da5d"}, + {file = "types_tabulate-0.9.0.1-py3-none-any.whl", hash = "sha256:be2ea0de05f615ccfcbadf6206aa720e265955eb1de23e343aec9d8bf3fa9aaa"}, +] types-urllib3 = [ {file = "types-urllib3-1.26.25.1.tar.gz", hash = "sha256:a948584944b2412c9a74b9cf64f6c48caf8652cb88b38361316f6d15d8a184cd"}, {file = "types_urllib3-1.26.25.1-py3-none-any.whl", hash = "sha256:f6422596cc9ee5fdf68f9d547f541096a20c2dcfd587e37c804c9ea720bf5cb2"}, diff --git a/pyproject.toml b/pyproject.toml index 6b4b0bb5fa..b1ad273cd7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,6 +59,7 @@ urllib3 = "^1.26.10" utm = "^0.7.0" websocket_client = "^1.3.3" polyline = "^1.4.0" +types-tabulate = "^0.9.0.1" [tool.poetry.group.dev.dependencies] diff --git a/system/hardware/tici/test_power_draw.py b/system/hardware/tici/test_power_draw.py index 6c3f5747e3..f563933285 100755 --- a/system/hardware/tici/test_power_draw.py +++ b/system/hardware/tici/test_power_draw.py @@ -3,6 +3,7 @@ import unittest import time import math from dataclasses import dataclass +from tabulate import tabulate from system.hardware import HARDWARE, TICI from system.hardware.tici.power_monitor import get_power @@ -58,15 +59,16 @@ class TestPowerDraw(unittest.TestCase): manager_cleanup() - print("-"*35) - print(f"Baseline {baseline:.2f}W\n") + tab = [] + tab.append(['process', 'expected (W)', 'current (W)']) for proc in PROCS: cur = used[proc.name] expected = proc.power - print(f"{proc.name.ljust(20)} {expected:.2f}W {cur:.2f}W") + tab.append([proc.name, round(expected, 2), round(cur, 2)]) with self.subTest(proc=proc.name): self.assertTrue(math.isclose(cur, expected, rel_tol=proc.rtol, abs_tol=proc.atol)) - print("-"*35) + print(tabulate(tab)) + print(f"Baseline {baseline:.2f}W\n") if __name__ == "__main__": From ddcafeb7dcac709dbd517e619fe3807cfc898198 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Wed, 8 Mar 2023 02:08:33 +0800 Subject: [PATCH 076/102] cabana: improve the performance of updating TreeView in real-time. (#27517) --- tools/cabana/signaledit.cc | 18 ++++++++++++------ tools/cabana/signaledit.h | 1 + 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/tools/cabana/signaledit.cc b/tools/cabana/signaledit.cc index e425a13f82..5684edf95a 100644 --- a/tools/cabana/signaledit.cc +++ b/tools/cabana/signaledit.cc @@ -1,7 +1,7 @@ #include "tools/cabana/signaledit.h" +#include #include -#include #include #include #include @@ -304,11 +304,17 @@ SignalItemDelegate::SignalItemDelegate(QObject *parent) : QStyledItemDelegate(pa } QSize SignalItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { - QSize size = QStyledItemDelegate::sizeHint(option, index); - if (index.column() == 0 && !index.parent().isValid()) { - size.rwidth() = std::min(option.widget->size().width() / 2, size.width() + color_label_width + 8); + int width = option.widget->size().width() / 2; + if (index.column() == 0) { + auto text = index.data(Qt::DisplayRole).toString(); + auto it = width_cache.find(text); + if (it == width_cache.end()) { + 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()); } - return size; + return {width, QApplication::fontMetrics().height()}; } void SignalItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { @@ -508,7 +514,7 @@ void SignalView::signalHovered(const Signal *sig) { for (int i = 0; i < children.size(); ++i) { 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)); + emit model->dataChanged(model->index(i, 0), model->index(i, 0), {Qt::DecorationRole}); } } } diff --git a/tools/cabana/signaledit.h b/tools/cabana/signaledit.h index 73a107f5c9..da3bc36c62 100644 --- a/tools/cabana/signaledit.h +++ b/tools/cabana/signaledit.h @@ -85,6 +85,7 @@ public: QValidator *name_validator, *double_validator; QFont small_font; const int color_label_width = 18; + mutable QHash width_cache; }; class SignalView : public QFrame { From 186c48137a8cf94ec28136ca9a6f50d8512c3987 Mon Sep 17 00:00:00 2001 From: Jason Young <46612682+jyoung8607@users.noreply.github.com> Date: Tue, 7 Mar 2023 13:39:36 -0500 Subject: [PATCH 077/102] =?UTF-8?q?VW=20MQB:=20=C5=A0koda=20Fabia=20Mk4=20?= =?UTF-8?q?(#27520)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * VW MQB: Škoda Fabia Mk4 * typo --- RELEASES.md | 1 + docs/CARS.md | 3 ++- selfdrive/car/tests/routes.py | 1 + selfdrive/car/torque_data/substitute.yaml | 1 + selfdrive/car/volkswagen/interface.py | 4 ++++ selfdrive/car/volkswagen/values.py | 19 +++++++++++++++++++ 6 files changed, 28 insertions(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index f71810784a..9cfcbafea1 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,6 +1,7 @@ Version 0.9.2 (2023-03-XX) ======================== * Draw MPC path instead of model predicted path, this is a more accurate representation of what the car will do. +* Škoda Fabia 2022-23 support thanks to jyoung8607! Version 0.9.1 (2023-02-28) ======================== diff --git a/docs/CARS.md b/docs/CARS.md index 20155f306b..426db94f89 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -4,7 +4,7 @@ A supported vehicle is one that just works when you install a comma three. All supported cars provide a better experience than any stock system. -# 237 Supported Cars +# 238 Supported Cars |Make|Model|Supported Package|ACC|No ACC accel below|No ALC below|Steering Torque|Resume from stop|Harness|Video| |---|---|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:| @@ -161,6 +161,7 @@ A supported vehicle is one that just works when you install a comma three. All s |Subaru|Outback 2020-22|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru B|| |Subaru|XV 2018-19|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|| |Subaru|XV 2020-21|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A|| +|Škoda|Fabia 2022-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,9](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533[10](#footnotes)|| |Škoda|Kamiq 2021[7](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,9](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533[10](#footnotes)|| |Škoda|Karoq 2019-21|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,9](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|| |Škoda|Kodiaq 2018-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,9](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|| diff --git a/selfdrive/car/tests/routes.py b/selfdrive/car/tests/routes.py index 02e37492d3..4ca7c0a16c 100644 --- a/selfdrive/car/tests/routes.py +++ b/selfdrive/car/tests/routes.py @@ -206,6 +206,7 @@ routes = [ CarTestRoute("0cd0b7f7e31a3853|2021-12-03--03-12-05", VOLKSWAGEN.AUDI_Q3_MK2), CarTestRoute("8f205bdd11bcbb65|2021-03-26--01-00-17", VOLKSWAGEN.SEAT_ATECA_MK1), CarTestRoute("fc6b6c9a3471c846|2021-05-27--13-39-56", VOLKSWAGEN.SEAT_LEON_MK3), + CarTestRoute("0bbe367c98fa1538|2023-03-04--17-46-11", VOLKSWAGEN.SKODA_FABIA_MK4), CarTestRoute("12d6ae3057c04b0d|2021-09-15--00-04-07", VOLKSWAGEN.SKODA_KAMIQ_MK1), CarTestRoute("12d6ae3057c04b0d|2021-09-04--21-21-21", VOLKSWAGEN.SKODA_KAROQ_MK1), CarTestRoute("90434ff5d7c8d603|2021-03-15--12-07-31", VOLKSWAGEN.SKODA_KODIAQ_MK1), diff --git a/selfdrive/car/torque_data/substitute.yaml b/selfdrive/car/torque_data/substitute.yaml index 61243424f0..696d9829d1 100644 --- a/selfdrive/car/torque_data/substitute.yaml +++ b/selfdrive/car/torque_data/substitute.yaml @@ -56,6 +56,7 @@ CADILLAC ATS Premium Performance 2018: CHEVROLET VOLT PREMIER 2017 CHEVROLET MALIBU PREMIER 2017: CHEVROLET VOLT PREMIER 2017 HOLDEN ASTRA RS-V BK 2017: CHEVROLET VOLT PREMIER 2017 +SKODA FABIA 4TH GEN: VOLKSWAGEN GOLF 7TH GEN SKODA OCTAVIA 3RD GEN: SKODA SUPERB 3RD GEN SKODA SCALA 1ST GEN: SKODA SUPERB 3RD GEN SKODA KODIAQ 1ST GEN: SKODA SUPERB 3RD GEN diff --git a/selfdrive/car/volkswagen/interface.py b/selfdrive/car/volkswagen/interface.py index 521c68184d..2f8bd8661b 100644 --- a/selfdrive/car/volkswagen/interface.py +++ b/selfdrive/car/volkswagen/interface.py @@ -187,6 +187,10 @@ class CarInterface(CarInterfaceBase): ret.mass = 1227 + STD_CARGO_KG ret.wheelbase = 2.64 + elif candidate == CAR.SKODA_FABIA_MK4: + ret.mass = 1266 + STD_CARGO_KG + ret.wheelbase = 2.56 + elif candidate == CAR.SKODA_KAMIQ_MK1: ret.mass = 1265 + STD_CARGO_KG ret.wheelbase = 2.66 diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py index 4eef1307be..c5868e16f3 100755 --- a/selfdrive/car/volkswagen/values.py +++ b/selfdrive/car/volkswagen/values.py @@ -129,6 +129,7 @@ class CAR: AUDI_Q3_MK2 = "AUDI Q3 2ND GEN" # Chassis 8U/F3/FS, Mk2 Audi Q3 and variants SEAT_ATECA_MK1 = "SEAT ATECA 1ST GEN" # Chassis 5F, Mk1 SEAT Ateca and CUPRA Ateca SEAT_LEON_MK3 = "SEAT LEON 3RD GEN" # Chassis 5F, Mk3 SEAT Leon and variants + SKODA_FABIA_MK4 = "SKODA FABIA 4TH GEN" # Chassis PJ, Mk4 Skoda Fabia SKODA_KAMIQ_MK1 = "SKODA KAMIQ 1ST GEN" # Chassis NW, Mk1 Skoda Kamiq SKODA_KAROQ_MK1 = "SKODA KAROQ 1ST GEN" # Chassis NU, Mk1 Skoda Karoq SKODA_KODIAQ_MK1 = "SKODA KODIAQ 1ST GEN" # Chassis NS, Mk1 Skoda Kodiaq @@ -239,6 +240,7 @@ CAR_INFO: Dict[str, Union[VWCarInfo, List[VWCarInfo]]] = { CAR.AUDI_Q3_MK2: VWCarInfo("Audi Q3 2019-23"), CAR.SEAT_ATECA_MK1: VWCarInfo("SEAT Ateca 2018"), CAR.SEAT_LEON_MK3: VWCarInfo("SEAT Leon 2014-20"), + CAR.SKODA_FABIA_MK4: VWCarInfo("Škoda Fabia 2022-23", footnotes=[Footnote.VW_MQB_A0]), CAR.SKODA_KAMIQ_MK1: VWCarInfo("Škoda Kamiq 2021", footnotes=[Footnote.VW_MQB_A0, Footnote.KAMIQ]), CAR.SKODA_KAROQ_MK1: VWCarInfo("Škoda Karoq 2019-21"), CAR.SKODA_KODIAQ_MK1: VWCarInfo("Škoda Kodiaq 2018-19"), @@ -1009,6 +1011,23 @@ FW_VERSIONS = { b'\xf1\x875Q0907572P \xf1\x890682', ], }, + CAR.SKODA_FABIA_MK4: { + (Ecu.engine, 0x7e0, None): [ + b'\xf1\x8705E906018CF\xf1\x891905', + ], + (Ecu.transmission, 0x7e1, None): [ + b'\xf1\x870CW300051M \xf1\x891936', + ], + (Ecu.srs, 0x715, None): [ + b'\xf1\x875QF959655AT\xf1\x890755\xf1\x82\x1311110011110011111100110200--1111120749', + ], + (Ecu.eps, 0x712, None): [ + b'\xf1\x872Q1909144S \xf1\x896042', + ], + (Ecu.fwdRadar, 0x757, None): [ + b'\xf1\x872Q0907572AA\xf1\x890396', + ], + }, CAR.SKODA_KAMIQ_MK1: { (Ecu.engine, 0x7e0, None): [ b'\xf1\x8705C906032M \xf1\x891333', From f7c15c1708ab0ab42f916162ea26ca52226ce81f Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 7 Mar 2023 11:05:20 -0800 Subject: [PATCH 078/102] pandad unit tests (#27516) * pandad unit tests * only one * in bootstub * run in jenkins * phone only --- Jenkinsfile | 1 + selfdrive/boardd/tests/test_pandad.py | 48 +++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100755 selfdrive/boardd/tests/test_pandad.py diff --git a/Jenkinsfile b/Jenkinsfile index 30c045e419..0450f33175 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -161,6 +161,7 @@ pipeline { ["test encoder", "LD_LIBRARY_PATH=/usr/local/lib python selfdrive/loggerd/tests/test_encoder.py"], ["test pigeond", "python selfdrive/sensord/tests/test_pigeond.py"], ["test manager", "python selfdrive/manager/test/test_manager.py"], + ["test pandad", "python selfdrive/boardd/tests/test_pandad.py"], ]) } } diff --git a/selfdrive/boardd/tests/test_pandad.py b/selfdrive/boardd/tests/test_pandad.py new file mode 100755 index 0000000000..3b2369b39b --- /dev/null +++ b/selfdrive/boardd/tests/test_pandad.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +import time +import unittest + +import cereal.messaging as messaging +from panda import Panda +from selfdrive.test.helpers import phone_only +from selfdrive.manager.process_config import managed_processes +from system.hardware import HARDWARE + + +class TestPandad(unittest.TestCase): + + def tearDown(self): + managed_processes['pandad'].stop() + + def _wait_for_boardd(self): + sm = messaging.SubMaster(['peripheralState']) + for _ in range(30): + sm.update(1000) + if sm.updated['peripheralState']: + break + + if not sm.updated['peripheralState']: + raise Exception("boardd failed to start") + + @phone_only + def test_in_dfu(self): + HARDWARE.recover_internal_panda() + time.sleep(1) + + managed_processes['pandad'].start() + self._wait_for_boardd() + + @phone_only + def test_in_bootstub(self): + with Panda() as p: + p.reset(enter_bootstub=True) + assert p.bootstub + managed_processes['pandad'].start() + self._wait_for_boardd() + + #def test_out_of_date_fw(self): + # pass + + +if __name__ == "__main__": + unittest.main() From 5326c14b433371861a0014675d833a4d3e6602bc Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 7 Mar 2023 16:17:23 -0800 Subject: [PATCH 079/102] bump panda (#27510) * bump panda * fix mypy * bump panda --- panda | 2 +- selfdrive/boardd/pandad.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/panda b/panda index e0e754de2c..79210e8c2b 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit e0e754de2c7fdbf943dd02db203b7bb40bf3e9b5 +Subproject commit 79210e8c2b8dbddda474cafd68d7ee0c8d0e4a40 diff --git a/selfdrive/boardd/pandad.py b/selfdrive/boardd/pandad.py index f61d9ee1a6..f292b921cf 100755 --- a/selfdrive/boardd/pandad.py +++ b/selfdrive/boardd/pandad.py @@ -84,9 +84,9 @@ def main() -> NoReturn: params.remove("PandaSignatures") # Flash all Pandas in DFU mode - for p in PandaDFU.list(): - cloudlog.info(f"Panda in DFU mode found, flashing recovery {p}") - PandaDFU(p).recover() + for serial in PandaDFU.list(): + cloudlog.info(f"Panda in DFU mode found, flashing recovery {serial}") + PandaDFU(serial).recover() time.sleep(1) panda_serials = Panda.list() From 38eea8948469bcfdb5ea376e6507bc8f0074313c Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 7 Mar 2023 20:37:40 -0800 Subject: [PATCH 080/102] bump panda --- panda | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda b/panda index 79210e8c2b..b231281c8b 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 79210e8c2b8dbddda474cafd68d7ee0c8d0e4a40 +Subproject commit b231281c8b2c79c46892576dee4c8a56d5e0b2d2 From ce900f34d08b423e9f3ebed0d028692bb9198dea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harald=20Sch=C3=A4fer?= Date: Tue, 7 Mar 2023 20:56:39 -0800 Subject: [PATCH 081/102] Ubloxd: subframe 0 is not valid (#27528) No 0 strings --- selfdrive/locationd/ublox_msg.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/selfdrive/locationd/ublox_msg.cc b/selfdrive/locationd/ublox_msg.cc index b746989466..77ca9099ed 100644 --- a/selfdrive/locationd/ublox_msg.cc +++ b/selfdrive/locationd/ublox_msg.cc @@ -183,7 +183,7 @@ kj::Array UbloxMsgParser::parse_gps_ephemeris(ubx_t::rxm_sfrbx_t *m gps_t subframe(&stream); int subframe_id = subframe.how()->subframe_id(); - if (subframe_id > 3) { + if (subframe_id > 3 || subframe_id < 1) { // dont parse almanac subframes return kj::Array(); } @@ -283,7 +283,7 @@ kj::Array UbloxMsgParser::parse_glonass_ephemeris(ubx_t::rxm_sfrbx_ glonass_t gl_string(&stream); int string_number = gl_string.string_number(); - if (string_number > 5 || gl_string.idle_chip()) { + if (string_number < 1 || string_number > 5 || gl_string.idle_chip()) { // dont parse non immediate data, idle_chip == 0 return kj::Array(); } From 6f40f0d4427f4238c3939a64d1d6baa7d77f1ecc Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 8 Mar 2023 10:56:54 -0800 Subject: [PATCH 082/102] sensord: move to system/ (#27531) * sensord: move to system/ * add gitignore to releaes files --- .gitignore | 3 --- Jenkinsfile | 6 ++--- SConstruct | 2 +- docs/c_docs.rst | 2 +- release/files_common | 13 ++++++----- release/files_tici | 2 +- selfdrive/locationd/locationd.h | 2 +- selfdrive/manager/process_config.py | 6 ++--- system/sensord/.gitignore | 1 + {selfdrive => system}/sensord/SConscript | 0 {selfdrive => system}/sensord/__init__.py | 0 {selfdrive => system}/sensord/pigeond.py | 0 .../sensord/rawgps/compare.py | 0 .../sensord/rawgps/modemdiag.py | 0 .../sensord/rawgps/rawgpsd.py | 4 ++-- .../sensord/rawgps/structs.py | 0 .../sensord/rawgps/test_rawgps.py | 0 {selfdrive => system}/sensord/sensord | 0 .../sensord/sensors/bmx055_accel.cc | 0 .../sensord/sensors/bmx055_accel.h | 2 +- .../sensord/sensors/bmx055_gyro.cc | 0 .../sensord/sensors/bmx055_gyro.h | 2 +- .../sensord/sensors/bmx055_magn.cc | 0 .../sensord/sensors/bmx055_magn.h | 2 +- .../sensord/sensors/bmx055_temp.cc | 2 +- .../sensord/sensors/bmx055_temp.h | 4 ++-- .../sensord/sensors/constants.h | 0 .../sensord/sensors/file_sensor.cc | 0 .../sensord/sensors/file_sensor.h | 2 +- .../sensord/sensors/i2c_sensor.cc | 0 .../sensord/sensors/i2c_sensor.h | 4 ++-- .../sensord/sensors/light_sensor.cc | 2 +- .../sensord/sensors/light_sensor.h | 0 .../sensord/sensors/lsm6ds3_accel.cc | 0 .../sensord/sensors/lsm6ds3_accel.h | 2 +- .../sensord/sensors/lsm6ds3_gyro.cc | 0 .../sensord/sensors/lsm6ds3_gyro.h | 2 +- .../sensord/sensors/lsm6ds3_temp.cc | 0 .../sensord/sensors/lsm6ds3_temp.h | 2 +- .../sensord/sensors/mmc5603nj_magn.cc | 0 .../sensord/sensors/mmc5603nj_magn.h | 2 +- .../sensord/sensors/sensor.h | 0 .../sensord/sensors_qcom2.cc | 22 +++++++++---------- .../sensord/tests/__init__.py | 0 .../sensord/tests/test_pigeond.py | 0 .../sensord/tests/test_sensord.py | 0 .../sensord/tests/ttff_test.py | 0 tools/gpstest/test_gps.py | 2 +- tools/gpstest/test_laikad.py | 2 +- 49 files changed, 47 insertions(+), 48 deletions(-) create mode 100644 system/sensord/.gitignore rename {selfdrive => system}/sensord/SConscript (100%) rename {selfdrive => system}/sensord/__init__.py (100%) rename {selfdrive => system}/sensord/pigeond.py (100%) rename {selfdrive => system}/sensord/rawgps/compare.py (100%) rename {selfdrive => system}/sensord/rawgps/modemdiag.py (100%) rename {selfdrive => system}/sensord/rawgps/rawgpsd.py (98%) rename {selfdrive => system}/sensord/rawgps/structs.py (100%) rename {selfdrive => system}/sensord/rawgps/test_rawgps.py (100%) rename {selfdrive => system}/sensord/sensord (100%) rename {selfdrive => system}/sensord/sensors/bmx055_accel.cc (100%) rename {selfdrive => system}/sensord/sensors/bmx055_accel.h (96%) rename {selfdrive => system}/sensord/sensors/bmx055_gyro.cc (100%) rename {selfdrive => system}/sensord/sensors/bmx055_gyro.h (95%) rename {selfdrive => system}/sensord/sensors/bmx055_magn.cc (100%) rename {selfdrive => system}/sensord/sensors/bmx055_magn.h (97%) rename {selfdrive => system}/sensord/sensors/bmx055_temp.cc (94%) rename {selfdrive => system}/sensord/sensors/bmx055_temp.h (71%) rename {selfdrive => system}/sensord/sensors/constants.h (100%) rename {selfdrive => system}/sensord/sensors/file_sensor.cc (100%) rename {selfdrive => system}/sensord/sensors/file_sensor.h (88%) rename {selfdrive => system}/sensord/sensors/i2c_sensor.cc (100%) rename {selfdrive => system}/sensord/sensors/i2c_sensor.h (93%) rename {selfdrive => system}/sensord/sensors/light_sensor.cc (92%) rename {selfdrive => system}/sensord/sensors/light_sensor.h (100%) rename {selfdrive => system}/sensord/sensors/lsm6ds3_accel.cc (100%) rename {selfdrive => system}/sensord/sensors/lsm6ds3_accel.h (97%) rename {selfdrive => system}/sensord/sensors/lsm6ds3_gyro.cc (100%) rename {selfdrive => system}/sensord/sensors/lsm6ds3_gyro.h (96%) rename {selfdrive => system}/sensord/sensors/lsm6ds3_temp.cc (100%) rename {selfdrive => system}/sensord/sensors/lsm6ds3_temp.h (92%) rename {selfdrive => system}/sensord/sensors/mmc5603nj_magn.cc (100%) rename {selfdrive => system}/sensord/sensors/mmc5603nj_magn.h (94%) rename {selfdrive => system}/sensord/sensors/sensor.h (100%) rename {selfdrive => system}/sensord/sensors_qcom2.cc (90%) rename {selfdrive => system}/sensord/tests/__init__.py (100%) rename {selfdrive => system}/sensord/tests/test_pigeond.py (100%) rename {selfdrive => system}/sensord/tests/test_sensord.py (100%) rename {selfdrive => system}/sensord/tests/ttff_test.py (100%) diff --git a/.gitignore b/.gitignore index 2b283d3b11..be6629f212 100644 --- a/.gitignore +++ b/.gitignore @@ -46,9 +46,6 @@ selfdrive/mapd/default_speeds_by_region.json system/proclogd/proclogd selfdrive/ui/_ui selfdrive/test/longitudinal_maneuvers/out -selfdrive/visiond/visiond -selfdrive/sensord/_gpsd -selfdrive/sensord/_sensord system/camerad/camerad system/camerad/test/ae_gray_test selfdrive/modeld/_modeld diff --git a/Jenkinsfile b/Jenkinsfile index 0450f33175..2067b9dac1 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -159,7 +159,7 @@ pipeline { ["test power draw", "python system/hardware/tici/test_power_draw.py"], ["test loggerd", "python selfdrive/loggerd/tests/test_loggerd.py"], ["test encoder", "LD_LIBRARY_PATH=/usr/local/lib python selfdrive/loggerd/tests/test_encoder.py"], - ["test pigeond", "python selfdrive/sensord/tests/test_pigeond.py"], + ["test pigeond", "python system/sensord/tests/test_pigeond.py"], ["test manager", "python selfdrive/manager/test/test_manager.py"], ["test pandad", "python selfdrive/boardd/tests/test_pandad.py"], ]) @@ -193,11 +193,11 @@ pipeline { steps { phone_steps("tici-lsmc", [ ["build", "cd selfdrive/manager && ./build.py"], - ["test sensord", "cd selfdrive/sensord/tests && python -m unittest test_sensord.py"], + ["test sensord", "cd system/sensord/tests && python -m unittest test_sensord.py"], ]) phone_steps("tici-bmx-lsm", [ ["build", "cd selfdrive/manager && ./build.py"], - ["test sensord", "cd selfdrive/sensord/tests && python -m unittest test_sensord.py"], + ["test sensord", "cd system/sensord/tests && python -m unittest test_sensord.py"], ]) } } diff --git a/SConstruct b/SConstruct index 007931b7f5..27c811686c 100644 --- a/SConstruct +++ b/SConstruct @@ -427,7 +427,7 @@ SConscript(['selfdrive/boardd/SConscript']) SConscript(['selfdrive/loggerd/SConscript']) SConscript(['selfdrive/locationd/SConscript']) -SConscript(['selfdrive/sensord/SConscript']) +SConscript(['system/sensord/SConscript']) SConscript(['selfdrive/ui/SConscript']) SConscript(['selfdrive/navd/SConscript']) diff --git a/docs/c_docs.rst b/docs/c_docs.rst index 77be7e51d8..5619cc8a51 100644 --- a/docs/c_docs.rst +++ b/docs/c_docs.rst @@ -83,7 +83,7 @@ common sensorsd ^^^^^^^^ .. autodoxygenindex:: - :project: selfdrive_sensord_sensors + :project: system_sensord_sensors boardd ^^^^^^ diff --git a/release/files_common b/release/files_common index e0f989e9be..334e08a322 100644 --- a/release/files_common +++ b/release/files_common @@ -276,12 +276,13 @@ selfdrive/loggerd/uploader.py selfdrive/loggerd/deleter.py selfdrive/loggerd/xattr_cache.py -selfdrive/sensord/SConscript -selfdrive/sensord/sensors_qcom2.cc -selfdrive/sensord/sensors/*.cc -selfdrive/sensord/sensors/*.h -selfdrive/sensord/sensord -selfdrive/sensord/pigeond.py +system/sensord/.gitignore +system/sensord/SConscript +system/sensord/sensors_qcom2.cc +system/sensord/sensors/*.cc +system/sensord/sensors/*.h +system/sensord/sensord +system/sensord/pigeond.py selfdrive/thermald/thermald.py selfdrive/thermald/power_monitoring.py diff --git a/release/files_tici b/release/files_tici index c8abd720d5..b4e0c50516 100644 --- a/release/files_tici +++ b/release/files_tici @@ -13,7 +13,7 @@ system/camerad/cameras/camera_util.cc system/camerad/cameras/camera_util.h system/camerad/cameras/real_debayer.cl -selfdrive/sensord/rawgps/* +system/sensord/rawgps/* selfdrive/ui/qt/spinner_larch64 selfdrive/ui/qt/text_larch64 diff --git a/selfdrive/locationd/locationd.h b/selfdrive/locationd/locationd.h index a292a3c936..b7e42a9df8 100755 --- a/selfdrive/locationd/locationd.h +++ b/selfdrive/locationd/locationd.h @@ -14,7 +14,7 @@ #include "common/timing.h" #include "common/util.h" -#include "selfdrive/sensord/sensors/constants.h" +#include "system/sensord/sensors/constants.h" #define VISION_DECIMATION 2 #define SENSOR_DECIMATION 10 #include "selfdrive/locationd/models/live_kf.h" diff --git a/selfdrive/manager/process_config.py b/selfdrive/manager/process_config.py index 8fc4d94e55..324063a68b 100644 --- a/selfdrive/manager/process_config.py +++ b/selfdrive/manager/process_config.py @@ -39,7 +39,7 @@ procs = [ NativeProcess("modeld", "selfdrive/modeld", ["./modeld"]), NativeProcess("mapsd", "selfdrive/navd", ["./map_renderer"], enabled=False), NativeProcess("navmodeld", "selfdrive/modeld", ["./navmodeld"], enabled=False), - NativeProcess("sensord", "selfdrive/sensord", ["./sensord"], enabled=not PC), + NativeProcess("sensord", "system/sensord", ["./sensord"], enabled=not PC), NativeProcess("ui", "selfdrive/ui", ["./ui"], offroad=True, watchdog_max_dt=(5 if not PC else None)), NativeProcess("soundd", "selfdrive/ui/soundd", ["./soundd"], offroad=True), NativeProcess("locationd", "selfdrive/locationd", ["./locationd"]), @@ -50,12 +50,12 @@ procs = [ PythonProcess("deleter", "selfdrive.loggerd.deleter", offroad=True), PythonProcess("dmonitoringd", "selfdrive.monitoring.dmonitoringd", enabled=(not PC or WEBCAM), callback=driverview), PythonProcess("laikad", "selfdrive.locationd.laikad"), - PythonProcess("rawgpsd", "selfdrive.sensord.rawgps.rawgpsd", enabled=TICI), + PythonProcess("rawgpsd", "system.sensord.rawgps.rawgpsd", enabled=TICI), PythonProcess("navd", "selfdrive.navd.navd"), PythonProcess("pandad", "selfdrive.boardd.pandad", offroad=True), PythonProcess("paramsd", "selfdrive.locationd.paramsd"), NativeProcess("ubloxd", "selfdrive/locationd", ["./ubloxd"], enabled=TICI, onroad=False, callback=ublox), - PythonProcess("pigeond", "selfdrive.sensord.pigeond", enabled=TICI, onroad=False, callback=ublox), + PythonProcess("pigeond", "system.sensord.pigeond", enabled=TICI, onroad=False, callback=ublox), PythonProcess("plannerd", "selfdrive.controls.plannerd"), PythonProcess("radard", "selfdrive.controls.radard"), PythonProcess("thermald", "selfdrive.thermald.thermald", offroad=True), diff --git a/system/sensord/.gitignore b/system/sensord/.gitignore new file mode 100644 index 0000000000..e9b8071b4b --- /dev/null +++ b/system/sensord/.gitignore @@ -0,0 +1 @@ +_sensord diff --git a/selfdrive/sensord/SConscript b/system/sensord/SConscript similarity index 100% rename from selfdrive/sensord/SConscript rename to system/sensord/SConscript diff --git a/selfdrive/sensord/__init__.py b/system/sensord/__init__.py similarity index 100% rename from selfdrive/sensord/__init__.py rename to system/sensord/__init__.py diff --git a/selfdrive/sensord/pigeond.py b/system/sensord/pigeond.py similarity index 100% rename from selfdrive/sensord/pigeond.py rename to system/sensord/pigeond.py diff --git a/selfdrive/sensord/rawgps/compare.py b/system/sensord/rawgps/compare.py similarity index 100% rename from selfdrive/sensord/rawgps/compare.py rename to system/sensord/rawgps/compare.py diff --git a/selfdrive/sensord/rawgps/modemdiag.py b/system/sensord/rawgps/modemdiag.py similarity index 100% rename from selfdrive/sensord/rawgps/modemdiag.py rename to system/sensord/rawgps/modemdiag.py diff --git a/selfdrive/sensord/rawgps/rawgpsd.py b/system/sensord/rawgps/rawgpsd.py similarity index 98% rename from selfdrive/sensord/rawgps/rawgpsd.py rename to system/sensord/rawgps/rawgpsd.py index 3fa5e927a2..f75ceee7ed 100755 --- a/selfdrive/sensord/rawgps/rawgpsd.py +++ b/system/sensord/rawgps/rawgpsd.py @@ -15,8 +15,8 @@ from common.gpio import gpio_init, gpio_set from laika.gps_time import GPSTime from system.hardware.tici.pins import GPIO from system.swaglog import cloudlog -from selfdrive.sensord.rawgps.modemdiag import ModemDiag, DIAG_LOG_F, setup_logs, send_recv -from selfdrive.sensord.rawgps.structs import (dict_unpacker, position_report, relist, +from system.sensord.rawgps.modemdiag import ModemDiag, DIAG_LOG_F, setup_logs, send_recv +from system.sensord.rawgps.structs import (dict_unpacker, position_report, relist, gps_measurement_report, gps_measurement_report_sv, glonass_measurement_report, glonass_measurement_report_sv, oemdre_measurement_report, oemdre_measurement_report_sv, oemdre_svpoly_report, diff --git a/selfdrive/sensord/rawgps/structs.py b/system/sensord/rawgps/structs.py similarity index 100% rename from selfdrive/sensord/rawgps/structs.py rename to system/sensord/rawgps/structs.py diff --git a/selfdrive/sensord/rawgps/test_rawgps.py b/system/sensord/rawgps/test_rawgps.py similarity index 100% rename from selfdrive/sensord/rawgps/test_rawgps.py rename to system/sensord/rawgps/test_rawgps.py diff --git a/selfdrive/sensord/sensord b/system/sensord/sensord similarity index 100% rename from selfdrive/sensord/sensord rename to system/sensord/sensord diff --git a/selfdrive/sensord/sensors/bmx055_accel.cc b/system/sensord/sensors/bmx055_accel.cc similarity index 100% rename from selfdrive/sensord/sensors/bmx055_accel.cc rename to system/sensord/sensors/bmx055_accel.cc diff --git a/selfdrive/sensord/sensors/bmx055_accel.h b/system/sensord/sensors/bmx055_accel.h similarity index 96% rename from selfdrive/sensord/sensors/bmx055_accel.h rename to system/sensord/sensors/bmx055_accel.h index 8ef660a99f..2cc316e992 100644 --- a/selfdrive/sensord/sensors/bmx055_accel.h +++ b/system/sensord/sensors/bmx055_accel.h @@ -1,6 +1,6 @@ #pragma once -#include "selfdrive/sensord/sensors/i2c_sensor.h" +#include "system/sensord/sensors/i2c_sensor.h" // Address of the chip on the bus #define BMX055_ACCEL_I2C_ADDR 0x18 diff --git a/selfdrive/sensord/sensors/bmx055_gyro.cc b/system/sensord/sensors/bmx055_gyro.cc similarity index 100% rename from selfdrive/sensord/sensors/bmx055_gyro.cc rename to system/sensord/sensors/bmx055_gyro.cc diff --git a/selfdrive/sensord/sensors/bmx055_gyro.h b/system/sensord/sensors/bmx055_gyro.h similarity index 95% rename from selfdrive/sensord/sensors/bmx055_gyro.h rename to system/sensord/sensors/bmx055_gyro.h index 80b93f128c..7be3e56563 100644 --- a/selfdrive/sensord/sensors/bmx055_gyro.h +++ b/system/sensord/sensors/bmx055_gyro.h @@ -1,6 +1,6 @@ #pragma once -#include "selfdrive/sensord/sensors/i2c_sensor.h" +#include "system/sensord/sensors/i2c_sensor.h" // Address of the chip on the bus #define BMX055_GYRO_I2C_ADDR 0x68 diff --git a/selfdrive/sensord/sensors/bmx055_magn.cc b/system/sensord/sensors/bmx055_magn.cc similarity index 100% rename from selfdrive/sensord/sensors/bmx055_magn.cc rename to system/sensord/sensors/bmx055_magn.cc diff --git a/selfdrive/sensord/sensors/bmx055_magn.h b/system/sensord/sensors/bmx055_magn.h similarity index 97% rename from selfdrive/sensord/sensors/bmx055_magn.h rename to system/sensord/sensors/bmx055_magn.h index e4a79bc7e0..15c4e734b9 100644 --- a/selfdrive/sensord/sensors/bmx055_magn.h +++ b/system/sensord/sensors/bmx055_magn.h @@ -1,7 +1,7 @@ #pragma once #include -#include "selfdrive/sensord/sensors/i2c_sensor.h" +#include "system/sensord/sensors/i2c_sensor.h" // Address of the chip on the bus #define BMX055_MAGN_I2C_ADDR 0x10 diff --git a/selfdrive/sensord/sensors/bmx055_temp.cc b/system/sensord/sensors/bmx055_temp.cc similarity index 94% rename from selfdrive/sensord/sensors/bmx055_temp.cc rename to system/sensord/sensors/bmx055_temp.cc index 95b8068ac1..68ee0da1d6 100644 --- a/selfdrive/sensord/sensors/bmx055_temp.cc +++ b/system/sensord/sensors/bmx055_temp.cc @@ -2,7 +2,7 @@ #include -#include "selfdrive/sensord/sensors/bmx055_accel.h" +#include "system/sensord/sensors/bmx055_accel.h" #include "common/swaglog.h" #include "common/timing.h" diff --git a/selfdrive/sensord/sensors/bmx055_temp.h b/system/sensord/sensors/bmx055_temp.h similarity index 71% rename from selfdrive/sensord/sensors/bmx055_temp.h rename to system/sensord/sensors/bmx055_temp.h index 0b6802deaa..a2eabae395 100644 --- a/selfdrive/sensord/sensors/bmx055_temp.h +++ b/system/sensord/sensors/bmx055_temp.h @@ -1,7 +1,7 @@ #pragma once -#include "selfdrive/sensord/sensors/bmx055_accel.h" -#include "selfdrive/sensord/sensors/i2c_sensor.h" +#include "system/sensord/sensors/bmx055_accel.h" +#include "system/sensord/sensors/i2c_sensor.h" class BMX055_Temp : public I2CSensor { uint8_t get_device_address() {return BMX055_ACCEL_I2C_ADDR;} diff --git a/selfdrive/sensord/sensors/constants.h b/system/sensord/sensors/constants.h similarity index 100% rename from selfdrive/sensord/sensors/constants.h rename to system/sensord/sensors/constants.h diff --git a/selfdrive/sensord/sensors/file_sensor.cc b/system/sensord/sensors/file_sensor.cc similarity index 100% rename from selfdrive/sensord/sensors/file_sensor.cc rename to system/sensord/sensors/file_sensor.cc diff --git a/selfdrive/sensord/sensors/file_sensor.h b/system/sensord/sensors/file_sensor.h similarity index 88% rename from selfdrive/sensord/sensors/file_sensor.h rename to system/sensord/sensors/file_sensor.h index 39d695167d..07d7e8f946 100644 --- a/selfdrive/sensord/sensors/file_sensor.h +++ b/system/sensord/sensors/file_sensor.h @@ -4,7 +4,7 @@ #include #include "cereal/gen/cpp/log.capnp.h" -#include "selfdrive/sensord/sensors/sensor.h" +#include "system/sensord/sensors/sensor.h" class FileSensor : public Sensor { protected: diff --git a/selfdrive/sensord/sensors/i2c_sensor.cc b/system/sensord/sensors/i2c_sensor.cc similarity index 100% rename from selfdrive/sensord/sensors/i2c_sensor.cc rename to system/sensord/sensors/i2c_sensor.cc diff --git a/selfdrive/sensord/sensors/i2c_sensor.h b/system/sensord/sensors/i2c_sensor.h similarity index 93% rename from selfdrive/sensord/sensors/i2c_sensor.h rename to system/sensord/sensors/i2c_sensor.h index 08ca6f09cd..ccac526c12 100644 --- a/selfdrive/sensord/sensors/i2c_sensor.h +++ b/system/sensord/sensors/i2c_sensor.h @@ -8,8 +8,8 @@ #include "common/gpio.h" #include "common/swaglog.h" -#include "selfdrive/sensord/sensors/constants.h" -#include "selfdrive/sensord/sensors/sensor.h" +#include "system/sensord/sensors/constants.h" +#include "system/sensord/sensors/sensor.h" int16_t read_12_bit(uint8_t lsb, uint8_t msb); int16_t read_16_bit(uint8_t lsb, uint8_t msb); diff --git a/selfdrive/sensord/sensors/light_sensor.cc b/system/sensord/sensors/light_sensor.cc similarity index 92% rename from selfdrive/sensord/sensors/light_sensor.cc rename to system/sensord/sensors/light_sensor.cc index 58c602ea39..99e321b47d 100644 --- a/selfdrive/sensord/sensors/light_sensor.cc +++ b/system/sensord/sensors/light_sensor.cc @@ -3,7 +3,7 @@ #include #include "common/timing.h" -#include "selfdrive/sensord/sensors/constants.h" +#include "system/sensord/sensors/constants.h" LightSensor::LightSensor(std::string filename) : FileSensor(filename) {} diff --git a/selfdrive/sensord/sensors/light_sensor.h b/system/sensord/sensors/light_sensor.h similarity index 100% rename from selfdrive/sensord/sensors/light_sensor.h rename to system/sensord/sensors/light_sensor.h diff --git a/selfdrive/sensord/sensors/lsm6ds3_accel.cc b/system/sensord/sensors/lsm6ds3_accel.cc similarity index 100% rename from selfdrive/sensord/sensors/lsm6ds3_accel.cc rename to system/sensord/sensors/lsm6ds3_accel.cc diff --git a/selfdrive/sensord/sensors/lsm6ds3_accel.h b/system/sensord/sensors/lsm6ds3_accel.h similarity index 97% rename from selfdrive/sensord/sensors/lsm6ds3_accel.h rename to system/sensord/sensors/lsm6ds3_accel.h index c3f66f5803..69667cb759 100644 --- a/selfdrive/sensord/sensors/lsm6ds3_accel.h +++ b/system/sensord/sensors/lsm6ds3_accel.h @@ -1,6 +1,6 @@ #pragma once -#include "selfdrive/sensord/sensors/i2c_sensor.h" +#include "system/sensord/sensors/i2c_sensor.h" // Address of the chip on the bus #define LSM6DS3_ACCEL_I2C_ADDR 0x6A diff --git a/selfdrive/sensord/sensors/lsm6ds3_gyro.cc b/system/sensord/sensors/lsm6ds3_gyro.cc similarity index 100% rename from selfdrive/sensord/sensors/lsm6ds3_gyro.cc rename to system/sensord/sensors/lsm6ds3_gyro.cc diff --git a/selfdrive/sensord/sensors/lsm6ds3_gyro.h b/system/sensord/sensors/lsm6ds3_gyro.h similarity index 96% rename from selfdrive/sensord/sensors/lsm6ds3_gyro.h rename to system/sensord/sensors/lsm6ds3_gyro.h index 220e6b0cec..adaae62dd2 100644 --- a/selfdrive/sensord/sensors/lsm6ds3_gyro.h +++ b/system/sensord/sensors/lsm6ds3_gyro.h @@ -1,6 +1,6 @@ #pragma once -#include "selfdrive/sensord/sensors/i2c_sensor.h" +#include "system/sensord/sensors/i2c_sensor.h" // Address of the chip on the bus #define LSM6DS3_GYRO_I2C_ADDR 0x6A diff --git a/selfdrive/sensord/sensors/lsm6ds3_temp.cc b/system/sensord/sensors/lsm6ds3_temp.cc similarity index 100% rename from selfdrive/sensord/sensors/lsm6ds3_temp.cc rename to system/sensord/sensors/lsm6ds3_temp.cc diff --git a/selfdrive/sensord/sensors/lsm6ds3_temp.h b/system/sensord/sensors/lsm6ds3_temp.h similarity index 92% rename from selfdrive/sensord/sensors/lsm6ds3_temp.h rename to system/sensord/sensors/lsm6ds3_temp.h index 1d6bcc228a..1b5b621814 100644 --- a/selfdrive/sensord/sensors/lsm6ds3_temp.h +++ b/system/sensord/sensors/lsm6ds3_temp.h @@ -1,6 +1,6 @@ #pragma once -#include "selfdrive/sensord/sensors/i2c_sensor.h" +#include "system/sensord/sensors/i2c_sensor.h" // Address of the chip on the bus #define LSM6DS3_TEMP_I2C_ADDR 0x6A diff --git a/selfdrive/sensord/sensors/mmc5603nj_magn.cc b/system/sensord/sensors/mmc5603nj_magn.cc similarity index 100% rename from selfdrive/sensord/sensors/mmc5603nj_magn.cc rename to system/sensord/sensors/mmc5603nj_magn.cc diff --git a/selfdrive/sensord/sensors/mmc5603nj_magn.h b/system/sensord/sensors/mmc5603nj_magn.h similarity index 94% rename from selfdrive/sensord/sensors/mmc5603nj_magn.h rename to system/sensord/sensors/mmc5603nj_magn.h index a364c7c37a..fce3f3fecb 100644 --- a/selfdrive/sensord/sensors/mmc5603nj_magn.h +++ b/system/sensord/sensors/mmc5603nj_magn.h @@ -1,6 +1,6 @@ #pragma once -#include "selfdrive/sensord/sensors/i2c_sensor.h" +#include "system/sensord/sensors/i2c_sensor.h" // Address of the chip on the bus #define MMC5603NJ_I2C_ADDR 0x30 diff --git a/selfdrive/sensord/sensors/sensor.h b/system/sensord/sensors/sensor.h similarity index 100% rename from selfdrive/sensord/sensors/sensor.h rename to system/sensord/sensors/sensor.h diff --git a/selfdrive/sensord/sensors_qcom2.cc b/system/sensord/sensors_qcom2.cc similarity index 90% rename from selfdrive/sensord/sensors_qcom2.cc rename to system/sensord/sensors_qcom2.cc index fc8dc8620b..349c67f498 100644 --- a/selfdrive/sensord/sensors_qcom2.cc +++ b/system/sensord/sensors_qcom2.cc @@ -12,17 +12,17 @@ #include "common/swaglog.h" #include "common/timing.h" #include "common/util.h" -#include "selfdrive/sensord/sensors/bmx055_accel.h" -#include "selfdrive/sensord/sensors/bmx055_gyro.h" -#include "selfdrive/sensord/sensors/bmx055_magn.h" -#include "selfdrive/sensord/sensors/bmx055_temp.h" -#include "selfdrive/sensord/sensors/constants.h" -#include "selfdrive/sensord/sensors/light_sensor.h" -#include "selfdrive/sensord/sensors/lsm6ds3_accel.h" -#include "selfdrive/sensord/sensors/lsm6ds3_gyro.h" -#include "selfdrive/sensord/sensors/lsm6ds3_temp.h" -#include "selfdrive/sensord/sensors/mmc5603nj_magn.h" -#include "selfdrive/sensord/sensors/sensor.h" +#include "system/sensord/sensors/bmx055_accel.h" +#include "system/sensord/sensors/bmx055_gyro.h" +#include "system/sensord/sensors/bmx055_magn.h" +#include "system/sensord/sensors/bmx055_temp.h" +#include "system/sensord/sensors/constants.h" +#include "system/sensord/sensors/light_sensor.h" +#include "system/sensord/sensors/lsm6ds3_accel.h" +#include "system/sensord/sensors/lsm6ds3_gyro.h" +#include "system/sensord/sensors/lsm6ds3_temp.h" +#include "system/sensord/sensors/mmc5603nj_magn.h" +#include "system/sensord/sensors/sensor.h" #define I2C_BUS_IMU 1 diff --git a/selfdrive/sensord/tests/__init__.py b/system/sensord/tests/__init__.py similarity index 100% rename from selfdrive/sensord/tests/__init__.py rename to system/sensord/tests/__init__.py diff --git a/selfdrive/sensord/tests/test_pigeond.py b/system/sensord/tests/test_pigeond.py similarity index 100% rename from selfdrive/sensord/tests/test_pigeond.py rename to system/sensord/tests/test_pigeond.py diff --git a/selfdrive/sensord/tests/test_sensord.py b/system/sensord/tests/test_sensord.py similarity index 100% rename from selfdrive/sensord/tests/test_sensord.py rename to system/sensord/tests/test_sensord.py diff --git a/selfdrive/sensord/tests/ttff_test.py b/system/sensord/tests/ttff_test.py similarity index 100% rename from selfdrive/sensord/tests/ttff_test.py rename to system/sensord/tests/ttff_test.py diff --git a/tools/gpstest/test_gps.py b/tools/gpstest/test_gps.py index 8bc5dc89a8..2c08c105a1 100644 --- a/tools/gpstest/test_gps.py +++ b/tools/gpstest/test_gps.py @@ -5,7 +5,7 @@ import struct from common.params import Params import cereal.messaging as messaging -import selfdrive.sensord.pigeond as pd +import system.sensord.pigeond as pd from system.hardware import TICI from selfdrive.test.helpers import with_processes diff --git a/tools/gpstest/test_laikad.py b/tools/gpstest/test_laikad.py index 410a9c70d3..24ffa6c424 100644 --- a/tools/gpstest/test_laikad.py +++ b/tools/gpstest/test_laikad.py @@ -4,7 +4,7 @@ import time import unittest import cereal.messaging as messaging -import selfdrive.sensord.pigeond as pd +import system.sensord.pigeond as pd from common.params import Params from system.hardware import TICI From 94eb2159802d3dba99620db0b08731c68a7e4733 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 8 Mar 2023 11:20:49 -0800 Subject: [PATCH 083/102] loggerd: move to system/ (#27534) --- .github/workflows/selfdrive_tests.yaml | 4 +- Jenkinsfile | 4 +- SConstruct | 2 +- docs/overview.rst | 2 +- release/files_common | 42 +++++++++---------- selfdrive/athena/athenad.py | 4 +- selfdrive/manager/manager.py | 2 +- selfdrive/manager/process_config.py | 8 ++-- selfdrive/statsd.py | 2 +- selfdrive/test/test_onroad.py | 2 +- selfdrive/thermald/thermald.py | 2 +- selfdrive/tombstoned.py | 2 +- {selfdrive => system}/loggerd/.gitignore | 0 {selfdrive => system}/loggerd/README.md | 0 {selfdrive => system}/loggerd/SConscript | 0 {selfdrive => system}/loggerd/__init__.py | 0 {selfdrive => system}/loggerd/bootlog.cc | 2 +- {selfdrive => system}/loggerd/config.py | 0 {selfdrive => system}/loggerd/deleter.py | 4 +- .../loggerd/encoder/encoder.cc | 2 +- .../loggerd/encoder/encoder.h | 2 +- .../loggerd/encoder/ffmpeg_encoder.cc | 2 +- .../loggerd/encoder/ffmpeg_encoder.h | 4 +- .../loggerd/encoder/v4l_encoder.cc | 2 +- .../loggerd/encoder/v4l_encoder.h | 2 +- {selfdrive => system}/loggerd/encoderd.cc | 2 +- {selfdrive => system}/loggerd/logger.cc | 2 +- {selfdrive => system}/loggerd/logger.h | 0 {selfdrive => system}/loggerd/loggerd.cc | 4 +- {selfdrive => system}/loggerd/loggerd.h | 8 ++-- .../loggerd/tests/__init__.py | 0 .../loggerd/tests/fill_eon.py | 4 +- .../loggerd/tests/loggerd_tests_common.py | 2 +- .../loggerd/tests/test_deleter.py | 4 +- .../loggerd/tests/test_encoder.py | 2 +- .../loggerd/tests/test_logger.cc | 2 +- .../loggerd/tests/test_loggerd.py | 4 +- .../loggerd/tests/test_runner.cc | 0 .../loggerd/tests/test_uploader.py | 4 +- .../loggerd/tools/mark_all_uploaded.py | 4 +- .../loggerd/tools/mark_unuploaded.py | 2 +- {selfdrive => system}/loggerd/uploader.py | 4 +- {selfdrive => system}/loggerd/video_writer.cc | 2 +- {selfdrive => system}/loggerd/video_writer.h | 0 {selfdrive => system}/loggerd/xattr_cache.py | 0 tools/lib/README.md | 2 +- 46 files changed, 74 insertions(+), 74 deletions(-) rename {selfdrive => system}/loggerd/.gitignore (100%) rename {selfdrive => system}/loggerd/README.md (100%) rename {selfdrive => system}/loggerd/SConscript (100%) rename {selfdrive => system}/loggerd/__init__.py (100%) rename {selfdrive => system}/loggerd/bootlog.cc (97%) rename {selfdrive => system}/loggerd/config.py (100%) rename {selfdrive => system}/loggerd/deleter.py (89%) rename {selfdrive => system}/loggerd/encoder/encoder.cc (98%) rename {selfdrive => system}/loggerd/encoder/encoder.h (97%) rename {selfdrive => system}/loggerd/encoder/ffmpeg_encoder.cc (98%) rename {selfdrive => system}/loggerd/encoder/ffmpeg_encoder.h (92%) rename {selfdrive => system}/loggerd/encoder/v4l_encoder.cc (99%) rename {selfdrive => system}/loggerd/encoder/v4l_encoder.h (95%) rename {selfdrive => system}/loggerd/encoderd.cc (99%) rename {selfdrive => system}/loggerd/logger.cc (99%) rename {selfdrive => system}/loggerd/logger.h (100%) rename {selfdrive => system}/loggerd/loggerd.cc (99%) rename {selfdrive => system}/loggerd/loggerd.h (92%) rename {selfdrive => system}/loggerd/tests/__init__.py (100%) rename {selfdrive => system}/loggerd/tests/fill_eon.py (79%) rename {selfdrive => system}/loggerd/tests/loggerd_tests_common.py (98%) rename {selfdrive => system}/loggerd/tests/test_deleter.py (96%) rename {selfdrive => system}/loggerd/tests/test_encoder.py (99%) rename {selfdrive => system}/loggerd/tests/test_logger.cc (99%) rename {selfdrive => system}/loggerd/tests/test_loggerd.py (99%) rename {selfdrive => system}/loggerd/tests/test_runner.cc (100%) rename {selfdrive => system}/loggerd/tests/test_uploader.py (97%) rename {selfdrive => system}/loggerd/tools/mark_all_uploaded.py (60%) rename {selfdrive => system}/loggerd/tools/mark_unuploaded.py (70%) rename {selfdrive => system}/loggerd/uploader.py (98%) rename {selfdrive => system}/loggerd/video_writer.cc (98%) rename {selfdrive => system}/loggerd/video_writer.h (100%) rename {selfdrive => system}/loggerd/xattr_cache.py (100%) diff --git a/.github/workflows/selfdrive_tests.yaml b/.github/workflows/selfdrive_tests.yaml index efddde720d..fb85a0fbb6 100644 --- a/.github/workflows/selfdrive_tests.yaml +++ b/.github/workflows/selfdrive_tests.yaml @@ -204,7 +204,7 @@ jobs: $UNIT_TEST selfdrive/boardd && \ $UNIT_TEST selfdrive/controls && \ $UNIT_TEST selfdrive/monitoring && \ - $UNIT_TEST selfdrive/loggerd && \ + $UNIT_TEST system/loggerd && \ $UNIT_TEST selfdrive/car && \ $UNIT_TEST selfdrive/locationd && \ selfdrive/locationd/test/_test_locationd_lib.py && \ @@ -219,7 +219,7 @@ jobs: ./common/tests/test_util && \ ./common/tests/test_swaglog && \ ./selfdrive/boardd/tests/test_boardd_usbprotocol && \ - ./selfdrive/loggerd/tests/test_logger &&\ + ./system/loggerd/tests/test_logger &&\ ./system/proclogd/tests/test_proclog && \ ./tools/replay/tests/test_replay && \ ./tools/cabana/tests/test_cabana && \ diff --git a/Jenkinsfile b/Jenkinsfile index 2067b9dac1..4e80b5fa3c 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -157,8 +157,8 @@ pipeline { phone_steps("tici-common", [ ["build", "cd selfdrive/manager && ./build.py"], ["test power draw", "python system/hardware/tici/test_power_draw.py"], - ["test loggerd", "python selfdrive/loggerd/tests/test_loggerd.py"], - ["test encoder", "LD_LIBRARY_PATH=/usr/local/lib python selfdrive/loggerd/tests/test_encoder.py"], + ["test loggerd", "python system/loggerd/tests/test_loggerd.py"], + ["test encoder", "LD_LIBRARY_PATH=/usr/local/lib python system/loggerd/tests/test_encoder.py"], ["test pigeond", "python system/sensord/tests/test_pigeond.py"], ["test manager", "python selfdrive/manager/test/test_manager.py"], ["test pandad", "python selfdrive/boardd/tests/test_pandad.py"], diff --git a/SConstruct b/SConstruct index 27c811686c..ba2b377e68 100644 --- a/SConstruct +++ b/SConstruct @@ -424,7 +424,7 @@ SConscript(['selfdrive/controls/lib/longitudinal_mpc_lib/SConscript']) SConscript(['selfdrive/boardd/SConscript']) -SConscript(['selfdrive/loggerd/SConscript']) +SConscript(['system/loggerd/SConscript']) SConscript(['selfdrive/locationd/SConscript']) SConscript(['system/sensord/SConscript']) diff --git a/docs/overview.rst b/docs/overview.rst index cc4c582155..b9a5700528 100644 --- a/docs/overview.rst +++ b/docs/overview.rst @@ -5,7 +5,7 @@ openpilot :maxdepth: 4 Debugging - selfdrive/loggerd/README.md + system/loggerd/README.md Driver Monitoring Process Replay diff --git a/release/files_common b/release/files_common index 334e08a322..42edaa9b12 100644 --- a/release/files_common +++ b/release/files_common @@ -253,28 +253,28 @@ system/proclogd/main.cc system/proclogd/proclog.cc system/proclogd/proclog.h -selfdrive/loggerd/.gitignore -selfdrive/loggerd/SConscript -selfdrive/loggerd/encoder/encoder.cc -selfdrive/loggerd/encoder/encoder.h -selfdrive/loggerd/encoder/v4l_encoder.cc -selfdrive/loggerd/encoder/v4l_encoder.h -selfdrive/loggerd/video_writer.cc -selfdrive/loggerd/video_writer.h -selfdrive/loggerd/logger.cc -selfdrive/loggerd/logger.h -selfdrive/loggerd/loggerd.cc -selfdrive/loggerd/loggerd.h -selfdrive/loggerd/encoderd.cc -selfdrive/loggerd/bootlog.cc -selfdrive/loggerd/encoder/ffmpeg_encoder.cc -selfdrive/loggerd/encoder/ffmpeg_encoder.h +system/loggerd/.gitignore +system/loggerd/SConscript +system/loggerd/encoder/encoder.cc +system/loggerd/encoder/encoder.h +system/loggerd/encoder/v4l_encoder.cc +system/loggerd/encoder/v4l_encoder.h +system/loggerd/video_writer.cc +system/loggerd/video_writer.h +system/loggerd/logger.cc +system/loggerd/logger.h +system/loggerd/loggerd.cc +system/loggerd/loggerd.h +system/loggerd/encoderd.cc +system/loggerd/bootlog.cc +system/loggerd/encoder/ffmpeg_encoder.cc +system/loggerd/encoder/ffmpeg_encoder.h -selfdrive/loggerd/__init__.py -selfdrive/loggerd/config.py -selfdrive/loggerd/uploader.py -selfdrive/loggerd/deleter.py -selfdrive/loggerd/xattr_cache.py +system/loggerd/__init__.py +system/loggerd/config.py +system/loggerd/uploader.py +system/loggerd/deleter.py +system/loggerd/xattr_cache.py system/sensord/.gitignore system/sensord/SConscript diff --git a/selfdrive/athena/athenad.py b/selfdrive/athena/athenad.py index d1cc4cea83..7cb6d5b845 100755 --- a/selfdrive/athena/athenad.py +++ b/selfdrive/athena/athenad.py @@ -36,8 +36,8 @@ from common.file_helpers import CallbackReader from common.params import Params from common.realtime import sec_since_boot, set_core_affinity from system.hardware import HARDWARE, PC, AGNOS -from selfdrive.loggerd.config import ROOT -from selfdrive.loggerd.xattr_cache import getxattr, setxattr +from system.loggerd.config import ROOT +from system.loggerd.xattr_cache import getxattr, setxattr from selfdrive.statsd import STATS_DIR from system.swaglog import SWAGLOG_DIR, cloudlog from system.version import get_commit, get_origin, get_short_branch, get_version diff --git a/selfdrive/manager/manager.py b/selfdrive/manager/manager.py index 963d94066b..1128097251 100755 --- a/selfdrive/manager/manager.py +++ b/selfdrive/manager/manager.py @@ -29,7 +29,7 @@ def manager_init() -> None: set_time(cloudlog) # save boot log - subprocess.call("./bootlog", cwd=os.path.join(BASEDIR, "selfdrive/loggerd")) + subprocess.call("./bootlog", cwd=os.path.join(BASEDIR, "system/loggerd")) params = Params() params.clear_all(ParamKeyType.CLEAR_ON_MANAGER_START) diff --git a/selfdrive/manager/process_config.py b/selfdrive/manager/process_config.py index 324063a68b..7b2b38af3a 100644 --- a/selfdrive/manager/process_config.py +++ b/selfdrive/manager/process_config.py @@ -34,8 +34,8 @@ procs = [ DaemonProcess("manage_athenad", "selfdrive.athena.manage_athenad", "AthenadPid"), NativeProcess("dmonitoringmodeld", "selfdrive/modeld", ["./dmonitoringmodeld"], enabled=(not PC or WEBCAM), callback=driverview), - NativeProcess("encoderd", "selfdrive/loggerd", ["./encoderd"]), - NativeProcess("loggerd", "selfdrive/loggerd", ["./loggerd"], onroad=False, callback=logging), + NativeProcess("encoderd", "system/loggerd", ["./encoderd"]), + NativeProcess("loggerd", "system/loggerd", ["./loggerd"], onroad=False, callback=logging), NativeProcess("modeld", "selfdrive/modeld", ["./modeld"]), NativeProcess("mapsd", "selfdrive/navd", ["./map_renderer"], enabled=False), NativeProcess("navmodeld", "selfdrive/modeld", ["./navmodeld"], enabled=False), @@ -47,7 +47,7 @@ procs = [ PythonProcess("calibrationd", "selfdrive.locationd.calibrationd"), PythonProcess("torqued", "selfdrive.locationd.torqued"), PythonProcess("controlsd", "selfdrive.controls.controlsd"), - PythonProcess("deleter", "selfdrive.loggerd.deleter", offroad=True), + PythonProcess("deleter", "system.loggerd.deleter", offroad=True), PythonProcess("dmonitoringd", "selfdrive.monitoring.dmonitoringd", enabled=(not PC or WEBCAM), callback=driverview), PythonProcess("laikad", "selfdrive.locationd.laikad"), PythonProcess("rawgpsd", "system.sensord.rawgps.rawgpsd", enabled=TICI), @@ -61,7 +61,7 @@ procs = [ PythonProcess("thermald", "selfdrive.thermald.thermald", offroad=True), PythonProcess("tombstoned", "selfdrive.tombstoned", enabled=not PC, offroad=True), PythonProcess("updated", "selfdrive.updated", enabled=not PC, onroad=False, offroad=True), - PythonProcess("uploader", "selfdrive.loggerd.uploader", offroad=True), + PythonProcess("uploader", "system.loggerd.uploader", offroad=True), PythonProcess("statsd", "selfdrive.statsd", offroad=True), # debug procs diff --git a/selfdrive/statsd.py b/selfdrive/statsd.py index 7dc002727e..e64907149c 100755 --- a/selfdrive/statsd.py +++ b/selfdrive/statsd.py @@ -13,7 +13,7 @@ from system.swaglog import cloudlog from system.hardware import HARDWARE from common.file_helpers import atomic_write_in_dir from system.version import get_normalized_origin, get_short_branch, get_short_version, is_dirty -from selfdrive.loggerd.config import STATS_DIR, STATS_DIR_FILE_LIMIT, STATS_SOCKET, STATS_FLUSH_TIME_S +from system.loggerd.config import STATS_DIR, STATS_DIR_FILE_LIMIT, STATS_SOCKET, STATS_FLUSH_TIME_S class METRIC_TYPE: diff --git a/selfdrive/test/test_onroad.py b/selfdrive/test/test_onroad.py index 84511771f7..07a3c61bc5 100755 --- a/selfdrive/test/test_onroad.py +++ b/selfdrive/test/test_onroad.py @@ -15,7 +15,7 @@ from common.basedir import BASEDIR from common.timeout import Timeout from common.params import Params from selfdrive.controls.lib.events import EVENTS, ET -from selfdrive.loggerd.config import ROOT +from system.loggerd.config import ROOT from selfdrive.test.helpers import set_params_enabled, release_only from tools.lib.logreader import LogReader diff --git a/selfdrive/thermald/thermald.py b/selfdrive/thermald/thermald.py index eedeff31f1..531e0b04d1 100755 --- a/selfdrive/thermald/thermald.py +++ b/selfdrive/thermald/thermald.py @@ -18,7 +18,7 @@ from common.params import Params from common.realtime import DT_TRML, sec_since_boot from selfdrive.controls.lib.alertmanager import set_offroad_alert from system.hardware import HARDWARE, TICI, AGNOS -from selfdrive.loggerd.config import get_available_percent +from system.loggerd.config import get_available_percent from selfdrive.statsd import statlog from system.swaglog import cloudlog from selfdrive.thermald.power_monitoring import PowerMonitoring diff --git a/selfdrive/tombstoned.py b/selfdrive/tombstoned.py index 61a575f141..65fb45b678 100755 --- a/selfdrive/tombstoned.py +++ b/selfdrive/tombstoned.py @@ -10,7 +10,7 @@ import glob from typing import NoReturn from common.file_helpers import mkdirs_exists_ok -from selfdrive.loggerd.config import ROOT +from system.loggerd.config import ROOT import selfdrive.sentry as sentry from system.swaglog import cloudlog from system.version import get_commit diff --git a/selfdrive/loggerd/.gitignore b/system/loggerd/.gitignore similarity index 100% rename from selfdrive/loggerd/.gitignore rename to system/loggerd/.gitignore diff --git a/selfdrive/loggerd/README.md b/system/loggerd/README.md similarity index 100% rename from selfdrive/loggerd/README.md rename to system/loggerd/README.md diff --git a/selfdrive/loggerd/SConscript b/system/loggerd/SConscript similarity index 100% rename from selfdrive/loggerd/SConscript rename to system/loggerd/SConscript diff --git a/selfdrive/loggerd/__init__.py b/system/loggerd/__init__.py similarity index 100% rename from selfdrive/loggerd/__init__.py rename to system/loggerd/__init__.py diff --git a/selfdrive/loggerd/bootlog.cc b/system/loggerd/bootlog.cc similarity index 97% rename from selfdrive/loggerd/bootlog.cc rename to system/loggerd/bootlog.cc index e882e4cf8d..4deb5b41f3 100644 --- a/selfdrive/loggerd/bootlog.cc +++ b/system/loggerd/bootlog.cc @@ -3,7 +3,7 @@ #include "cereal/messaging/messaging.h" #include "common/swaglog.h" -#include "selfdrive/loggerd/logger.h" +#include "system/loggerd/logger.h" static kj::Array build_boot_log() { diff --git a/selfdrive/loggerd/config.py b/system/loggerd/config.py similarity index 100% rename from selfdrive/loggerd/config.py rename to system/loggerd/config.py diff --git a/selfdrive/loggerd/deleter.py b/system/loggerd/deleter.py similarity index 89% rename from selfdrive/loggerd/deleter.py rename to system/loggerd/deleter.py index 5606288024..5fb2b9eb41 100644 --- a/selfdrive/loggerd/deleter.py +++ b/system/loggerd/deleter.py @@ -3,8 +3,8 @@ import os import shutil import threading from system.swaglog import cloudlog -from selfdrive.loggerd.config import ROOT, get_available_bytes, get_available_percent -from selfdrive.loggerd.uploader import listdir_by_creation +from system.loggerd.config import ROOT, get_available_bytes, get_available_percent +from system.loggerd.uploader import listdir_by_creation MIN_BYTES = 5 * 1024 * 1024 * 1024 MIN_PERCENT = 10 diff --git a/selfdrive/loggerd/encoder/encoder.cc b/system/loggerd/encoder/encoder.cc similarity index 98% rename from selfdrive/loggerd/encoder/encoder.cc rename to system/loggerd/encoder/encoder.cc index 943f37803d..08eaf0ff01 100644 --- a/selfdrive/loggerd/encoder/encoder.cc +++ b/system/loggerd/encoder/encoder.cc @@ -1,5 +1,5 @@ #include -#include "selfdrive/loggerd/encoder/encoder.h" +#include "system/loggerd/encoder/encoder.h" VideoEncoder::~VideoEncoder() {} diff --git a/selfdrive/loggerd/encoder/encoder.h b/system/loggerd/encoder/encoder.h similarity index 97% rename from selfdrive/loggerd/encoder/encoder.h rename to system/loggerd/encoder/encoder.h index 21ef65cf12..88dd5cee23 100644 --- a/selfdrive/loggerd/encoder/encoder.h +++ b/system/loggerd/encoder/encoder.h @@ -7,7 +7,7 @@ #include "cereal/messaging/messaging.h" #include "cereal/visionipc/visionipc.h" #include "common/queue.h" -#include "selfdrive/loggerd/video_writer.h" +#include "system/loggerd/video_writer.h" #include "system/camerad/cameras/camera_common.h" #define V4L2_BUF_FLAG_KEYFRAME 8 diff --git a/selfdrive/loggerd/encoder/ffmpeg_encoder.cc b/system/loggerd/encoder/ffmpeg_encoder.cc similarity index 98% rename from selfdrive/loggerd/encoder/ffmpeg_encoder.cc rename to system/loggerd/encoder/ffmpeg_encoder.cc index 5f8d140e8b..275da34f18 100644 --- a/selfdrive/loggerd/encoder/ffmpeg_encoder.cc +++ b/system/loggerd/encoder/ffmpeg_encoder.cc @@ -1,6 +1,6 @@ #pragma clang diagnostic ignored "-Wdeprecated-declarations" -#include "selfdrive/loggerd/encoder/ffmpeg_encoder.h" +#include "system/loggerd/encoder/ffmpeg_encoder.h" #include #include diff --git a/selfdrive/loggerd/encoder/ffmpeg_encoder.h b/system/loggerd/encoder/ffmpeg_encoder.h similarity index 92% rename from selfdrive/loggerd/encoder/ffmpeg_encoder.h rename to system/loggerd/encoder/ffmpeg_encoder.h index 497a28b651..9095a6e815 100644 --- a/selfdrive/loggerd/encoder/ffmpeg_encoder.h +++ b/system/loggerd/encoder/ffmpeg_encoder.h @@ -11,8 +11,8 @@ extern "C" { #include } -#include "selfdrive/loggerd/encoder/encoder.h" -#include "selfdrive/loggerd/loggerd.h" +#include "system/loggerd/encoder/encoder.h" +#include "system/loggerd/loggerd.h" class FfmpegEncoder : public VideoEncoder { public: diff --git a/selfdrive/loggerd/encoder/v4l_encoder.cc b/system/loggerd/encoder/v4l_encoder.cc similarity index 99% rename from selfdrive/loggerd/encoder/v4l_encoder.cc rename to system/loggerd/encoder/v4l_encoder.cc index 88aeb21256..16e7246ff4 100644 --- a/selfdrive/loggerd/encoder/v4l_encoder.cc +++ b/system/loggerd/encoder/v4l_encoder.cc @@ -2,7 +2,7 @@ #include #include -#include "selfdrive/loggerd/encoder/v4l_encoder.h" +#include "system/loggerd/encoder/v4l_encoder.h" #include "common/util.h" #include "common/timing.h" diff --git a/selfdrive/loggerd/encoder/v4l_encoder.h b/system/loggerd/encoder/v4l_encoder.h similarity index 95% rename from selfdrive/loggerd/encoder/v4l_encoder.h rename to system/loggerd/encoder/v4l_encoder.h index c2a53dd6ef..d4b0a1211d 100644 --- a/selfdrive/loggerd/encoder/v4l_encoder.h +++ b/system/loggerd/encoder/v4l_encoder.h @@ -1,7 +1,7 @@ #pragma once #include "common/queue.h" -#include "selfdrive/loggerd/encoder/encoder.h" +#include "system/loggerd/encoder/encoder.h" #define BUF_IN_COUNT 7 #define BUF_OUT_COUNT 6 diff --git a/selfdrive/loggerd/encoderd.cc b/system/loggerd/encoderd.cc similarity index 99% rename from selfdrive/loggerd/encoderd.cc rename to system/loggerd/encoderd.cc index db5f4b61ab..12b58b6591 100644 --- a/selfdrive/loggerd/encoderd.cc +++ b/system/loggerd/encoderd.cc @@ -1,4 +1,4 @@ -#include "selfdrive/loggerd/loggerd.h" +#include "system/loggerd/loggerd.h" ExitHandler do_exit; diff --git a/selfdrive/loggerd/logger.cc b/system/loggerd/logger.cc similarity index 99% rename from selfdrive/loggerd/logger.cc rename to system/loggerd/logger.cc index aaf267e523..0599aa1e54 100644 --- a/selfdrive/loggerd/logger.cc +++ b/system/loggerd/logger.cc @@ -1,4 +1,4 @@ -#include "selfdrive/loggerd/logger.h" +#include "system/loggerd/logger.h" #include #include diff --git a/selfdrive/loggerd/logger.h b/system/loggerd/logger.h similarity index 100% rename from selfdrive/loggerd/logger.h rename to system/loggerd/logger.h diff --git a/selfdrive/loggerd/loggerd.cc b/system/loggerd/loggerd.cc similarity index 99% rename from selfdrive/loggerd/loggerd.cc rename to system/loggerd/loggerd.cc index e09cdfaa9e..a7f7db4801 100644 --- a/selfdrive/loggerd/loggerd.cc +++ b/system/loggerd/loggerd.cc @@ -1,5 +1,5 @@ -#include "selfdrive/loggerd/loggerd.h" -#include "selfdrive/loggerd/video_writer.h" +#include "system/loggerd/loggerd.h" +#include "system/loggerd/video_writer.h" ExitHandler do_exit; diff --git a/selfdrive/loggerd/loggerd.h b/system/loggerd/loggerd.h similarity index 92% rename from selfdrive/loggerd/loggerd.h rename to system/loggerd/loggerd.h index 1fa6349828..1b8f9e0d2a 100644 --- a/selfdrive/loggerd/loggerd.h +++ b/system/loggerd/loggerd.h @@ -23,13 +23,13 @@ #include "common/util.h" #include "system/hardware/hw.h" -#include "selfdrive/loggerd/encoder/encoder.h" -#include "selfdrive/loggerd/logger.h" +#include "system/loggerd/encoder/encoder.h" +#include "system/loggerd/logger.h" #ifdef QCOM2 -#include "selfdrive/loggerd/encoder/v4l_encoder.h" +#include "system/loggerd/encoder/v4l_encoder.h" #define Encoder V4LEncoder #else -#include "selfdrive/loggerd/encoder/ffmpeg_encoder.h" +#include "system/loggerd/encoder/ffmpeg_encoder.h" #define Encoder FfmpegEncoder #endif diff --git a/selfdrive/loggerd/tests/__init__.py b/system/loggerd/tests/__init__.py similarity index 100% rename from selfdrive/loggerd/tests/__init__.py rename to system/loggerd/tests/__init__.py diff --git a/selfdrive/loggerd/tests/fill_eon.py b/system/loggerd/tests/fill_eon.py similarity index 79% rename from selfdrive/loggerd/tests/fill_eon.py rename to system/loggerd/tests/fill_eon.py index b40982fa9f..e0c52ea0d7 100755 --- a/selfdrive/loggerd/tests/fill_eon.py +++ b/system/loggerd/tests/fill_eon.py @@ -3,8 +3,8 @@ import os -from selfdrive.loggerd.config import ROOT, get_available_percent -from selfdrive.loggerd.tests.loggerd_tests_common import create_random_file +from system.loggerd.config import ROOT, get_available_percent +from system.loggerd.tests.loggerd_tests_common import create_random_file if __name__ == "__main__": diff --git a/selfdrive/loggerd/tests/loggerd_tests_common.py b/system/loggerd/tests/loggerd_tests_common.py similarity index 98% rename from selfdrive/loggerd/tests/loggerd_tests_common.py rename to system/loggerd/tests/loggerd_tests_common.py index 80cfb162f1..6aca83858b 100644 --- a/selfdrive/loggerd/tests/loggerd_tests_common.py +++ b/system/loggerd/tests/loggerd_tests_common.py @@ -5,7 +5,7 @@ import random import tempfile import unittest -import selfdrive.loggerd.uploader as uploader +import system.loggerd.uploader as uploader def create_random_file(file_path, size_mb, lock=False): try: diff --git a/selfdrive/loggerd/tests/test_deleter.py b/system/loggerd/tests/test_deleter.py similarity index 96% rename from selfdrive/loggerd/tests/test_deleter.py rename to system/loggerd/tests/test_deleter.py index 80fb5c997f..5b54a43f3b 100755 --- a/selfdrive/loggerd/tests/test_deleter.py +++ b/system/loggerd/tests/test_deleter.py @@ -6,8 +6,8 @@ import unittest from collections import namedtuple from common.timeout import Timeout, TimeoutException -import selfdrive.loggerd.deleter as deleter -from selfdrive.loggerd.tests.loggerd_tests_common import UploaderTestCase +import system.loggerd.deleter as deleter +from system.loggerd.tests.loggerd_tests_common import UploaderTestCase Stats = namedtuple("Stats", ['f_bavail', 'f_blocks', 'f_frsize']) diff --git a/selfdrive/loggerd/tests/test_encoder.py b/system/loggerd/tests/test_encoder.py similarity index 99% rename from selfdrive/loggerd/tests/test_encoder.py rename to system/loggerd/tests/test_encoder.py index 1b9bcef2d7..81f4e9fb9d 100755 --- a/selfdrive/loggerd/tests/test_encoder.py +++ b/system/loggerd/tests/test_encoder.py @@ -14,7 +14,7 @@ from tqdm import trange from common.params import Params from common.timeout import Timeout from system.hardware import TICI -from selfdrive.loggerd.config import ROOT +from system.loggerd.config import ROOT from selfdrive.manager.process_config import managed_processes from tools.lib.logreader import LogReader diff --git a/selfdrive/loggerd/tests/test_logger.cc b/system/loggerd/tests/test_logger.cc similarity index 99% rename from selfdrive/loggerd/tests/test_logger.cc rename to system/loggerd/tests/test_logger.cc index ba7835d632..9c82299091 100644 --- a/selfdrive/loggerd/tests/test_logger.cc +++ b/system/loggerd/tests/test_logger.cc @@ -9,7 +9,7 @@ #include "catch2/catch.hpp" #include "cereal/messaging/messaging.h" #include "common/util.h" -#include "selfdrive/loggerd/logger.h" +#include "system/loggerd/logger.h" #include "tools/replay/util.h" typedef cereal::Sentinel::SentinelType SentinelType; diff --git a/selfdrive/loggerd/tests/test_loggerd.py b/system/loggerd/tests/test_loggerd.py similarity index 99% rename from selfdrive/loggerd/tests/test_loggerd.py rename to system/loggerd/tests/test_loggerd.py index 857dc5c4e9..54098d13d0 100755 --- a/selfdrive/loggerd/tests/test_loggerd.py +++ b/system/loggerd/tests/test_loggerd.py @@ -15,7 +15,7 @@ from cereal.services import service_list from common.basedir import BASEDIR from common.params import Params from common.timeout import Timeout -from selfdrive.loggerd.config import ROOT +from system.loggerd.config import ROOT from selfdrive.manager.process_config import managed_processes from system.version import get_version from tools.lib.logreader import LogReader @@ -51,7 +51,7 @@ class TestLoggerd(unittest.TestCase): def _gen_bootlog(self): with Timeout(5): - out = subprocess.check_output("./bootlog", cwd=os.path.join(BASEDIR, "selfdrive/loggerd"), encoding='utf-8') + out = subprocess.check_output("./bootlog", cwd=os.path.join(BASEDIR, "system/loggerd"), encoding='utf-8') log_fn = self._get_log_fn(out) diff --git a/selfdrive/loggerd/tests/test_runner.cc b/system/loggerd/tests/test_runner.cc similarity index 100% rename from selfdrive/loggerd/tests/test_runner.cc rename to system/loggerd/tests/test_runner.cc diff --git a/selfdrive/loggerd/tests/test_uploader.py b/system/loggerd/tests/test_uploader.py similarity index 97% rename from selfdrive/loggerd/tests/test_uploader.py rename to system/loggerd/tests/test_uploader.py index 6090bbe2aa..11b273cec8 100755 --- a/selfdrive/loggerd/tests/test_uploader.py +++ b/system/loggerd/tests/test_uploader.py @@ -7,9 +7,9 @@ import logging import json from system.swaglog import cloudlog -import selfdrive.loggerd.uploader as uploader +import system.loggerd.uploader as uploader -from selfdrive.loggerd.tests.loggerd_tests_common import UploaderTestCase +from system.loggerd.tests.loggerd_tests_common import UploaderTestCase class TestLogHandler(logging.Handler): diff --git a/selfdrive/loggerd/tools/mark_all_uploaded.py b/system/loggerd/tools/mark_all_uploaded.py similarity index 60% rename from selfdrive/loggerd/tools/mark_all_uploaded.py rename to system/loggerd/tools/mark_all_uploaded.py index e60e6cfa2c..c963014748 100644 --- a/selfdrive/loggerd/tools/mark_all_uploaded.py +++ b/system/loggerd/tools/mark_all_uploaded.py @@ -1,7 +1,7 @@ import os -from selfdrive.loggerd.uploader import UPLOAD_ATTR_NAME, UPLOAD_ATTR_VALUE +from system.loggerd.uploader import UPLOAD_ATTR_NAME, UPLOAD_ATTR_VALUE -from selfdrive.loggerd.config import ROOT +from system.loggerd.config import ROOT for folder in os.walk(ROOT): for file1 in folder[2]: full_path = os.path.join(folder[0], file1) diff --git a/selfdrive/loggerd/tools/mark_unuploaded.py b/system/loggerd/tools/mark_unuploaded.py similarity index 70% rename from selfdrive/loggerd/tools/mark_unuploaded.py rename to system/loggerd/tools/mark_unuploaded.py index 343805d5fc..3d1d4472b0 100755 --- a/selfdrive/loggerd/tools/mark_unuploaded.py +++ b/system/loggerd/tools/mark_unuploaded.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 import os import sys -from selfdrive.loggerd.uploader import UPLOAD_ATTR_NAME +from system.loggerd.uploader import UPLOAD_ATTR_NAME for fn in sys.argv[1:]: print(f"unmarking {fn}") diff --git a/selfdrive/loggerd/uploader.py b/system/loggerd/uploader.py similarity index 98% rename from selfdrive/loggerd/uploader.py rename to system/loggerd/uploader.py index f97bafecb9..d4ed6dca28 100644 --- a/selfdrive/loggerd/uploader.py +++ b/system/loggerd/uploader.py @@ -16,8 +16,8 @@ from common.api import Api from common.params import Params from common.realtime import set_core_affinity from system.hardware import TICI -from selfdrive.loggerd.xattr_cache import getxattr, setxattr -from selfdrive.loggerd.config import ROOT +from system.loggerd.xattr_cache import getxattr, setxattr +from system.loggerd.config import ROOT from system.swaglog import cloudlog NetworkType = log.DeviceState.NetworkType diff --git a/selfdrive/loggerd/video_writer.cc b/system/loggerd/video_writer.cc similarity index 98% rename from selfdrive/loggerd/video_writer.cc rename to system/loggerd/video_writer.cc index 4f79ccafc8..91bf09355f 100644 --- a/selfdrive/loggerd/video_writer.cc +++ b/system/loggerd/video_writer.cc @@ -2,7 +2,7 @@ #include #include -#include "selfdrive/loggerd/video_writer.h" +#include "system/loggerd/video_writer.h" #include "common/swaglog.h" #include "common/util.h" diff --git a/selfdrive/loggerd/video_writer.h b/system/loggerd/video_writer.h similarity index 100% rename from selfdrive/loggerd/video_writer.h rename to system/loggerd/video_writer.h diff --git a/selfdrive/loggerd/xattr_cache.py b/system/loggerd/xattr_cache.py similarity index 100% rename from selfdrive/loggerd/xattr_cache.py rename to system/loggerd/xattr_cache.py diff --git a/tools/lib/README.md b/tools/lib/README.md index 3cf239d2df..d77eef5ac5 100644 --- a/tools/lib/README.md +++ b/tools/lib/README.md @@ -1,6 +1,6 @@ ## LogReader -Route is a class for conveniently accessing all the [logs](/selfdrive/loggerd/) from your routes. The LogReader class reads the non-video logs, i.e. rlog.bz2 and qlog.bz2. There's also a matching FrameReader class for reading the videos. +Route is a class for conveniently accessing all the [logs](/system/loggerd/) from your routes. The LogReader class reads the non-video logs, i.e. rlog.bz2 and qlog.bz2. There's also a matching FrameReader class for reading the videos. ```python from tools.lib.route import Route From 3ff8fc110cbd29f304ed364f4f619afcdf0a729e Mon Sep 17 00:00:00 2001 From: Jason Young <46612682+jyoung8607@users.noreply.github.com> Date: Wed, 8 Mar 2023 16:06:17 -0500 Subject: [PATCH 084/102] =?UTF-8?q?VW=20MQB:=20Add=20FW=20for=202017=20?= =?UTF-8?q?=C5=A0koda=20Kodiaq=20(#27532)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * VW MQB: Add FW for 2017 Škoda Kodiaq * retry CI --- docs/CARS.md | 2 +- selfdrive/car/volkswagen/values.py | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/CARS.md b/docs/CARS.md index 426db94f89..070d068cab 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -164,7 +164,7 @@ A supported vehicle is one that just works when you install a comma three. All s |Škoda|Fabia 2022-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,9](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533[10](#footnotes)|| |Škoda|Kamiq 2021[7](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,9](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533[10](#footnotes)|| |Škoda|Karoq 2019-21|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,9](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|| -|Škoda|Kodiaq 2018-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,9](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|| +|Škoda|Kodiaq 2017-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,9](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|| |Škoda|Octavia 2015, 2018-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,9](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|| |Škoda|Octavia RS 2016|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,9](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533|| |Škoda|Scala 2020|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,9](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533[10](#footnotes)|| diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py index c5868e16f3..8e12923983 100755 --- a/selfdrive/car/volkswagen/values.py +++ b/selfdrive/car/volkswagen/values.py @@ -243,7 +243,7 @@ CAR_INFO: Dict[str, Union[VWCarInfo, List[VWCarInfo]]] = { CAR.SKODA_FABIA_MK4: VWCarInfo("Škoda Fabia 2022-23", footnotes=[Footnote.VW_MQB_A0]), CAR.SKODA_KAMIQ_MK1: VWCarInfo("Škoda Kamiq 2021", footnotes=[Footnote.VW_MQB_A0, Footnote.KAMIQ]), CAR.SKODA_KAROQ_MK1: VWCarInfo("Škoda Karoq 2019-21"), - CAR.SKODA_KODIAQ_MK1: VWCarInfo("Škoda Kodiaq 2018-19"), + CAR.SKODA_KODIAQ_MK1: VWCarInfo("Škoda Kodiaq 2017-23"), CAR.SKODA_SCALA_MK1: VWCarInfo("Škoda Scala 2020", footnotes=[Footnote.VW_MQB_A0]), CAR.SKODA_SUPERB_MK3: VWCarInfo("Škoda Superb 2015-22"), CAR.SKODA_OCTAVIA_MK3: [ @@ -1071,17 +1071,20 @@ FW_VERSIONS = { (Ecu.engine, 0x7e0, None): [ b'\xf1\x8704E906027DD\xf1\x893123', b'\xf1\x8704L906026DE\xf1\x895418', + b'\xf1\x8704L906026EJ\xf1\x893661', b'\xf1\x8704L906026HT\xf1\x893617', b'\xf1\x875NA907115E \xf1\x890003', b'\xf1\x875NA907115E \xf1\x890005', ], (Ecu.transmission, 0x7e1, None): [ b'\xf1\x870D9300043 \xf1\x895202', + b'\xf1\x870DL300011N \xf1\x892014', b'\xf1\x870DL300012M \xf1\x892107', b'\xf1\x870DL300012N \xf1\x892110', b'\xf1\x870DL300013G \xf1\x892119', ], (Ecu.srs, 0x715, None): [ + b'\xf1\x873Q0959655AP\xf1\x890306\xf1\x82\r11110011110011421111314211', b'\xf1\x873Q0959655BJ\xf1\x890703\xf1\x82\x0e1213001211001205212111052100', b'\xf1\x873Q0959655BK\xf1\x890703\xf1\x82\x0e1213001211001244212111442100', b'\xf1\x873Q0959655CN\xf1\x890720\xf1\x82\x0e1213001211001205212112052100', @@ -1096,6 +1099,7 @@ FW_VERSIONS = { (Ecu.fwdRadar, 0x757, None): [ b'\xf1\x872Q0907572Q \xf1\x890342', b'\xf1\x872Q0907572R \xf1\x890372', + b'\xf1\x872Q0907572T \xf1\x890383', b'\xf1\x872Q0907572AA\xf1\x890396', ], }, From 231e9a950dc32b322602815a25486fdc50ec2091 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harald=20Sch=C3=A4fer?= Date: Wed, 8 Mar 2023 13:07:33 -0800 Subject: [PATCH 085/102] Pigeond: Request sat info msgs (#27529) request sat info msgs --- selfdrive/locationd/test/ublox.py | 1 + selfdrive/locationd/test/ubloxd.py | 1 + selfdrive/locationd/ublox_msg.cc | 3 +++ system/sensord/pigeond.py | 1 + 4 files changed, 6 insertions(+) diff --git a/selfdrive/locationd/test/ublox.py b/selfdrive/locationd/test/ublox.py index 9cffbeac40..80abc64e2c 100644 --- a/selfdrive/locationd/test/ublox.py +++ b/selfdrive/locationd/test/ublox.py @@ -54,6 +54,7 @@ MSG_NAV_DOP = 0x04 MSG_NAV_EKFSTATUS = 0x40 MSG_NAV_SBAS = 0x32 MSG_NAV_SOL = 0x06 +MSG_NAV_SAT = 0x35 # RXM messages MSG_RXM_RAW = 0x15 diff --git a/selfdrive/locationd/test/ubloxd.py b/selfdrive/locationd/test/ubloxd.py index 82aa502ceb..7c7e68b23b 100755 --- a/selfdrive/locationd/test/ubloxd.py +++ b/selfdrive/locationd/test/ubloxd.py @@ -60,6 +60,7 @@ def configure_ublox(dev): dev.configure_message_rate(ublox.CLASS_RXM, ublox.MSG_RXM_SFRBX, 1) dev.configure_message_rate(ublox.CLASS_MON, ublox.MSG_MON_HW, 1) dev.configure_message_rate(ublox.CLASS_MON, ublox.MSG_MON_HW2, 1) + dev.configure_message_rate(ublox.CLASS_NAV, ublox.MSG_NAV_SAT, 1) # Query the backup restore status print("backup restore polling message (implement custom response handler!):") diff --git a/selfdrive/locationd/ublox_msg.cc b/selfdrive/locationd/ublox_msg.cc index 77ca9099ed..ebd904f72f 100644 --- a/selfdrive/locationd/ublox_msg.cc +++ b/selfdrive/locationd/ublox_msg.cc @@ -126,6 +126,9 @@ std::pair> UbloxMsgParser::gen_msg() { return {"ubloxGnss", gen_mon_hw(static_cast(body))}; case 0x0a0b: return {"ubloxGnss", gen_mon_hw2(static_cast(body))}; + case 0x0135: + // TODO return {"ubloxGnss", gen_nav_sat(static_cast(body))}; + return {"ubloxGnss", kj::Array()}; default: LOGE("Unknown message type %x", ubx_message.msg_type()); return {"ubloxGnss", kj::Array()}; diff --git a/system/sensord/pigeond.py b/system/sensord/pigeond.py index 9d0a62bd3b..c9ad7ff22a 100755 --- a/system/sensord/pigeond.py +++ b/system/sensord/pigeond.py @@ -183,6 +183,7 @@ def initialize_pigeon(pigeon: TTYPigeon) -> bool: pigeon.send_with_ack(b"\xB5\x62\x06\x01\x03\x00\x02\x13\x01\x20\x6C") pigeon.send_with_ack(b"\xB5\x62\x06\x01\x03\x00\x0A\x09\x01\x1E\x70") pigeon.send_with_ack(b"\xB5\x62\x06\x01\x03\x00\x0A\x0B\x01\x20\x74") + pigeon.send_with_ack(b"\xB5\x62\x06\x01\x03\x00\x01\x35\x01\x41\xAD") cloudlog.debug("pigeon configured") # try restoring almanac backup From c97911dbad15c3cc7dc577b305ab9aed775e021f Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 8 Mar 2023 16:11:18 -0800 Subject: [PATCH 086/102] ubloxd: move to system/ (#27536) * ubloxd: move to system/ * more fixes * add missing sconscript * fix valgrind tests * uncomment --- .github/workflows/selfdrive_tests.yaml | 3 ++- SConstruct | 1 + release/files_common | 15 ++++++------- selfdrive/locationd/.gitignore | 3 --- selfdrive/locationd/SConscript | 21 ++----------------- selfdrive/manager/process_config.py | 2 +- selfdrive/test/test_valgrind_replay.py | 2 +- system/ubloxd/.gitignore | 2 ++ system/ubloxd/SConscript | 20 ++++++++++++++++++ .../ubloxd}/generated/glonass.cpp | 0 .../ubloxd}/generated/glonass.h | 0 .../ubloxd}/generated/gps.cpp | 0 .../ubloxd}/generated/gps.h | 0 .../ubloxd}/generated/ubx.cpp | 0 .../ubloxd}/generated/ubx.h | 0 .../locationd => system/ubloxd}/glonass.ksy | 0 .../ubloxd}/glonass_fix.patch | 6 +++--- .../locationd => system/ubloxd}/gps.ksy | 0 .../ubloxd/tests}/print_gps_stats.py | 0 .../ubloxd/tests}/test_glonass_kaitai.cc | 2 +- .../ubloxd/tests}/test_glonass_runner.cc | 0 .../ubloxd/tests}/test_ublox_processing.py | 0 .../test => system/ubloxd/tests}/ublox.py | 0 .../test => system/ubloxd/tests}/ubloxd.py | 0 .../locationd => system/ubloxd}/ublox_msg.cc | 0 .../locationd => system/ubloxd}/ublox_msg.h | 6 +++--- .../locationd => system/ubloxd}/ubloxd.cc | 2 +- .../locationd => system/ubloxd}/ubx.ksy | 0 28 files changed, 45 insertions(+), 40 deletions(-) create mode 100644 system/ubloxd/.gitignore create mode 100644 system/ubloxd/SConscript rename {selfdrive/locationd => system/ubloxd}/generated/glonass.cpp (100%) rename {selfdrive/locationd => system/ubloxd}/generated/glonass.h (100%) rename {selfdrive/locationd => system/ubloxd}/generated/gps.cpp (100%) rename {selfdrive/locationd => system/ubloxd}/generated/gps.h (100%) rename {selfdrive/locationd => system/ubloxd}/generated/ubx.cpp (100%) rename {selfdrive/locationd => system/ubloxd}/generated/ubx.h (100%) rename {selfdrive/locationd => system/ubloxd}/glonass.ksy (100%) rename {selfdrive/locationd => system/ubloxd}/glonass_fix.patch (68%) rename {selfdrive/locationd => system/ubloxd}/gps.ksy (100%) rename {selfdrive/locationd/test => system/ubloxd/tests}/print_gps_stats.py (100%) rename {selfdrive/locationd/test => system/ubloxd/tests}/test_glonass_kaitai.cc (99%) rename {selfdrive/locationd/test => system/ubloxd/tests}/test_glonass_runner.cc (100%) rename {selfdrive/locationd/test => system/ubloxd/tests}/test_ublox_processing.py (100%) rename {selfdrive/locationd/test => system/ubloxd/tests}/ublox.py (100%) rename {selfdrive/locationd/test => system/ubloxd/tests}/ubloxd.py (100%) rename {selfdrive/locationd => system/ubloxd}/ublox_msg.cc (100%) rename {selfdrive/locationd => system/ubloxd}/ublox_msg.h (96%) rename {selfdrive/locationd => system/ubloxd}/ubloxd.cc (97%) rename {selfdrive/locationd => system/ubloxd}/ubx.ksy (100%) diff --git a/.github/workflows/selfdrive_tests.yaml b/.github/workflows/selfdrive_tests.yaml index fb85a0fbb6..5873e7aee6 100644 --- a/.github/workflows/selfdrive_tests.yaml +++ b/.github/workflows/selfdrive_tests.yaml @@ -207,8 +207,9 @@ jobs: $UNIT_TEST system/loggerd && \ $UNIT_TEST selfdrive/car && \ $UNIT_TEST selfdrive/locationd && \ + $UNIT_TEST system/ubloxd && \ selfdrive/locationd/test/_test_locationd_lib.py && \ - ./selfdrive/locationd/test/test_glonass_runner && \ + ./system/ubloxd/tests/test_glonass_runner && \ $UNIT_TEST selfdrive/athena && \ $UNIT_TEST selfdrive/thermald && \ $UNIT_TEST system/hardware/tici && \ diff --git a/SConstruct b/SConstruct index ba2b377e68..387d2e76f4 100644 --- a/SConstruct +++ b/SConstruct @@ -398,6 +398,7 @@ SConscript([ 'system/camerad/SConscript', 'system/clocksd/SConscript', 'system/proclogd/SConscript', + 'system/ubloxd/SConscript', ]) if arch != "Darwin": SConscript(['system/logcatd/SConscript']) diff --git a/release/files_common b/release/files_common index 42edaa9b12..a20f71018b 100644 --- a/release/files_common +++ b/release/files_common @@ -219,14 +219,15 @@ system/hardware/pc/__init__.py system/hardware/pc/hardware.h system/hardware/pc/hardware.py -selfdrive/locationd/__init__.py -selfdrive/locationd/.gitignore -selfdrive/locationd/SConscript -selfdrive/locationd/ubloxd.cc -selfdrive/locationd/ublox_msg.cc -selfdrive/locationd/ublox_msg.h -selfdrive/locationd/generated/* +system/ubloxd/.gitignore +system/ubloxd/SConscript +system/ubloxd/generated/* +system/ubloxd/*.h +system/ubloxd/*.cc +selfdrive/locationd/__init__.py +selfdrive/locationd/SConscript +selfdrive/locationd/.gitignore selfdrive/locationd/laikad.py selfdrive/locationd/locationd.h selfdrive/locationd/locationd.cc diff --git a/selfdrive/locationd/.gitignore b/selfdrive/locationd/.gitignore index 86a228a6ff..11b9f127b2 100644 --- a/selfdrive/locationd/.gitignore +++ b/selfdrive/locationd/.gitignore @@ -1,6 +1,3 @@ -ubloxd -ubloxd_test params_learner paramsd locationd -test/test_glonass_runner diff --git a/selfdrive/locationd/SConscript b/selfdrive/locationd/SConscript index 61a0ed7f42..740f827a49 100644 --- a/selfdrive/locationd/SConscript +++ b/selfdrive/locationd/SConscript @@ -1,20 +1,6 @@ Import('env', 'common', 'cereal', 'messaging', 'libkf', 'transformations') -loc_libs = [cereal, messaging, 'zmq', common, 'capnp', 'kj', 'kaitai', 'pthread'] - -if GetOption('kaitai'): - generated = Dir('generated').srcnode().abspath - cmd = f"kaitai-struct-compiler --target cpp_stl --outdir {generated} $SOURCES" - env.Command(['generated/ubx.cpp', 'generated/ubx.h'], 'ubx.ksy', cmd) - env.Command(['generated/gps.cpp', 'generated/gps.h'], 'gps.ksy', cmd) - glonass = env.Command(['generated/glonass.cpp', 'generated/glonass.h'], 'glonass.ksy', cmd) - - # kaitai issue: https://github.com/kaitai-io/kaitai_struct/issues/910 - patch = env.Command(None, 'glonass_fix.patch', 'git apply $SOURCES') - env.Depends(patch, glonass) - -glonass_obj = env.Object('generated/glonass.cpp') -env.Program("ubloxd", ["ubloxd.cc", "ublox_msg.cc", "generated/ubx.cpp", "generated/gps.cpp", glonass_obj], LIBS=loc_libs) +loc_libs = [cereal, messaging, 'zmq', common, 'capnp', 'kj', 'pthread'] ekf_sym_cc = env.SharedObject("#rednose/helpers/ekf_sym.cc") locationd_sources = ["locationd.cc", "models/live_kf.cc", ekf_sym_cc] @@ -25,7 +11,4 @@ lenv.Depends(locationd, libkf) if File("liblocationd.cc").exists(): liblocationd = lenv.SharedLibrary("liblocationd", ["liblocationd.cc"] + locationd_sources, LIBS=loc_libs + transformations) - lenv.Depends(liblocationd, libkf) - -if GetOption('test'): - env.Program("test/test_glonass_runner", ['test/test_glonass_runner.cc', 'test/test_glonass_kaitai.cc', glonass_obj], LIBS=[loc_libs]) \ No newline at end of file + lenv.Depends(liblocationd, libkf) \ No newline at end of file diff --git a/selfdrive/manager/process_config.py b/selfdrive/manager/process_config.py index 7b2b38af3a..2bacd951a7 100644 --- a/selfdrive/manager/process_config.py +++ b/selfdrive/manager/process_config.py @@ -54,7 +54,7 @@ procs = [ PythonProcess("navd", "selfdrive.navd.navd"), PythonProcess("pandad", "selfdrive.boardd.pandad", offroad=True), PythonProcess("paramsd", "selfdrive.locationd.paramsd"), - NativeProcess("ubloxd", "selfdrive/locationd", ["./ubloxd"], enabled=TICI, onroad=False, callback=ublox), + NativeProcess("ubloxd", "system/ubloxd", ["./ubloxd"], enabled=TICI, onroad=False, callback=ublox), PythonProcess("pigeond", "system.sensord.pigeond", enabled=TICI, onroad=False, callback=ublox), PythonProcess("plannerd", "selfdrive.controls.plannerd"), PythonProcess("radard", "selfdrive.controls.radard"), diff --git a/selfdrive/test/test_valgrind_replay.py b/selfdrive/test/test_valgrind_replay.py index 238b822ec9..46dd4901e5 100755 --- a/selfdrive/test/test_valgrind_replay.py +++ b/selfdrive/test/test_valgrind_replay.py @@ -28,7 +28,7 @@ CONFIGS = [ }, ignore=[], command="./ubloxd", - path="selfdrive/locationd/", + path="system/ubloxd", segment="0375fdf7b1ce594d|2019-06-13--08-32-25--3", wait_for_response=True ), diff --git a/system/ubloxd/.gitignore b/system/ubloxd/.gitignore new file mode 100644 index 0000000000..05263ff67c --- /dev/null +++ b/system/ubloxd/.gitignore @@ -0,0 +1,2 @@ +ubloxd +tests/test_glonass_runner diff --git a/system/ubloxd/SConscript b/system/ubloxd/SConscript new file mode 100644 index 0000000000..fff0986efd --- /dev/null +++ b/system/ubloxd/SConscript @@ -0,0 +1,20 @@ +Import('env', 'common', 'cereal', 'messaging') + +loc_libs = [cereal, messaging, 'zmq', common, 'capnp', 'kj', 'kaitai', 'pthread'] + +if GetOption('kaitai'): + generated = Dir('generated').srcnode().abspath + cmd = f"kaitai-struct-compiler --target cpp_stl --outdir {generated} $SOURCES" + env.Command(['generated/ubx.cpp', 'generated/ubx.h'], 'ubx.ksy', cmd) + env.Command(['generated/gps.cpp', 'generated/gps.h'], 'gps.ksy', cmd) + glonass = env.Command(['generated/glonass.cpp', 'generated/glonass.h'], 'glonass.ksy', cmd) + + # kaitai issue: https://github.com/kaitai-io/kaitai_struct/issues/910 + patch = env.Command(None, 'glonass_fix.patch', 'git apply $SOURCES') + env.Depends(patch, glonass) + +glonass_obj = env.Object('generated/glonass.cpp') +env.Program("ubloxd", ["ubloxd.cc", "ublox_msg.cc", "generated/ubx.cpp", "generated/gps.cpp", glonass_obj], LIBS=loc_libs) + +if GetOption('test'): + env.Program("tests/test_glonass_runner", ['tests/test_glonass_runner.cc', 'tests/test_glonass_kaitai.cc', glonass_obj], LIBS=[loc_libs]) \ No newline at end of file diff --git a/selfdrive/locationd/generated/glonass.cpp b/system/ubloxd/generated/glonass.cpp similarity index 100% rename from selfdrive/locationd/generated/glonass.cpp rename to system/ubloxd/generated/glonass.cpp diff --git a/selfdrive/locationd/generated/glonass.h b/system/ubloxd/generated/glonass.h similarity index 100% rename from selfdrive/locationd/generated/glonass.h rename to system/ubloxd/generated/glonass.h diff --git a/selfdrive/locationd/generated/gps.cpp b/system/ubloxd/generated/gps.cpp similarity index 100% rename from selfdrive/locationd/generated/gps.cpp rename to system/ubloxd/generated/gps.cpp diff --git a/selfdrive/locationd/generated/gps.h b/system/ubloxd/generated/gps.h similarity index 100% rename from selfdrive/locationd/generated/gps.h rename to system/ubloxd/generated/gps.h diff --git a/selfdrive/locationd/generated/ubx.cpp b/system/ubloxd/generated/ubx.cpp similarity index 100% rename from selfdrive/locationd/generated/ubx.cpp rename to system/ubloxd/generated/ubx.cpp diff --git a/selfdrive/locationd/generated/ubx.h b/system/ubloxd/generated/ubx.h similarity index 100% rename from selfdrive/locationd/generated/ubx.h rename to system/ubloxd/generated/ubx.h diff --git a/selfdrive/locationd/glonass.ksy b/system/ubloxd/glonass.ksy similarity index 100% rename from selfdrive/locationd/glonass.ksy rename to system/ubloxd/glonass.ksy diff --git a/selfdrive/locationd/glonass_fix.patch b/system/ubloxd/glonass_fix.patch similarity index 68% rename from selfdrive/locationd/glonass_fix.patch rename to system/ubloxd/glonass_fix.patch index fa34a8ef15..7eb973a348 100644 --- a/selfdrive/locationd/glonass_fix.patch +++ b/system/ubloxd/glonass_fix.patch @@ -1,7 +1,7 @@ -diff --git a/selfdrive/locationd/generated/glonass.cpp b/selfdrive/locationd/generated/glonass.cpp +diff --git a/system/ubloxd/generated/glonass.cpp b/system/ubloxd/generated/glonass.cpp index 5b17bc327..b5c6aa610 100644 ---- a/selfdrive/locationd/generated/glonass.cpp -+++ b/selfdrive/locationd/generated/glonass.cpp +--- a/system/ubloxd/generated/glonass.cpp ++++ b/system/ubloxd/generated/glonass.cpp @@ -17,7 +17,7 @@ glonass_t::glonass_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, glonass void glonass_t::_read() { m_idle_chip = m__io->read_bits_int_be(1); diff --git a/selfdrive/locationd/gps.ksy b/system/ubloxd/gps.ksy similarity index 100% rename from selfdrive/locationd/gps.ksy rename to system/ubloxd/gps.ksy diff --git a/selfdrive/locationd/test/print_gps_stats.py b/system/ubloxd/tests/print_gps_stats.py similarity index 100% rename from selfdrive/locationd/test/print_gps_stats.py rename to system/ubloxd/tests/print_gps_stats.py diff --git a/selfdrive/locationd/test/test_glonass_kaitai.cc b/system/ubloxd/tests/test_glonass_kaitai.cc similarity index 99% rename from selfdrive/locationd/test/test_glonass_kaitai.cc rename to system/ubloxd/tests/test_glonass_kaitai.cc index 22f5202a3d..5ad274142a 100644 --- a/selfdrive/locationd/test/test_glonass_kaitai.cc +++ b/system/ubloxd/tests/test_glonass_kaitai.cc @@ -6,7 +6,7 @@ #include #include "catch2/catch.hpp" -#include "selfdrive/locationd/generated/glonass.h" +#include "system/ubloxd/generated/glonass.h" typedef std::vector> string_data; diff --git a/selfdrive/locationd/test/test_glonass_runner.cc b/system/ubloxd/tests/test_glonass_runner.cc similarity index 100% rename from selfdrive/locationd/test/test_glonass_runner.cc rename to system/ubloxd/tests/test_glonass_runner.cc diff --git a/selfdrive/locationd/test/test_ublox_processing.py b/system/ubloxd/tests/test_ublox_processing.py similarity index 100% rename from selfdrive/locationd/test/test_ublox_processing.py rename to system/ubloxd/tests/test_ublox_processing.py diff --git a/selfdrive/locationd/test/ublox.py b/system/ubloxd/tests/ublox.py similarity index 100% rename from selfdrive/locationd/test/ublox.py rename to system/ubloxd/tests/ublox.py diff --git a/selfdrive/locationd/test/ubloxd.py b/system/ubloxd/tests/ubloxd.py similarity index 100% rename from selfdrive/locationd/test/ubloxd.py rename to system/ubloxd/tests/ubloxd.py diff --git a/selfdrive/locationd/ublox_msg.cc b/system/ubloxd/ublox_msg.cc similarity index 100% rename from selfdrive/locationd/ublox_msg.cc rename to system/ubloxd/ublox_msg.cc diff --git a/selfdrive/locationd/ublox_msg.h b/system/ubloxd/ublox_msg.h similarity index 96% rename from selfdrive/locationd/ublox_msg.h rename to system/ubloxd/ublox_msg.h index 6988f20b74..3989bbf85b 100644 --- a/selfdrive/locationd/ublox_msg.h +++ b/system/ubloxd/ublox_msg.h @@ -9,9 +9,9 @@ #include "cereal/messaging/messaging.h" #include "common/util.h" -#include "selfdrive/locationd/generated/gps.h" -#include "selfdrive/locationd/generated/glonass.h" -#include "selfdrive/locationd/generated/ubx.h" +#include "system/ubloxd/generated/gps.h" +#include "system/ubloxd/generated/glonass.h" +#include "system/ubloxd/generated/ubx.h" using namespace std::string_literals; diff --git a/selfdrive/locationd/ubloxd.cc b/system/ubloxd/ubloxd.cc similarity index 97% rename from selfdrive/locationd/ubloxd.cc rename to system/ubloxd/ubloxd.cc index d9b3e7647d..81731ac931 100644 --- a/selfdrive/locationd/ubloxd.cc +++ b/system/ubloxd/ubloxd.cc @@ -5,7 +5,7 @@ #include "cereal/messaging/messaging.h" #include "common/swaglog.h" #include "common/util.h" -#include "selfdrive/locationd/ublox_msg.h" +#include "system/ubloxd/ublox_msg.h" ExitHandler do_exit; using namespace ublox; diff --git a/selfdrive/locationd/ubx.ksy b/system/ubloxd/ubx.ksy similarity index 100% rename from selfdrive/locationd/ubx.ksy rename to system/ubloxd/ubx.ksy From 75eaca3cf360614dcc86a7028921bbf022e30fa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harald=20Sch=C3=A4fer?= Date: Thu, 9 Mar 2023 11:12:42 -0800 Subject: [PATCH 087/102] Update amplifier config (#27443) * update tizi amplifier * Update attenuation --- system/hardware/tici/amplifier.py | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/system/hardware/tici/amplifier.py b/system/hardware/tici/amplifier.py index 8233834d11..840d575fdf 100644 --- a/system/hardware/tici/amplifier.py +++ b/system/hardware/tici/amplifier.py @@ -24,13 +24,10 @@ BASE_CONFIG = [ AmpConfig("MCLK prescaler", 0b01, 0x10, 4, 0b00110000), AmpConfig("PM: enable speakers", 0b11, 0x4D, 4, 0b00110000), AmpConfig("PM: enable DACs", 0b11, 0x4D, 0, 0b00000011), - AmpConfig("Right speaker output from right DAC", 0b1, 0x2C, 0, 0b11111111), - AmpConfig("Right Speaker Mixer Gain", 0b00, 0x2D, 2, 0b00001100), AmpConfig("Enable PLL1", 0b1, 0x12, 7, 0b10000000), AmpConfig("Enable PLL2", 0b1, 0x1A, 7, 0b10000000), AmpConfig("DAI1: I2S mode", 0b00100, 0x14, 2, 0b01111100), AmpConfig("DAI2: I2S mode", 0b00100, 0x1C, 2, 0b01111100), - AmpConfig("Right speaker output volume", 0x1c, 0x3E, 0, 0b00011111), AmpConfig("DAI1 Passband filtering: music mode", 0b1, 0x18, 7, 0b10000000), AmpConfig("DAI1 voice mode gain (DV1G)", 0b00, 0x2F, 4, 0b00110000), AmpConfig("DAI1 attenuation (DV1)", 0x0, 0x2F, 0, 0b00001111), @@ -41,7 +38,6 @@ BASE_CONFIG = [ AmpConfig("ALC/excursion limiter release time", 0b101, 0x43, 4, 0b01110000), AmpConfig("ALC multiband enable", 0b1, 0x43, 3, 0b00001000), AmpConfig("DAI1 EQ enable", 0b0, 0x49, 0, 0b00000001), - AmpConfig("DAI2 EQ enable", 0b1, 0x49, 1, 0b00000010), AmpConfig("DAI2 EQ clip detection disabled", 0b1, 0x32, 4, 0b00010000), AmpConfig("DAI2 EQ attenuation", 0x5, 0x32, 0, 0b00001111), AmpConfig("Excursion limiter upper corner freq", 0b100, 0x41, 4, 0b01110000), @@ -64,6 +60,11 @@ BASE_CONFIG = [ CONFIGS = { "tici": [ + AmpConfig("Right speaker output from right DAC", 0b1, 0x2C, 0, 0b11111111), + AmpConfig("Right Speaker Mixer Gain", 0b00, 0x2D, 2, 0b00001100), + AmpConfig("Right speaker output volume", 0x1c, 0x3E, 0, 0b00011111), + AmpConfig("DAI2 EQ enable", 0b1, 0x49, 1, 0b00000010), + *configs_from_eq_params(0x84, EQParams(0x274F, 0xC0FF, 0x3BF9, 0x0B3C, 0x1656)), *configs_from_eq_params(0x8E, EQParams(0x1009, 0xC6BF, 0x2952, 0x1C97, 0x30DF)), *configs_from_eq_params(0x98, EQParams(0x0F75, 0xCBE5, 0x0ED2, 0x2528, 0x3E42)), @@ -72,11 +73,13 @@ CONFIGS = { ], "tizi": [ AmpConfig("Left speaker output from left DAC", 0b1, 0x2B, 0, 0b11111111), + AmpConfig("Right speaker output from right DAC", 0b1, 0x2C, 0, 0b11111111), AmpConfig("Left Speaker Mixer Gain", 0b00, 0x2D, 0, 0b00000011), - AmpConfig("Left speaker output volume", 0x1F, 0x3D, 0, 0b00011111), - AmpConfig("Right speaker output volume", 0x1F, 0x3E, 0, 0b00011111), - AmpConfig("DAI1 attenuation (DV1)", 0x4, 0x2F, 0, 0b00001111), - AmpConfig("DAI2 attenuation (DV2)", 0x4, 0x31, 0, 0b00001111), + AmpConfig("Right Speaker Mixer Gain", 0b00, 0x2D, 2, 0b00001100), + AmpConfig("Left speaker output volume", 0x17, 0x3D, 0, 0b00011111), + AmpConfig("Right speaker output volume", 0x17, 0x3E, 0, 0b00011111), + + AmpConfig("DAI2 EQ enable", 0b0, 0x49, 1, 0b00000010), AmpConfig("DAI2: DC blocking", 0b0, 0x20, 0, 0b00000001), AmpConfig("ALC enable", 0b0, 0x43, 7, 0b10000000), AmpConfig("DAI2 EQ attenuation", 0x2, 0x32, 0, 0b00001111), @@ -91,12 +94,6 @@ CONFIGS = { AmpConfig("Right DAC input mixer: DAI2 left", 0b0, 0x22, 1, 0b00000010), AmpConfig("Right DAC input mixer: DAI2 right", 0b1, 0x22, 0, 0b00000001), AmpConfig("Volume adjustment smoothing disabled", 0b1, 0x49, 6, 0b01000000), - - *configs_from_eq_params(0x84, EQParams(0x3084, 0xC023, 0x3D60, 0x042B, 0x1222)), - *configs_from_eq_params(0x8E, EQParams(0x2FB2, 0xC05C, 0x3BD3, 0x06C5, 0x16BB)), - *configs_from_eq_params(0x98, EQParams(0x21F5, 0xDF73, 0x2DFE, 0x371A, 0x2C80)), - *configs_from_eq_params(0xA2, EQParams(0x2A5A, 0x0AD0, 0x14FA, 0x3F14, 0x3C76)), - *configs_from_eq_params(0xAC, EQParams(0x1577, 0x3FAE, 0xEE60, 0x0664, 0x3D86)), ], } From 9b28897f09112ec1dc28d7196964588989029940 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Fri, 10 Mar 2023 05:13:29 +0800 Subject: [PATCH 088/102] replay: fix incorrect format string in seekTo (#27547) --- tools/replay/replay.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/replay/replay.cc b/tools/replay/replay.cc index 178b116a87..b68330f688 100644 --- a/tools/replay/replay.cc +++ b/tools/replay/replay.cc @@ -193,7 +193,7 @@ std::optional Replay::find(FindFlag flag) { void Replay::pause(bool pause) { updateEvents([=]() { - rWarning("%s at %d s", pause ? "paused..." : "resuming", currentSeconds()); + rWarning("%s at %.2f s", pause ? "paused..." : "resuming", currentSeconds()); paused_ = pause; return true; }); From b5d29b550c4b900d5e5e9dd9322a478e12ec9013 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Fri, 10 Mar 2023 05:13:46 +0800 Subject: [PATCH 089/102] cabana: get icon size from QStyle::PM_SmallIconSize (#27548) --- tools/cabana/util.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/cabana/util.cc b/tools/cabana/util.cc index 1a0b9d93ef..778ffbc859 100644 --- a/tools/cabana/util.cc +++ b/tools/cabana/util.cc @@ -170,6 +170,8 @@ QToolButton *toolButton(const QString &icon, const QString &tooltip) { btn->setIcon(utils::icon(icon)); btn->setToolTip(tooltip); btn->setAutoRaise(true); + const int metric = qApp->style()->pixelMetric(QStyle::PM_SmallIconSize); + btn->setIconSize({metric, metric}); return btn; }; From b79f4594c42b4af0fc371b5d48445ce86c1cb3ff Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Thu, 9 Mar 2023 22:14:06 +0100 Subject: [PATCH 090/102] cabana: scrub by shift dragging on graph (#27545) * cabana: scrub by shift dragging on graph * not while live streaming --- tools/cabana/chartswidget.cc | 26 ++++++++++++++++++++++++++ tools/cabana/chartswidget.h | 2 ++ 2 files changed, 28 insertions(+) diff --git a/tools/cabana/chartswidget.cc b/tools/cabana/chartswidget.cc index 54966be578..8ef2ae7b4f 100644 --- a/tools/cabana/chartswidget.cc +++ b/tools/cabana/chartswidget.cc @@ -668,6 +668,16 @@ void ChartView::mousePressEvent(QMouseEvent *event) { if (dropAction == Qt::MoveAction) { return; } + } else if (event->button() == Qt::LeftButton && QApplication::keyboardModifiers().testFlag(Qt::ShiftModifier)) { + if (!can->liveStreaming()) { + // Save current playback state when scrubbing + resume_after_scrub = !can->isPaused(); + if (resume_after_scrub) { + can->pause(true); + } + + is_scrubbing = true; + } } else { QChartView::mousePressEvent(event); } @@ -701,9 +711,25 @@ void ChartView::mouseReleaseEvent(QMouseEvent *event) { } else { QGraphicsView::mouseReleaseEvent(event); } + + // Resume playback if we were scrubbing + is_scrubbing = false; + if (resume_after_scrub) { + can->pause(false); + resume_after_scrub = false; + } } void ChartView::mouseMoveEvent(QMouseEvent *ev) { + // Scrubbing + if (is_scrubbing && QApplication::keyboardModifiers().testFlag(Qt::ShiftModifier)) { + double t = chart()->mapToValue({(double)ev->x(), (double)ev->y()}).x(); + // Prevent seeking past the end of the route + t = std::clamp(t, 0., can->totalSeconds()); + can->seekTo(t); + return; + } + auto rubber = findChild(); bool is_zooming = rubber && rubber->isVisible(); const auto plot_area = chart()->plotArea(); diff --git a/tools/cabana/chartswidget.h b/tools/cabana/chartswidget.h index c86c19a04e..22ba020b29 100644 --- a/tools/cabana/chartswidget.h +++ b/tools/cabana/chartswidget.h @@ -97,6 +97,8 @@ private: double cur_sec = 0; const QString mime_type = "application/x-cabanachartview"; SeriesType series_type = SeriesType::Line; + bool is_scrubbing = false; + bool resume_after_scrub = false; friend class ChartsWidget; }; From 5b3a72267c628785859e673eaecc2787e02f1220 Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Thu, 9 Mar 2023 22:14:21 +0100 Subject: [PATCH 091/102] cabana: fix changing message size (#27544) * cabana: fix changing message size * fix naming signal untitled --- tools/cabana/detailwidget.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/cabana/detailwidget.cc b/tools/cabana/detailwidget.cc index 01fbccf7db..71dbf8d56b 100644 --- a/tools/cabana/detailwidget.cc +++ b/tools/cabana/detailwidget.cc @@ -194,7 +194,7 @@ EditMessageDialog::EditMessageDialog(const MessageId &msg_id, const QString &tit form_layout->addRow(tr("Size"), size_spin); btn_box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - btn_box->button(QDialogButtonBox::Ok)->setEnabled(false); + validateName(name_edit->text()); form_layout->addRow(btn_box); setFixedWidth(parent->width() * 0.9); @@ -204,9 +204,9 @@ EditMessageDialog::EditMessageDialog(const MessageId &msg_id, const QString &tit } void EditMessageDialog::validateName(const QString &text) { - bool valid = false; + bool valid = text.compare(UNTITLED, Qt::CaseInsensitive) != 0; error_label->setVisible(false); - if (!text.isEmpty() && text != original_name && text.compare(UNTITLED, Qt::CaseInsensitive) != 0) { + if (!text.isEmpty() && valid && text != original_name) { valid = std::none_of(dbc()->messages().begin(), dbc()->messages().end(), [&text](auto &m) { return m.second.name == text; }); if (!valid) { From 572eba78a675836e036456afc6e1bb2f14e9a3d6 Mon Sep 17 00:00:00 2001 From: AlexandreSato <66435071+AlexandreSato@users.noreply.github.com> Date: Thu, 9 Mar 2023 22:17:22 -0300 Subject: [PATCH 092/102] Multilanguage: update pt-BR translations (#27546) update pt-BR translations --- selfdrive/ui/translations/main_pt-BR.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/selfdrive/ui/translations/main_pt-BR.ts b/selfdrive/ui/translations/main_pt-BR.ts index 5c4eab3327..8dc3a9830d 100644 --- a/selfdrive/ui/translations/main_pt-BR.ts +++ b/selfdrive/ui/translations/main_pt-BR.ts @@ -596,16 +596,17 @@ trabalho definido Unable to mount data partition. Partition may be corrupted. Press confirm to erase and reset your device. - + Não é possível montar a partição de dados. Partição corrompida. Confirme para apagar e redefinir o dispositivo. Press confirm to erase all content and settings. Press cancel to resume boot. - + Pressione confirmar para apagar todo o conteúdo e configurações. Pressione cancelar para voltar. Resetting device... This may take up to a minute. - + Redefinindo o dispositivo +Isso pode levar até um minuto. @@ -707,11 +708,11 @@ This may take up to a minute. No custom software found at this URL. - + Não há software personalizado nesta URL. Something went wrong. Reboot the device. - + Algo deu errado. Reinicie o dispositivo. From 7d32554fe36dd428efa45f9998b3cb0e018d9a40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harald=20Sch=C3=A4fer?= Date: Thu, 9 Mar 2023 18:48:32 -0800 Subject: [PATCH 093/102] Parse GLONASS ephemeris from mystery satellites (#27541) parse unknown glonass --- system/ubloxd/ublox_msg.cc | 62 ++++++++++++++++++++++++++------------ system/ubloxd/ublox_msg.h | 6 ++-- system/ubloxd/ubloxd.cc | 3 +- 3 files changed, 48 insertions(+), 23 deletions(-) diff --git a/system/ubloxd/ublox_msg.cc b/system/ubloxd/ublox_msg.cc index ebd904f72f..83e64b7ddc 100644 --- a/system/ubloxd/ublox_msg.cc +++ b/system/ubloxd/ublox_msg.cc @@ -81,7 +81,8 @@ inline uint16_t UbloxMsgParser::get_glonass_year(uint8_t N4, uint16_t Nt) { return year; } -bool UbloxMsgParser::add_data(const uint8_t *incoming_data, uint32_t incoming_data_len, size_t &bytes_consumed) { +bool UbloxMsgParser::add_data(float log_time, const uint8_t *incoming_data, uint32_t incoming_data_len, size_t &bytes_consumed) { + last_log_time = log_time; int needed = needed_bytes(); if(needed > 0) { bytes_consumed = std::min((uint32_t)needed, incoming_data_len ); @@ -266,12 +267,8 @@ kj::Array UbloxMsgParser::parse_gps_ephemeris(ubx_t::rxm_sfrbx_t *m } kj::Array UbloxMsgParser::parse_glonass_ephemeris(ubx_t::rxm_sfrbx_t *msg) { - if (msg->sv_id() == 255) { - // data can be decoded before identifying the SV number, in this case 255 - // is returned, which means "unknown" (ublox p32) - return kj::Array(); - } - + // This parser assumes that no 2 satellites of the same frequency + // can be in view at the same time auto body = *msg->body(); assert(body.size() == 4); { @@ -284,23 +281,48 @@ kj::Array UbloxMsgParser::parse_glonass_ephemeris(ubx_t::rxm_sfrbx_ kaitai::kstream stream(string_data); glonass_t gl_string(&stream); - int string_number = gl_string.string_number(); if (string_number < 1 || string_number > 5 || gl_string.idle_chip()) { // dont parse non immediate data, idle_chip == 0 return kj::Array(); } - // immediate data is the same within one superframe - if (glonass_superframes[msg->sv_id()] != gl_string.superframe_number()) { - glonass_strings[msg->sv_id()].clear(); - glonass_superframes[msg->sv_id()] = gl_string.superframe_number(); + // Check if new string either has same superframe_id or log transmission times make sense + bool superframe_unknown = false; + bool needs_clear = false; + for (int i = 1; i <= 5; i++) { + if (glonass_strings[msg->freq_id()].find(i) == glonass_strings[msg->freq_id()].end()) + continue; + if (glonass_string_superframes[msg->freq_id()][i] == 0 || gl_string.superframe_number() == 0) { + superframe_unknown = true; + } + else if (glonass_string_superframes[msg->freq_id()][i] != gl_string.superframe_number()) { + needs_clear = true; + } + // Check if string times add up to being from the same frame + // If superframe is known this is redundant + // Strings are sent 2s apart and frames are 30s apart + if (superframe_unknown && + std::abs((glonass_string_times[msg->freq_id()][i] - 2.0 * i) - (last_log_time - 2.0 * string_number)) > 10) + needs_clear = true; } - glonass_strings[msg->sv_id()][string_number] = string_data; + if (needs_clear) { + glonass_strings[msg->freq_id()].clear(); + glonass_string_superframes[msg->freq_id()].clear(); + glonass_string_times[msg->freq_id()].clear(); + } + glonass_strings[msg->freq_id()][string_number] = string_data; + glonass_string_superframes[msg->freq_id()][string_number] = gl_string.superframe_number(); + glonass_string_times[msg->freq_id()][string_number] = last_log_time; + } + if (msg->sv_id() == 255) { + // data can be decoded before identifying the SV number, in this case 255 + // is returned, which means "unknown" (ublox p32) + return kj::Array(); } // publish if strings 1-5 have been collected - if (glonass_strings[msg->sv_id()].size() != 5) { + if (glonass_strings[msg->freq_id()].size() != 5) { return kj::Array(); } @@ -311,7 +333,7 @@ kj::Array UbloxMsgParser::parse_glonass_ephemeris(ubx_t::rxm_sfrbx_ // string number 1 { - kaitai::kstream stream(glonass_strings[msg->sv_id()][1]); + kaitai::kstream stream(glonass_strings[msg->freq_id()][1]); glonass_t gl_stream(&stream); glonass_t::string_1_t* data = static_cast(gl_stream.data()); @@ -324,7 +346,7 @@ kj::Array UbloxMsgParser::parse_glonass_ephemeris(ubx_t::rxm_sfrbx_ // string number 2 { - kaitai::kstream stream(glonass_strings[msg->sv_id()][2]); + kaitai::kstream stream(glonass_strings[msg->freq_id()][2]); glonass_t gl_stream(&stream); glonass_t::string_2_t* data = static_cast(gl_stream.data()); @@ -338,7 +360,7 @@ kj::Array UbloxMsgParser::parse_glonass_ephemeris(ubx_t::rxm_sfrbx_ // string number 3 { - kaitai::kstream stream(glonass_strings[msg->sv_id()][3]); + kaitai::kstream stream(glonass_strings[msg->freq_id()][3]); glonass_t gl_stream(&stream); glonass_t::string_3_t* data = static_cast(gl_stream.data()); @@ -352,7 +374,7 @@ kj::Array UbloxMsgParser::parse_glonass_ephemeris(ubx_t::rxm_sfrbx_ // string number 4 { - kaitai::kstream stream(glonass_strings[msg->sv_id()][4]); + kaitai::kstream stream(glonass_strings[msg->freq_id()][4]); glonass_t gl_stream(&stream); glonass_t::string_4_t* data = static_cast(gl_stream.data()); @@ -370,7 +392,7 @@ kj::Array UbloxMsgParser::parse_glonass_ephemeris(ubx_t::rxm_sfrbx_ // string number 5 { - kaitai::kstream stream(glonass_strings[msg->sv_id()][5]); + kaitai::kstream stream(glonass_strings[msg->freq_id()][5]); glonass_t gl_stream(&stream); glonass_t::string_5_t* data = static_cast(gl_stream.data()); @@ -399,7 +421,7 @@ kj::Array UbloxMsgParser::parse_glonass_ephemeris(ubx_t::rxm_sfrbx_ eph.setSecond((eph.getTk() & 0x1) * 30); } - glonass_strings[msg->sv_id()].clear(); + glonass_strings[msg->freq_id()].clear(); return capnp::messageToFlatArray(msg_builder); } diff --git a/system/ubloxd/ublox_msg.h b/system/ubloxd/ublox_msg.h index 3989bbf85b..06877cc50d 100644 --- a/system/ubloxd/ublox_msg.h +++ b/system/ubloxd/ublox_msg.h @@ -86,7 +86,7 @@ namespace ublox { class UbloxMsgParser { public: - bool add_data(const uint8_t *incoming_data, uint32_t incoming_data_len, size_t &bytes_consumed); + bool add_data(float log_time, const uint8_t *incoming_data, uint32_t incoming_data_len, size_t &bytes_consumed); inline void reset() {bytes_in_parse_buf = 0;} inline int needed_bytes(); inline std::string data() {return std::string((const char*)msg_parse_buf, bytes_in_parse_buf);} @@ -109,6 +109,7 @@ class UbloxMsgParser { std::unordered_map> gps_subframes; + float last_log_time = 0.0; size_t bytes_in_parse_buf = 0; uint8_t msg_parse_buf[ublox::UBLOX_HEADER_SIZE + ublox::UBLOX_MAX_MSG_SIZE]; @@ -119,5 +120,6 @@ class UbloxMsgParser { {11, 64}, {12, 128}, {13, 256}, {14, 512}, {15, 1024}}; std::unordered_map> glonass_strings; - std::unordered_map glonass_superframes; + std::unordered_map> glonass_string_times; + std::unordered_map> glonass_string_superframes; }; diff --git a/system/ubloxd/ubloxd.cc b/system/ubloxd/ubloxd.cc index 81731ac931..1dae6dc866 100644 --- a/system/ubloxd/ubloxd.cc +++ b/system/ubloxd/ubloxd.cc @@ -35,6 +35,7 @@ int main() { capnp::FlatArrayMessageReader cmsg(aligned_buf.align(msg.get())); cereal::Event::Reader event = cmsg.getRoot(); auto ubloxRaw = event.getUbloxRaw(); + float log_time = 1e-9 * event.getLogMonoTime(); const uint8_t *data = ubloxRaw.begin(); size_t len = ubloxRaw.size(); @@ -42,7 +43,7 @@ int main() { while(bytes_consumed < len && !do_exit) { size_t bytes_consumed_this_time = 0U; - if(parser.add_data(data + bytes_consumed, (uint32_t)(len - bytes_consumed), bytes_consumed_this_time)) { + if(parser.add_data(log_time, data + bytes_consumed, (uint32_t)(len - bytes_consumed), bytes_consumed_this_time)) { try { auto ublox_msg = parser.gen_msg(); From e4d591ecbfaaf12b267e3f93927a89e9b4f6a7b9 Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Fri, 10 Mar 2023 20:19:37 +0100 Subject: [PATCH 094/102] cabana: refactor Msg and Signal into dbc.cc (#27552) --- tools/cabana/SConscript | 2 +- tools/cabana/binaryview.cc | 16 +-- tools/cabana/binaryview.h | 23 ++-- tools/cabana/chartswidget.cc | 14 +-- tools/cabana/chartswidget.h | 31 +++-- tools/cabana/commands.cc | 6 +- tools/cabana/commands.h | 17 ++- tools/cabana/dbc.cc | 77 ++++++++++++ tools/cabana/dbc.h | 78 ++++++++++++ tools/cabana/dbcmanager.cc | 168 +++++++------------------- tools/cabana/dbcmanager.h | 90 ++------------ tools/cabana/detailwidget.cc | 2 +- tools/cabana/historylog.h | 4 +- tools/cabana/mainwin.cc | 2 +- tools/cabana/messageswidget.h | 1 - tools/cabana/signaledit.cc | 28 ++--- tools/cabana/signaledit.h | 26 ++-- tools/cabana/tests/test_cabana.cc | 1 - tools/cabana/tools/findsimilarbits.cc | 1 - tools/cabana/tools/findsimilarbits.h | 1 - tools/cabana/util.cc | 2 +- tools/cabana/util.h | 5 +- tools/cabana/videowidget.h | 1 - 23 files changed, 295 insertions(+), 301 deletions(-) create mode 100644 tools/cabana/dbc.cc create mode 100644 tools/cabana/dbc.h diff --git a/tools/cabana/SConscript b/tools/cabana/SConscript index ddd6208c07..3cb5913c01 100644 --- a/tools/cabana/SConscript +++ b/tools/cabana/SConscript @@ -28,7 +28,7 @@ cabana_env.Depends(assets, Glob('/assets/*', exclude=[assets, assets_src, "asset prev_moc_path = cabana_env['QT_MOCHPREFIX'] 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', 'signaledit.cc', 'dbcmanager.cc', +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', 'signaledit.cc', 'dbc.cc', '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) diff --git a/tools/cabana/binaryview.cc b/tools/cabana/binaryview.cc index 120a85a330..b81f7d5e79 100644 --- a/tools/cabana/binaryview.cc +++ b/tools/cabana/binaryview.cc @@ -75,8 +75,8 @@ void BinaryView::addShortcuts() { QShortcut *shortcut_endian = new QShortcut(QKeySequence(Qt::Key_E), this); QObject::connect(shortcut_endian, &QShortcut::activated, [=]{ if (hovered_sig != nullptr) { - const Signal *hovered_sig_prev = hovered_sig; - Signal s = *hovered_sig; + const cabana::Signal *hovered_sig_prev = hovered_sig; + cabana::Signal s = *hovered_sig; s.is_little_endian = !s.is_little_endian; emit editSignal(hovered_sig, s); @@ -89,8 +89,8 @@ void BinaryView::addShortcuts() { QShortcut *shortcut_sign = new QShortcut(QKeySequence(Qt::Key_S), this); QObject::connect(shortcut_sign, &QShortcut::activated, [=]{ if (hovered_sig != nullptr) { - const Signal *hovered_sig_prev = hovered_sig; - Signal s = *hovered_sig; + const cabana::Signal *hovered_sig_prev = hovered_sig; + cabana::Signal s = *hovered_sig; s.is_signed = !s.is_signed; emit editSignal(hovered_sig, s); @@ -117,7 +117,7 @@ QSize BinaryView::minimumSizeHint() const { CELL_HEIGHT * std::min(model->rowCount(), 10) + 2}; } -void BinaryView::highlight(const Signal *sig) { +void BinaryView::highlight(const cabana::Signal *sig) { if (sig != hovered_sig) { for (int i = 0; i < model->items.size(); ++i) { auto &item_sigs = model->items[i].sigs; @@ -176,7 +176,7 @@ void BinaryView::mousePressEvent(QMouseEvent *event) { void BinaryView::highlightPosition(const QPoint &pos) { if (auto index = indexAt(viewport()->mapFromGlobal(pos)); index.isValid()) { auto item = (BinaryViewModel::Item *)index.internalPointer(); - const Signal *sig = item->sigs.isEmpty() ? nullptr : item->sigs.back(); + const cabana::Signal *sig = item->sigs.isEmpty() ? nullptr : item->sigs.back(); highlight(sig); } } @@ -226,8 +226,8 @@ void BinaryView::refresh() { highlightPosition(QCursor::pos()); } -QSet BinaryView::getOverlappingSignals() const { - QSet overlapping; +QSet BinaryView::getOverlappingSignals() const { + QSet overlapping; for (auto &item : model->items) { if (item.sigs.size() > 1) for (auto s : item.sigs) overlapping += s; diff --git a/tools/cabana/binaryview.h b/tools/cabana/binaryview.h index 681ac1fbf3..f677d11941 100644 --- a/tools/cabana/binaryview.h +++ b/tools/cabana/binaryview.h @@ -8,7 +8,6 @@ #include "tools/cabana/dbcmanager.h" #include "tools/cabana/streams/abstractstream.h" -using namespace dbcmanager; class BinaryItemDelegate : public QStyledItemDelegate { public: @@ -44,7 +43,7 @@ public: bool is_msb = false; bool is_lsb = false; QString val = "-"; - QList sigs; + QList sigs; }; std::vector items; @@ -59,19 +58,19 @@ class BinaryView : public QTableView { public: BinaryView(QWidget *parent = nullptr); void setMessage(const MessageId &message_id); - void highlight(const Signal *sig); - QSet getOverlappingSignals() const; + void highlight(const cabana::Signal *sig); + QSet getOverlappingSignals() const; inline void updateState() { model->updateState(); } QSize minimumSizeHint() const override; signals: - void signalClicked(const Signal *sig); - void signalHovered(const Signal *sig); + void signalClicked(const cabana::Signal *sig); + void signalHovered(const cabana::Signal *sig); void addSignal(int start_bit, int size, bool little_endian); - void resizeSignal(const Signal *sig, int from, int size); - void removeSignal(const Signal *sig); - void editSignal(const Signal *origin_s, Signal &s); - void showChart(const MessageId &id, const Signal *sig, bool show, bool merge); + void resizeSignal(const cabana::Signal *sig, int from, int size); + void removeSignal(const cabana::Signal *sig); + void editSignal(const cabana::Signal *origin_s, cabana::Signal &s); + void showChart(const MessageId &id, const cabana::Signal *sig, bool show, bool merge); private: void addShortcuts(); @@ -87,7 +86,7 @@ private: QModelIndex anchor_index; BinaryViewModel *model; BinaryItemDelegate *delegate; - const Signal *resize_sig = nullptr; - const Signal *hovered_sig = nullptr; + const cabana::Signal *resize_sig = nullptr; + const cabana::Signal *hovered_sig = nullptr; friend class BinaryItemDelegate; }; diff --git a/tools/cabana/chartswidget.cc b/tools/cabana/chartswidget.cc index 8ef2ae7b4f..5bab261ba7 100644 --- a/tools/cabana/chartswidget.cc +++ b/tools/cabana/chartswidget.cc @@ -189,7 +189,7 @@ void ChartsWidget::settingChanged() { } } -ChartView *ChartsWidget::findChart(const MessageId &id, const Signal *sig) { +ChartView *ChartsWidget::findChart(const MessageId &id, const cabana::Signal *sig) { for (auto c : charts) if (c->hasSeries(id, sig)) return c; return nullptr; @@ -212,7 +212,7 @@ ChartView *ChartsWidget::createChart() { return chart; } -void ChartsWidget::showChart(const MessageId &id, const Signal *sig, bool show, bool merge) { +void ChartsWidget::showChart(const MessageId &id, const cabana::Signal *sig, bool show, bool merge) { ChartView *chart = findChart(id, sig); if (show && !chart) { chart = merge && charts.size() > 0 ? charts.back() : createChart(); @@ -377,7 +377,7 @@ void ChartView::createToolButtons() { }); } -void ChartView::addSeries(const MessageId &msg_id, const Signal *sig) { +void ChartView::addSeries(const MessageId &msg_id, const cabana::Signal *sig) { if (hasSeries(msg_id, sig)) return; QXYSeries *series = createSeries(series_type, getColor(sig)); @@ -388,7 +388,7 @@ void ChartView::addSeries(const MessageId &msg_id, const Signal *sig) { emit seriesAdded(msg_id, sig); } -bool ChartView::hasSeries(const MessageId &msg_id, const Signal *sig) const { +bool ChartView::hasSeries(const MessageId &msg_id, const cabana::Signal *sig) const { return std::any_of(sigs.begin(), sigs.end(), [&](auto &s) { return s.msg_id == msg_id && s.sig == sig; }); } @@ -413,7 +413,7 @@ void ChartView::removeIf(std::function predicate) { } } -void ChartView::signalUpdated(const Signal *sig) { +void ChartView::signalUpdated(const cabana::Signal *sig) { if (std::any_of(sigs.begin(), sigs.end(), [=](auto &s) { return s.sig == sig; })) { updateTitle(); // TODO: don't update series if only name changed. @@ -502,7 +502,7 @@ void ChartView::updateSeriesPoints() { } } -void ChartView::updateSeries(const Signal *sig, const std::vector *events, bool clear) { +void ChartView::updateSeries(const cabana::Signal *sig, const std::vector *events, bool clear) { events = events ? events : can->events(); for (auto &s : sigs) { if (!sig || s.sig == sig) { @@ -980,7 +980,7 @@ void SeriesSelector::updateAvailableList(int index) { } } -void SeriesSelector::addItemToList(QListWidget *parent, const MessageId id, const Signal *sig, bool show_msg_name) { +void SeriesSelector::addItemToList(QListWidget *parent, const MessageId id, const cabana::Signal *sig, bool show_msg_name) { QString text = QString(" %1").arg(getColor(sig).name(), sig->name); if (show_msg_name) text += QString(" %0 %1").arg(msgName(id), id.toString()); diff --git a/tools/cabana/chartswidget.h b/tools/cabana/chartswidget.h index 22ba020b29..fdfbbc11ff 100644 --- a/tools/cabana/chartswidget.h +++ b/tools/cabana/chartswidget.h @@ -15,7 +15,6 @@ #include "tools/cabana/dbcmanager.h" #include "tools/cabana/streams/abstractstream.h" -using namespace dbcmanager; using namespace QtCharts; const int CHART_MIN_WIDTH = 300; @@ -31,16 +30,16 @@ class ChartView : public QChartView { public: ChartView(QWidget *parent = nullptr); - void addSeries(const MessageId &msg_id, const Signal *sig); - bool hasSeries(const MessageId &msg_id, const Signal *sig) const; - void updateSeries(const Signal *sig = nullptr, const std::vector *events = nullptr, bool clear = true); + void addSeries(const MessageId &msg_id, const cabana::Signal *sig); + bool hasSeries(const MessageId &msg_id, const cabana::Signal *sig) const; + void updateSeries(const cabana::Signal *sig = nullptr, const std::vector *events = nullptr, bool clear = true); void updatePlot(double cur, double min, double max); void setSeriesType(SeriesType type); void updatePlotArea(int left); struct SigItem { MessageId msg_id; - const Signal *sig = nullptr; + const cabana::Signal *sig = nullptr; QXYSeries *series = nullptr; QVector vals; QVector step_vals; @@ -50,8 +49,8 @@ public: }; signals: - void seriesRemoved(const MessageId &id, const Signal *sig); - void seriesAdded(const MessageId &id, const Signal *sig); + void seriesRemoved(const MessageId &id, const cabana::Signal *sig); + void seriesAdded(const MessageId &id, const cabana::Signal *sig); void zoomIn(double min, double max); void zoomReset(); void remove(); @@ -59,11 +58,11 @@ signals: private slots: void msgUpdated(uint32_t address); - void signalUpdated(const Signal *sig); + void signalUpdated(const cabana::Signal *sig); void manageSeries(); void handleMarkerClicked(); void msgRemoved(uint32_t address) { removeIf([=](auto &s) { return s.msg_id.address == address; }); } - void signalRemoved(const Signal *sig) { removeIf([=](auto &s) { return s.sig == sig; }); } + void signalRemoved(const cabana::Signal *sig) { removeIf([=](auto &s) { return s.sig == sig; }); } private: void createToolButtons(); @@ -107,8 +106,8 @@ class ChartsWidget : public QFrame { public: ChartsWidget(QWidget *parent = nullptr); - void showChart(const MessageId &id, const Signal *sig, bool show, bool merge); - inline bool hasSignal(const MessageId &id, const Signal *sig) { return findChart(id, sig) != nullptr; } + void showChart(const MessageId &id, const cabana::Signal *sig, bool show, bool merge); + inline bool hasSignal(const MessageId &id, const cabana::Signal *sig) { return findChart(id, sig) != nullptr; } public slots: void setColumnCount(int n); @@ -134,7 +133,7 @@ private: void updateLayout(); void settingChanged(); bool eventFilter(QObject *obj, QEvent *event) override; - ChartView *findChart(const MessageId &id, const Signal *sig); + ChartView *findChart(const MessageId &id, const cabana::Signal *sig); QLabel *title_label; QLabel *range_lb; @@ -160,18 +159,18 @@ private: class SeriesSelector : public QDialog { public: struct ListItem : public QListWidgetItem { - ListItem(const MessageId &msg_id, const Signal *sig, QListWidget *parent) : msg_id(msg_id), sig(sig), QListWidgetItem(parent) {} + ListItem(const MessageId &msg_id, const cabana::Signal *sig, QListWidget *parent) : msg_id(msg_id), sig(sig), QListWidgetItem(parent) {} MessageId msg_id; - const Signal *sig; + const cabana::Signal *sig; }; SeriesSelector(QString title, QWidget *parent); QList seletedItems(); - inline void addSelected(const MessageId &id, const Signal *sig) { addItemToList(selected_list, id, sig, true); } + inline void addSelected(const MessageId &id, const cabana::Signal *sig) { addItemToList(selected_list, id, sig, true); } private: void updateAvailableList(int index); - void addItemToList(QListWidget *parent, const MessageId id, const Signal *sig, bool show_msg_name = false); + void addItemToList(QListWidget *parent, const MessageId id, const cabana::Signal *sig, bool show_msg_name = false); void add(QListWidgetItem *item); void remove(QListWidgetItem *item); diff --git a/tools/cabana/commands.cc b/tools/cabana/commands.cc index 9b9724aada..337de1c702 100644 --- a/tools/cabana/commands.cc +++ b/tools/cabana/commands.cc @@ -50,7 +50,7 @@ void RemoveMsgCommand::redo() { // AddSigCommand -AddSigCommand::AddSigCommand(const MessageId &id, const Signal &sig, QUndoCommand *parent) +AddSigCommand::AddSigCommand(const MessageId &id, const cabana::Signal &sig, QUndoCommand *parent) : id(id), signal(sig), QUndoCommand(parent) { setText(QObject::tr("add signal %1 to %2:%3").arg(sig.name).arg(msgName(id)).arg(id.address)); } @@ -60,7 +60,7 @@ void AddSigCommand::redo() { dbc()->addSignal(id, signal); } // RemoveSigCommand -RemoveSigCommand::RemoveSigCommand(const MessageId &id, const Signal *sig, QUndoCommand *parent) +RemoveSigCommand::RemoveSigCommand(const MessageId &id, const cabana::Signal *sig, QUndoCommand *parent) : id(id), signal(*sig), QUndoCommand(parent) { setText(QObject::tr("remove signal %1 from %2:%3").arg(signal.name).arg(msgName(id)).arg(id.address)); } @@ -70,7 +70,7 @@ void RemoveSigCommand::redo() { dbc()->removeSignal(id, signal.name); } // EditSignalCommand -EditSignalCommand::EditSignalCommand(const MessageId &id, const Signal *sig, const Signal &new_sig, QUndoCommand *parent) +EditSignalCommand::EditSignalCommand(const MessageId &id, const cabana::Signal *sig, const cabana::Signal &new_sig, QUndoCommand *parent) : id(id), old_signal(*sig), new_signal(new_sig), QUndoCommand(parent) { setText(QObject::tr("edit signal %1 in %2:%3").arg(old_signal.name).arg(msgName(id)).arg(id.address)); } diff --git a/tools/cabana/commands.h b/tools/cabana/commands.h index 3565211eb9..2a5f40d584 100644 --- a/tools/cabana/commands.h +++ b/tools/cabana/commands.h @@ -5,7 +5,6 @@ #include "tools/cabana/dbcmanager.h" #include "tools/cabana/streams/abstractstream.h" -using namespace dbcmanager; class EditMsgCommand : public QUndoCommand { public: @@ -27,41 +26,41 @@ public: private: const MessageId id; - Msg message; + cabana::Msg message; }; class AddSigCommand : public QUndoCommand { public: - AddSigCommand(const MessageId &id, const Signal &sig, QUndoCommand *parent = nullptr); + AddSigCommand(const MessageId &id, const cabana::Signal &sig, QUndoCommand *parent = nullptr); void undo() override; void redo() override; private: const MessageId id; - Signal signal = {}; + cabana::Signal signal = {}; }; class RemoveSigCommand : public QUndoCommand { public: - RemoveSigCommand(const MessageId &id, const Signal *sig, QUndoCommand *parent = nullptr); + RemoveSigCommand(const MessageId &id, const cabana::Signal *sig, QUndoCommand *parent = nullptr); void undo() override; void redo() override; private: const MessageId id; - Signal signal = {}; + cabana::Signal signal = {}; }; class EditSignalCommand : public QUndoCommand { public: - EditSignalCommand(const MessageId &id, const Signal *sig, const Signal &new_sig, QUndoCommand *parent = nullptr); + EditSignalCommand(const MessageId &id, const cabana::Signal *sig, const cabana::Signal &new_sig, QUndoCommand *parent = nullptr); void undo() override; void redo() override; private: const MessageId id; - Signal old_signal = {}; - Signal new_signal = {}; + cabana::Signal old_signal = {}; + cabana::Signal new_signal = {}; }; namespace UndoStack { diff --git a/tools/cabana/dbc.cc b/tools/cabana/dbc.cc new file mode 100644 index 0000000000..8ffb660286 --- /dev/null +++ b/tools/cabana/dbc.cc @@ -0,0 +1,77 @@ +#include "tools/cabana/dbc.h" + +uint qHash(const MessageId &item) { + return qHash(item.source) ^ qHash(item.address); +} + +std::vector cabana::Msg::getSignals() const { + std::vector ret; + ret.reserve(sigs.size()); + for (auto &sig : sigs) ret.push_back(&sig); + std::sort(ret.begin(), ret.end(), [](auto l, auto r) { return l->start_bit < r->start_bit; }); + return ret; +} + +// helper functions + +static QVector BIG_ENDIAN_START_BITS = []() { + QVector ret; + for (int i = 0; i < 64; i++) + for (int j = 7; j >= 0; j--) + ret.push_back(j + i * 8); + return ret; +}(); + +double get_raw_value(uint8_t *data, size_t data_size, const cabana::Signal &sig) { + int64_t val = 0; + + int i = sig.msb / 8; + int bits = sig.size; + while (i >= 0 && i < data_size && bits > 0) { + int lsb = (int)(sig.lsb / 8) == i ? sig.lsb : i * 8; + int msb = (int)(sig.msb / 8) == i ? sig.msb : (i + 1) * 8 - 1; + int size = msb - lsb + 1; + + uint64_t d = (data[i] >> (lsb - (i * 8))) & ((1ULL << size) - 1); + val |= d << (bits - size); + + bits -= size; + i = sig.is_little_endian ? i - 1 : i + 1; + } + if (sig.is_signed) { + val -= ((val >> (sig.size - 1)) & 0x1) ? (1ULL << sig.size) : 0; + } + return val * sig.factor + sig.offset; +} + +bool cabana::operator==(const cabana::Signal &l, const cabana::Signal &r) { + return l.name == r.name && l.size == r.size && + l.start_bit == r.start_bit && + l.msb == r.msb && l.lsb == r.lsb && + l.is_signed == r.is_signed && l.is_little_endian == r.is_little_endian && + l.factor == r.factor && l.offset == r.offset && + l.min == r.min && l.max == r.max && l.comment == r.comment && l.unit == r.unit && l.val_desc == r.val_desc; +} + +int bigEndianStartBitsIndex(int start_bit) { return BIG_ENDIAN_START_BITS[start_bit]; } +int bigEndianBitIndex(int index) { return BIG_ENDIAN_START_BITS.indexOf(index); } + +void updateSigSizeParamsFromRange(cabana::Signal &s, int start_bit, int size) { + s.start_bit = s.is_little_endian ? start_bit : bigEndianBitIndex(start_bit); + s.size = size; + if (s.is_little_endian) { + s.lsb = s.start_bit; + s.msb = s.start_bit + s.size - 1; + } else { + s.lsb = bigEndianStartBitsIndex(bigEndianBitIndex(s.start_bit) + s.size - 1); + s.msb = s.start_bit; + } +} + +std::pair getSignalRange(const cabana::Signal *s) { + int from = s->is_little_endian ? s->start_bit : bigEndianBitIndex(s->start_bit); + int to = from + s->size - 1; + return {from, to}; +} + +std::vector allDBCNames() { return get_dbc_names(); } diff --git a/tools/cabana/dbc.h b/tools/cabana/dbc.h new file mode 100644 index 0000000000..3c58e38055 --- /dev/null +++ b/tools/cabana/dbc.h @@ -0,0 +1,78 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include "opendbc/can/common_dbc.h" + +const QString UNTITLED = "untitled"; + +struct MessageId { + uint8_t source; + uint32_t address; + + QString toString() const { + return QString("%1:%2").arg(source).arg(address, 1, 16); + } + + bool operator==(const MessageId &other) const { + return source == other.source && address == other.address; + } + + bool operator!=(const MessageId &other) const { + return !(*this == other); + } + + bool operator<(const MessageId &other) const { + return std::pair{source, address} < std::pair{other.source, other.address}; + } + + bool operator>(const MessageId &other) const { + return std::pair{source, address} > std::pair{other.source, other.address}; + } +}; + +uint qHash(const MessageId &item); +Q_DECLARE_METATYPE(MessageId); + + +typedef QList> ValueDescription; + +namespace cabana { + struct Signal { + QString name; + int start_bit, msb, lsb, size; + bool is_signed; + double factor, offset; + bool is_little_endian; + QString min, max, unit; + QString comment; + ValueDescription val_desc; + }; + + struct Msg { + QString name; + uint32_t size; + QList sigs; + + std::vector getSignals() const; + const cabana::Signal *sig(const QString &sig_name) const { + auto it = std::find_if(sigs.begin(), sigs.end(), [&](auto &s) { return s.name == sig_name; }); + return it != sigs.end() ? &(*it) : nullptr; + } + }; + + bool operator==(const cabana::Signal &l, const cabana::Signal &r); + inline bool operator!=(const cabana::Signal &l, const cabana::Signal &r) { return !(l == r); } +} + +// Helper functions +double get_raw_value(uint8_t *data, size_t data_size, const cabana::Signal &sig); +int bigEndianStartBitsIndex(int start_bit); +int bigEndianBitIndex(int index); +void updateSigSizeParamsFromRange(cabana::Signal &s, int start_bit, int size); +std::pair getSignalRange(const cabana::Signal *s); +std::vector allDBCNames(); diff --git a/tools/cabana/dbcmanager.cc b/tools/cabana/dbcmanager.cc index 32113c2f22..e9ebcd2791 100644 --- a/tools/cabana/dbcmanager.cc +++ b/tools/cabana/dbcmanager.cc @@ -8,8 +8,6 @@ #include #include -namespace dbcmanager { - bool DBCManager::open(const QString &dbc_file_name, QString *error) { QString opendbc_file_path = QString("%1/%2.dbc").arg(OPENDBC_FILE_PATH, dbc_file_name); QFile file(opendbc_file_path); @@ -19,15 +17,49 @@ bool DBCManager::open(const QString &dbc_file_name, QString *error) { return false; } +bool DBCManager::open(const QString &name, const QString &content, QString *error) { + try { + std::istringstream stream(content.toStdString()); + auto dbc = const_cast(dbc_parse_from_stream(name.toStdString(), stream)); + msgs.clear(); + for (auto &msg : dbc->msgs) { + auto &m = msgs[msg.address]; + m.name = msg.name.c_str(); + m.size = msg.size; + for (auto &s : msg.sigs) { + m.sigs.push_back({}); + auto &sig = m.sigs.last(); + sig.name = s.name.c_str(); + sig.start_bit = s.start_bit; + sig.msb = s.msb; + sig.lsb = s.lsb; + sig.size = s.size; + sig.is_signed = s.is_signed; + sig.factor = s.factor; + sig.offset = s.offset; + sig.is_little_endian = s.is_little_endian; + } + } + parseExtraInfo(content); + name_ = name; + emit DBCFileChanged(); + delete dbc; + } catch (std::exception &e) { + if (error) *error = e.what(); + return false; + } + return true; +} + void DBCManager::parseExtraInfo(const QString &content) { static QRegularExpression bo_regexp(R"(^BO_ (\w+) (\w+) *: (\w+) (\w+))"); static QRegularExpression sg_regexp(R"(^SG_ (\w+) : (\d+)\|(\d+)@(\d+)([\+|\-]) \(([0-9.+\-eE]+),([0-9.+\-eE]+)\) \[([0-9.+\-eE]+)\|([0-9.+\-eE]+)\] \"(.*)\" (.*))"); static QRegularExpression sgm_regexp(R"(^SG_ (\w+) (\w+) *: (\d+)\|(\d+)@(\d+)([\+|\-]) \(([0-9.+\-eE]+),([0-9.+\-eE]+)\) \[([0-9.+\-eE]+)\|([0-9.+\-eE]+)\] \"(.*)\" (.*))"); static QRegularExpression sg_comment_regexp(R"(^CM_ SG_ *(\w+) *(\w+) *\"(.*)\";)"); static QRegularExpression val_regexp(R"(VAL_ (\w+) (\w+) (.*);)"); - auto get_sig = [this](uint32_t address, const QString &name) -> Signal * { - auto m = (Msg *)msg(address); - return m ? (Signal *)m->sig(name) : nullptr; + auto get_sig = [this](uint32_t address, const QString &name) -> cabana::Signal * { + auto m = (cabana::Msg *)msg(address); + return m ? (cabana::Signal *)m->sig(name) : nullptr; }; QTextStream stream((QString *)&content); @@ -119,17 +151,17 @@ void DBCManager::removeMsg(const MessageId &id) { emit msgRemoved(id.address); } -void DBCManager::addSignal(const MessageId &id, const Signal &sig) { - if (auto m = const_cast(msg(id.address))) { +void DBCManager::addSignal(const MessageId &id, const cabana::Signal &sig) { + if (auto m = const_cast(msg(id.address))) { m->sigs.push_back(sig); auto s = &m->sigs.last(); emit signalAdded(id.address, s); } } -void DBCManager::updateSignal(const MessageId &id, const QString &sig_name, const Signal &sig) { - if (auto m = const_cast(msg(id))) { - if (auto s = (Signal *)m->sig(sig_name)) { +void DBCManager::updateSignal(const MessageId &id, const QString &sig_name, const cabana::Signal &sig) { + if (auto m = const_cast(msg(id))) { + if (auto s = (cabana::Signal *)m->sig(sig_name)) { *s = sig; emit signalUpdated(s); } @@ -137,7 +169,7 @@ void DBCManager::updateSignal(const MessageId &id, const QString &sig_name, cons } void DBCManager::removeSignal(const MessageId &id, const QString &sig_name) { - if (auto m = const_cast(msg(id))) { + if (auto m = const_cast(msg(id))) { auto it = std::find_if(m->sigs.begin(), m->sigs.end(), [&](auto &s) { return s.name == sig_name; }); if (it != m->sigs.end()) { emit signalRemoved(&(*it)); @@ -151,117 +183,3 @@ DBCManager *dbc() { return &dbc_manager; } -// Msg - -std::vector Msg::getSignals() const { - std::vector ret; - ret.reserve(sigs.size()); - for (auto &sig : sigs) ret.push_back(&sig); - std::sort(ret.begin(), ret.end(), [](auto l, auto r) { return l->start_bit < r->start_bit; }); - return ret; -} - -// helper functions - -static QVector BIG_ENDIAN_START_BITS = []() { - QVector ret; - for (int i = 0; i < 64; i++) - for (int j = 7; j >= 0; j--) - ret.push_back(j + i * 8); - return ret; -}(); - -int bigEndianStartBitsIndex(int start_bit) { return BIG_ENDIAN_START_BITS[start_bit]; } -int bigEndianBitIndex(int index) { return BIG_ENDIAN_START_BITS.indexOf(index); } - -double get_raw_value(uint8_t *data, size_t data_size, const Signal &sig) { - int64_t val = 0; - - int i = sig.msb / 8; - int bits = sig.size; - while (i >= 0 && i < data_size && bits > 0) { - int lsb = (int)(sig.lsb / 8) == i ? sig.lsb : i * 8; - int msb = (int)(sig.msb / 8) == i ? sig.msb : (i + 1) * 8 - 1; - int size = msb - lsb + 1; - - uint64_t d = (data[i] >> (lsb - (i * 8))) & ((1ULL << size) - 1); - val |= d << (bits - size); - - bits -= size; - i = sig.is_little_endian ? i - 1 : i + 1; - } - if (sig.is_signed) { - val -= ((val >> (sig.size - 1)) & 0x1) ? (1ULL << sig.size) : 0; - } - return val * sig.factor + sig.offset; -} - -void updateSigSizeParamsFromRange(Signal &s, int start_bit, int size) { - s.start_bit = s.is_little_endian ? start_bit : bigEndianBitIndex(start_bit); - s.size = size; - if (s.is_little_endian) { - s.lsb = s.start_bit; - s.msb = s.start_bit + s.size - 1; - } else { - s.lsb = bigEndianStartBitsIndex(bigEndianBitIndex(s.start_bit) + s.size - 1); - s.msb = s.start_bit; - } -} - -std::pair getSignalRange(const Signal *s) { - int from = s->is_little_endian ? s->start_bit : bigEndianBitIndex(s->start_bit); - int to = from + s->size - 1; - return {from, to}; -} - -bool operator==(const Signal &l, const Signal &r) { - return l.name == r.name && l.size == r.size && - l.start_bit == r.start_bit && - l.msb == r.msb && l.lsb == r.lsb && - l.is_signed == r.is_signed && l.is_little_endian == r.is_little_endian && - l.factor == r.factor && l.offset == r.offset && - l.min == r.min && l.max == r.max && l.comment == r.comment && l.unit == r.unit && l.val_desc == r.val_desc; -} - -} // namespace dbcmanager - -#include "opendbc/can/common_dbc.h" -std::vector dbcmanager::DBCManager::allDBCNames() { return get_dbc_names(); } - -bool dbcmanager::DBCManager::open(const QString &name, const QString &content, QString *error) { - try { - std::istringstream stream(content.toStdString()); - auto dbc = const_cast(dbc_parse_from_stream(name.toStdString(), stream)); - msgs.clear(); - for (auto &msg : dbc->msgs) { - auto &m = msgs[msg.address]; - m.name = msg.name.c_str(); - m.size = msg.size; - for (auto &s : msg.sigs) { - m.sigs.push_back({}); - auto &sig = m.sigs.last(); - sig.name = s.name.c_str(); - sig.start_bit = s.start_bit; - sig.msb = s.msb; - sig.lsb = s.lsb; - sig.size = s.size; - sig.is_signed = s.is_signed; - sig.factor = s.factor; - sig.offset = s.offset; - sig.is_little_endian = s.is_little_endian; - } - } - parseExtraInfo(content); - name_ = name; - emit DBCFileChanged(); - delete dbc; - } catch (std::exception &e) { - if (error) *error = e.what(); - return false; - } - return true; -} - -uint qHash(const MessageId &item) { - return qHash(item.source) ^ qHash(item.address); -} diff --git a/tools/cabana/dbcmanager.h b/tools/cabana/dbcmanager.h index d877347796..3b222b1dcb 100644 --- a/tools/cabana/dbcmanager.h +++ b/tools/cabana/dbcmanager.h @@ -6,63 +6,7 @@ #include #include -struct MessageId { - uint8_t source; - uint32_t address; - - QString toString() const { - return QString("%1:%2").arg(source).arg(address, 1, 16); - } - - bool operator==(const MessageId &other) const { - return source == other.source && address == other.address; - } - - bool operator!=(const MessageId &other) const { - return !(*this == other); - } - - bool operator<(const MessageId &other) const { - return std::pair{source, address} < std::pair{other.source, other.address}; - } - - bool operator>(const MessageId &other) const { - return std::pair{source, address} > std::pair{other.source, other.address}; - } -}; - -uint qHash(const MessageId &item); -Q_DECLARE_METATYPE(MessageId); - -namespace dbcmanager { - -typedef QList> ValueDescription; - -struct Signal { - QString name; - int start_bit, msb, lsb, size; - bool is_signed; - double factor, offset; - bool is_little_endian; - QString min, max, unit; - QString comment; - ValueDescription val_desc; -}; - -struct Msg { - QString name; - uint32_t size; - - std::vector getSignals() const; - const Signal *sig(const QString &sig_name) const { - auto it = std::find_if(sigs.begin(), sigs.end(), [&](auto &s) { return s.name == sig_name; }); - return it != sigs.end() ? &(*it) : nullptr; - } - -private: - QList sigs; - friend class DBCManager; -}; +#include "tools/cabana/dbc.h" class DBCManager : public QObject { Q_OBJECT @@ -73,49 +17,37 @@ public: bool open(const QString &dbc_file_name, QString *error = nullptr); bool open(const QString &name, const QString &content, QString *error = nullptr); QString generateDBC(); - void addSignal(const MessageId &id, const Signal &sig); - void updateSignal(const MessageId &id, const QString &sig_name, const Signal &sig); + void addSignal(const MessageId &id, const cabana::Signal &sig); + void updateSignal(const MessageId &id, const QString &sig_name, const cabana::Signal &sig); void removeSignal(const MessageId &id, const QString &sig_name); - static std::vector allDBCNames(); inline QString name() const { return name_; } void updateMsg(const MessageId &id, const QString &name, uint32_t size); void removeMsg(const MessageId &id); - inline const std::map &messages() const { return msgs; } - inline const Msg *msg(const MessageId &id) const { return msg(id.address); } - inline const Msg *msg(uint32_t address) const { + inline const std::map &messages() const { return msgs; } + inline const cabana::Msg *msg(const MessageId &id) const { return msg(id.address); } + inline const cabana::Msg *msg(uint32_t address) const { auto it = msgs.find(address); return it != msgs.end() ? &it->second : nullptr; } signals: - void signalAdded(uint32_t address, const Signal *sig); - void signalRemoved(const Signal *sig); - void signalUpdated(const Signal *sig); + void signalAdded(uint32_t address, const cabana::Signal *sig); + void signalRemoved(const cabana::Signal *sig); + void signalUpdated(const cabana::Signal *sig); void msgUpdated(uint32_t address); void msgRemoved(uint32_t address); void DBCFileChanged(); private: void parseExtraInfo(const QString &content); - std::map msgs; + std::map msgs; QString name_; }; -const QString UNTITLED = "untitled"; - -// TODO: Add helper function in dbc.h -double get_raw_value(uint8_t *data, size_t data_size, const Signal &sig); -bool operator==(const Signal &l, const Signal &r); -inline bool operator!=(const Signal &l, const Signal &r) { return !(l == r); } -int bigEndianStartBitsIndex(int start_bit); -int bigEndianBitIndex(int index); -void updateSigSizeParamsFromRange(Signal &s, int start_bit, int size); -std::pair getSignalRange(const Signal *s); DBCManager *dbc(); + inline QString msgName(const MessageId &id) { auto msg = dbc()->msg(id); return msg ? msg->name : UNTITLED; } - -} // namespace dbcmanager diff --git a/tools/cabana/detailwidget.cc b/tools/cabana/detailwidget.cc index 71dbf8d56b..05a0528d0e 100644 --- a/tools/cabana/detailwidget.cc +++ b/tools/cabana/detailwidget.cc @@ -68,7 +68,7 @@ DetailWidget::DetailWidget(ChartsWidget *charts, QWidget *parent) : charts(chart QObject::connect(binary_view, &BinaryView::resizeSignal, signal_view->model, &SignalModel::resizeSignal); QObject::connect(binary_view, &BinaryView::addSignal, signal_view->model, &SignalModel::addSignal); QObject::connect(binary_view, &BinaryView::signalHovered, signal_view, &SignalView::signalHovered); - QObject::connect(binary_view, &BinaryView::signalClicked, [this](const Signal *s) { signal_view->selectSignal(s, true); }); + QObject::connect(binary_view, &BinaryView::signalClicked, [this](const cabana::Signal *s) { signal_view->selectSignal(s, true); }); QObject::connect(binary_view, &BinaryView::editSignal, signal_view->model, &SignalModel::saveSignal); QObject::connect(binary_view, &BinaryView::removeSignal, signal_view->model, &SignalModel::removeSignal); QObject::connect(binary_view, &BinaryView::showChart, charts, &ChartsWidget::showChart); diff --git a/tools/cabana/historylog.h b/tools/cabana/historylog.h index 206d53bc8d..119b61a0e8 100644 --- a/tools/cabana/historylog.h +++ b/tools/cabana/historylog.h @@ -11,8 +11,6 @@ #include "tools/cabana/streams/abstractstream.h" #include "tools/cabana/util.h" -using namespace dbcmanager; - class HeaderView : public QHeaderView { public: HeaderView(Qt::Orientation orientation, QWidget *parent = nullptr) : QHeaderView(orientation, parent) {} @@ -64,7 +62,7 @@ public: uint64_t last_fetch_time = 0; std::function filter_cmp = nullptr; std::deque messages; - std::vector sigs; + std::vector sigs; bool dynamic_mode = true; bool display_signals_mode = true; }; diff --git a/tools/cabana/mainwin.cc b/tools/cabana/mainwin.cc index abcb4948a9..17b720bd55 100644 --- a/tools/cabana/mainwin.cc +++ b/tools/cabana/mainwin.cc @@ -97,7 +97,7 @@ void MainWindow::createActions() { file_menu->addSeparator(); QMenu *load_opendbc_menu = file_menu->addMenu(tr("Load DBC from commaai/opendbc")); // load_opendbc_menu->setStyleSheet("QMenu { menu-scrollable: true; }"); - auto dbc_names = dbc()->allDBCNames(); + auto dbc_names = allDBCNames(); std::sort(dbc_names.begin(), dbc_names.end()); for (const auto &name : dbc_names) { load_opendbc_menu->addAction(QString::fromStdString(name), this, &MainWindow::openOpendbcFile); diff --git a/tools/cabana/messageswidget.h b/tools/cabana/messageswidget.h index ed9e241b0c..08dac0d69a 100644 --- a/tools/cabana/messageswidget.h +++ b/tools/cabana/messageswidget.h @@ -8,7 +8,6 @@ #include "tools/cabana/dbcmanager.h" #include "tools/cabana/streams/abstractstream.h" -using namespace dbcmanager; class MessageListModel : public QAbstractTableModel { Q_OBJECT diff --git a/tools/cabana/signaledit.cc b/tools/cabana/signaledit.cc index 5684edf95a..8c28d92437 100644 --- a/tools/cabana/signaledit.cc +++ b/tools/cabana/signaledit.cc @@ -22,7 +22,7 @@ SignalModel::SignalModel(QObject *parent) : root(new Item), QAbstractItemModel(p QObject::connect(can, &AbstractStream::msgsReceived, this, &SignalModel::updateState); } -void SignalModel::insertItem(SignalModel::Item *parent_item, int pos, const Signal *sig) { +void SignalModel::insertItem(SignalModel::Item *parent_item, int pos, const cabana::Signal *sig) { Item *item = new Item{.sig = sig, .parent = parent_item, .title = sig->name, .type = Item::Sig}; parent_item->children.insert(pos, item); QString titles[]{"Name", "Size", "Little Endian", "Signed", "Offset", "Factor", "Extra Info", "Unit", "Comment", "Minimum Value", "Maximum Value", "Value Descriptions"}; @@ -104,7 +104,7 @@ Qt::ItemFlags SignalModel::flags(const QModelIndex &index) const { return flags; } -int SignalModel::signalRow(const Signal *sig) const { +int SignalModel::signalRow(const cabana::Signal *sig) const { for (int i = 0; i < root->children.size(); ++i) { if (root->children[i]->sig == sig) return i; } @@ -168,7 +168,7 @@ bool SignalModel::setData(const QModelIndex &index, const QVariant &value, int r if (role != Qt::EditRole && role != Qt::CheckStateRole) return false; Item *item = getItem(index); - Signal s = *item->sig; + cabana::Signal s = *item->sig; switch (item->type) { case Item::Name: s.name = value.toString(); break; case Item::Size: s.size = value.toInt(); break; @@ -203,7 +203,7 @@ void SignalModel::showExtraInfo(const QModelIndex &index) { } } -bool SignalModel::saveSignal(const Signal *origin_s, Signal &s) { +bool SignalModel::saveSignal(const cabana::Signal *origin_s, cabana::Signal &s) { auto msg = dbc()->msg(msg_id); if (s.name != origin_s->name && msg->sig(s.name) != nullptr) { QString text = tr("There is already a signal with the same name '%1'").arg(s.name); @@ -243,7 +243,7 @@ void SignalModel::addSignal(int start_bit, int size, bool little_endian) { } } - Signal sig = {.is_little_endian = little_endian, .factor = 1}; + cabana::Signal sig = {.is_little_endian = little_endian, .factor = 1}; for (int i = 1; /**/; ++i) { sig.name = QString("NEW_SIGNAL_%1").arg(i); if (msg->sig(sig.name) == nullptr) break; @@ -252,13 +252,13 @@ void SignalModel::addSignal(int start_bit, int size, bool little_endian) { UndoStack::push(new AddSigCommand(msg_id, sig)); } -void SignalModel::resizeSignal(const Signal *sig, int start_bit, int size) { - Signal s = *sig; +void SignalModel::resizeSignal(const cabana::Signal *sig, int start_bit, int size) { + cabana::Signal s = *sig; updateSigSizeParamsFromRange(s, start_bit, size); saveSignal(sig, s); } -void SignalModel::removeSignal(const Signal *sig) { +void SignalModel::removeSignal(const cabana::Signal *sig) { UndoStack::push(new RemoveSigCommand(msg_id, sig)); } @@ -268,7 +268,7 @@ void SignalModel::handleMsgChanged(uint32_t address) { } } -void SignalModel::handleSignalAdded(uint32_t address, const Signal *sig) { +void SignalModel::handleSignalAdded(uint32_t address, const cabana::Signal *sig) { if (address == msg_id.address) { int i = 0; for (; i < root->children.size(); ++i) { @@ -280,13 +280,13 @@ void SignalModel::handleSignalAdded(uint32_t address, const Signal *sig) { } } -void SignalModel::handleSignalUpdated(const Signal *sig) { +void SignalModel::handleSignalUpdated(const cabana::Signal *sig) { if (int row = signalRow(sig); row != -1) { emit dataChanged(index(row, 0), index(row, 1), {Qt::DisplayRole, Qt::EditRole, Qt::CheckStateRole}); } } -void SignalModel::handleSignalRemoved(const Signal *sig) { +void SignalModel::handleSignalRemoved(const cabana::Signal *sig) { if (int row = signalRow(sig); row != -1) { beginRemoveRows({}, row, row); delete root->children.takeAt(row); @@ -431,7 +431,7 @@ SignalView::SignalView(ChartsWidget *charts, QWidget *parent) : charts(charts), QObject::connect(model, &QAbstractItemModel::modelReset, this, &SignalView::rowsChanged); QObject::connect(model, &QAbstractItemModel::rowsInserted, this, &SignalView::rowsChanged); QObject::connect(model, &QAbstractItemModel::rowsRemoved, this, &SignalView::rowsChanged); - QObject::connect(dbc(), &DBCManager::signalAdded, [this](uint32_t address, const Signal *sig) { selectSignal(sig); }); + QObject::connect(dbc(), &DBCManager::signalAdded, [this](uint32_t address, const cabana::Signal *sig) { selectSignal(sig); }); setWhatsThis(tr(R"( Signal view
@@ -485,7 +485,7 @@ void SignalView::rowClicked(const QModelIndex &index) { } } -void SignalView::selectSignal(const Signal *sig, bool expand) { +void SignalView::selectSignal(const cabana::Signal *sig, bool expand) { if (int row = model->signalRow(sig); row != -1) { auto idx = model->index(row, 0); if (expand) { @@ -509,7 +509,7 @@ void SignalView::updateChartState() { } } -void SignalView::signalHovered(const Signal *sig) { +void SignalView::signalHovered(const cabana::Signal *sig) { auto &children = model->root->children; for (int i = 0; i < children.size(); ++i) { bool highlight = children[i]->sig == sig; diff --git a/tools/cabana/signaledit.h b/tools/cabana/signaledit.h index da3bc36c62..39fe5f270f 100644 --- a/tools/cabana/signaledit.h +++ b/tools/cabana/signaledit.h @@ -21,7 +21,7 @@ public: Item *parent = nullptr; QList children; - const Signal *sig = nullptr; + const cabana::Signal *sig = nullptr; QString title; bool highlight = false; bool extra_expanded = false; @@ -39,18 +39,18 @@ public: void setMessage(const MessageId &id); void setFilter(const QString &txt); void addSignal(int start_bit, int size, bool little_endian); - bool saveSignal(const Signal *origin_s, Signal &s); - void resizeSignal(const Signal *sig, int start_bit, int size); - void removeSignal(const Signal *sig); + bool saveSignal(const cabana::Signal *origin_s, cabana::Signal &s); + void resizeSignal(const cabana::Signal *sig, int start_bit, int size); + void removeSignal(const cabana::Signal *sig); Item *getItem(const QModelIndex &index) const; - int signalRow(const Signal *sig) const; + int signalRow(const cabana::Signal *sig) const; void showExtraInfo(const QModelIndex &index); private: - void insertItem(SignalModel::Item *parent_item, int pos, const Signal *sig); - void handleSignalAdded(uint32_t address, const Signal *sig); - void handleSignalUpdated(const Signal *sig); - void handleSignalRemoved(const Signal *sig); + void insertItem(SignalModel::Item *parent_item, int pos, const cabana::Signal *sig); + void handleSignalAdded(uint32_t address, const cabana::Signal *sig); + void handleSignalUpdated(const cabana::Signal *sig); + void handleSignalRemoved(const cabana::Signal *sig); void handleMsgChanged(uint32_t address); void refresh(); void updateState(const QHash *msgs); @@ -94,15 +94,15 @@ class SignalView : public QFrame { public: SignalView(ChartsWidget *charts, QWidget *parent); void setMessage(const MessageId &id); - void signalHovered(const Signal *sig); + void signalHovered(const cabana::Signal *sig); void updateChartState(); - void selectSignal(const Signal *sig, bool expand = false); + void selectSignal(const cabana::Signal *sig, bool expand = false); void rowClicked(const QModelIndex &index); SignalModel *model = nullptr; signals: - void highlight(const Signal *sig); - void showChart(const MessageId &id, const Signal *sig, bool show, bool merge); + void highlight(const cabana::Signal *sig); + void showChart(const MessageId &id, const cabana::Signal *sig, bool show, bool merge); private: void rowsChanged(); diff --git a/tools/cabana/tests/test_cabana.cc b/tools/cabana/tests/test_cabana.cc index 6f9f2d016b..124eb7428a 100644 --- a/tools/cabana/tests/test_cabana.cc +++ b/tools/cabana/tests/test_cabana.cc @@ -5,7 +5,6 @@ #include "tools/replay/logreader.h" #include "tools/cabana/dbcmanager.h" #include "tools/cabana/streams/abstractstream.h" -using namespace dbcmanager; // demo route, first segment const std::string TEST_RLOG_URL = "https://commadata2.blob.core.windows.net/commadata2/4cf7a6ad03080c90/2021-09-29--13-46-36/0/rlog.bz2"; diff --git a/tools/cabana/tools/findsimilarbits.cc b/tools/cabana/tools/findsimilarbits.cc index 27cb7bced8..ffb0e54b0e 100644 --- a/tools/cabana/tools/findsimilarbits.cc +++ b/tools/cabana/tools/findsimilarbits.cc @@ -9,7 +9,6 @@ #include "tools/cabana/dbcmanager.h" #include "tools/cabana/streams/abstractstream.h" -using namespace dbcmanager; FindSimilarBitsDlg::FindSimilarBitsDlg(QWidget *parent) : QDialog(parent, Qt::WindowFlags() | Qt::Window) { setWindowTitle(tr("Find similar bits")); diff --git a/tools/cabana/tools/findsimilarbits.h b/tools/cabana/tools/findsimilarbits.h index ba9b063baf..53d7806a8f 100644 --- a/tools/cabana/tools/findsimilarbits.h +++ b/tools/cabana/tools/findsimilarbits.h @@ -7,7 +7,6 @@ #include #include "tools/cabana/dbcmanager.h" -using namespace dbcmanager; class FindSimilarBitsDlg : public QDialog { Q_OBJECT diff --git a/tools/cabana/util.cc b/tools/cabana/util.cc index 778ffbc859..656c97489c 100644 --- a/tools/cabana/util.cc +++ b/tools/cabana/util.cc @@ -128,7 +128,7 @@ void MessageBytesDelegate::paint(QPainter *painter, const QStyleOptionViewItem & } } -QColor getColor(const Signal *sig) { +QColor getColor(const cabana::Signal *sig) { float h = 19 * (float)sig->lsb / 64.0; h = fmod(h, 1.0); diff --git a/tools/cabana/util.h b/tools/cabana/util.h index cf1b5d4b20..03732ee13f 100644 --- a/tools/cabana/util.h +++ b/tools/cabana/util.h @@ -11,8 +11,7 @@ #include #include -#include "tools/cabana/dbcmanager.h" -using namespace dbcmanager; +#include "tools/cabana/dbc.h" class ChangeTracker { public: @@ -59,7 +58,7 @@ public: inline QString toHex(const QByteArray &dat) { return dat.toHex(' ').toUpper(); } QString toHex(uint8_t byte); -QColor getColor(const dbcmanager::Signal *sig); +QColor getColor(const cabana::Signal *sig); class NameValidator : public QRegExpValidator { Q_OBJECT diff --git a/tools/cabana/videowidget.h b/tools/cabana/videowidget.h index 1a7e27f1b3..d10b09fec5 100644 --- a/tools/cabana/videowidget.h +++ b/tools/cabana/videowidget.h @@ -13,7 +13,6 @@ #include "selfdrive/ui/qt/widgets/controls.h" #include "tools/cabana/dbcmanager.h" #include "tools/cabana/streams/abstractstream.h" -using namespace dbcmanager; class Slider : public QSlider { Q_OBJECT From c32a45b5b59396d7c7b90ede8db4e8ad678f39c5 Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Fri, 10 Mar 2023 20:20:59 +0100 Subject: [PATCH 095/102] cabana: autocomplete signal names (#27553) --- tools/cabana/dbcmanager.cc | 13 +++++++++++++ tools/cabana/dbcmanager.h | 1 + tools/cabana/signaledit.cc | 9 +++++++++ 3 files changed, 23 insertions(+) diff --git a/tools/cabana/dbcmanager.cc b/tools/cabana/dbcmanager.cc index e9ebcd2791..b3a90e0b70 100644 --- a/tools/cabana/dbcmanager.cc +++ b/tools/cabana/dbcmanager.cc @@ -178,6 +178,19 @@ void DBCManager::removeSignal(const MessageId &id, const QString &sig_name) { } } +QStringList DBCManager::signalNames() { + // Used for autocompletion + QStringList ret; + for (auto const& [_, msg] : msgs) { + for (auto sig: msg.getSignals()) { + ret << sig->name; + } + } + ret.sort(); + ret.removeDuplicates(); + return ret; +} + DBCManager *dbc() { static DBCManager dbc_manager(nullptr); return &dbc_manager; diff --git a/tools/cabana/dbcmanager.h b/tools/cabana/dbcmanager.h index 3b222b1dcb..4be7593808 100644 --- a/tools/cabana/dbcmanager.h +++ b/tools/cabana/dbcmanager.h @@ -30,6 +30,7 @@ public: auto it = msgs.find(address); return it != msgs.end() ? &it->second : nullptr; } + QStringList signalNames(); signals: void signalAdded(uint32_t address, const cabana::Signal *sig); diff --git a/tools/cabana/signaledit.cc b/tools/cabana/signaledit.cc index 8c28d92437..5fb56dc1bc 100644 --- a/tools/cabana/signaledit.cc +++ b/tools/cabana/signaledit.cc @@ -1,6 +1,7 @@ #include "tools/cabana/signaledit.h" #include +#include #include #include #include @@ -368,6 +369,14 @@ QWidget *SignalItemDelegate::createEditor(QWidget *parent, const QStyleOptionVie QLineEdit *e = new QLineEdit(parent); e->setFrame(false); e->setValidator(index.row() == 0 ? name_validator : double_validator); + + if (item->type == SignalModel::Item::Name) { + QCompleter *completer = new QCompleter(dbc()->signalNames()); + completer->setCaseSensitivity(Qt::CaseInsensitive); + completer->setFilterMode(Qt::MatchContains); + e->setCompleter(completer); + } + return e; } else if (item->type == SignalModel::Item::Size) { QSpinBox *spin = new QSpinBox(parent); From ee615a30775c56be2c13a4acb4a755072000b8d6 Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Fri, 10 Mar 2023 20:21:34 +0100 Subject: [PATCH 096/102] cabana: create autosave file when there are unsaved changes (#27542) --- tools/cabana/mainwin.cc | 31 ++++++++++++++++++++++++++++++- tools/cabana/mainwin.h | 4 ++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/tools/cabana/mainwin.cc b/tools/cabana/mainwin.cc index 17b720bd55..1559700951 100644 --- a/tools/cabana/mainwin.cc +++ b/tools/cabana/mainwin.cc @@ -214,6 +214,7 @@ void MainWindow::undoStackIndexChanged(int index) { } prev_undostack_index = index; prev_undostack_count = count; + autoSave(); } void MainWindow::undoStackCleanChanged(bool clean) { @@ -255,7 +256,18 @@ void MainWindow::openFile() { void MainWindow::loadFile(const QString &fn) { if (!fn.isEmpty()) { - QFile file(fn); + QString dbc_fn = fn; + + // Prompt user to load auto saved file if it exists. + if (QFile::exists(fn + AUTO_SAVE_EXTENSION)) { + auto ret = QMessageBox::question(this, tr("Auto saved DBC found"), tr("Auto saved DBC file from previous session found. Do you want to load it instead?")); + if (ret == QMessageBox::Yes) { + dbc_fn += AUTO_SAVE_EXTENSION; + UndoStack::instance()->resetClean(); // Force user to save on close so the auto saved file is not lost + } + } + + QFile file(dbc_fn); if (file.open(QIODevice::ReadOnly)) { auto dbc_name = QFileInfo(fn).baseName(); QString error; @@ -340,7 +352,23 @@ void MainWindow::save() { } } +void MainWindow::autoSave() { + if (!current_file.isEmpty() && !UndoStack::instance()->isClean()) { + QFile file(current_file + AUTO_SAVE_EXTENSION); + if (file.open(QIODevice::WriteOnly)) { + file.write(dbc()->generateDBC().toUtf8()); + } + } +} + +void MainWindow::cleanupAutoSaveFile() { + if (!current_file.isEmpty()) { + QFile::remove(current_file + AUTO_SAVE_EXTENSION); + } +} + void MainWindow::saveFile(const QString &fn) { + cleanupAutoSaveFile(); QFile file(fn); if (file.open(QIODevice::WriteOnly)) { file.write(dbc()->generateDBC().toUtf8()); @@ -445,6 +473,7 @@ void MainWindow::dockCharts(bool dock) { } void MainWindow::closeEvent(QCloseEvent *event) { + cleanupAutoSaveFile(); remindSaveChanges(); main_win = nullptr; diff --git a/tools/cabana/mainwin.h b/tools/cabana/mainwin.h index 1c21d69370..3258b95cde 100644 --- a/tools/cabana/mainwin.h +++ b/tools/cabana/mainwin.h @@ -13,6 +13,8 @@ #include "tools/cabana/videowidget.h" #include "tools/cabana/tools/findsimilarbits.h" +const QString AUTO_SAVE_EXTENSION = ".tmp"; + class MainWindow : public QMainWindow { Q_OBJECT @@ -42,6 +44,8 @@ signals: protected: void remindSaveChanges(); void saveFile(const QString &fn); + void autoSave(); + void cleanupAutoSaveFile(); void setCurrentFile(const QString &fn); void updateRecentFileActions(); void createActions(); From 0fb8e974801b3a9fc664076830a8595a752d5c87 Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Fri, 10 Mar 2023 22:29:11 +0100 Subject: [PATCH 097/102] cabana: use ID as NEW_MSG_ suffix (#27554) * cabana: use ID as NEW_MSG_ suffix * start suffix at _1 --- tools/cabana/signaledit.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/cabana/signaledit.cc b/tools/cabana/signaledit.cc index 5fb56dc1bc..ced7cd7d24 100644 --- a/tools/cabana/signaledit.cc +++ b/tools/cabana/signaledit.cc @@ -236,8 +236,9 @@ bool SignalModel::saveSignal(const cabana::Signal *origin_s, cabana::Signal &s) void SignalModel::addSignal(int start_bit, int size, bool little_endian) { auto msg = dbc()->msg(msg_id); - for (int i = 1; !msg; ++i) { - QString name = QString("NEW_MSG_%1").arg(i); + for (int i = 0; !msg; ++i) { + QString name = QString("NEW_MSG_") + QString::number(msg_id.address, 16).toUpper(); + if (i > 0) name += QString("_%1").arg(i); if (std::none_of(dbc()->messages().begin(), dbc()->messages().end(), [&](auto &m) { return m.second.name == name; })) { UndoStack::push(new EditMsgCommand(msg_id, name, can->lastMessage(msg_id).dat.size())); msg = dbc()->msg(msg_id); From dc5a65049ef93cd0c342d32cc5eecef32e0bb145 Mon Sep 17 00:00:00 2001 From: protonchang <2095341+protonchang@users.noreply.github.com> Date: Sat, 11 Mar 2023 07:39:16 +0800 Subject: [PATCH 098/102] Update CHT translation (#27530) * Update zh-CHT translation * Update zh-CHT translation * Update zh-CHT Translation * Update to resolve translation consistency issue * Update zh-CHT translation --- selfdrive/ui/translations/main_zh-CHT.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts index e4058ee0db..83db0b7301 100644 --- a/selfdrive/ui/translations/main_zh-CHT.ts +++ b/selfdrive/ui/translations/main_zh-CHT.ts @@ -200,7 +200,7 @@
openpilot requires the device to be mounted within 4° left or right and within 5° up or 8° down. openpilot is continuously calibrating, resetting is rarely required. - openpilot 需要將裝置固定在左右偏差 4° 以內,朝上偏差 5° 以内或朝下偏差 8° 以内。鏡頭在後台會持續自動校準,很少有需要重置的情况。 + openpilot 需要將設備固定在左右偏差 4° 以內,朝上偏差 5° 以内或朝下偏差 8° 以内。鏡頭在後台會持續自動校準,很少有需要重置的情况。 Your device is pointed %1° %2 and %3° %4. @@ -592,16 +592,16 @@ location set Unable to mount data partition. Partition may be corrupted. Press confirm to erase and reset your device. - + 無法掛載資料分割區 分割區可能已經毀損 請確認是否要刪除並重新設定 Press confirm to erase all content and settings. Press cancel to resume boot. - + 按下確認以刪除所有內容及設定 按下取消來繼續開機 Resetting device... This may take up to a minute. - + 設備重置中 此過程可能需要幾分鐘
@@ -703,11 +703,11 @@ This may take up to a minute. No custom software found at this URL. - + 無法在此URL找到定制的軟體 Something went wrong. Reboot the device. - + 發生了一些錯誤 請重新啟動您的設備 @@ -1028,11 +1028,11 @@ This may take up to a minute. openpilot longitudinal control may come in a future update. - + 未來可能會推出openpilot縱向控制 An experimental version of openpilot longitudinal control can be tested, along with Experimental mode, on non-release branches. - + 在非發行分支中 可找到包含實驗模式的openpilot縱向控制測試版本 Enable experimental longitudinal control to allow Experimental mode. From eb67deef92be8af17596c08e9f98c240fc7d23e3 Mon Sep 17 00:00:00 2001 From: Erich Moraga <33645296+ErichMoraga@users.noreply.github.com> Date: Fri, 10 Mar 2023 17:43:18 -0600 Subject: [PATCH 099/102] Add missing LEXUS_ESH_TSS2 engine f/w (#27506) `awesome-fu#6174` 2019 Lexus ES300h DongleID/route e5fc06c3b27fb519|2023-03-05--17-21-28 https://github.com/commaai/openpilot/issues/27501 --- selfdrive/car/toyota/values.py | 1 + 1 file changed, 1 insertion(+) diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py index 35e2db8b1e..a8e143e80a 100644 --- a/selfdrive/car/toyota/values.py +++ b/selfdrive/car/toyota/values.py @@ -1637,6 +1637,7 @@ FW_VERSIONS = { b'\x028966333S8000\x00\x00\x00\x00897CF3305001\x00\x00\x00\x00', b'\x028966333T0100\x00\x00\x00\x00897CF3305001\x00\x00\x00\x00', b'\x028966333V4000\x00\x00\x00\x00897CF3305001\x00\x00\x00\x00', + b'\x028966333W1000\x00\x00\x00\x00897CF3305001\x00\x00\x00\x00', b'\x02896633T09000\x00\x00\x00\x00897CF3307001\x00\x00\x00\x00', b'\x01896633T38000\x00\x00\x00\x00', b'\x01896633T58000\x00\x00\x00\x00', From dc31c50aa7bda8d5aab43b0382342ae5162ed37d Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Sun, 12 Mar 2023 04:47:34 +0800 Subject: [PATCH 100/102] cabana: split events into chunks and processed concurrently (#27562) --- tools/cabana/streams/abstractstream.cc | 56 ++++++++++++++++++-------- 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/tools/cabana/streams/abstractstream.cc b/tools/cabana/streams/abstractstream.cc index 3e631d3709..6af831a1d0 100644 --- a/tools/cabana/streams/abstractstream.cc +++ b/tools/cabana/streams/abstractstream.cc @@ -1,5 +1,7 @@ #include "tools/cabana/streams/abstractstream.h" +#include + AbstractStream *can = nullptr; AbstractStream::AbstractStream(QObject *parent, bool is_live_streaming) : is_live_streaming(is_live_streaming), QObject(parent) { @@ -59,39 +61,59 @@ const CanData &AbstractStream::lastMessage(const MessageId &id) { return it != can_msgs.end() ? it.value() : empty_data; } -void AbstractStream::updateLastMsgsTo(double sec) { - QHash last_msgs; - last_msgs.reserve(can_msgs.size()); - double route_start_time = routeStartTime(); - uint64_t last_ts = (sec + route_start_time) * 1e9; - auto evs = events(); - auto last = std::upper_bound(evs->rbegin(), evs->rend(), last_ts, [](uint64_t ts, auto &e) { return e->mono_time < ts; }); - for (auto it = last; it != evs->rend(); ++it) { +static QHash parseEvents(std::vector::const_reverse_iterator first, + std::vector::const_reverse_iterator last, double route_start_time) { + QHash msgs; + msgs.reserve(500); + for (auto it = first; it != last; ++it) { if ((*it)->which == cereal::Event::Which::CAN) { for (const auto &c : (*it)->event.getCan()) { - auto &m = last_msgs[{.source = c.getSrc(), .address = c.getAddress()}]; + auto &m = msgs[{.source = c.getSrc(), .address = c.getAddress()}]; if (++m.count == 1) { m.ts = ((*it)->mono_time / 1e9) - route_start_time; m.dat = QByteArray((char *)c.getDat().begin(), c.getDat().size()); m.colors = QVector(m.dat.size(), QColor(0, 0, 0, 0)); m.last_change_t = QVector(m.dat.size(), m.ts); m.bit_change_counts.resize(m.dat.size()); - } else { - m.freq = m.count / std::max(1.0, m.ts); } } } } + return msgs; +}; + +// it is thread safe to update data in updateLastMsgsTo. +// updateEvent will not be called before replayStream::seekedTo return. +void AbstractStream::updateLastMsgsTo(double sec) { + uint64_t ts = (sec + routeStartTime()) * 1e9; + const uint64_t delta = std::max(std::ceil(sec / std::thread::hardware_concurrency()), 30.0) * 1e9; + const auto evs = events(); + auto first = std::upper_bound(evs->crbegin(), evs->crend(), ts, [](uint64_t ts, auto &e) { return ts > e->mono_time; }); + QFutureSynchronizer> synchronizer; + while(first != evs->crend()) { + ts = (*first)->mono_time > delta ? (*first)->mono_time - delta : 0; + auto last = std::lower_bound(first, evs->crend(), ts, [](auto &e, uint64_t ts) { return e->mono_time > ts; }); + synchronizer.addFuture(QtConcurrent::run(parseEvents, first, last, routeStartTime())); + first = last; + } + synchronizer.waitForFinished(); - // it is thread safe to update data here. - // updateEvent will not be called before replayStream::seekedTo return. new_msgs->clear(); change_trackers.clear(); - counters.clear(); can_msgs.clear(); - for (auto it = last_msgs.cbegin(); it != last_msgs.cend(); ++it) { - can_msgs[it.key()] = it.value(); - counters[it.key()] = it.value().count; + counters.clear(); + for (const auto &f : synchronizer.futures()) { + auto msgs = f.result(); + for (auto it = msgs.cbegin(); it != msgs.cend(); ++it) { + counters[it.key()] += it.value().count; + auto m = can_msgs.find(it.key()); + if (m == can_msgs.end()) { + m = can_msgs.insert(it.key(), it.value()); + } else { + m.value().count += it.value().count; + } + m.value().freq = m.value().count / std::max(1.0, m.value().ts); + } } emit updated(); emit msgsReceived(&can_msgs); From fc44ed63d78c3b45020db1130dae41f597c91e18 Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Sat, 11 Mar 2023 21:47:53 +0100 Subject: [PATCH 101/102] cabana: extend max chart range to 30 minutes (#27555) --- tools/cabana/chartswidget.cc | 4 ++-- tools/cabana/chartswidget.h | 2 +- tools/cabana/settings.cc | 2 +- tools/cabana/settings.h | 2 +- tools/cabana/util.h | 18 ++++++++++++++++++ 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/tools/cabana/chartswidget.cc b/tools/cabana/chartswidget.cc index 5bab261ba7..c0432d0c09 100644 --- a/tools/cabana/chartswidget.cc +++ b/tools/cabana/chartswidget.cc @@ -45,7 +45,7 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QFrame(parent) { toolbar->addWidget(stretch_label); range_lb_action = toolbar->addWidget(range_lb = new QLabel(this)); - range_slider = new QSlider(Qt::Horizontal, this); + range_slider = new LogSlider(1000, Qt::Horizontal, this); range_slider->setMaximumWidth(200); range_slider->setToolTip(tr("Set the chart range")); range_slider->setRange(1, settings.max_cached_minutes * 60); @@ -163,7 +163,7 @@ void ChartsWidget::updateState() { } void ChartsWidget::setMaxChartRange(int value) { - max_chart_range = settings.chart_range = value; + max_chart_range = settings.chart_range = range_slider->value(); updateToolBar(); updateState(); } diff --git a/tools/cabana/chartswidget.h b/tools/cabana/chartswidget.h index fdfbbc11ff..adce1e0f4d 100644 --- a/tools/cabana/chartswidget.h +++ b/tools/cabana/chartswidget.h @@ -137,7 +137,7 @@ private: QLabel *title_label; QLabel *range_lb; - QSlider *range_slider; + LogSlider *range_slider; QAction *range_lb_action; QAction *range_slider_action; bool docking = true; diff --git a/tools/cabana/settings.cc b/tools/cabana/settings.cc index 23f001efff..00bbb94de5 100644 --- a/tools/cabana/settings.cc +++ b/tools/cabana/settings.cc @@ -32,7 +32,7 @@ void Settings::save() { void Settings::load() { QSettings s("settings", QSettings::IniFormat); fps = s.value("fps", 10).toInt(); - max_cached_minutes = s.value("max_cached_minutes", 5).toInt(); + max_cached_minutes = s.value("max_cached_minutes", 30).toInt(); chart_height = s.value("chart_height", 200).toInt(); chart_range = s.value("chart_range", 3 * 60).toInt(); chart_column_count = s.value("chart_column_count", 1).toInt(); diff --git a/tools/cabana/settings.h b/tools/cabana/settings.h index a302d20077..c3ba906576 100644 --- a/tools/cabana/settings.h +++ b/tools/cabana/settings.h @@ -14,7 +14,7 @@ public: void load(); int fps = 10; - int max_cached_minutes = 5; + int max_cached_minutes = 30; int chart_height = 200; int chart_column_count = 1; int chart_range = 3 * 60; // e minutes diff --git a/tools/cabana/util.h b/tools/cabana/util.h index 03732ee13f..b1acdd8c6e 100644 --- a/tools/cabana/util.h +++ b/tools/cabana/util.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -29,6 +30,23 @@ private: QByteArray prev_dat; }; +class LogSlider : public QSlider { + Q_OBJECT + +public: + LogSlider(double factor, Qt::Orientation orientation, QWidget *parent = nullptr) : factor(factor), QSlider(orientation, parent) {}; + + void setRange(double min, double max) { QSlider::setRange(logScale(min), logScale(max)); } + int value() const { return invLogScale(QSlider::value()); } + void setValue(int value) { QSlider::setValue(logScale(value)); } + +private: + double factor; + int logScale(int value) const { return factor * std::log10(value); } + int invLogScale(int value) const { return std::pow(10, value / factor); } +}; + + enum { ColorsRole = Qt::UserRole + 1, BytesRole = Qt::UserRole + 2 From e146bb1a96e98e2dc3d9b777a259044e73a9a633 Mon Sep 17 00:00:00 2001 From: YassineYousfi Date: Sat, 11 Mar 2023 16:26:39 -0800 Subject: [PATCH 102/102] update modeld/models readme (#27564) * update readme with new model design * typo * space --- selfdrive/modeld/models/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/selfdrive/modeld/models/README.md b/selfdrive/modeld/models/README.md index 6b704cbfa8..1bfca8e95a 100644 --- a/selfdrive/modeld/models/README.md +++ b/selfdrive/modeld/models/README.md @@ -2,7 +2,7 @@ To view the architecture of the ONNX networks, you can use [netron](https://netron.app/) ## Supercombo -### Supercombo input format (Full size: 393738 x float32) +### Supercombo input format (Full size: 799906 x float32) * **image stream** * Two consecutive images (256 * 512 * 3 in RGB) recorded at 20 Hz : 393216 = 2 * 6 * 128 * 256 * Each 256 * 512 image is represented in YUV420 with 6 channels : 6 * 128 * 256 @@ -16,11 +16,11 @@ To view the architecture of the ONNX networks, you can use [netron](https://netr * Channel 4 represents the half-res U channel * Channel 5 represents the half-res V channel * **desire** - * one-hot encoded vector to command model to execute certain actions, bit only needs to be sent for 1 frame : 8 + * one-hot encoded buffer to command model to execute certain actions, bit needs to be sent for the past 5 seconds (at 20FPS) : 100 * 8 * **traffic convention** * one-hot encoded vector to tell model whether traffic is right-hand or left-hand traffic : 2 -* **recurrent state** - * The recurrent state vector that is fed back into the GRU for temporal context : 512 +* **feature buffer** + * A buffer of intermediate features that gets appended to the current feature to form a 5 seconds temporal context (at 20FPS) : 99 * 128 ### Supercombo output format (Full size: XXX x float32)