diff --git a/selfdrive/car/hyundai/carstate.py b/selfdrive/car/hyundai/carstate.py index bd6b72f461..f3ce1709c3 100644 --- a/selfdrive/car/hyundai/carstate.py +++ b/selfdrive/car/hyundai/carstate.py @@ -200,8 +200,7 @@ class CarState(CarStateBase): ret.cruiseState.available = True cruise_btn_msg = "CRUISE_BUTTONS_ALT" if self.CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS else "CRUISE_BUTTONS" - distance_unit_msg = cruise_btn_msg if self.CP.carFingerprint == CAR.KIA_SORENTO_PHEV_4TH_GEN else "CLUSTER_INFO" - self.is_metric = cp.vl[distance_unit_msg]["DISTANCE_UNIT"] != 1 + self.is_metric = cp.vl["CRUISE_BUTTONS_ALT"]["DISTANCE_UNIT"] != 1 if not self.CP.openpilotLongitudinalControl: speed_factor = CV.KPH_TO_MS if self.is_metric else CV.MPH_TO_MS cp_cruise_info = cp_cam if self.CP.flags & HyundaiFlags.CANFD_CAMERA_SCC else cp @@ -439,8 +438,7 @@ class CarState(CarStateBase): ("COUNTER", cruise_btn_msg), ("CRUISE_BUTTONS", cruise_btn_msg), ("ADAPTIVE_CRUISE_MAIN_BTN", cruise_btn_msg), - - ("DISTANCE_UNIT", "CLUSTER_INFO"), + ("DISTANCE_UNIT", "CRUISE_BUTTONS_ALT"), ("LEFT_LAMP", "BLINKERS"), ("RIGHT_LAMP", "BLINKERS"), @@ -449,21 +447,20 @@ class CarState(CarStateBase): ("DRIVER_SEATBELT_LATCHED", "DOORS_SEATBELTS"), ] - if CP.carFingerprint == CAR.KIA_SORENTO_PHEV_4TH_GEN: - signals.append(("DISTANCE_UNIT", cruise_btn_msg)) - checks = [ ("WHEEL_SPEEDS", 100), (gear_msg, 100), ("STEERING_SENSORS", 100), ("MDPS", 100), ("TCS", 50), - (cruise_btn_msg, 50), - ("CLUSTER_INFO", 4), + ("CRUISE_BUTTONS_ALT", 50), ("BLINKERS", 4), ("DOORS_SEATBELTS", 4), ] + if not (CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS): + checks.append(("CRUISE_BUTTONS", 50)) + if CP.enableBsm: signals += [ ("FL_INDICATOR", "BLINDSPOTS_REAR_CORNERS"), diff --git a/tools/cabana/binaryview.cc b/tools/cabana/binaryview.cc index aa256b4ce1..b98c75d452 100644 --- a/tools/cabana/binaryview.cc +++ b/tools/cabana/binaryview.cc @@ -10,7 +10,7 @@ // BinaryView -const int CELL_HEIGHT = 26; +const int CELL_HEIGHT = 36; inline int get_bit_index(const QModelIndex &index, bool little_endian) { return index.row() * 8 + (little_endian ? 7 - index.column() : index.column()); @@ -24,14 +24,13 @@ BinaryView::BinaryView(QWidget *parent) : QTableView(parent) { horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); verticalHeader()->setSectionsClickable(false); verticalHeader()->setSectionResizeMode(QHeaderView::Fixed); + verticalHeader()->setDefaultSectionSize(CELL_HEIGHT); horizontalHeader()->hide(); - setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents); setFrameShape(QFrame::NoFrame); setShowGrid(false); - setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); setMouseTracking(true); + setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents); + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); } void BinaryView::highlight(const Signal *sig) { @@ -57,7 +56,7 @@ void BinaryView::setSelection(const QRect &rect, QItemSelectionModel::SelectionF } void BinaryView::mousePressEvent(QMouseEvent *event) { - delegate->setSelectionColor(style()->standardPalette().color(QPalette::Active, QPalette::Highlight)); + delegate->selection_color = (palette().color(QPalette::Active, QPalette::Highlight)); if (auto index = indexAt(event->pos()); index.isValid() && index.column() != 8) { anchor_index = index; auto item = (const BinaryViewModel::Item *)anchor_index.internalPointer(); @@ -66,7 +65,7 @@ void BinaryView::mousePressEvent(QMouseEvent *event) { if (bit_idx == s->lsb || bit_idx == s->msb) { anchor_index = model->bitIndex(bit_idx == s->lsb ? s->msb : s->lsb, true); resize_sig = s; - delegate->setSelectionColor(item->bg_color); + delegate->selection_color = item->bg_color; break; } } @@ -79,8 +78,7 @@ void BinaryView::highlightPosition(const QPoint &pos) { auto item = (BinaryViewModel::Item *)index.internalPointer(); const Signal *sig = item->sigs.isEmpty() ? nullptr : item->sigs.back(); highlight(sig); - sig ? QToolTip::showText(pos, sig->name.c_str(), this, rect()) - : QToolTip::hideText(); + QToolTip::showText(pos, sig ? sig->name.c_str() : "", this, rect()); } } @@ -214,7 +212,7 @@ QVariant BinaryViewModel::headerData(int section, Qt::Orientation orientation, i if (orientation == Qt::Vertical) { switch (role) { case Qt::DisplayRole: return section; - case Qt::SizeHintRole: return QSize(30, CELL_HEIGHT); + case Qt::SizeHintRole: return QSize(30, 0); case Qt::TextAlignmentRole: return Qt::AlignCenter; } } @@ -224,16 +222,9 @@ QVariant BinaryViewModel::headerData(int section, Qt::Orientation orientation, i // BinaryItemDelegate BinaryItemDelegate::BinaryItemDelegate(QObject *parent) : QStyledItemDelegate(parent) { - // cache fonts and color - small_font.setPointSize(6); + small_font.setPixelSize(8); hex_font = QFontDatabase::systemFont(QFontDatabase::FixedFont); hex_font.setBold(true); - selection_color = QApplication::style()->standardPalette().color(QPalette::Active, QPalette::Highlight); -} - -QSize BinaryItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { - QSize sz = QStyledItemDelegate::sizeHint(option, index); - return {sz.width(), CELL_HEIGHT}; } void BinaryItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { @@ -245,12 +236,10 @@ void BinaryItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op painter->setFont(hex_font); } else if (option.state & QStyle::State_Selected) { painter->fillRect(option.rect, selection_color); - painter->setPen(QApplication::style()->standardPalette().color(QPalette::BrightText)); + painter->setPen(option.palette.color(QPalette::BrightText)); } else if (!item->sigs.isEmpty() && (!bin_view->selectionModel()->hasSelection() || !item->sigs.contains(bin_view->resize_sig))) { painter->fillRect(option.rect, item->bg_color); - painter->setPen(item->sigs.contains(bin_view->hovered_sig) - ? QApplication::style()->standardPalette().color(QPalette::BrightText) - : Qt::black); + painter->setPen(item->sigs.contains(bin_view->hovered_sig) ? option.palette.color(QPalette::BrightText) : Qt::black); } painter->drawText(option.rect, Qt::AlignCenter, item->val); @@ -258,6 +247,5 @@ void BinaryItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op painter->setFont(small_font); painter->drawText(option.rect, Qt::AlignHCenter | Qt::AlignBottom, item->is_msb ? "MSB" : "LSB"); } - painter->restore(); } diff --git a/tools/cabana/binaryview.h b/tools/cabana/binaryview.h index c37b378e44..e936efc658 100644 --- a/tools/cabana/binaryview.h +++ b/tools/cabana/binaryview.h @@ -9,22 +9,16 @@ #include "tools/cabana/dbcmanager.h" class BinaryItemDelegate : public QStyledItemDelegate { - Q_OBJECT - public: BinaryItemDelegate(QObject *parent); void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; - QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; void setSelectionColor(const QColor &color) { selection_color = color; } -private: QFont small_font, hex_font; QColor selection_color; }; class BinaryViewModel : public QAbstractTableModel { - Q_OBJECT - public: BinaryViewModel(QObject *parent) : QAbstractTableModel(parent) {} void setMessage(const QString &message_id); @@ -52,7 +46,7 @@ public: private: QString msg_id; - const DBCMsg *dbc_msg; + const DBCMsg *dbc_msg = nullptr; int row_count = 0; const int column_count = 9; }; diff --git a/tools/cabana/chartswidget.cc b/tools/cabana/chartswidget.cc index 79b40133a5..0fb19681e9 100644 --- a/tools/cabana/chartswidget.cc +++ b/tools/cabana/chartswidget.cc @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include @@ -19,6 +18,7 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QWidget(parent) { title_label = new QLabel(); title_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); toolbar->addWidget(title_label); + show_all_values_btn = toolbar->addAction(""); toolbar->addWidget(range_label = new QLabel()); reset_zoom_btn = toolbar->addAction("⟲"); reset_zoom_btn->setToolTip(tr("Reset zoom (drag on chart to zoom X-Axis)")); @@ -26,7 +26,6 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QWidget(parent) { remove_all_btn->setToolTip(tr("Remove all charts")); dock_btn = toolbar->addAction(""); main_layout->addWidget(toolbar); - updateToolBar(); // charts QWidget *charts_container = new QWidget(this); @@ -37,14 +36,16 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QWidget(parent) { charts_scroll->setWidgetResizable(true); charts_scroll->setWidget(charts_container); charts_scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - main_layout->addWidget(charts_scroll); + max_chart_range = settings.max_chart_x_range; use_dark_theme = palette().color(QPalette::WindowText).value() > palette().color(QPalette::Background).value(); + updateToolBar(); QObject::connect(dbc(), &DBCManager::DBCFileChanged, this, &ChartsWidget::removeAll); QObject::connect(can, &CANMessages::eventsMerged, this, &ChartsWidget::eventsMerged); QObject::connect(can, &CANMessages::updated, this, &ChartsWidget::updateState); + QObject::connect(show_all_values_btn, &QAction::triggered, this, &ChartsWidget::showAllData); QObject::connect(remove_all_btn, &QAction::triggered, this, &ChartsWidget::removeAll); QObject::connect(reset_zoom_btn, &QAction::triggered, this, &ChartsWidget::zoomReset); QObject::connect(dock_btn, &QAction::triggered, [this]() { @@ -58,7 +59,7 @@ void ChartsWidget::eventsMerged() { if (auto events = can->events(); events && !events->empty()) { event_range.first = (events->front()->mono_time / (double)1e9) - can->routeStartTime(); event_range.second = (events->back()->mono_time / (double)1e9) - can->routeStartTime(); - updateDisplayRange(); + updateState(); } } @@ -69,8 +70,8 @@ void ChartsWidget::updateDisplayRange() { // reached the end, or seeked to a timestamp out of range. display_range.first = current_sec - 5; } - display_range.first = std::max(display_range.first, event_range.first); - display_range.second = std::min(display_range.first + settings.max_chart_x_range, event_range.second); + display_range.first = std::floor(std::max(display_range.first, event_range.first) * 10.0) / 10.0; + display_range.second = std::floor(std::min(display_range.first + max_chart_range, event_range.second) * 10.0) / 10.0; if (prev_range != display_range) { QFutureSynchronizer future_synchronizer; for (auto c : charts) @@ -100,13 +101,29 @@ void ChartsWidget::updateState() { } const auto &range = is_zoomed ? zoomed_range : display_range; + setUpdatesEnabled(false); for (auto c : charts) { c->setDisplayRange(range.first, range.second); c->scene()->invalidate({}, QGraphicsScene::ForegroundLayer); } + setUpdatesEnabled(true); +} + +void ChartsWidget::showAllData() { + bool switch_to_show_all = max_chart_range == settings.max_chart_x_range; + max_chart_range = switch_to_show_all ? settings.cached_segment_limit * 60 + : settings.max_chart_x_range; + max_chart_range = std::min(max_chart_range, (uint32_t)can->totalSeconds()); + updateToolBar(); + updateState(); } void ChartsWidget::updateToolBar() { + int min_range = std::min(settings.max_chart_x_range, (int)can->totalSeconds()); + bool displaying_all = max_chart_range != min_range; + show_all_values_btn->setText(tr("%1 minutes").arg(max_chart_range / 60)); + show_all_values_btn->setToolTip(tr("Click to display %1 data").arg(displaying_all ? tr("%1 minutes").arg(min_range / 60) : tr("ALL cached"))); + show_all_values_btn->setVisible(!is_zoomed); remove_all_btn->setEnabled(!charts.isEmpty()); reset_zoom_btn->setEnabled(is_zoomed); range_label->setText(is_zoomed ? tr("%1 - %2").arg(zoomed_range.first, 0, 'f', 2).arg(zoomed_range.second, 0, 'f', 2) : ""); @@ -232,6 +249,7 @@ void ChartView::addSeries(const QString &msg_id, const Signal *sig) { sigs.push_back({.msg_id = msg_id, .address = address, .source = source, .sig = sig, .series = series}); updateTitle(); updateSeries(sig); + updateAxisY(); } void ChartView::removeSeries(const QString &msg_id, const Signal *sig) { @@ -242,8 +260,7 @@ void ChartView::removeSeries(const QString &msg_id, const Signal *sig) { } bool ChartView::hasSeries(const QString &msg_id, const Signal *sig) const { - auto it = std::find_if(sigs.begin(), sigs.end(), [&](auto &s) { return s.msg_id == msg_id && s.sig == sig; }); - return it != sigs.end(); + return std::any_of(sigs.begin(), sigs.end(), [&](auto &s) { return s.msg_id == msg_id && s.sig == sig; }); } QList::iterator ChartView::removeSeries(const QList::iterator &it) { @@ -261,11 +278,11 @@ QList::iterator ChartView::removeSeries(const QListreplace(s.vals); } } - updateAxisY(); } // auto zoom on yaxis @@ -422,11 +437,39 @@ void ChartView::updateAxisY() { axis_y->setRange(min_y - 1, max_y + 1); } else { double range = max_y - min_y; - axis_y->setRange(min_y - range * 0.05, max_y + range * 0.05); - axis_y->applyNiceNumbers(); + applyNiceNumbers(min_y - range * 0.05, max_y + range * 0.05); } - QTimer::singleShot(0, this, &ChartView::adjustChartMargins); + adjustChartMargins(); +} + +void ChartView::applyNiceNumbers(qreal min, qreal max) { + int tick_count = axis_y->tickCount(); + qreal range = niceNumber((max - min), true); // range with ceiling + qreal step = niceNumber(range / (tick_count - 1), false); + min = qFloor(min / step); + max = qCeil(max / step); + tick_count = int(max - min) + 1; + axis_y->setRange(min * step, max * step); + axis_y->setTickCount(tick_count); +} + +//nice numbers can be expressed as form of 1*10^n, 2* 10^n or 5*10^n +qreal ChartView::niceNumber(qreal x, bool ceiling) { + qreal z = qPow(10, qFloor(std::log10(x))); //find corresponding number of the form of 10^n than is smaller than x + qreal q = x / z; //q<10 && q>=1; + if (ceiling) { + if (q <= 1.0) q = 1; + else if (q <= 2.0) q = 2; + else if (q <= 5.0) q = 5; + else q = 10; + } else { + if (q < 1.5) q = 1; + else if (q < 3.0) q = 2; + else if (q < 7.0) q = 5; + else q = 10; + } + return q * z; } void ChartView::leaveEvent(QEvent *event) { diff --git a/tools/cabana/chartswidget.h b/tools/cabana/chartswidget.h index 3e3277c5b8..b3a4bcf2a0 100644 --- a/tools/cabana/chartswidget.h +++ b/tools/cabana/chartswidget.h @@ -66,6 +66,8 @@ private: void updateTitle(); void updateFromSettings(); void drawForeground(QPainter *painter, const QRectF &rect) override; + void applyNiceNumbers(qreal min, qreal max); + qreal niceNumber(qreal x, bool ceiling); QValueAxis *axis_x; QValueAxis *axis_y; @@ -102,17 +104,20 @@ private: void zoomReset(); void updateToolBar(); void removeAll(); + void showAllData(); bool eventFilter(QObject *obj, QEvent *event) override; ChartView *findChart(const QString &id, const Signal *sig); QLabel *title_label; QLabel *range_label; bool docking = true; + QAction *show_all_values_btn; QAction *dock_btn; QAction *reset_zoom_btn; QAction *remove_all_btn; QVBoxLayout *charts_layout; QList charts; + uint32_t max_chart_range = 0; bool is_zoomed = false; std::pair event_range; std::pair display_range;