From d124f620786720efe44bba2594bb1908e4b6b822 Mon Sep 17 00:00:00 2001 From: Jason Wen <47793918+sunnyhaibin@users.noreply.github.com> Date: Sun, 12 Mar 2023 16:23:00 -0400 Subject: [PATCH] ui: developer ui (#48) * Hide 2nd row dev UI when map is visible * Dev UI init * fixup! Dev UI init * fixup! Dev UI init * fixup! Dev UI init * fixup! Dev UI init * fixup! Dev UI init * fixup! Dev UI init * Disable lateraState for now? * Revert "Disable lateraState for now?" This reverts commit ff669862e9ab7cfe421a0266dfc503b3b190143a. * add cs.laterelState * should be bool * bruh * change dm icon too * Bruh should be y * don't draw border * bolded text * bring back memory usage * angleSteer status color * move it higher * higher * lower * closer together * Move this button too * fixup! Move this button too * Move this text? * to the left * left and down * missed an argument * move them a bit * readjust bottom row positioning * test position * revert to this * wider! * proper space reference * unused * other method * fix * shorter * more spaces * wider * do it like this * should be width * add on top * wider * lineup right * align this right * different one * try this * fix * align right! * make unit strings standalone * Try this out * adjust * align to unit strings * adjust! * adjust! * Revert "adjust!" This reverts commit 748b74c21a986b4ed62acdcceb83226ff523e5ce. * Revert "adjust!" This reverts commit 4f5373b0de503203098c5fd495e72227f4525be4. * more adjust * final adjust? * final adjust? * wider * keep left * Try this out * more together * hmm * adjust * align differently * adjust final * adjust more * adjust more * Try this out * last * Try this * Try that * wider * only check when starting * comment * remove second column and second row; change settings to 5 or 10 metrics; implement in future PRs * fixup! remove second column and second row; change settings to 5 or 10 metrics; implement in future PRs * fixup! remove second column and second row; change settings to 5 or 10 metrics; implement in future PRs --- common/params.cc | 2 +- selfdrive/controls/controlsd.py | 1 + selfdrive/manager/manager.py | 2 +- selfdrive/ui/qt/home.cc | 2 + .../ui/qt/offroad/sunnypilot_settings.cc | 22 +- selfdrive/ui/qt/offroad/sunnypilot_settings.h | 4 +- selfdrive/ui/qt/onroad.cc | 374 +++++++++++++++++- selfdrive/ui/qt/onroad.h | 62 +++ .../ui/qt/screenrecorder/screenrecorder.cc | 4 +- selfdrive/ui/ui.cc | 7 +- selfdrive/ui/ui.h | 7 + 11 files changed, 464 insertions(+), 23 deletions(-) diff --git a/common/params.cc b/common/params.cc index c5886d580b..18d1e426b1 100644 --- a/common/params.cc +++ b/common/params.cc @@ -222,7 +222,7 @@ std::unordered_map keys = { {"CustomStockLong", PERSISTENT}, {"CustomTorqueLateral", PERSISTENT}, {"DevUI", PERSISTENT}, - {"DevUIRow", PERSISTENT}, + {"DevUIInfo", PERSISTENT}, {"DisableOnroadUploads", PERSISTENT}, {"DisengageLateralOnBrake", PERSISTENT}, {"DynamicLaneProfile", PERSISTENT}, diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index 595d30c6e7..6807ee978f 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -843,6 +843,7 @@ class Controls: controlsState.lateralControlState.torqueState = lac_log elif lat_tuning == 'indi': controlsState.lateralControlState.indiState = lac_log + controlsState.lateralState = lat_tuning self.pm.send('controlsState', dat) diff --git a/selfdrive/manager/manager.py b/selfdrive/manager/manager.py index 19d6303066..7fa790aa98 100755 --- a/selfdrive/manager/manager.py +++ b/selfdrive/manager/manager.py @@ -60,7 +60,7 @@ def manager_init() -> None: ("CustomBootScreen", "0"), ("CustomOffsets", "0"), ("DevUI", "1"), - ("DevUIRow", "1"), + ("DevUIInfo", "1"), ("DisableOnroadUploads", "0"), ("DisengageLateralOnBrake", "1"), ("DynamicLaneProfile", "2"), diff --git a/selfdrive/ui/qt/home.cc b/selfdrive/ui/qt/home.cc index 41a97f805f..4d651ce37f 100644 --- a/selfdrive/ui/qt/home.cc +++ b/selfdrive/ui/qt/home.cc @@ -56,6 +56,8 @@ void HomeWindow::updateState(const UIState &s) { body->setEnabled(true); slayout->setCurrentWidget(body); } + + uiState()->scene.map_visible = onroad->isMapVisible(); } void HomeWindow::offroadTransition(bool offroad) { diff --git a/selfdrive/ui/qt/offroad/sunnypilot_settings.cc b/selfdrive/ui/qt/offroad/sunnypilot_settings.cc index e1cbde7f15..0f553d62cd 100644 --- a/selfdrive/ui/qt/offroad/sunnypilot_settings.cc +++ b/selfdrive/ui/qt/offroad/sunnypilot_settings.cc @@ -585,7 +585,7 @@ SPVisualsPanel::SPVisualsPanel(QWidget *parent) : QWidget(parent) { ); devUiSub->setContentsMargins(QMargins()); devUiSub->addWidget(horizontal_line()); - devUiSub->addWidget(new DevUiRow()); + devUiSub->addWidget(new DevUiInfo()); connect(devUi, &ToggleControl::toggleFlipped, [=](bool state) { updateToggles(); }); @@ -1697,8 +1697,8 @@ void VwAccType::refresh() { btnplus.setText("+"); } -// Developer UI Rows (Dev UI) -DevUiRow::DevUiRow() : AbstractControl( +// Developer UI Info (Dev UI) +DevUiInfo::DevUiInfo() : AbstractControl( tr("Developer UI List"), tr("Select the number of lists of real-time parameters you would like to display on the sunnypilot screen while driving."), "../assets/offroad/icon_blank.png") @@ -1730,37 +1730,37 @@ DevUiRow::DevUiRow() : AbstractControl( hlayout->addWidget(&btnplus); QObject::connect(&btnminus, &QPushButton::clicked, [=]() { - auto str = QString::fromStdString(params.get("DevUIRow")); + auto str = QString::fromStdString(params.get("DevUIInfo")); int value = str.toInt(); value = value - 1; if (value <= 0 ) { value = 0; } QString values = QString::number(value); - params.put("DevUIRow", values.toStdString()); + params.put("DevUIInfo", values.toStdString()); refresh(); }); QObject::connect(&btnplus, &QPushButton::clicked, [=]() { - auto str = QString::fromStdString(params.get("DevUIRow")); + auto str = QString::fromStdString(params.get("DevUIInfo")); int value = str.toInt(); value = value + 1; if (value >= 1 ) { value = 1; } QString values = QString::number(value); - params.put("DevUIRow", values.toStdString()); + params.put("DevUIInfo", values.toStdString()); refresh(); }); refresh(); } -void DevUiRow::refresh() { - QString option = QString::fromStdString(params.get("DevUIRow")); +void DevUiInfo::refresh() { + QString option = QString::fromStdString(params.get("DevUIInfo")); if (option == "0") { - label.setText(tr("1-Row")); + label.setText(tr("5 Metrics")); } else { - label.setText(tr("2-Row")); + label.setText(tr("10 Metrics")); } btnminus.setText("-"); btnplus.setText("+"); diff --git a/selfdrive/ui/qt/offroad/sunnypilot_settings.h b/selfdrive/ui/qt/offroad/sunnypilot_settings.h index 9fdba678d5..272cccbe12 100644 --- a/selfdrive/ui/qt/offroad/sunnypilot_settings.h +++ b/selfdrive/ui/qt/offroad/sunnypilot_settings.h @@ -323,11 +323,11 @@ private: void refresh(); }; -class DevUiRow : public AbstractControl { +class DevUiInfo : public AbstractControl { Q_OBJECT public: - DevUiRow(); + DevUiInfo(); private: QPushButton btnplus; diff --git a/selfdrive/ui/qt/onroad.cc b/selfdrive/ui/qt/onroad.cc index d7aded3b6a..7698c8eeef 100644 --- a/selfdrive/ui/qt/onroad.cc +++ b/selfdrive/ui/qt/onroad.cc @@ -155,8 +155,8 @@ void OnroadWindow::mousePressEvent(QMouseEvent* e) { auto car_state = sm["carState"].getCarState(); auto controls_state = sm["controlsState"].getControlsState(); - QRect dlp_btn_rect = QRect(bdr_s * 2 + 220, (rect().bottom() - footer_h / 2 - 75), 150, 150); - QRect gac_btn_rect = QRect(bdr_s * 2 + 220 + 180, (rect().bottom() - footer_h / 2 - 75), 150, 150); + QRect dlp_btn_rect = QRect(bdr_s * 2 + 220, (rect().bottom() - footer_h / 2 - 75) - scene.rn_offset, 150, 150); + QRect gac_btn_rect = QRect(bdr_s * 2 + 220 + 180, (rect().bottom() - footer_h / 2 - 75) - scene.rn_offset, 150, 150); QRect debug_tap_rect = QRect(rect().center().x() - 200, rect().center().y() - 200, 400, 400); QRect speed_limit_touch_rect = speed_sgn_rc.adjusted(-50, -50, 50, 50); @@ -377,6 +377,9 @@ void AnnotatedCameraWidget::updateState(const UIState &s) { const auto cs = sm["controlsState"].getControlsState(); const auto car_state = sm["carState"].getCarState(); const auto car_control = sm["carControl"].getCarControl(); + const auto radar_state = sm["radarState"].getRadarState(); + const auto gpsLocationExternal = sm["gpsLocationExternal"].getGpsLocationExternal(); + const auto ltp = sm["liveTorqueParameters"].getLiveTorqueParameters(); // Handle older routes where vCruiseCluster is not set float v_cruise = cs.getVCruiseCluster() == 0.0 ? cs.getVCruise() : cs.getVCruiseCluster(); @@ -436,6 +439,33 @@ void AnnotatedCameraWidget::updateState(const UIState &s) { car_state.getCruiseState().getAvailable()); setProperty("gacTr", s.scene.gac_tr); + setProperty("mapVisible", s.scene.map_visible); + + // ############################## DEV UI START ############################## + setProperty("lead_d_rel", radar_state.getLeadOne().getDRel()); + setProperty("lead_v_rel", radar_state.getLeadOne().getVRel()); + setProperty("lead_status", radar_state.getLeadOne().getStatus()); + setProperty("lateralState", QString::fromStdString(cs.getLateralState())); + setProperty("angleSteers", car_state.getSteeringAngleDeg()); + setProperty("steerAngleDesired", cs.getLateralControlState().getPidState().getSteeringAngleDesiredDeg()); + setProperty("curvature", cs.getCurvature()); + setProperty("roll", sm["liveParameters"].getLiveParameters().getRoll()); + setProperty("memoryUsagePercent", sm["deviceState"].getDeviceState().getMemoryUsagePercent()); + setProperty("devUiEnabled", s.scene.dev_ui_enabled); + setProperty("devUiInfo", s.scene.dev_ui_info); + setProperty("gpsAccuracy", gpsLocationExternal.getAccuracy()); + setProperty("altitude", gpsLocationExternal.getAltitude()); + setProperty("vEgo", car_state.getVEgo()); + setProperty("aEgo", car_state.getAEgo()); + setProperty("steeringTorqueEps", car_state.getSteeringTorqueEps()); + setProperty("bearingAccuracyDeg", gpsLocationExternal.getBearingAccuracyDeg()); + setProperty("bearingDeg", gpsLocationExternal.getBearingDeg()); + setProperty("torquedUseParams", s.scene.live_torque_toggle && !s.scene.custom_torque_toggle); + setProperty("latAccelFactorFiltered", ltp.getLatAccelFactorFiltered()); + setProperty("frictionCoefficientFiltered", ltp.getFrictionCoefficientFiltered()); + setProperty("liveValid", ltp.getLiveValid()); + // ############################## DEV UI END ############################## + // update engageability/experimental mode button experimental_btn->updateState(s); @@ -690,13 +720,32 @@ void AnnotatedCameraWidget::drawHud(QPainter &p) { drawText(p, rect().center().x(), 290, speedUnit, 200); } + // ####### 1 ROW ####### + QRect bar_rect1(rect().left(), rect().bottom() - 60, rect().width(), 61); + if (devUiEnabled && !mapVisible && devUiInfo == 1) { + p.setPen(Qt::NoPen); + p.setBrush(QColor(0, 0, 0, 100)); + p.drawRect(bar_rect1); + drawNewDevUi2(p, bar_rect1.left(), bar_rect1.center().y()); + } + + // ####### 1 COLUMN ######## + QRect rc2(rect().right() - (bdr_s * 2), bdr_s * 1.5, 184, 152); + if (devUiEnabled) { + drawRightDevUi(p, rect().right() - 184 - bdr_s * 2, bdr_s * 2 + rc2.height()); + } + + int rn_btn = 0; + rn_btn = devUiEnabled && !mapVisible && devUiInfo == 1 ? 30 : 0; + uiState()->scene.rn_offset = rn_btn; + // Dynamic Lane Profile Button if (dynamicLaneProfileToggle) { - drawDlpButton(p, bdr_s * 2 + 220, (rect().bottom() - footer_h / 2 - 75), 150, 150); + drawDlpButton(p, bdr_s * 2 + 220, (rect().bottom() - footer_h / 2 - 75) - rn_btn, 150, 150); } if (gac) { - drawGacButton(p, bdr_s * 2 + 220 + 180, (rect().bottom() - footer_h / 2 - 75), 150, 150); + drawGacButton(p, bdr_s * 2 + 220 + 180, (rect().bottom() - footer_h / 2 - 75) - rn_btn, 150, 150); } // Stand Still Timer @@ -938,6 +987,321 @@ void AnnotatedCameraWidget::drawTrunSpeedSign(QPainter &p, QRect rc, const QStri drawCenteredText(p, x, y + 65, sub_text, text_color); } +// ############################## DEV UI START ############################## +void AnnotatedCameraWidget::drawCenteredLeftText(QPainter &p, int x, int y, const QString &text1, QColor color1, const QString &text2, const QString &text3, QColor color2) { + QFontMetrics fm(p.font()); + QRect init_rect = fm.boundingRect(text1 + " "); + QRect real_rect = fm.boundingRect(init_rect, 0, text1 + " "); + real_rect.moveCenter({x, y}); + + QRect init_rect3 = fm.boundingRect(text3); + QRect real_rect3 = fm.boundingRect(init_rect3, 0, text3); + real_rect3.moveTop(real_rect.top()); + real_rect3.moveLeft(real_rect.right() + 135); + + QRect init_rect2 = fm.boundingRect(text2); + QRect real_rect2 = fm.boundingRect(init_rect2, 0, text2); + real_rect2.moveTop(real_rect.top()); + real_rect2.moveRight(real_rect.right() + 125); + + p.setPen(color1); + p.drawText(real_rect, Qt::AlignLeft | Qt::AlignVCenter, text1); + + p.setPen(color2); + p.drawText(real_rect2, Qt::AlignRight | Qt::AlignVCenter, text2); + p.drawText(real_rect3, Qt::AlignLeft | Qt::AlignVCenter, text3); +} + +int AnnotatedCameraWidget::drawDevUiElementRight(QPainter &p, int x, int y, const char* value, const char* label, const char* units, QColor &color) { + configFont(p, "Inter", 30 * 2, "Bold"); + drawColoredText(p, x + 92, y + 80, QString(value), color); + + configFont(p, "Inter", 28, "Bold"); + drawText(p, x + 92, y + 80 + 42, QString(label), 255); + + if (strlen(units) > 0) { + p.save(); + p.translate(x + 54 + 30 - 3 + 92 + 30, y + 37 + 25); + p.rotate(-90); + drawText(p, 0, 0, QString(units), 255); + p.restore(); + } + + return 110; +} + +void AnnotatedCameraWidget::drawRightDevUi(QPainter &p, int x, int y) { + int rh = 5; + int ry = y; + + // Add Relative Distance to Primary Lead Car + // Unit: Meters + if (true) { + char val_str[16]; + char units_str[8]; + QColor valueColor = QColor(255, 255, 255, 255); + + if (lead_status) { + // Orange if close, Red if very close + if (lead_d_rel < 5) { + valueColor = QColor(255, 0, 0, 255); + } else if (lead_d_rel < 15) { + valueColor = QColor(255, 188, 0, 255); + } + snprintf(val_str, sizeof(val_str), "%d", (int)lead_d_rel); + } else { + snprintf(val_str, sizeof(val_str), "-"); + } + + snprintf(units_str, sizeof(units_str), "m"); + + rh += drawDevUiElementRight(p, x, ry, val_str, "REL DIST", units_str, valueColor); + ry = y + rh; + } + + // Add Relative Velocity vs Primary Lead Car + // Unit: kph if metric, else mph + if (true) { + char val_str[16]; + QColor valueColor = QColor(255, 255, 255, 255); + + if (lead_status) { + // Red if approaching faster than 10mph + // Orange if approaching (negative) + if (lead_v_rel < -4.4704) { + valueColor = QColor(255, 0, 0, 255); + } else if (lead_v_rel < 0) { + valueColor = QColor(255, 188, 0, 255); + } + + if (speedUnit == "mph") { + snprintf(val_str, sizeof(val_str), "%d", (int)(lead_v_rel * 2.236936)); //mph + } else { + snprintf(val_str, sizeof(val_str), "%d", (int)(lead_v_rel * 3.6)); //kph + } + } else { + snprintf(val_str, sizeof(val_str), "-"); + } + + rh += drawDevUiElementRight(p, x, ry, val_str, "REL SPEED", speedUnit.toStdString().c_str(), valueColor); + ry = y + rh; + } + + // Add Real Steering Angle + // Unit: Degrees + if (true) { + char val_str[16]; + QColor valueColor = QColor(255, 255, 255, 255); + if (madsEnabled && latActive) { + valueColor = QColor(0, 255, 0, 255); + } else { + valueColor = QColor(255, 255, 255, 255); + } + + // Red if large steering angle + // Orange if moderate steering angle + if (std::fabs(angleSteers) > 180) { + valueColor = QColor(255, 0, 0, 255); + } else if (std::fabs(angleSteers) > 90) { + valueColor = QColor(255, 188, 0, 255); + } + + snprintf(val_str, sizeof(val_str), "%.1f%s%s", angleSteers , "°", ""); + + rh += drawDevUiElementRight(p, x, ry, val_str, "REAL STEER", "", valueColor); + ry = y + rh; + } + + // Add Actual Lateral Acceleration (roll compensated) when using Torque + // Unit: m/s² + // Add Desired Steering Angle when using PID + // Unit: Degrees + if (lateralState == "torque") { + char val_str[16]; + QColor valueColor = QColor(255, 255, 255, 255); + + float actualLateralAccel = (curvature * pow(vEgo, 2)) - (roll * 9.81); + + if (madsEnabled && latActive) { + snprintf(val_str, sizeof(val_str), "%.2f", actualLateralAccel); + } else { + snprintf(val_str, sizeof(val_str), "-"); + } + + rh += drawDevUiElementRight(p, x, ry, val_str, "ACTUAL LAT", "m/s²", valueColor); + ry = y + rh; + } else { + char val_str[16]; + QColor valueColor = QColor(255, 255, 255, 255); + + if (madsEnabled && latActive) { + // Red if large steering angle + // Orange if moderate steering angle + if (std::fabs(angleSteers) > 180) { + valueColor = QColor(255, 0, 0, 255); + } else if (std::fabs(angleSteers) > 90) { + valueColor = QColor(255, 188, 0, 255); + } + + snprintf(val_str, sizeof(val_str), "%.1f%s%s", steerAngleDesired, "°", ""); + } else { + snprintf(val_str, sizeof(val_str), "-"); + } + + rh += drawDevUiElementRight(p, x, ry, val_str, "DESIR STEER", "", valueColor); + ry = y + rh; + } + + // Add Device Memory Usage + // Unit: Percent + if (true) { + char val_str[16]; + QColor valueColor = QColor(255, 255, 255, 255); + + if (memoryUsagePercent > 75) { + valueColor = QColor(255, 188, 0, 255); + } + + snprintf(val_str, sizeof(val_str), "%d%s", (int)memoryUsagePercent, "%"); + + rh += drawDevUiElementRight(p, x, ry, val_str, "MEMORY", "", valueColor); + ry = y + rh; + } + + rh += 25; + p.setBrush(QColor(0, 0, 0, 0)); + QRect ldu(x, y, 184, rh); +} + +int AnnotatedCameraWidget::drawNewDevUiElement(QPainter &p, int x, int y, const char* value, const char* label, const char* units, QColor &color) { + configFont(p, "Inter", 38, "Bold"); + drawCenteredLeftText(p, x, y, QString(label), whiteColor(), QString(value), QString(units), color); + + return 430; +} + +void AnnotatedCameraWidget::drawNewDevUi2(QPainter &p, int x, int y) { + int rw = 90; + + // Add Acceleration from Car + // Unit: Meters per Second Squared + if (true) { + char val_str[16]; + QColor valueColor = QColor(255, 255, 255, 255); + + snprintf(val_str, sizeof(val_str), "%.1f", aEgo); + + rw += drawNewDevUiElement(p, rw, y, val_str, "ACC.", "m/s²", valueColor); + } + + // Add Velocity of Primary Lead Car + // Unit: kph if metric, else mph + if (true) { + char val_str[16]; + QColor valueColor = QColor(255, 255, 255, 255); + + if (lead_status) { + if (speedUnit == "mph") { + snprintf(val_str, sizeof(val_str), "%d", (int)((lead_v_rel + vEgo) * 2.236936)); //mph + } else { + snprintf(val_str, sizeof(val_str), "%d", (int)((lead_v_rel + vEgo) * 3.6)); //kph + } + } else { + snprintf(val_str, sizeof(val_str), "-"); + } + + rw += drawNewDevUiElement(p, rw, y, val_str, "L.S.", speedUnit.toStdString().c_str(), valueColor); + } + + // Add Friction Coefficient Raw from torqued + // Unit: None + if (torquedUseParams) { + char val_str[16]; + QColor valueColor = QColor(255, 255, 255, 255); + + if (liveValid) valueColor = QColor(0, 255, 0, 255); + snprintf(val_str, sizeof(val_str), "%.3f", frictionCoefficientFiltered); + + rw += drawNewDevUiElement(p, rw, y, val_str, "FRIC.", "", valueColor); + } + + // Add Steering Torque from Car EPS + // Unit: Newton Meters + else { + char val_str[16]; + QColor valueColor = QColor(255, 255, 255, 255); + + snprintf(val_str, sizeof(val_str), "%.1f", std::fabs(steeringTorqueEps)); + + rw += drawNewDevUiElement(p, rw, y, val_str, "E.T.", "N·dm", valueColor); + } + + // Add Lateral Acceleration Factor Raw from torqued + // Unit: m/s² + if (torquedUseParams) { + char val_str[16]; + QColor valueColor = QColor(255, 255, 255, 255); + + if (liveValid) valueColor = QColor(0, 255, 0, 255); + snprintf(val_str, sizeof(val_str), "%.3f", latAccelFactorFiltered); + + rw += drawNewDevUiElement(p, rw, y, val_str, "L.A.", "m/s²", valueColor); + } + + // Add Bearing Degree and Direction from Car (Compass) + // Unit: Meters + else { + char val_str[16]; + char dir_str[8]; + char data_string[30]; + QColor valueColor = QColor(255, 255, 255, 255); + + if (bearingAccuracyDeg != 180.00) { + snprintf(val_str, sizeof(val_str), "%.0d%s%s", (int)bearingDeg, "°", ""); + if (((bearingDeg >= 337.5) && (bearingDeg <= 360)) || ((bearingDeg >= 0) && (bearingDeg <= 22.5))) { + snprintf(dir_str, sizeof(dir_str), "N"); + } else if ((bearingDeg > 22.5) && (bearingDeg < 67.5)) { + snprintf(dir_str, sizeof(dir_str), "NE"); + } else if ((bearingDeg >= 67.5) && (bearingDeg <= 112.5)) { + snprintf(dir_str, sizeof(dir_str), "E"); + } else if ((bearingDeg > 112.5) && (bearingDeg < 157.5)) { + snprintf(dir_str, sizeof(dir_str), "SE"); + } else if ((bearingDeg >= 157.5) && (bearingDeg <= 202.5)) { + snprintf(dir_str, sizeof(dir_str), "S"); + } else if ((bearingDeg > 202.5) && (bearingDeg < 247.5)) { + snprintf(dir_str, sizeof(dir_str), "SW"); + } else if ((bearingDeg >= 247.5) && (bearingDeg <= 292.5)) { + snprintf(dir_str, sizeof(dir_str), "W"); + } else if ((bearingDeg > 292.5) && (bearingDeg < 337.5)) { + snprintf(dir_str, sizeof(dir_str), "NW"); + } + } else { + snprintf(dir_str, sizeof(dir_str), "OFF"); + snprintf(val_str, sizeof(val_str), "-"); + } + + snprintf(data_string, sizeof(data_string), "%s | %s", dir_str, val_str); + + rw += drawNewDevUiElement(p, rw, y, "B.D.", data_string, "", valueColor); + } + + // Add Altitude of Current Location + // Unit: Meters + if (true) { + char val_str[16]; + QColor valueColor = QColor(255, 255, 255, 255); + + if (gpsAccuracy != 0.00) { + snprintf(val_str, sizeof(val_str), "%.1f", altitude); + } else { + snprintf(val_str, sizeof(val_str), "-"); + } + + rw += drawNewDevUiElement(p, rw, y, val_str, "ALT.", "m", valueColor); + } +} + +// ############################## DEV UI END ############################## void AnnotatedCameraWidget::initializeGL() { CameraWidget::initializeGL(); @@ -1068,7 +1432,7 @@ void AnnotatedCameraWidget::drawDriverState(QPainter &painter, const UIState *s) // base icon int x = rightHandDM ? rect().right() - (btn_size - 24) / 2 - (bdr_s * 2) : (btn_size - 24) / 2 + (bdr_s * 2); - int y = rect().bottom() - footer_h / 2; + int y = rect().bottom() - footer_h / 2 - scene.rn_offset; float opacity = dmActive ? 0.65 : 0.2; drawIcon(painter, x, y, dm_img, blackColor(0), opacity); diff --git a/selfdrive/ui/qt/onroad.h b/selfdrive/ui/qt/onroad.h index 2996c047ec..6ad7b4df60 100644 --- a/selfdrive/ui/qt/onroad.h +++ b/selfdrive/ui/qt/onroad.h @@ -109,6 +109,33 @@ class AnnotatedCameraWidget : public CameraWidget { Q_PROPERTY(bool gac MEMBER gac); Q_PROPERTY(int gacTr MEMBER gacTr); + Q_PROPERTY(bool mapVisible MEMBER mapVisible); + + // ############################## DEV UI START ############################## + Q_PROPERTY(bool lead_status MEMBER lead_status); + Q_PROPERTY(float lead_d_rel MEMBER lead_d_rel); + Q_PROPERTY(float lead_v_rel MEMBER lead_v_rel); + Q_PROPERTY(QString lateralState MEMBER lateralState); + Q_PROPERTY(float angleSteers MEMBER angleSteers); + Q_PROPERTY(float steerAngleDesired MEMBER steerAngleDesired); + Q_PROPERTY(float curvature MEMBER curvature); + Q_PROPERTY(float roll MEMBER roll); + Q_PROPERTY(int memoryUsagePercent MEMBER memoryUsagePercent); + Q_PROPERTY(bool devUiEnabled MEMBER devUiEnabled); + Q_PROPERTY(int devUiInfo MEMBER devUiInfo); + Q_PROPERTY(float gpsAccuracy MEMBER gpsAccuracy); + Q_PROPERTY(float altitude MEMBER altitude); + Q_PROPERTY(float vEgo MEMBER vEgo); + Q_PROPERTY(float aEgo MEMBER aEgo); + Q_PROPERTY(float steeringTorqueEps MEMBER steeringTorqueEps); + Q_PROPERTY(float bearingAccuracyDeg MEMBER bearingAccuracyDeg); + Q_PROPERTY(float bearingDeg MEMBER bearingDeg); + Q_PROPERTY(bool torquedUseParams MEMBER torquedUseParams); + Q_PROPERTY(float latAccelFactorFiltered MEMBER latAccelFactorFiltered); + Q_PROPERTY(float frictionCoefficientFiltered MEMBER frictionCoefficientFiltered); + Q_PROPERTY(bool liveValid MEMBER liveValid); + // ############################## DEV UI END ############################## + public: explicit AnnotatedCameraWidget(VisionStreamType type, QWidget* parent = 0); void updateState(const UIState &s); @@ -130,6 +157,14 @@ private: void drawColoredText(QPainter &p, int x, int y, const QString &text, QColor color); void drawStandstillTimer(QPainter &p, int x, int y); + // ############################## DEV UI START ############################## + void drawRightDevUi(QPainter &p, int x, int y); + int drawDevUiElementRight(QPainter &p, int x, int y, const char* value, const char* label, const char* units, QColor &color); + int drawNewDevUiElement(QPainter &p, int x, int y, const char* value, const char* label, const char* units, QColor &color); + void drawNewDevUi2(QPainter &p, int x, int y); + void drawCenteredLeftText(QPainter &p, int x, int y, const QString &text1, QColor color1, const QString &text2, const QString &text3, QColor color2); + // ############################## DEV UI END ############################## + uint64_t last_update_params; ExperimentalButton *experimental_btn; @@ -199,6 +234,33 @@ private: bool gac; int gacTr; + bool mapVisible; + + // ############################## DEV UI START ############################## + bool lead_status; + float lead_d_rel = 0; + float lead_v_rel = 0; + QString lateralState; + float angleSteers = 0; + float steerAngleDesired = 0; + float curvature; + float roll; + int memoryUsagePercent; + bool devUiEnabled; + int devUiInfo; + float gpsAccuracy; + float altitude; + float vEgo; + float aEgo; + float steeringTorqueEps; + float bearingAccuracyDeg; + float bearingDeg; + bool torquedUseParams; + float latAccelFactorFiltered; + float frictionCoefficientFiltered; + bool liveValid; + // ############################## DEV UI END ############################## + protected: void paintGL() override; void initializeGL() override; diff --git a/selfdrive/ui/qt/screenrecorder/screenrecorder.cc b/selfdrive/ui/qt/screenrecorder/screenrecorder.cc index c3ac79cb5e..df527c435c 100644 --- a/selfdrive/ui/qt/screenrecorder/screenrecorder.cc +++ b/selfdrive/ui/qt/screenrecorder/screenrecorder.cc @@ -100,8 +100,8 @@ void ScreenRecoder::paintEvent(QPaintEvent *event) { QPainter p(this); p.setRenderHint(QPainter::Antialiasing); - QPoint center(btn_size / 2, btn_size / 2); - QRect rec_btn(36, 36, 120, 120); + QPoint center(btn_size / 2 - 25, btn_size / 2 + 10 - uiState()->scene.rn_offset); + QRect rec_btn(36 - 25, 36 + 10 - uiState()->scene.rn_offset, 120, 120); p.setOpacity(1.0); p.setPen(Qt::NoPen); diff --git a/selfdrive/ui/ui.cc b/selfdrive/ui/ui.cc index ec2d4bf530..12247c8b93 100644 --- a/selfdrive/ui/ui.cc +++ b/selfdrive/ui/ui.cc @@ -243,6 +243,8 @@ void ui_update_params(UIState *s) { s->scene.gac_mode = std::atoi(params.get("GapAdjustCruiseMode").c_str()); s->scene.gac_min = std::atoi(params.get("GapAdjustCruiseMin").c_str()); s->scene.gac_max = std::atoi(params.get("GapAdjustCruiseMax").c_str()); + s->scene.dev_ui_enabled = params.getBool("DevUI"); + s->scene.dev_ui_info = std::atoi(params.get("DevUIInfo").c_str()); if (s->scene.onroadScreenOff > 0) { s->scene.osoTimer = s->scene.onroadScreenOff * 60 * UI_FREQ; @@ -279,6 +281,8 @@ void UIState::updateStatus() { status = STATUS_DISENGAGED; scene.started_frame = sm->frame; wide_cam_only = Params().getBool("WideCameraOnly"); + scene.live_torque_toggle = Params().getBool("LiveTorque"); + scene.custom_torque_toggle = Params().getBool("CustomTorqueLateral"); } started_prev = scene.started; emit offroadTransition(!scene.started); @@ -297,7 +301,8 @@ UIState::UIState(QObject *parent) : QObject(parent) { "modelV2", "controlsState", "liveCalibration", "radarState", "deviceState", "roadCameraState", "pandaStates", "carParams", "driverMonitoringState", "carState", "liveLocationKalman", "driverStateV2", "wideRoadCameraState", "managerState", "navInstruction", "navRoute", "gnssMeasurements", - "uiPlan", "carControl", "lateralPlan", "longitudinalPlan", "liveMapData", + "uiPlan", "carControl", "lateralPlan", "longitudinalPlan", "liveMapData", "gpsLocationExternal", "liveParameters", + "liveTorqueParameters", }); Params params; diff --git a/selfdrive/ui/ui.h b/selfdrive/ui/ui.h index fb7c4e82f4..70d1439646 100644 --- a/selfdrive/ui/ui.h +++ b/selfdrive/ui/ui.h @@ -169,6 +169,13 @@ typedef struct UIScene { bool gac; int gac_mode, gac_tr, gac_min, gac_max; + + bool map_visible; + bool dev_ui_enabled; + int dev_ui_info; + int rn_offset; + bool live_torque_toggle; + bool custom_torque_toggle; } UIScene; class UIState : public QObject {