From 698a1647a09c0b51f1e20db32b30e5b75f73e05b Mon Sep 17 00:00:00 2001 From: Brian Hanson Date: Mon, 13 Apr 2026 23:24:37 -0500 Subject: [PATCH] nightrider mode improvements, nice monitor, ready text 1x - Nightrider: lines 1px wider (3px outline), engagement border hidden, planner lines hidden when disengaged, stay on onroad view in park - Normal mode only: return to ready splash on park - Ready text sprite at native 1x size - Nice monitor: keeps claude processes at nice 19, runs every 30s Co-Authored-By: Claude Opus 4.6 (1M context) --- launch_openpilot.sh | 3 +++ selfdrive/ui/qt/home.cc | 13 +++++++++---- selfdrive/ui/qt/onroad.cc | 26 +++++++++++++++++++++----- selfdrive/ui/qt/ready.cc | 5 ++--- system/clearpilot/nice-monitor.sh | 19 +++++++++++++++++++ 5 files changed, 54 insertions(+), 12 deletions(-) create mode 100755 system/clearpilot/nice-monitor.sh diff --git a/launch_openpilot.sh b/launch_openpilot.sh index 8644263..e564b26 100755 --- a/launch_openpilot.sh +++ b/launch_openpilot.sh @@ -20,6 +20,9 @@ bash /data/openpilot/system/clearpilot/on_start.sh # CLEARPILOT: start VPN monitor (kills previous instances, runs as root) sudo bash -c 'nohup /data/openpilot/system/clearpilot/vpn-monitor.sh >> /tmp/vpn-monitor.log 2>&1 &' +# CLEARPILOT: start nice monitor (keeps claude at nice 19) +sudo bash -c 'nohup /data/openpilot/system/clearpilot/nice-monitor.sh > /dev/null 2>&1 &' + # CLEARPILOT: pass --bench flag through to manager via env var if [ "$1" = "--bench" ]; then export BENCH_MODE=1 diff --git a/selfdrive/ui/qt/home.cc b/selfdrive/ui/qt/home.cc index cf8e4eb..11e07bc 100755 --- a/selfdrive/ui/qt/home.cc +++ b/selfdrive/ui/qt/home.cc @@ -85,19 +85,24 @@ void HomeWindow::updateState(const UIState &s) { showDriverView(s.scene.driver_camera_timer >= 10, true); // CLEARPILOT: show splash screen when onroad but in park + // In nightrider mode (states 1,4), stay on onroad view in park — only offroad transition shows splash bool parked = s.scene.parked; + int screenMode = paramsMemory.getInt("ScreenDisplayMode"); + bool nightrider = (screenMode == 1 || screenMode == 4); + if (parked && !was_parked_onroad) { - LOGW("CLP UI: park transition -> showing splash"); - slayout->setCurrentWidget(ready); + if (!nightrider) { + LOGW("CLP UI: park transition -> showing splash"); + slayout->setCurrentWidget(ready); + } } else if (!parked && was_parked_onroad) { LOGW("CLP UI: drive transition -> showing onroad"); slayout->setCurrentWidget(onroad); } was_parked_onroad = parked; - // CLEARPILOT: honor display on/off while showing splash in park + // CLEARPILOT: honor display on/off while showing splash in park (normal mode only) if (parked && ready->isVisible()) { - int screenMode = paramsMemory.getInt("ScreenDisplayMode"); if (screenMode == 3) { Hardware::set_display_power(false); } else { diff --git a/selfdrive/ui/qt/onroad.cc b/selfdrive/ui/qt/onroad.cc index f72098d..b89d7f7 100755 --- a/selfdrive/ui/qt/onroad.cc +++ b/selfdrive/ui/qt/onroad.cc @@ -177,7 +177,14 @@ void OnroadWindow::offroadTransition(bool offroad) { void OnroadWindow::paintEvent(QPaintEvent *event) { QPainter p(this); - p.fillRect(rect(), QColor(bg.red(), bg.green(), bg.blue(), 255)); + // CLEARPILOT: hide engagement border in nightrider mode + int dm = paramsMemory.getInt("ScreenDisplayMode"); + bool nightrider = (dm == 1 || dm == 4); + if (nightrider) { + p.fillRect(rect(), Qt::black); + } else { + p.fillRect(rect(), QColor(bg.red(), bg.green(), bg.blue(), 255)); + } QString logicsDisplayString = QString(); if (scene.show_jerk) { @@ -596,11 +603,20 @@ void AnnotatedCameraWidget::drawLaneLines(QPainter &painter, const UIState *s) { // CLEARPILOT: nightrider mode — outline only, no fill bool outlineOnly = nightriderMode; + // CLEARPILOT: in nightrider mode, hide all lines when not engaged + if (outlineOnly && edgeColor == bg_colors[STATUS_DISENGAGED]) { + painter.restore(); + return; + } + + // CLEARPILOT: nightrider lines are 1px wider (3 instead of 2) + int outlineWidth = outlineOnly ? 3 : 2; + // lanelines for (int i = 0; i < std::size(scene.lane_line_vertices); ++i) { QColor lineColor = QColor::fromRgbF(1.0, 1.0, 1.0, std::clamp(scene.lane_line_probs[i], 0.0, 0.7)); if (outlineOnly) { - painter.setPen(QPen(lineColor, 2)); + painter.setPen(QPen(lineColor, outlineWidth)); painter.setBrush(Qt::NoBrush); } else { painter.setPen(Qt::NoPen); @@ -614,7 +630,7 @@ void AnnotatedCameraWidget::drawLaneLines(QPainter &painter, const UIState *s) { for (int i = 0; i < std::size(scene.road_edge_vertices); ++i) { QColor edgeCol = QColor::fromRgbF(1.0, 0, 0, std::clamp(1.0 - scene.road_edge_stds[i], 0.0, 1.0)); if (outlineOnly) { - painter.setPen(QPen(edgeCol, 2)); + painter.setPen(QPen(edgeCol, outlineWidth)); painter.setBrush(Qt::NoBrush); } else { painter.setPen(Qt::NoPen); @@ -689,7 +705,7 @@ void AnnotatedCameraWidget::drawLaneLines(QPainter &painter, const UIState *s) { if (outlineOnly) { painter.setPen(QPen(QColor(center_lane_color.red(), center_lane_color.green(), - center_lane_color.blue(), 180), 2)); + center_lane_color.blue(), 180), outlineWidth)); painter.setBrush(Qt::NoBrush); } else { painter.setPen(Qt::NoPen); @@ -718,7 +734,7 @@ void AnnotatedCameraWidget::drawLaneLines(QPainter &painter, const UIState *s) { if (scene.blind_spot_path) { QColor bsColor = QColor::fromHslF(0 / 360., 0.75, 0.50, 0.6); if (outlineOnly) { - painter.setPen(QPen(bsColor, 2)); + painter.setPen(QPen(bsColor, outlineWidth)); painter.setBrush(Qt::NoBrush); } else { QLinearGradient bs(0, height(), 0, 0); diff --git a/selfdrive/ui/qt/ready.cc b/selfdrive/ui/qt/ready.cc index b6864c8..a529380 100755 --- a/selfdrive/ui/qt/ready.cc +++ b/selfdrive/ui/qt/ready.cc @@ -74,10 +74,9 @@ void ReadyWindow::paintEvent(QPaintEvent *event) { // "READY!" 8-bit text sprite, 2x size, 15% below center static QPixmap ready_text("/data/openpilot/selfdrive/clearpilot/theme/clearpilot/images/ready_text.png"); if (!ready_text.isNull()) { - QPixmap scaled = ready_text.scaled(ready_text.width() * 3 / 2, ready_text.height() * 3 / 2, Qt::KeepAspectRatio, Qt::FastTransformation); - int tx = (width() - scaled.width()) / 2; + int tx = (width() - ready_text.width()) / 2; int ty = height() / 2 + height() * 15 / 100; - painter.drawPixmap(tx, ty, scaled); + painter.drawPixmap(tx, ty, ready_text); } } else { // Error state: red text at 25% below center diff --git a/system/clearpilot/nice-monitor.sh b/system/clearpilot/nice-monitor.sh new file mode 100755 index 0000000..354690b --- /dev/null +++ b/system/clearpilot/nice-monitor.sh @@ -0,0 +1,19 @@ +#!/usr/bin/bash + +# Nice monitor — ensures claude processes run at lowest CPU priority. +# Checks every 30 seconds and renices any claude process not already at nice 19. + +# Kill other instances of this script +for pid in $(pgrep -f 'nice-monitor.sh' | grep -v $$); do + kill "$pid" 2>/dev/null +done + +while true; do + for pid in $(pgrep -f 'claude' 2>/dev/null); do + cur=$(awk '{print $19}' /proc/$pid/stat 2>/dev/null) + if [ -n "$cur" ] && [ "$cur" != "19" ]; then + renice 19 -p "$pid" > /dev/null 2>&1 + fi + done + sleep 30 +done