diff --git a/selfdrive/assets/offroad/icon_wifi_uploading.svg b/selfdrive/assets/offroad/icon_wifi_uploading.svg
new file mode 100644
index 0000000000..95cb0e283e
--- /dev/null
+++ b/selfdrive/assets/offroad/icon_wifi_uploading.svg
@@ -0,0 +1,6 @@
+
diff --git a/selfdrive/test/test_onroad.py b/selfdrive/test/test_onroad.py
index 793530b964..12a3ef48ac 100755
--- a/selfdrive/test/test_onroad.py
+++ b/selfdrive/test/test_onroad.py
@@ -18,6 +18,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 system.hardware import HARDWARE
from system.loggerd.config import ROOT
from selfdrive.test.helpers import set_params_enabled, release_only
from tools.lib.logreader import LogReader
@@ -35,7 +36,6 @@ PROCS = {
"./_sensord": 12.0,
"selfdrive.controls.radard": 4.5,
"./_modeld": 4.48,
- "./boardd": 3.63,
"./_dmonitoringmodeld": 5.0,
"selfdrive.thermald.thermald": 3.87,
"selfdrive.locationd.calibrationd": 2.0,
@@ -45,12 +45,10 @@ PROCS = {
"./proclogd": 1.54,
"system.logmessaged": 0.2,
"./clocksd": 0.02,
- "./ubloxd": 0.02,
"selfdrive.tombstoned": 0,
"./logcatd": 0,
"system.micd": 10.0,
"system.timezoned": 0,
- "system.sensord.pigeond": 6.0,
"selfdrive.boardd.pandad": 0,
"selfdrive.statsd": 0.4,
"selfdrive.navd.navd": 0.4,
@@ -59,6 +57,18 @@ PROCS = {
"selfdrive.locationd.laikad": None, # TODO: laikad cpu usage is sporadic
}
+PROCS.update({
+ "tici": {
+ "./boardd": 4.0,
+ "./ubloxd": 0.02,
+ "system.sensord.pigeond": 6.0,
+ },
+ "tizi": {
+ "./boardd": 19.0,
+ "system.sensord.rawgps.rawgpsd": 1.0,
+ }
+}[HARDWARE.get_device_type()])
+
TIMINGS = {
# rtols: max/min, rsd
"can": [2.5, 0.35],
@@ -96,7 +106,9 @@ class TestOnroad(unittest.TestCase):
# setup env
params = Params()
- params.clear_all()
+ if "CI" in os.environ:
+ params.clear_all()
+ params.remove("CurrentRoute")
set_params_enabled()
os.environ['TESTING_CLOSET'] = '1'
if os.path.exists(ROOT):
@@ -156,11 +168,11 @@ class TestOnroad(unittest.TestCase):
for s, msgs in self.service_msgs.items():
if s in ('initData', 'sentinel'):
continue
-
+
# skip gps services for now
- if s in ('ubloxGnss', 'ubloxRaw', 'gnssMeasurements', 'gpsLocationExternal'):
+ if s in ('ubloxGnss', 'ubloxRaw', 'gnssMeasurements', 'gpsLocation', 'gpsLocationExternal', 'qcomGnss'):
continue
-
+
with self.subTest(service=s):
assert len(msgs) >= math.floor(service_list[s].frequency*55)
@@ -258,6 +270,23 @@ class TestOnroad(unittest.TestCase):
result += "------------------------------------------------\n"
print(result)
+ @unittest.skip("TODO: enable once timings are fixed")
+ def test_camera_frame_timings(self):
+ result = "\n"
+ result += "------------------------------------------------\n"
+ result += "----------------- SoF Timing ------------------\n"
+ result += "------------------------------------------------\n"
+ for name in ['roadCameraState', 'wideRoadCameraState', 'driverCameraState']:
+ ts = [getattr(getattr(m, m.which()), "timestampSof") for m in self.lr if name in m.which()]
+ d_ms = np.diff(ts) / 1e6
+ d50 = np.abs(d_ms-50)
+ self.assertLess(max(d50), 1.0, f"high sof delta vs 50ms: {max(d50)}")
+ result += f"{name} sof delta vs 50ms: min {min(d50):.5f}s\n"
+ result += f"{name} sof delta vs 50ms: max {max(d50):.5f}s\n"
+ result += f"{name} sof delta vs 50ms: mean {d50.mean():.5f}s\n"
+ result += "------------------------------------------------\n"
+ print(result)
+
def test_mpc_execution_timings(self):
result = "\n"
result += "------------------------------------------------\n"
diff --git a/selfdrive/ui/SConscript b/selfdrive/ui/SConscript
index f54d72ae31..f46e3d5873 100644
--- a/selfdrive/ui/SConscript
+++ b/selfdrive/ui/SConscript
@@ -20,7 +20,7 @@ if arch == "Darwin":
qt_env['FRAMEWORKS'] += ['OpenCL']
qt_util = qt_env.Library("qt_util", ["#selfdrive/ui/qt/api.cc", "#selfdrive/ui/qt/util.cc"], LIBS=base_libs)
-widgets_src = ["ui.cc", "qt/widgets/input.cc", "qt/widgets/drive_stats.cc",
+widgets_src = ["ui.cc", "qt/widgets/input.cc", "qt/widgets/drive_stats.cc", "qt/widgets/wifi.cc",
"qt/widgets/ssh_keys.cc", "qt/widgets/toggle.cc", "qt/widgets/controls.cc",
"qt/widgets/offroad_alerts.cc", "qt/widgets/prime.cc", "qt/widgets/keyboard.cc",
"qt/widgets/scrollview.cc", "qt/widgets/cameraview.cc", "#third_party/qrcode/QrCode.cc",
diff --git a/selfdrive/ui/qt/home.cc b/selfdrive/ui/qt/home.cc
index 2b8974f73a..587e2f445e 100644
--- a/selfdrive/ui/qt/home.cc
+++ b/selfdrive/ui/qt/home.cc
@@ -2,6 +2,7 @@
#include
#include
+#include
#include
#include "selfdrive/ui/qt/offroad/experimental_mode.h"
@@ -136,21 +137,34 @@ OffroadHome::OffroadHome(QWidget* parent) : QFrame(parent) {
home_layout->setContentsMargins(0, 0, 0, 0);
home_layout->setSpacing(30);
- // left: ExperimentalModeButton, DriveStats
- QWidget* left_widget = new QWidget(this);
- QVBoxLayout* left_column = new QVBoxLayout(left_widget);
- left_column->setContentsMargins(0, 0, 0, 0);
- left_column->setSpacing(30);
+ // left: DriveStats/PrimeAdWidget
+ QStackedWidget *left_widget = new QStackedWidget(this);
+ left_widget->addWidget(new DriveStats);
+ left_widget->addWidget(new PrimeAdWidget);
+
+ left_widget->setCurrentIndex(uiState()->primeType() ? 0 : 1);
+ connect(uiState(), &UIState::primeTypeChanged, [=](int prime_type) {
+ left_widget->setCurrentIndex(prime_type ? 0 : 1);
+ });
+
+ home_layout->addWidget(left_widget, 1);
+
+ // right: ExperimentalModeButton, SetupWidget
+ QWidget* right_widget = new QWidget(this);
+ QVBoxLayout* right_column = new QVBoxLayout(right_widget);
+ right_column->setContentsMargins(0, 0, 0, 0);
+ right_widget->setFixedWidth(750);
+ right_column->setSpacing(30);
ExperimentalModeButton *experimental_mode = new ExperimentalModeButton(this);
QObject::connect(experimental_mode, &ExperimentalModeButton::openSettings, this, &OffroadHome::openSettings);
- left_column->addWidget(experimental_mode, 1);
- left_column->addWidget(new DriveStats, 1);
+ right_column->addWidget(experimental_mode, 1);
- home_layout->addWidget(left_widget, 1);
+ SetupWidget *setup_widget = new SetupWidget;
+ QObject::connect(setup_widget, &SetupWidget::openSettings, this, &OffroadHome::openSettings);
+ right_column->addWidget(setup_widget, 1);
- // right: SetupWidget
- home_layout->addWidget(new SetupWidget);
+ home_layout->addWidget(right_widget, 1);
}
center_layout->addWidget(home_widget);
@@ -170,7 +184,7 @@ OffroadHome::OffroadHome(QWidget* parent) : QFrame(parent) {
setStyleSheet(R"(
* {
- color: white;
+ color: white;
}
OffroadHome {
background-color: black;
diff --git a/selfdrive/ui/qt/widgets/prime.cc b/selfdrive/ui/qt/widgets/prime.cc
index fb4aea2b1c..86bd918e0c 100644
--- a/selfdrive/ui/qt/widgets/prime.cc
+++ b/selfdrive/ui/qt/widgets/prime.cc
@@ -14,6 +14,7 @@
#include "selfdrive/ui/qt/request_repeater.h"
#include "selfdrive/ui/qt/util.h"
#include "selfdrive/ui/qt/qt_window.h"
+#include "selfdrive/ui/qt/widgets/wifi.h"
using qrcodegen::QrCode;
@@ -123,26 +124,18 @@ PrimeUserWidget::PrimeUserWidget(QWidget* parent) : QFrame(parent) {
QWidget *primeWidget = new QWidget;
primeWidget->setObjectName("primeWidget");
QVBoxLayout *primeLayout = new QVBoxLayout(primeWidget);
- primeLayout->setContentsMargins(60, 50, 60, 50);
+ primeLayout->setContentsMargins(56, 40, 56, 40);
+ primeLayout->setSpacing(20);
QLabel *subscribed = new QLabel(tr("✓ SUBSCRIBED"));
subscribed->setStyleSheet("font-size: 41px; font-weight: bold; color: #86FF4E;");
- primeLayout->addWidget(subscribed, 0, Qt::AlignTop);
-
- primeLayout->addSpacing(60);
+ primeLayout->addWidget(subscribed);
QLabel *commaPrime = new QLabel(tr("comma prime"));
commaPrime->setStyleSheet("font-size: 75px; font-weight: bold;");
- primeLayout->addWidget(commaPrime, 0, Qt::AlignTop);
-
- primeLayout->addSpacing(20);
-
- QLabel *connectUrl = new QLabel(tr("CONNECT.COMMA.AI"));
- connectUrl->setStyleSheet("font-size: 41px; font-family: Inter SemiBold; color: #A0A0A0;");
- primeLayout->addWidget(connectUrl, 0, Qt::AlignTop);
+ primeLayout->addWidget(commaPrime);
mainLayout->addWidget(primeWidget);
-
mainLayout->addStretch();
}
@@ -195,8 +188,8 @@ SetupWidget::SetupWidget(QWidget* parent) : QFrame(parent) {
QFrame* finishRegistration = new QFrame;
finishRegistration->setObjectName("primeWidget");
QVBoxLayout* finishRegistationLayout = new QVBoxLayout(finishRegistration);
- finishRegistationLayout->setSpacing(40);
- finishRegistationLayout->setContentsMargins(64, 64, 64, 64);
+ finishRegistationLayout->setSpacing(38);
+ finishRegistationLayout->setContentsMargins(64, 48, 64, 48);
QLabel* registrationTitle = new QLabel(tr("Finish Setup"));
registrationTitle->setStyleSheet("font-size: 75px; font-weight: bold;");
@@ -204,7 +197,7 @@ SetupWidget::SetupWidget(QWidget* parent) : QFrame(parent) {
QLabel* registrationDescription = new QLabel(tr("Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer."));
registrationDescription->setWordWrap(true);
- registrationDescription->setStyleSheet("font-size: 55px; font-weight: light;");
+ registrationDescription->setStyleSheet("font-size: 50px; font-weight: light;");
finishRegistationLayout->addWidget(registrationDescription);
finishRegistationLayout->addStretch();
@@ -234,15 +227,24 @@ SetupWidget::SetupWidget(QWidget* parent) : QFrame(parent) {
outer_layout->setContentsMargins(0, 0, 0, 0);
outer_layout->addWidget(mainLayout);
- primeAd = new PrimeAdWidget;
- mainLayout->addWidget(primeAd);
+ QWidget *content = new QWidget;
+ QVBoxLayout *content_layout = new QVBoxLayout(content);
+ content_layout->setContentsMargins(0, 0, 0, 0);
+ content_layout->setSpacing(30);
primeUser = new PrimeUserWidget;
- mainLayout->addWidget(primeUser);
+ content_layout->addWidget(primeUser);
- mainLayout->setCurrentWidget(uiState()->primeType() ? (QWidget*)primeUser : (QWidget*)primeAd);
+ WiFiPromptWidget *wifi_prompt = new WiFiPromptWidget;
+ QObject::connect(wifi_prompt, &WiFiPromptWidget::openSettings, this, &SetupWidget::openSettings);
+ content_layout->addWidget(wifi_prompt);
+ content_layout->addStretch();
+
+ mainLayout->addWidget(content);
+
+ primeUser->setVisible(uiState()->primeType());
+ mainLayout->setCurrentIndex(1);
- setFixedWidth(750);
setStyleSheet(R"(
#primeWidget {
border-radius: 10px;
@@ -282,10 +284,7 @@ void SetupWidget::replyFinished(const QString &response, bool success) {
} else {
popup->reject();
- if (prime_type) {
- mainLayout->setCurrentWidget(primeUser);
- } else {
- mainLayout->setCurrentWidget(primeAd);
- }
+ primeUser->setVisible(prime_type);
+ mainLayout->setCurrentIndex(1);
}
}
diff --git a/selfdrive/ui/qt/widgets/prime.h b/selfdrive/ui/qt/widgets/prime.h
index 9c7b4460fc..b41bab1695 100644
--- a/selfdrive/ui/qt/widgets/prime.h
+++ b/selfdrive/ui/qt/widgets/prime.h
@@ -69,10 +69,12 @@ class SetupWidget : public QFrame {
public:
explicit SetupWidget(QWidget* parent = 0);
+signals:
+ void openSettings(int index = 0, const QString ¶m = "");
+
private:
PairingPopup *popup;
QStackedWidget *mainLayout;
- PrimeAdWidget *primeAd;
PrimeUserWidget *primeUser;
private slots:
diff --git a/selfdrive/ui/qt/widgets/wifi.cc b/selfdrive/ui/qt/widgets/wifi.cc
new file mode 100644
index 0000000000..b717a00d98
--- /dev/null
+++ b/selfdrive/ui/qt/widgets/wifi.cc
@@ -0,0 +1,103 @@
+#include "selfdrive/ui/qt/widgets/wifi.h"
+
+#include
+#include
+#include
+#include
+
+WiFiPromptWidget::WiFiPromptWidget(QWidget *parent) : QFrame(parent) {
+ stack = new QStackedLayout(this);
+
+ // Setup Wi-Fi
+ QFrame *setup = new QFrame;
+ QVBoxLayout *setup_layout = new QVBoxLayout(setup);
+ setup_layout->setContentsMargins(56, 40, 56, 40);
+ setup_layout->setSpacing(20);
+ {
+ QHBoxLayout *title_layout = new QHBoxLayout;
+ title_layout->setSpacing(32);
+ {
+ QLabel *icon = new QLabel;
+ QPixmap *pixmap = new QPixmap("../assets/offroad/icon_wifi_strength_full.svg");
+ icon->setPixmap(pixmap->scaledToWidth(80, Qt::SmoothTransformation));
+ title_layout->addWidget(icon);
+
+ QLabel *title = new QLabel(tr("Setup Wi-Fi"));
+ title->setStyleSheet("font-size: 64px; font-weight: 600;");
+ title_layout->addWidget(title);
+ title_layout->addStretch();
+ }
+ setup_layout->addLayout(title_layout);
+
+ QLabel *desc = new QLabel(tr("Connect to Wi-Fi to upload driving data and help improve openpilot"));
+ desc->setStyleSheet("font-size: 40px; font-weight: 400;");
+ desc->setWordWrap(true);
+ setup_layout->addWidget(desc);
+
+ QPushButton *settings_btn = new QPushButton(tr("Open Settings"));
+ connect(settings_btn, &QPushButton::clicked, [=]() { emit openSettings(1); });
+ settings_btn->setStyleSheet(R"(
+ QPushButton {
+ font-size: 48px;
+ font-weight: 500;
+ border-radius: 10px;
+ background-color: #465BEA;
+ padding: 32px;
+ }
+ QPushButton:pressed {
+ background-color: #3049F4;
+ }
+ )");
+ setup_layout->addWidget(settings_btn);
+ }
+ stack->addWidget(setup);
+
+ // Uploading data
+ QWidget *uploading = new QWidget;
+ QVBoxLayout *uploading_layout = new QVBoxLayout(uploading);
+ uploading_layout->setContentsMargins(64, 56, 64, 56);
+ uploading_layout->setSpacing(36);
+ {
+ QHBoxLayout *title_layout = new QHBoxLayout;
+ {
+ QLabel *title = new QLabel(tr("Uploading training data"));
+ title->setStyleSheet("font-size: 64px; font-weight: 600;");
+ title->setWordWrap(true);
+ title->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
+ title_layout->addWidget(title);
+ title_layout->addStretch();
+
+ QLabel *icon = new QLabel;
+ QPixmap *pixmap = new QPixmap("../assets/offroad/icon_wifi_uploading.svg");
+ icon->setPixmap(pixmap->scaledToWidth(120, Qt::SmoothTransformation));
+ title_layout->addWidget(icon);
+ }
+ uploading_layout->addLayout(title_layout);
+
+ QLabel *desc = new QLabel(tr("Your data is used to train driving models and help improve openpilot"));
+ desc->setStyleSheet("font-size: 48px; font-weight: 400;");
+ desc->setWordWrap(true);
+ uploading_layout->addWidget(desc);
+ }
+ stack->addWidget(uploading);
+
+ setStyleSheet(R"(
+ WiFiPromptWidget {
+ background-color: #333333;
+ border-radius: 10px;
+ }
+ )");
+
+ QObject::connect(uiState(), &UIState::uiUpdate, this, &WiFiPromptWidget::updateState);
+}
+
+void WiFiPromptWidget::updateState(const UIState &s) {
+ if (!isVisible()) return;
+
+ auto &sm = *(s.sm);
+
+ auto network_type = sm["deviceState"].getDeviceState().getNetworkType();
+ auto uploading = network_type == cereal::DeviceState::NetworkType::WIFI ||
+ network_type == cereal::DeviceState::NetworkType::ETHERNET;
+ stack->setCurrentIndex(uploading ? 1 : 0);
+}
diff --git a/selfdrive/ui/qt/widgets/wifi.h b/selfdrive/ui/qt/widgets/wifi.h
new file mode 100644
index 0000000000..60c865f2b8
--- /dev/null
+++ b/selfdrive/ui/qt/widgets/wifi.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include
+#include
+#include
+
+#include "selfdrive/ui/ui.h"
+
+class WiFiPromptWidget : public QFrame {
+ Q_OBJECT
+
+public:
+ explicit WiFiPromptWidget(QWidget* parent = 0);
+
+signals:
+ void openSettings(int index = 0, const QString ¶m = "");
+
+public slots:
+ void updateState(const UIState &s);
+
+protected:
+ QStackedLayout *stack;
+};
diff --git a/selfdrive/ui/translations/main_de.ts b/selfdrive/ui/translations/main_de.ts
index 5bec3f674a..71f3df7597 100644
--- a/selfdrive/ui/translations/main_de.ts
+++ b/selfdrive/ui/translations/main_de.ts
@@ -517,10 +517,6 @@ location set
comma prime
comma prime
-
- CONNECT.COMMA.AI
- CONNECT.COMMA.AI
-
QObject
@@ -1076,6 +1072,29 @@ This may take up to a minute.
Aktualisierung fehlgeschlagen
+
+ WiFiPromptWidget
+
+ Setup Wi-Fi
+
+
+
+ Connect to Wi-Fi to upload driving data and help improve openpilot
+
+
+
+ Open Settings
+
+
+
+ Uploading training data
+
+
+
+ Your data is used to train driving models and help improve openpilot
+
+
+
WifiUI
diff --git a/selfdrive/ui/translations/main_ja.ts b/selfdrive/ui/translations/main_ja.ts
index 43e4974784..019eb1b71b 100644
--- a/selfdrive/ui/translations/main_ja.ts
+++ b/selfdrive/ui/translations/main_ja.ts
@@ -518,10 +518,6 @@ location set
comma prime
comma prime
-
- CONNECT.COMMA.AI
- CONNECT.COMMA.AI
-
QObject
@@ -1070,6 +1066,29 @@ This may take up to a minute.
更新失敗
+
+ WiFiPromptWidget
+
+ Setup Wi-Fi
+
+
+
+ Connect to Wi-Fi to upload driving data and help improve openpilot
+
+
+
+ Open Settings
+
+
+
+ Uploading training data
+
+
+
+ Your data is used to train driving models and help improve openpilot
+
+
+
WifiUI
diff --git a/selfdrive/ui/translations/main_ko.ts b/selfdrive/ui/translations/main_ko.ts
index c985fae0e9..cab5e2ada6 100644
--- a/selfdrive/ui/translations/main_ko.ts
+++ b/selfdrive/ui/translations/main_ko.ts
@@ -518,10 +518,6 @@ location set
comma prime
comma prime
-
- CONNECT.COMMA.AI
- CONNECT.COMMA.AI
-
QObject
@@ -1071,6 +1067,29 @@ This may take up to a minute.
업데이트 실패
+
+ WiFiPromptWidget
+
+ Setup Wi-Fi
+
+
+
+ Connect to Wi-Fi to upload driving data and help improve openpilot
+
+
+
+ Open Settings
+
+
+
+ Uploading training data
+
+
+
+ Your data is used to train driving models and help improve openpilot
+
+
+
WifiUI
diff --git a/selfdrive/ui/translations/main_pt-BR.ts b/selfdrive/ui/translations/main_pt-BR.ts
index 9eeedea29c..70f06670a9 100644
--- a/selfdrive/ui/translations/main_pt-BR.ts
+++ b/selfdrive/ui/translations/main_pt-BR.ts
@@ -519,10 +519,6 @@ trabalho definido
comma prime
comma prime
-
- CONNECT.COMMA.AI
- CONNECT.COMMA.AI
-
QObject
@@ -1075,6 +1071,29 @@ Isso pode levar até um minuto.
Falha na atualização
+
+ WiFiPromptWidget
+
+ Setup Wi-Fi
+
+
+
+ Connect to Wi-Fi to upload driving data and help improve openpilot
+
+
+
+ Open Settings
+
+
+
+ Uploading training data
+
+
+
+ Your data is used to train driving models and help improve openpilot
+
+
+
WifiUI
diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts
index 9302047ab0..f6924b3c57 100644
--- a/selfdrive/ui/translations/main_zh-CHS.ts
+++ b/selfdrive/ui/translations/main_zh-CHS.ts
@@ -516,10 +516,6 @@ location set
comma prime
comma prime
-
- CONNECT.COMMA.AI
- CONNECT.COMMA.AI
-
QObject
@@ -1068,6 +1064,29 @@ This may take up to a minute.
更新失败
+
+ WiFiPromptWidget
+
+ Setup Wi-Fi
+
+
+
+ Connect to Wi-Fi to upload driving data and help improve openpilot
+
+
+
+ Open Settings
+
+
+
+ Uploading training data
+
+
+
+ Your data is used to train driving models and help improve openpilot
+
+
+
WifiUI
diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts
index 5d17a7b86a..243a91ebd1 100644
--- a/selfdrive/ui/translations/main_zh-CHT.ts
+++ b/selfdrive/ui/translations/main_zh-CHT.ts
@@ -518,10 +518,6 @@ location set
comma prime
comma 高級會員
-
- CONNECT.COMMA.AI
- CONNECT.COMMA.AI
-
QObject
@@ -1070,6 +1066,29 @@ This may take up to a minute.
更新失敗
+
+ WiFiPromptWidget
+
+ Setup Wi-Fi
+
+
+
+ Connect to Wi-Fi to upload driving data and help improve openpilot
+
+
+
+ Open Settings
+
+
+
+ Uploading training data
+
+
+
+ Your data is used to train driving models and help improve openpilot
+
+
+
WifiUI
diff --git a/system/sensord/rawgps/rawgpsd.py b/system/sensord/rawgps/rawgpsd.py
index 539a6308a7..a5eafb268d 100755
--- a/system/sensord/rawgps/rawgpsd.py
+++ b/system/sensord/rawgps/rawgpsd.py
@@ -110,36 +110,52 @@ def gps_enabled() -> bool:
raise Exception("failed to execute QGPS mmcli command") from exc
def download_and_inject_assistance():
- assist_data_file = '/tmp/xtra3grc.bin'
+ assist_data_file = '/tmp/xtra3grc.bin'
assistance_url = 'http://xtrapath3.izatcloud.net/xtra3grc.bin'
+
try:
- c = pycurl.Curl()
- c.setopt(c.URL, assistance_url)
- c.setopt(c.NOBODY, 1)
- c.setopt(pycurl.CONNECTTIMEOUT, 2)
- c.perform()
- c.close()
- bytes_n = c.getinfo(c.CONTENT_LENGTH_DOWNLOAD)
- if bytes_n > 1e5:
- cloudlog.exception("Qcom assistance data larger than expected")
- return
- with open(assist_data_file, "wb") as fp:
+ # download assistance
+ try:
c = pycurl.Curl()
- c.setopt(pycurl.URL, assistance_url)
- c.setopt(pycurl.CONNECTTIMEOUT, 5)
-
- c.setopt(pycurl.WRITEDATA, fp)
+ c.setopt(c.URL, assistance_url)
+ c.setopt(c.NOBODY, 1)
+ c.setopt(pycurl.CONNECTTIMEOUT, 2)
c.perform()
+ bytes_n = c.getinfo(c.CONTENT_LENGTH_DOWNLOAD)
c.close()
- except pycurl.error as e:
- cloudlog.exception(f'Failed to download assistance file with error: {e}')
- if os.path.isfile(assist_data_file):
+ if bytes_n > 1e5:
+ cloudlog.error("Qcom assistance data larger than expected")
+ return
+
+ with open(assist_data_file, 'wb') as fp:
+ c = pycurl.Curl()
+ c.setopt(pycurl.URL, assistance_url)
+ c.setopt(pycurl.CONNECTTIMEOUT, 5)
+
+ c.setopt(pycurl.WRITEDATA, fp)
+ c.perform()
+ c.close()
+ except pycurl.error:
+ cloudlog.exception("Failed to download assistance file")
+ return
+
+ # inject into module
try:
- subprocess.check_call(f"mmcli -m any --timeout 30 --location-inject-assistance-data={assist_data_file}", shell=True)
- except subprocess.CalledProcessError:
- cloudlog.exception("rawgps.mmcli_command_failed")
- if os.path.isfile(assist_data_file):
- os.remove(assist_data_file)
+ cmd = f"mmcli -m any --timeout 30 --location-inject-assistance-data={assist_data_file}"
+ subprocess.check_output(cmd, stderr=subprocess.PIPE, shell=True)
+ cloudlog.info("successfully loaded assistance data")
+ except subprocess.CalledProcessError as e:
+ cloudlog.event(
+ "rawgps.assistance_loading_failed",
+ error=True,
+ cmd=e.cmd,
+ output=e.output,
+ returncode=e.returncode
+ )
+ finally:
+ if os.path.exists(assist_data_file):
+ os.remove(assist_data_file)
+
def setup_quectel(diag: ModemDiag):
# enable OEMDRE in the NV
diff --git a/tools/cabana/dbc/dbcfile.cc b/tools/cabana/dbc/dbcfile.cc
index d9938b0fbc..2a8d3d2d54 100644
--- a/tools/cabana/dbc/dbcfile.cc
+++ b/tools/cabana/dbc/dbcfile.cc
@@ -212,7 +212,7 @@ void DBCFile::parseExtraInfo(const QString &content) {
uint32_t address = 0;
while (!stream.atEnd()) {
++line_num;
- line = stream.readLine();
+ line = stream.readLine().trimmed();
if (line.startsWith("BO_ ")) {
auto match = bo_regexp.match(line);
dbc_assert(match.hasMatch());
diff --git a/tools/cabana/tests/test_cabana.cc b/tools/cabana/tests/test_cabana.cc
index a3921d727b..abbb3dbf13 100644
--- a/tools/cabana/tests/test_cabana.cc
+++ b/tools/cabana/tests/test_cabana.cc
@@ -69,3 +69,44 @@ TEST_CASE("Parse can messages") {
}
}
}
+
+TEST_CASE("Parse dbc") {
+ QString content = R"(
+BO_ 160 message_1: 8 XXX
+ SG_ signal_1 : 0|12@1+ (1,0) [0|4095] "unit" XXX
+ SG_ signal_2 : 12|1@1+ (1.0,0.0) [0.0|1] "" XXX
+
+VAL_ 160 signal_1 0 "disabled" 1.2 "initializing" 2 "fault";
+
+CM_ BO_ 160 "message comment";
+CM_ SG_ 160 signal_1 "signal comment";
+CM_ SG_ 160 signal_2 "multiple line comment
+1
+2
+";)";
+
+ DBCFile file("", content);
+ auto msg = file.msg(160);
+ REQUIRE(msg != nullptr);
+ REQUIRE(msg->name == "message_1");
+ REQUIRE(msg->size == 8);
+ REQUIRE(msg->comment == "message comment");
+ REQUIRE(msg->sigs.size() == 2);
+ REQUIRE(file.msg("message_1") != nullptr);
+
+ auto &sig_1 = msg->sigs[0];
+ REQUIRE(sig_1.name == "signal_1");
+ REQUIRE(sig_1.start_bit == 0);
+ REQUIRE(sig_1.size == 12);
+ REQUIRE(sig_1.min == 0);
+ REQUIRE(sig_1.max == 4095);
+ REQUIRE(sig_1.unit == "unit");
+ REQUIRE(sig_1.comment == "signal comment");
+ REQUIRE(sig_1.val_desc.size() == 3);
+ REQUIRE(sig_1.val_desc[0] == std::pair{0, "disabled"});
+ REQUIRE(sig_1.val_desc[1] == std::pair{1.2, "initializing"});
+ REQUIRE(sig_1.val_desc[2] == std::pair{2, "fault"});
+
+ auto &sig_2 = msg->sigs[1];
+ REQUIRE(sig_2.comment == "multiple line comment\n1\n2");
+}