From 3794b4f06bb7ba1992ce5044dd5725a8826299b6 Mon Sep 17 00:00:00 2001 From: FrogAi <91348155+FrogAi@users.noreply.github.com> Date: Tue, 27 Feb 2024 16:34:47 -0700 Subject: [PATCH] Device metrics in the sidebar Added functions to enable device monitoring in the sidebar by tapping on their respective metric boxes. --- cereal/custom.capnp | 2 + common/params.cc | 5 ++ selfdrive/thermald/thermald.py | 5 +- selfdrive/ui/qt/sidebar.cc | 97 ++++++++++++++++++++++++++++++++-- selfdrive/ui/qt/sidebar.h | 11 ++++ system/loggerd/config.py | 11 ++++ 6 files changed, 127 insertions(+), 4 deletions(-) diff --git a/cereal/custom.capnp b/cereal/custom.capnp index 78fc4aa..b7bfb20 100644 --- a/cereal/custom.capnp +++ b/cereal/custom.capnp @@ -13,6 +13,8 @@ struct FrogPilotCarControl @0x81c2f05a394cf4af { } struct FrogPilotDeviceState @0xaedffd8f31e7b55d { + freeSpace @0 :Int16; + usedSpace @1 :Int16; } struct FrogPilotNavigation @0xf35cc4560bbf6ec2 { diff --git a/common/params.cc b/common/params.cc index 24f6f00..7d80442 100644 --- a/common/params.cc +++ b/common/params.cc @@ -267,6 +267,11 @@ std::unordered_map keys = { {"RelaxedJerk", PERSISTENT}, {"RoadEdgesWidth", PERSISTENT}, {"SilentMode", PERSISTENT}, + {"ShowCPU", PERSISTENT}, + {"ShowGPU", PERSISTENT}, + {"ShowMemoryUsage", PERSISTENT}, + {"ShowStorageLeft", PERSISTENT}, + {"ShowStorageUsed", PERSISTENT}, {"StandardFollow", PERSISTENT}, {"StandardJerk", PERSISTENT}, {"StockTune", PERSISTENT}, diff --git a/selfdrive/thermald/thermald.py b/selfdrive/thermald/thermald.py index 6a02499..33ef4e2 100755 --- a/selfdrive/thermald/thermald.py +++ b/selfdrive/thermald/thermald.py @@ -19,7 +19,7 @@ from openpilot.common.params import Params from openpilot.common.realtime import DT_TRML from openpilot.selfdrive.controls.lib.alertmanager import set_offroad_alert from openpilot.system.hardware import HARDWARE, TICI, AGNOS -from openpilot.system.loggerd.config import get_available_percent +from openpilot.system.loggerd.config import get_available_bytes, get_available_percent, get_used_bytes from openpilot.selfdrive.statsd import statlog from openpilot.common.swaglog import cloudlog from openpilot.selfdrive.thermald.power_monitoring import PowerMonitoring @@ -244,6 +244,9 @@ def thermald_thread(end_event, hw_queue) -> None: fpmsg = messaging.new_message('frogpilotDeviceState') + fpmsg.frogpilotDeviceState.freeSpace = round(get_available_bytes(default=32.0 * (2 ** 30)) / (2 ** 30)) + fpmsg.frogpilotDeviceState.usedSpace = round(get_used_bytes(default=0.0 * (2 ** 30)) / (2 ** 30)) + pm.send("frogpilotDeviceState", fpmsg) msg.deviceState.freeSpacePercent = get_available_percent(default=100.0) diff --git a/selfdrive/ui/qt/sidebar.cc b/selfdrive/ui/qt/sidebar.cc index 41631c5..5d0ac9e 100644 --- a/selfdrive/ui/qt/sidebar.cc +++ b/selfdrive/ui/qt/sidebar.cc @@ -40,6 +40,13 @@ Sidebar::Sidebar(QWidget *parent) : QFrame(parent), onroad(false), flag_pressed( pm = std::make_unique>({"userFlag"}); // FrogPilot variables + isCPU = params.getBool("ShowCPU"); + isGPU = params.getBool("ShowGPU"); + + isMemoryUsage = params.getBool("ShowMemoryUsage"); + isStorageLeft = params.getBool("ShowStorageLeft"); + isStorageUsed = params.getBool("ShowStorageUsed"); + themeConfiguration = { {0, {"stock", {QColor(255, 255, 255)}}}, {1, {"frog_theme", {QColor(23, 134, 68)}}}, @@ -65,7 +72,31 @@ Sidebar::Sidebar(QWidget *parent) : QFrame(parent), onroad(false), flag_pressed( } void Sidebar::mousePressEvent(QMouseEvent *event) { - if (onroad && home_btn.contains(event->pos())) { + // Declare the click boxes + QRect cpuRect = {30, 496, 240, 126}; + QRect memoryRect = {30, 654, 240, 126}; + + static int showChip = 0; + static int showMemory = 0; + + // Swap between the respective metrics upon tap + if (cpuRect.contains(event->pos())) { + showChip = (showChip + 1) % 3; + isCPU = (showChip == 1); + isGPU = (showChip == 2); + params.putBoolNonBlocking("ShowCPU", isCPU); + params.putBoolNonBlocking("ShowGPU", isGPU); + update(); + } else if (memoryRect.contains(event->pos())) { + showMemory = (showMemory + 1) % 4; + isMemoryUsage = (showMemory == 1); + isStorageLeft = (showMemory == 2); + isStorageUsed = (showMemory == 3); + params.putBoolNonBlocking("ShowMemoryUsage", isMemoryUsage); + params.putBoolNonBlocking("ShowStorageLeft", isStorageLeft); + params.putBoolNonBlocking("ShowStorageUsed", isStorageUsed); + update(); + } else if (onroad && home_btn.contains(event->pos())) { flag_pressed = true; update(); } else if (settings_btn.contains(event->pos())) { @@ -114,6 +145,54 @@ void Sidebar::updateState(const UIState &s) { QColor theme_color = currentColors[0]; + // FrogPilot metrics + if (isCPU || isGPU) { + auto cpu_loads = deviceState.getCpuUsagePercent(); + int cpu_usage = std::accumulate(cpu_loads.begin(), cpu_loads.end(), 0) / cpu_loads.size(); + int gpu_usage = deviceState.getGpuUsagePercent(); + + QString cpu = QString::number(cpu_usage) + "%"; + QString gpu = QString::number(gpu_usage) + "%"; + + QString metric = isGPU ? gpu : cpu; + int usage = isGPU ? gpu_usage : cpu_usage; + + ItemStatus cpuStatus = {{tr(isGPU ? "GPU" : "CPU"), metric}, theme_color}; + if (usage >= 85) { + cpuStatus = {{tr(isGPU ? "GPU" : "CPU"), metric}, danger_color}; + } else if (usage >= 70) { + cpuStatus = {{tr(isGPU ? "GPU" : "CPU"), metric}, warning_color}; + } + setProperty("cpuStatus", QVariant::fromValue(cpuStatus)); + } + + if (isMemoryUsage || isStorageLeft || isStorageUsed) { + int memory_usage = deviceState.getMemoryUsagePercent(); + int storage_left = frogpilotDeviceState.getFreeSpace(); + int storage_used = frogpilotDeviceState.getUsedSpace(); + + QString memory = QString::number(memory_usage) + "%"; + QString storage = QString::number(isStorageLeft ? storage_left : storage_used) + " GB"; + + if (isMemoryUsage) { + ItemStatus memoryStatus = {{tr("MEMORY"), memory}, theme_color}; + if (memory_usage >= 85) { + memoryStatus = {{tr("MEMORY"), memory}, danger_color}; + } else if (memory_usage >= 70) { + memoryStatus = {{tr("MEMORY"), memory}, warning_color}; + } + setProperty("memoryStatus", QVariant::fromValue(memoryStatus)); + } else { + ItemStatus storageStatus = {{tr(isStorageLeft ? "LEFT" : "USED"), storage}, theme_color}; + if (10 <= storage_left && storage_left < 25) { + storageStatus = {{tr(isStorageLeft ? "LEFT" : "USED"), storage}, warning_color}; + } else if (storage_left < 10) { + storageStatus = {{tr(isStorageLeft ? "LEFT" : "USED"), storage}, danger_color}; + } + setProperty("storageStatus", QVariant::fromValue(storageStatus)); + } + } + ItemStatus connectStatus; auto last_ping = deviceState.getLastAthenaPingTime(); if (last_ping == 0) { @@ -173,6 +252,18 @@ void Sidebar::paintEvent(QPaintEvent *event) { // metrics drawMetric(p, temp_status.first, temp_status.second, 338); - drawMetric(p, panda_status.first, panda_status.second, 496); - drawMetric(p, connect_status.first, connect_status.second, 654); + + if (isCPU || isGPU) { + drawMetric(p, cpu_status.first, cpu_status.second, 496); + } else { + drawMetric(p, panda_status.first, panda_status.second, 496); + } + + if (isMemoryUsage) { + drawMetric(p, memory_status.first, memory_status.second, 654); + } else if (isStorageLeft || isStorageUsed) { + drawMetric(p, storage_status.first, storage_status.second, 654); + } else { + drawMetric(p, connect_status.first, connect_status.second, 654); + } } diff --git a/selfdrive/ui/qt/sidebar.h b/selfdrive/ui/qt/sidebar.h index 97b1716..20a94b5 100644 --- a/selfdrive/ui/qt/sidebar.h +++ b/selfdrive/ui/qt/sidebar.h @@ -19,6 +19,9 @@ class Sidebar : public QFrame { Q_PROPERTY(int netStrength MEMBER net_strength NOTIFY valueChanged); // FrogPilot properties + Q_PROPERTY(ItemStatus cpuStatus MEMBER cpu_status NOTIFY valueChanged) + Q_PROPERTY(ItemStatus memoryStatus MEMBER memory_status NOTIFY valueChanged) + Q_PROPERTY(ItemStatus storageStatus MEMBER storage_status NOTIFY valueChanged) public: explicit Sidebar(QWidget* parent = 0); @@ -66,6 +69,14 @@ private: Params params; UIScene &scene; + ItemStatus cpu_status, memory_status, storage_status; + + bool isCPU; + bool isGPU; + bool isMemoryUsage; + bool isStorageLeft; + bool isStorageUsed; + std::unordered_map>> themeConfiguration; std::unordered_map flag_imgs; std::unordered_map home_imgs; diff --git a/system/loggerd/config.py b/system/loggerd/config.py index 5c2c89b..2941e39 100644 --- a/system/loggerd/config.py +++ b/system/loggerd/config.py @@ -27,3 +27,14 @@ def get_available_bytes(default=None): available_bytes = default return available_bytes + +def get_used_bytes(default=None): + try: + statvfs = os.statvfs(Paths.log_root()) + total_bytes = statvfs.f_blocks * statvfs.f_frsize + available_bytes = statvfs.f_bavail * statvfs.f_frsize + used_bytes = total_bytes - available_bytes + except OSError: + used_bytes = default + + return used_bytes