From 3038f234f42d0b9ecc64ff7fa71c6c0d6f17e4d0 Mon Sep 17 00:00:00 2001 From: FrogAi <91348155+FrogAi@users.noreply.github.com> Date: Thu, 20 Jun 2024 06:49:37 -0700 Subject: [PATCH] Visuals - Developer UI - FPS counter Display the 'Frames Per Second' (FPS) of your onroad UI for monitoring system performance. --- selfdrive/ui/qt/onroad/annotated_camera.cc | 1 + selfdrive/ui/qt/onroad/onroad_home.cc | 47 +++++++++++++++++++++- selfdrive/ui/qt/onroad/onroad_home.h | 2 + selfdrive/ui/ui.cc | 1 + selfdrive/ui/ui.h | 3 ++ system/camerad/cameras/camera_qcom2.cc | 14 +++++++ 6 files changed, 67 insertions(+), 1 deletion(-) diff --git a/selfdrive/ui/qt/onroad/annotated_camera.cc b/selfdrive/ui/qt/onroad/annotated_camera.cc index f1ecb9a26..361e97d94 100644 --- a/selfdrive/ui/qt/onroad/annotated_camera.cc +++ b/selfdrive/ui/qt/onroad/annotated_camera.cc @@ -613,6 +613,7 @@ void AnnotatedCameraWidget::paintGL() { double cur_draw_t = millis_since_boot(); double dt = cur_draw_t - prev_draw_t; double fps = fps_filter.update(1. / dt * 1000); + s->scene.fps = fps; if (fps < 15) { LOGW("slow frame rate: %.2f fps", fps); } diff --git a/selfdrive/ui/qt/onroad/onroad_home.cc b/selfdrive/ui/qt/onroad/onroad_home.cc index f7c8640b0..924d2333c 100644 --- a/selfdrive/ui/qt/onroad/onroad_home.cc +++ b/selfdrive/ui/qt/onroad/onroad_home.cc @@ -86,7 +86,9 @@ void OnroadWindow::updateState(const UIState &s) { blindSpotLeft = scene.blind_spot_left; blindSpotRight = scene.blind_spot_right; + fps = scene.fps; showBlindspot = scene.show_blind_spot && (blindSpotLeft || blindSpotRight); + showFPS = scene.show_fps; showSignal = scene.show_signal && (turnSignalLeft || turnSignalRight); showSteering = scene.show_steering; steer = scene.steer; @@ -94,7 +96,7 @@ void OnroadWindow::updateState(const UIState &s) { turnSignalLeft = scene.turn_signal_left; turnSignalRight = scene.turn_signal_right; - if (showBlindspot || showSignal || showSteering) { + if (showBlindspot || showFPS || showSignal || showSteering) { shouldUpdate = true; } @@ -316,4 +318,47 @@ void OnroadWindow::paintEvent(QPaintEvent *event) { p.fillRect(signalRectRight, signalBorderColorRight); } } + + if (showFPS) { + qint64 currentMillis = QDateTime::currentMSecsSinceEpoch(); + static std::queue> fpsQueue; + + static float avgFPS = 0.0; + static float maxFPS = 0.0; + static float minFPS = 99.9; + + minFPS = std::min(minFPS, fps); + maxFPS = std::max(maxFPS, fps); + + fpsQueue.push({currentMillis, fps}); + + while (!fpsQueue.empty() && currentMillis - fpsQueue.front().first > 60000) { + fpsQueue.pop(); + } + + if (!fpsQueue.empty()) { + float totalFPS = 0.0; + for (auto tempQueue = fpsQueue; !tempQueue.empty(); tempQueue.pop()) { + totalFPS += tempQueue.front().second; + } + avgFPS = totalFPS / fpsQueue.size(); + } + + QString fpsDisplayString = QString("FPS: %1 (%2) | Min: %3 | Max: %4 | Avg: %5") + .arg(qRound(fps)) + .arg(paramsMemory.getInt("CameraFPS")) + .arg(qRound(minFPS)) + .arg(qRound(maxFPS)) + .arg(qRound(avgFPS)); + + p.setFont(InterFont(28, QFont::DemiBold)); + p.setRenderHint(QPainter::TextAntialiasing); + p.setPen(Qt::white); + + int textWidth = p.fontMetrics().horizontalAdvance(fpsDisplayString); + int xPos = (rect.width() - textWidth) / 2; + int yPos = rect.bottom() - 5; + + p.drawText(xPos, yPos, fpsDisplayString); + } } diff --git a/selfdrive/ui/qt/onroad/onroad_home.h b/selfdrive/ui/qt/onroad/onroad_home.h index 0a8225ad3..3312b9d3d 100644 --- a/selfdrive/ui/qt/onroad/onroad_home.h +++ b/selfdrive/ui/qt/onroad/onroad_home.h @@ -28,11 +28,13 @@ private: bool blindSpotLeft; bool blindSpotRight; bool showBlindspot; + bool showFPS; bool showSignal; bool showSteering; bool turnSignalLeft; bool turnSignalRight; + float fps; float steer; int steeringAngleDeg; diff --git a/selfdrive/ui/ui.cc b/selfdrive/ui/ui.cc index 7f58e07ba..bc61f91ce 100644 --- a/selfdrive/ui/ui.cc +++ b/selfdrive/ui/ui.cc @@ -341,6 +341,7 @@ void ui_update_frogpilot_params(UIState *s) { bool developer_ui = params.getBool("DeveloperUI"); bool border_metrics = developer_ui && params.getBool("BorderMetrics"); scene.show_blind_spot = border_metrics && params.getBool("BlindSpotMetrics"); + scene.show_fps = developer_ui && params.getBool("FPSCounter"); scene.show_signal = border_metrics && params.getBool("SignalMetrics"); scene.show_steering = border_metrics && params.getBool("ShowSteering"); diff --git a/selfdrive/ui/ui.h b/selfdrive/ui/ui.h index 5c56d474d..928c2abb4 100644 --- a/selfdrive/ui/ui.h +++ b/selfdrive/ui/ui.h @@ -154,6 +154,7 @@ typedef struct UIScene { bool show_aol_status_bar; bool show_blind_spot; bool show_cem_status_bar; + bool show_fps; bool show_signal; bool show_slc_offset; bool show_slc_offset_ui; @@ -173,6 +174,8 @@ typedef struct UIScene { bool use_vienna_slc_sign; bool vtsc_controlling_curve; + double fps; + float adjusted_cruise; float lane_detection_width; float lane_width_left; diff --git a/system/camerad/cameras/camera_qcom2.cc b/system/camerad/cameras/camera_qcom2.cc index ab7548f73..67215aea9 100644 --- a/system/camerad/cameras/camera_qcom2.cc +++ b/system/camerad/cameras/camera_qcom2.cc @@ -960,6 +960,9 @@ void process_road_camera(MultiCameraState *s, CameraState *c, int cnt) { void cameras_run(MultiCameraState *s) { // FrogPilot variables Params paramsMemory{"/dev/shm/params"}; + const std::chrono::seconds fpsUpdateInterval(1); + std::chrono::steady_clock::time_point startTime = std::chrono::steady_clock::now(); + int frameCount = 0; LOG("-- Starting threads"); std::vector threads; @@ -1003,6 +1006,17 @@ void cameras_run(MultiCameraState *s) { // for debugging //do_exit = do_exit || event_data->u.frame_msg.frame_id > (30*20); + frameCount++; + + std::chrono::steady_clock::time_point currentTime = std::chrono::steady_clock::now(); + if (currentTime - startTime >= fpsUpdateInterval) { + auto duration = std::chrono::duration_cast(currentTime - startTime).count(); + double fps = frameCount / duration; + paramsMemory.putIntNonBlocking("CameraFPS", fps / 3); + frameCount = 0; + startTime = currentTime; + } + if (event_data->session_hdl == s->road_cam.session_handle) { s->road_cam.handle_camera_event(event_data); } else if (event_data->session_hdl == s->wide_road_cam.session_handle) {