Merge remote-tracking branch 'upstream/master' into random-test-segs

pull/30653/head
Shane Smiskol 1 year ago
commit d393bfdcf8
  1. 5
      Jenkinsfile
  2. 2
      cereal
  3. 5
      selfdrive/athena/athenad.py
  4. 25
      selfdrive/athena/tests/test_athenad_ping.py
  5. 15
      selfdrive/ui/soundd.py
  6. 9
      system/camerad/cameras/camera_common.cc
  7. 3
      system/camerad/cameras/camera_common.h
  8. 46
      system/camerad/cameras/camera_qcom2.cc
  9. 5
      system/camerad/cameras/camera_qcom2.h
  10. 1
      system/camerad/sensors/ar0231.cc
  11. 1
      system/camerad/sensors/ox03c10.cc
  12. 1
      system/camerad/sensors/sensor.h
  13. 19
      system/micd.py
  14. 2
      teleoprtc_repo
  15. 4
      tools/cabana/dbc/dbc.h
  16. 9
      tools/cabana/dbc/dbcfile.cc
  17. 6
      tools/cabana/dbc/dbcfile.h
  18. 25
      tools/cabana/dbc/dbcmanager.cc
  19. 7
      tools/cabana/dbc/dbcmanager.h
  20. 26
      tools/cabana/mainwin.cc
  21. 1
      tools/cabana/mainwin.h
  22. 4
      tools/cabana/tests/test_cabana.cc
  23. 1
      tools/cabana/util.cc
  24. 2
      tools/sim/lib/camerad.py
  25. 8
      tools/sim/lib/simulated_sensors.py

5
Jenkinsfile vendored

@ -234,9 +234,8 @@ node {
'car tests': {
pcStage("car tests") {
sh label: "build", script: "selfdrive/manager/build.py"
sh label: "test_models.py", script: "INTERNAL_SEG_CNT=250 INTERNAL_SEG_LIST=selfdrive/car/tests/test_models_segs.txt FILEREADER_CACHE=1 \
pytest selfdrive/car/tests/test_models.py"
sh label: "test_car_interfaces.py", script: "MAX_EXAMPLES=100 pytest selfdrive/car/tests/test_car_interfaces.py"
sh label: "run car tests", script: "cd selfdrive/car/tests && MAX_EXAMPLES=100 INTERNAL_SEG_CNT=250 FILEREADER_CACHE=1 \
INTERNAL_SEG_LIST=selfdrive/car/tests/test_models_segs.txt pytest test_models.py test_car_interfaces.py"
}
},

@ -1 +1 @@
Subproject commit 4fb8352484c4ef074bee775975c0d1d1e8f57a78
Subproject commit a3a6e4969e58875f7cdfc9e6cc6b1af3ee2392b5

@ -41,9 +41,6 @@ from openpilot.system.version import get_commit, get_origin, get_short_branch, g
from openpilot.system.hardware.hw import Paths
# TODO: use socket constant when mypy recognizes this as a valid attribute
TCP_USER_TIMEOUT = 18
ATHENA_HOST = os.getenv('ATHENA_HOST', 'wss://athena.comma.ai')
HANDLER_THREADS = int(os.getenv('HANDLER_THREADS', "4"))
LOCAL_PORT_WHITELIST = {8022}
@ -760,7 +757,7 @@ def ws_manage(ws: WebSocket, end_event: threading.Event) -> None:
if onroad != onroad_prev:
onroad_prev = onroad
sock.setsockopt(socket.IPPROTO_TCP, TCP_USER_TIMEOUT, 16000 if onroad else 0)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_USER_TIMEOUT, 16000 if onroad else 0)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 7 if onroad else 30)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 7 if onroad else 10)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 2 if onroad else 3)

@ -3,8 +3,8 @@ import subprocess
import threading
import time
import unittest
from typing import Callable, cast, Optional
from unittest.mock import MagicMock
from typing import cast, Optional
from unittest import mock
from openpilot.common.params import Params
from openpilot.common.timeout import Timeout
@ -27,8 +27,6 @@ class TestAthenadPing(unittest.TestCase):
athenad: threading.Thread
exit_event: threading.Event
_create_connection: Callable
def _get_ping_time(self) -> Optional[str]:
return cast(Optional[str], self.params.get("LastAthenaPingTime", encoding="utf-8"))
@ -38,15 +36,9 @@ class TestAthenadPing(unittest.TestCase):
def _received_ping(self) -> bool:
return self._get_ping_time() is not None
@classmethod
def setUpClass(cls) -> None:
cls._create_connection = athenad.create_connection
athenad.create_connection = MagicMock(wraps=cls._create_connection)
@classmethod
def tearDownClass(cls) -> None:
wifi_radio(True)
athenad.create_connection = cls._create_connection
def setUp(self) -> None:
self.params = Params()
@ -58,19 +50,18 @@ class TestAthenadPing(unittest.TestCase):
self.exit_event = threading.Event()
self.athenad = threading.Thread(target=athenad.main, args=(self.exit_event,))
athenad.create_connection.reset_mock()
def tearDown(self) -> None:
if self.athenad.is_alive():
self.exit_event.set()
self.athenad.join()
def assertTimeout(self, reconnect_time: float) -> None:
@mock.patch('openpilot.selfdrive.athena.athenad.create_connection', autospec=True)
def assertTimeout(self, reconnect_time: float, mock_create_connection: mock.MagicMock) -> None:
self.athenad.start()
time.sleep(1)
athenad.create_connection.assert_called_once()
athenad.create_connection.reset_mock()
mock_create_connection.assert_called_once()
mock_create_connection.reset_mock()
# check normal behaviour
with self.subTest("Wi-Fi: receives ping"), Timeout(70, "no ping received"):
@ -78,7 +69,7 @@ class TestAthenadPing(unittest.TestCase):
time.sleep(0.1)
print("ping received")
athenad.create_connection.assert_not_called()
mock_create_connection.assert_not_called()
# websocket should attempt reconnect after short time
with self.subTest("LTE: attempt reconnect"):
@ -86,7 +77,7 @@ class TestAthenadPing(unittest.TestCase):
print("waiting for reconnect attempt")
start_time = time.monotonic()
with Timeout(reconnect_time, "no reconnect attempt"):
while not athenad.create_connection.called:
while not mock_create_connection.called:
time.sleep(0.1)
print(f"reconnect attempt after {time.monotonic() - start_time:.2f}s")

@ -10,9 +10,9 @@ from openpilot.common.basedir import BASEDIR
from openpilot.common.filter_simple import FirstOrderFilter
from openpilot.system import micd
from openpilot.system.hardware import TICI
from openpilot.common.realtime import Ratekeeper
from openpilot.system.hardware import PC
from openpilot.common.swaglog import cloudlog
SAMPLE_RATE = 48000
@ -130,16 +130,13 @@ class Soundd:
# sounddevice must be imported after forking processes
import sounddevice as sd
rk = Ratekeeper(20)
if TICI:
micd.wait_for_devices(sd) # wait for alsa to be initialized on device
sm = messaging.SubMaster(['controlsState', 'microphone'])
with sd.OutputStream(channels=1, samplerate=SAMPLE_RATE, callback=self.callback) as stream:
rk = Ratekeeper(20)
sm = messaging.SubMaster(['controlsState', 'microphone'])
if PC:
device = None
else:
device = "sdm845-tavil-snd-card: - (hw:0,0)"
with sd.OutputStream(device=device, channels=1, samplerate=SAMPLE_RATE, callback=self.callback) as stream:
cloudlog.info(f"soundd stream started: {stream.samplerate=} {stream.channels=} {stream.dtype=} {stream.device=}")
while True:
sm.update(0)

@ -36,7 +36,7 @@ public:
"-DIS_OX=%d -DCAM_NUM=%d%s",
ci->frame_width, ci->frame_height, ci->frame_stride, ci->frame_offset,
b->rgb_width, b->rgb_height, b->rgb_stride, buf_width, uv_offset,
s->camera_id==CAMERA_ID_OX03C10 ? 1 : 0, s->camera_num, s->camera_num==1 ? " -DVIGNETTING" : "");
ci->image_sensor == cereal::FrameData::ImageSensor::OX03C10, s->camera_num, s->camera_num==1 ? " -DVIGNETTING" : "");
const char *cl_file = "cameras/real_debayer.cl";
cl_program prg_debayer = cl_program_from_file(context, device_id, cl_file, args);
krnl_ = CL_CHECK_ERR(clCreateKernel(prg_debayer, "debayer10", &err));
@ -154,12 +154,7 @@ void fill_frame_data(cereal::FrameData::Builder &framed, const FrameMetadata &fr
const float ev = c->cur_ev[frame_data.frame_id % 3];
const float perc = util::map_val(ev, c->ci->min_ev, c->ci->max_ev, 0.0f, 100.0f);
framed.setExposureValPercent(perc);
if (c->camera_id == CAMERA_ID_AR0231) {
framed.setSensor(cereal::FrameData::ImageSensor::AR0231);
} else if (c->camera_id == CAMERA_ID_OX03C10) {
framed.setSensor(cereal::FrameData::ImageSensor::OX03C10);
}
framed.setSensor(c->ci->image_sensor);
}
kj::Array<uint8_t> get_raw_frame_image(const CameraBuf *b) {

@ -14,9 +14,6 @@
#include "common/swaglog.h"
#include "system/hardware/hw.h"
#define CAMERA_ID_AR0231 0
#define CAMERA_ID_OX03C10 1
const int YUV_BUFFER_COUNT = 20;
enum CameraType {

@ -106,8 +106,6 @@ static cam_cmd_power *power_set_wait(cam_cmd_power *power, int16_t delay_ms) {
}
int CameraState::sensors_init() {
create_sensor();
uint32_t cam_packet_handle = 0;
int size = sizeof(struct cam_packet)+sizeof(struct cam_cmd_buf_desc)*2;
auto pkt = mm.alloc<struct cam_packet>(size, &cam_packet_handle);
@ -403,15 +401,7 @@ void CameraState::enqueue_req_multi(int start, int n, bool dp) {
// ******************* camera *******************
void CameraState::create_sensor() {
if (camera_id == CAMERA_ID_AR0231) {
ci = std::make_unique<AR0231>();
} else if (camera_id == CAMERA_ID_OX03C10) {
ci = std::make_unique<OX03C10>();
} else {
assert(false);
}
void CameraState::sensor_set_parameters() {
target_grey_fraction = 0.3;
dc_gain_enabled = false;
@ -436,9 +426,8 @@ void CameraState::camera_map_bufs(MultiCameraState *s) {
enqueue_req_multi(1, FRAME_BUF_COUNT, 0);
}
void CameraState::camera_init(MultiCameraState *s, VisionIpcServer * v, int camera_id_, unsigned int fps, cl_device_id device_id, cl_context ctx, VisionStreamType yuv_type) {
void CameraState::camera_init(MultiCameraState *s, VisionIpcServer * v, cl_device_id device_id, cl_context ctx, VisionStreamType yuv_type) {
if (!enabled) return;
camera_id = camera_id_;
LOGD("camera init %d", camera_num);
request_id_last = 0;
@ -462,22 +451,25 @@ void CameraState::camera_open(MultiCameraState *multi_cam_state_, int camera_num
// init memorymanager for this camera
mm.init(multi_cam_state->video0_fd);
// probe the sensor
LOGD("-- Probing sensor %d", camera_num);
camera_id = CAMERA_ID_AR0231;
ret = sensors_init();
if (ret != 0) {
// TODO: use build flag instead?
LOGD("AR0231 init failed, trying OX03C10");
camera_id = CAMERA_ID_OX03C10;
ret = sensors_init();
}
LOGD("-- Probing sensor %d done with %d", camera_num, ret);
if (ret != 0) {
auto init_sensor_lambda = [this](SensorInfo *sensor) {
ci.reset(sensor);
int ret = sensors_init();
if (ret == 0) {
sensor_set_parameters();
}
return ret == 0;
};
// Try different sensors one by one until it success.
if (!init_sensor_lambda(new AR0231) &&
!init_sensor_lambda(new OX03C10)) {
LOGE("** sensor %d FAILED bringup, disabling", camera_num);
enabled = false;
return;
}
LOGD("-- Probing sensor %d success", camera_num);
// create session
struct cam_req_mgr_session_info session_info = {};
@ -626,9 +618,9 @@ void CameraState::camera_open(MultiCameraState *multi_cam_state_, int camera_num
}
void cameras_init(VisionIpcServer *v, MultiCameraState *s, cl_device_id device_id, cl_context ctx) {
s->driver_cam.camera_init(s, v, s->driver_cam.camera_id, 20, device_id, ctx, VISION_STREAM_DRIVER);
s->road_cam.camera_init(s, v, s->road_cam.camera_id, 20, device_id, ctx, VISION_STREAM_ROAD);
s->wide_road_cam.camera_init(s, v, s->wide_road_cam.camera_id, 20, device_id, ctx, VISION_STREAM_WIDE_ROAD);
s->driver_cam.camera_init(s, v, device_id, ctx, VISION_STREAM_DRIVER);
s->road_cam.camera_init(s, v, device_id, ctx, VISION_STREAM_ROAD);
s->wide_road_cam.camera_init(s, v, device_id, ctx, VISION_STREAM_WIDE_ROAD);
s->pm = new PubMaster({"roadCameraState", "driverCameraState", "wideRoadCameraState", "thumbnail"});
}

@ -48,9 +48,9 @@ public:
void sensors_start();
void camera_open(MultiCameraState *multi_cam_state, int camera_num, bool enabled);
void create_sensor();
void sensor_set_parameters();
void camera_map_bufs(MultiCameraState *s);
void camera_init(MultiCameraState *s, VisionIpcServer *v, int camera_id, unsigned int fps, cl_device_id device_id, cl_context ctx, VisionStreamType yuv_type);
void camera_init(MultiCameraState *s, VisionIpcServer *v, cl_device_id device_id, cl_context ctx, VisionStreamType yuv_type);
void camera_close();
int32_t session_handle;
@ -68,7 +68,6 @@ public:
int frame_id_last;
int idx_offset;
bool skipped;
int camera_id;
CameraBuf buf;
MemoryManager mm;

@ -77,6 +77,7 @@ float ar0231_parse_temp_sensor(uint16_t calib1, uint16_t calib2, uint16_t data_r
} // namespace
AR0231::AR0231() {
image_sensor = cereal::FrameData::ImageSensor::AR0231;
data_word = true;
frame_width = FRAME_WIDTH;
frame_height = FRAME_HEIGHT;

@ -22,6 +22,7 @@ const uint32_t VS_TIME_MAX_OX03C10 = 34; // vs < 35
} // namespace
OX03C10::OX03C10() {
image_sensor = cereal::FrameData::ImageSensor::OX03C10;
data_word = false;
frame_width = FRAME_WIDTH;
frame_height = FRAME_HEIGHT;

@ -23,6 +23,7 @@ public:
virtual int getSlaveAddress(int port) const { assert(0); }
virtual void processRegisters(CameraState *c, cereal::FrameData::Builder &framed) const {}
cereal::FrameData::ImageSensor image_sensor = cereal::FrameData::ImageSensor::UNKNOWN;
uint32_t frame_width, frame_height;
uint32_t frame_stride;
uint32_t frame_offset = 0;

@ -3,7 +3,9 @@ import numpy as np
from cereal import messaging
from openpilot.common.realtime import Ratekeeper
from openpilot.common.retry import retry
from openpilot.common.swaglog import cloudlog
from openpilot.system.hardware import TICI
RATE = 10
FFT_SAMPLES = 4096
@ -11,6 +13,18 @@ REFERENCE_SPL = 2e-5 # newtons/m^2
SAMPLE_RATE = 44100
@retry(attempts=7, delay=3)
def wait_for_devices(sd):
# reload sounddevice to reinitialize portaudio
sd._terminate()
sd._initialize()
devices = sd.query_devices()
cloudlog.info(f"sounddevice available devices: {list(devices)}")
assert len(devices) > 0
def calculate_spl(measurements):
# https://www.engineeringtoolbox.com/sound-pressure-d_711.html
sound_pressure = np.sqrt(np.mean(measurements ** 2)) # RMS of amplitudes
@ -81,7 +95,10 @@ class Mic:
# sounddevice must be imported after forking processes
import sounddevice as sd
with sd.InputStream(channels=1, samplerate=SAMPLE_RATE, callback=self.callback) as stream:
if TICI:
wait_for_devices(sd) # wait for alsa to be initialized on device
with sd.InputStream(channels=1, samplerate=SAMPLE_RATE, callback=self.callback) as stream:
cloudlog.info(f"micd stream started: {stream.samplerate=} {stream.channels=} {stream.dtype=} {stream.device=}")
while True:
self.update()

@ -1 +1 @@
Subproject commit 8ec477868591eed9a6136a44f16428bc0468b4e9
Subproject commit 4df237c512622d3914a73f4fc15a3fc89b7f5a97

@ -1,12 +1,10 @@
#pragma once
#include <limits>
#include <string>
#include <utility>
#include <vector>
#include <QColor>
#include <QList>
#include <QMetaType>
#include <QString>
@ -47,7 +45,7 @@ struct std::hash<MessageId> {
std::size_t operator()(const MessageId &k) const noexcept { return qHash(k); }
};
typedef QList<std::pair<double, QString>> ValueDescription;
typedef std::vector<std::pair<double, QString>> ValueDescription;
namespace cabana {

@ -52,8 +52,7 @@ void DBCFile::cleanupAutoSaveFile() {
bool DBCFile::writeContents(const QString &fn) {
QFile file(fn);
if (file.open(QIODevice::WriteOnly)) {
file.write(generateDBC().toUtf8());
return true;
return file.write(generateDBC().toUtf8()) >= 0;
}
return false;
}
@ -77,10 +76,6 @@ cabana::Msg *DBCFile::msg(const QString &name) {
return it != msgs.end() ? &(it->second) : nullptr;
}
int DBCFile::signalCount() {
return std::accumulate(msgs.cbegin(), msgs.cend(), 0, [](int &n, const auto &m) { return n + m.second.sigs.size(); });
}
void DBCFile::parse(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]+)\] \"(.*)\" (.*))");
@ -226,7 +221,7 @@ QString DBCFile::generateDBC() {
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()) {
if (!sig->val_desc.empty()) {
QStringList text;
for (auto &[val, desc] : sig->val_desc) {
text << QString("%1 \"%2\"").arg(val).arg(desc);

@ -27,10 +27,8 @@ public:
cabana::Msg *msg(const QString &name);
inline cabana::Msg *msg(const MessageId &id) { return msg(id.address); }
int signalCount();
inline int msgCount() { return msgs.size(); }
inline QString name() { return name_.isEmpty() ? "untitled" : name_; }
inline bool isEmpty() { return (signalCount() == 0) && name_.isEmpty(); }
inline QString name() const { return name_.isEmpty() ? "untitled" : name_; }
inline bool isEmpty() const { return msgs.empty() && name_.isEmpty(); }
QString filename;

@ -106,12 +106,6 @@ QString DBCManager::newSignalName(const MessageId &id) {
return m ? m->newSignalName() : "";
}
const std::vector<uint8_t> &DBCManager::mask(const MessageId &id) {
static std::vector<uint8_t> empty_mask;
auto m = msg(id);
return m ? m->mask : empty_mask;
}
const std::map<uint32_t, cabana::Msg> &DBCManager::getMessages(uint8_t source) {
static std::map<uint32_t, cabana::Msg> empty_msgs;
auto dbc_file = findDBCFile(source);
@ -143,25 +137,6 @@ QStringList DBCManager::signalNames() {
return ret;
}
int DBCManager::signalCount(const MessageId &id) {
auto m = msg(id);
return m ? m->sigs.size() : 0;
}
int DBCManager::signalCount() {
auto files = allDBCFiles();
return std::accumulate(files.cbegin(), files.cend(), 0, [](int &n, auto &f) { return n + f->signalCount(); });
}
int DBCManager::msgCount() {
auto files = allDBCFiles();
return std::accumulate(files.cbegin(), files.cend(), 0, [](int &n, auto &f) { return n + f->msgCount(); });
}
int DBCManager::dbcCount() {
return allDBCFiles().size();
}
int DBCManager::nonEmptyDBCCount() {
auto files = allDBCFiles();
return std::count_if(files.cbegin(), files.cend(), [](auto &f) { return !f->isEmpty(); });

@ -4,7 +4,6 @@
#include <memory>
#include <map>
#include <set>
#include <vector>
#include "tools/cabana/dbc/dbcfile.h"
@ -34,17 +33,13 @@ public:
QString newMsgName(const MessageId &id);
QString newSignalName(const MessageId &id);
const std::vector<uint8_t>& mask(const MessageId &id);
const std::map<uint32_t, cabana::Msg> &getMessages(uint8_t source);
cabana::Msg *msg(const MessageId &id);
cabana::Msg* msg(uint8_t source, const QString &name);
QStringList signalNames();
int signalCount(const MessageId &id);
int signalCount();
int msgCount();
int dbcCount();
inline int dbcCount() { return allDBCFiles().size(); }
int nonEmptyDBCCount();
const SourceSet sources(const DBCFile *dbc_file) const;

@ -46,7 +46,6 @@ MainWindow::MainWindow() : QMainWindow() {
static auto static_main_win = this;
qRegisterMetaType<uint64_t>("uint64_t");
qRegisterMetaType<SourceSet>("SourceSet");
qRegisterMetaType<ReplyMsgType>("ReplyMsgType");
installDownloadProgressHandler([](uint64_t cur, uint64_t total, bool success) {
emit static_main_win->updateProgressBar(cur, total, success);
});
@ -54,9 +53,7 @@ MainWindow::MainWindow() : QMainWindow() {
if (type == QtDebugMsg) std::cout << msg.toStdString() << std::endl;
emit static_main_win->showMessage(msg, 2000);
});
installMessageHandler([](ReplyMsgType type, const std::string msg) {
qInfo() << QString::fromStdString(msg);
});
installMessageHandler([](ReplyMsgType type, const std::string msg) { qInfo() << msg.c_str(); });
setStyleSheet(QString(R"(QMainWindow::separator {
width: %1px; /* when vertical */
@ -329,7 +326,7 @@ void MainWindow::loadFromClipboard(SourceSet s, bool close_all) {
QString dbc_str = QGuiApplication::clipboard()->text();
QString error;
bool ret = dbc()->open(s, "", dbc_str, &error);
if (ret && dbc()->msgCount() > 0) {
if (ret && dbc()->nonEmptyDBCCount() > 0) {
QMessageBox::information(this, tr("Load From Clipboard"), tr("DBC Successfully Loaded!"));
} else {
QMessageBox msg_box(QMessageBox::Warning, tr("Failed to load DBC from clipboard"), tr("Make sure that you paste the text with correct format."));
@ -356,7 +353,7 @@ void MainWindow::streamStarted() {
video_splitter->setSizes({1, 1});
}
// Don't overwrite already loaded DBC
if (!dbc()->msgCount()) {
if (!dbc()->nonEmptyDBCCount()) {
newFile();
}
@ -371,7 +368,7 @@ void MainWindow::eventsMerged() {
.arg(can->routeName())
.arg(car_fingerprint.isEmpty() ? tr("Unknown Car") : car_fingerprint));
// Don't overwrite already loaded DBC
if (!dbc()->msgCount() && !car_fingerprint.isEmpty()) {
if (!dbc()->nonEmptyDBCCount() && !car_fingerprint.isEmpty()) {
auto dbc_name = fingerprint_to_dbc[car_fingerprint];
if (dbc_name != QJsonValue::Undefined) {
// Prevent dialog that load autosaved file from blocking replay->start().
@ -529,7 +526,6 @@ void MainWindow::updateRecentFiles(const QString &fn) {
void MainWindow::updateRecentFileActions() {
int num_recent_files = std::min<int>(settings.recent_files.size(), MAX_RECENT_FILES);
for (int i = 0; i < num_recent_files; ++i) {
QString text = tr("&%1 %2").arg(i + 1).arg(QFileInfo(settings.recent_files[i]).fileName());
recent_files_acts[i]->setText(text);
@ -543,15 +539,11 @@ void MainWindow::updateRecentFileActions() {
}
void MainWindow::remindSaveChanges() {
bool discard_changes = false;
while (!UndoStack::instance()->isClean() && !discard_changes) {
while (!UndoStack::instance()->isClean()) {
QString text = tr("You have unsaved changes. Press ok to save them, cancel to discard.");
int ret = (QMessageBox::question(this, tr("Unsaved Changes"), text, QMessageBox::Ok | QMessageBox::Cancel));
if (ret == QMessageBox::Ok) {
save();
} else {
discard_changes = true;
}
int ret = QMessageBox::question(this, tr("Unsaved Changes"), text, QMessageBox::Ok | QMessageBox::Cancel);
if (ret != QMessageBox::Ok) break;
save();
}
UndoStack::instance()->clear();
}
@ -660,7 +652,7 @@ HelpOverlay::HelpOverlay(MainWindow *parent) : QWidget(parent) {
void HelpOverlay::paintEvent(QPaintEvent *event) {
QPainter painter(this);
painter.fillRect(rect(), QColor(0, 0, 0, 50));
MainWindow *parent = (MainWindow *)parentWidget();
auto parent = parentWidget();
drawHelpForWidget(painter, parent->findChild<MessagesWidget *>());
drawHelpForWidget(painter, parent->findChild<BinaryView *>());
drawHelpForWidget(painter, parent->findChild<SignalView *>());

@ -101,7 +101,6 @@ protected:
int prev_undostack_index = 0;
int prev_undostack_count = 0;
QByteArray default_state;
friend class OnlineHelp;
};
class HelpOverlay : public QWidget {

@ -3,9 +3,7 @@
#include <QDir>
#include "catch2/catch.hpp"
#include "tools/replay/logreader.h"
#include "tools/cabana/dbc/dbcmanager.h"
#include "tools/cabana/streams/abstractstream.h"
const std::string TEST_RLOG_URL = "https://commadataci.blob.core.windows.net/openpilotci/0c94aa1e1296d7c6/2021-05-05--19-48-37/0/rlog.bz2";
@ -14,7 +12,7 @@ TEST_CASE("DBCFile::generateDBC") {
DBCFile dbc_origin(fn);
DBCFile dbc_from_generated("", dbc_origin.generateDBC());
REQUIRE(dbc_origin.msgCount() == dbc_from_generated.msgCount());
REQUIRE(dbc_origin.getMessages().size() == dbc_from_generated.getMessages().size());
auto &msgs = dbc_origin.getMessages();
auto &new_msgs = dbc_from_generated.getMessages();
for (auto &[id, m] : msgs) {

@ -12,7 +12,6 @@
#include <QDateTime>
#include <QFontDatabase>
#include <QLocale>
#include <QPainter>
#include <QPixmapCache>
#include "selfdrive/ui/qt/util.h"

@ -59,7 +59,7 @@ class Camerad:
eof = int(frame_id * 0.05 * 1e9)
self.vipc_server.send(yuv_type, yuv, frame_id, eof, eof)
dat = messaging.new_message(pub_type)
dat = messaging.new_message(pub_type, valid=True)
msg = {
"frameId": frame_id,
"transform": [1.0, 0.0, 0.0,

@ -23,7 +23,7 @@ class SimulatedSensors:
def send_imu_message(self, simulator_state: 'SimulatorState'):
for _ in range(5):
dat = messaging.new_message('accelerometer')
dat = messaging.new_message('accelerometer', valid=True)
dat.accelerometer.sensor = 4
dat.accelerometer.type = 0x10
dat.accelerometer.timestamp = dat.logMonoTime # TODO: use the IMU timestamp
@ -32,7 +32,7 @@ class SimulatedSensors:
self.pm.send('accelerometer', dat)
# copied these numbers from locationd
dat = messaging.new_message('gyroscope')
dat = messaging.new_message('gyroscope', valid=True)
dat.gyroscope.sensor = 5
dat.gyroscope.type = 0x10
dat.gyroscope.timestamp = dat.logMonoTime # TODO: use the IMU timestamp
@ -53,7 +53,7 @@ class SimulatedSensors:
]
for _ in range(10):
dat = messaging.new_message('gpsLocationExternal')
dat = messaging.new_message('gpsLocationExternal', valid=True)
dat.gpsLocationExternal = {
"unixTimestampMillis": int(time.time() * 1000),
"flags": 1, # valid fix
@ -94,7 +94,7 @@ class SimulatedSensors:
self.pm.send('driverStateV2', dat)
# dmonitoringd output
dat = messaging.new_message('driverMonitoringState')
dat = messaging.new_message('driverMonitoringState', valid=True)
dat.driverMonitoringState = {
"faceDetected": True,
"isDistracted": False,

Loading…
Cancel
Save