Compare commits
3 Commits
02f25f83c4
...
2ddb7fc764
| Author | SHA1 | Date | |
|---|---|---|---|
| 2ddb7fc764 | |||
| 22ced0c558 | |||
| ef4e02e354 |
+1
-1
@@ -251,7 +251,6 @@ std::unordered_map<std::string, uint32_t> keys = {
|
|||||||
{"CarMake", PERSISTENT},
|
{"CarMake", PERSISTENT},
|
||||||
{"CarModel", PERSISTENT},
|
{"CarModel", PERSISTENT},
|
||||||
|
|
||||||
{"CarCruiseDisplayActual", PERSISTENT},
|
|
||||||
{"CarSpeedLimit", PERSISTENT},
|
{"CarSpeedLimit", PERSISTENT},
|
||||||
|
|
||||||
{"CarSpeedLimitWarning", PERSISTENT},
|
{"CarSpeedLimitWarning", PERSISTENT},
|
||||||
@@ -293,6 +292,7 @@ std::unordered_map<std::string, uint32_t> keys = {
|
|||||||
{"CEStopLights", PERSISTENT},
|
{"CEStopLights", PERSISTENT},
|
||||||
{"CEStopLightsLead", PERSISTENT},
|
{"CEStopLightsLead", PERSISTENT},
|
||||||
{"Compass", PERSISTENT},
|
{"Compass", PERSISTENT},
|
||||||
|
{"ClearpilotShowHealthMetrics", PERSISTENT},
|
||||||
{"ConditionalExperimental", PERSISTENT},
|
{"ConditionalExperimental", PERSISTENT},
|
||||||
{"CrosstrekTorque", PERSISTENT},
|
{"CrosstrekTorque", PERSISTENT},
|
||||||
{"CurrentHolidayTheme", PERSISTENT},
|
{"CurrentHolidayTheme", PERSISTENT},
|
||||||
|
|||||||
@@ -51,7 +51,6 @@ class CarState(CarStateBase):
|
|||||||
# CLEARPILOT: cache to avoid per-cycle atomic writes to /dev/shm (eats CPU via fsync/flock)
|
# CLEARPILOT: cache to avoid per-cycle atomic writes to /dev/shm (eats CPU via fsync/flock)
|
||||||
self._prev_car_speed_limit = None
|
self._prev_car_speed_limit = None
|
||||||
self._prev_car_is_metric = None
|
self._prev_car_is_metric = None
|
||||||
self._prev_car_cruise_display = None
|
|
||||||
|
|
||||||
self.cruise_info = {}
|
self.cruise_info = {}
|
||||||
|
|
||||||
@@ -223,10 +222,6 @@ class CarState(CarStateBase):
|
|||||||
if self.is_metric != self._prev_car_is_metric:
|
if self.is_metric != self._prev_car_is_metric:
|
||||||
self.params_memory.put("CarIsMetric", "1" if self.is_metric else "0")
|
self.params_memory.put("CarIsMetric", "1" if self.is_metric else "0")
|
||||||
self._prev_car_is_metric = self.is_metric
|
self._prev_car_is_metric = self.is_metric
|
||||||
car_cruise_display = cp_cruise.vl["SCC11"]["VSetDis"]
|
|
||||||
if car_cruise_display != self._prev_car_cruise_display:
|
|
||||||
self.params_memory.put_float("CarCruiseDisplayActual", car_cruise_display)
|
|
||||||
self._prev_car_cruise_display = car_cruise_display
|
|
||||||
|
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ from openpilot.common.numpy_fast import clip
|
|||||||
from openpilot.selfdrive.car import CanBusBase
|
from openpilot.selfdrive.car import CanBusBase
|
||||||
from openpilot.selfdrive.car.hyundai.values import HyundaiFlags
|
from openpilot.selfdrive.car.hyundai.values import HyundaiFlags
|
||||||
|
|
||||||
from openpilot.common.params import Params
|
|
||||||
|
|
||||||
class CanBus(CanBusBase):
|
class CanBus(CanBusBase):
|
||||||
def __init__(self, CP, hda2=None, fingerprint=None) -> None:
|
def __init__(self, CP, hda2=None, fingerprint=None) -> None:
|
||||||
@@ -127,8 +126,6 @@ def create_buttons(packer, CP, CAN, cnt, btn):
|
|||||||
|
|
||||||
def create_buttons_alt(packer, CP, CAN, cnt, btn, template):
|
def create_buttons_alt(packer, CP, CAN, cnt, btn, template):
|
||||||
return
|
return
|
||||||
params_memory = Params("/dev/shm/params")
|
|
||||||
CarCruiseDisplayActual = params_memory.get_float("CarCruiseDisplayActual")
|
|
||||||
|
|
||||||
values = {
|
values = {
|
||||||
"COUNTER": cnt,
|
"COUNTER": cnt,
|
||||||
|
|||||||
Binary file not shown.
@@ -273,17 +273,21 @@ def main(demo=False):
|
|||||||
last_vipc_frame_id = meta_main.frame_id
|
last_vipc_frame_id = meta_main.frame_id
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Reduced framerate: 4fps when not lat active and not standstill
|
# Reduced framerate: daylight 10fps (skip 1/2), night 4fps (skip 4/5)
|
||||||
# Skip 4 out of every 5 frames (20fps -> 4fps)
|
# Daytime runs twice as fast — better model responsiveness when lighting is good
|
||||||
|
# and the neural net has more signal. Night stays conservative for power.
|
||||||
# Write standby timestamp so controlsd suppresses transient errors
|
# Write standby timestamp so controlsd suppresses transient errors
|
||||||
if not full_rate:
|
if not full_rate:
|
||||||
if params_memory.get("ModelFps") != b"4":
|
is_daylight = params_memory.get_bool("IsDaylight")
|
||||||
params_memory.put("ModelFps", "4")
|
skip_interval = 2 if is_daylight else 5
|
||||||
|
target_fps = b"10" if is_daylight else b"4"
|
||||||
|
if params_memory.get("ModelFps") != target_fps:
|
||||||
|
params_memory.put("ModelFps", target_fps.decode())
|
||||||
now = _time.monotonic()
|
now = _time.monotonic()
|
||||||
if now - last_standby_ts_write > 1.0:
|
if now - last_standby_ts_write > 1.0:
|
||||||
params_memory.put("ModelStandbyTs", str(now))
|
params_memory.put("ModelStandbyTs", str(now))
|
||||||
last_standby_ts_write = now
|
last_standby_ts_write = now
|
||||||
if run_count % 5 != 0:
|
if run_count % skip_interval != 0:
|
||||||
last_vipc_frame_id = meta_main.frame_id
|
last_vipc_frame_id = meta_main.frame_id
|
||||||
run_count += 1
|
run_count += 1
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -338,6 +338,15 @@ ClearPilotPanel::ClearPilotPanel(QWidget* parent) : QFrame(parent) {
|
|||||||
});
|
});
|
||||||
debug_panel->addItem(telemetry_toggle);
|
debug_panel->addItem(telemetry_toggle);
|
||||||
|
|
||||||
|
auto *health_metrics_toggle = new ToggleControl("System Health Overlay",
|
||||||
|
"Show controls lag, model frame drops, temperature, CPU, and memory usage "
|
||||||
|
"in the lower-right of the onroad UI. For diagnosing slowdown issues.", "",
|
||||||
|
Params().getBool("ClearpilotShowHealthMetrics"), this);
|
||||||
|
QObject::connect(health_metrics_toggle, &ToggleControl::toggleFlipped, [](bool on) {
|
||||||
|
Params().putBool("ClearpilotShowHealthMetrics", on);
|
||||||
|
});
|
||||||
|
debug_panel->addItem(health_metrics_toggle);
|
||||||
|
|
||||||
auto *vpn_toggle = new ToggleControl("VPN",
|
auto *vpn_toggle = new ToggleControl("VPN",
|
||||||
"Connect to vpn.hanson.xyz for remote SSH access. "
|
"Connect to vpn.hanson.xyz for remote SSH access. "
|
||||||
"Disabling kills the active tunnel and stops reconnection attempts.", "",
|
"Disabling kills the active tunnel and stops reconnection attempts.", "",
|
||||||
|
|||||||
@@ -468,6 +468,9 @@ void AnnotatedCameraWidget::drawHud(QPainter &p) {
|
|||||||
drawSpeedLimitSign(p);
|
drawSpeedLimitSign(p);
|
||||||
drawCruiseWarningSign(p);
|
drawCruiseWarningSign(p);
|
||||||
|
|
||||||
|
// CLEARPILOT: system health metrics in lower-right (debug overlay)
|
||||||
|
drawHealthMetrics(p);
|
||||||
|
|
||||||
// Draw FrogPilot widgets
|
// Draw FrogPilot widgets
|
||||||
paintFrogPilotWidgets(p);
|
paintFrogPilotWidgets(p);
|
||||||
}
|
}
|
||||||
@@ -727,6 +730,82 @@ void AnnotatedCameraWidget::drawText(QPainter &p, int x, int y, const QString &t
|
|||||||
p.drawText(real_rect.x(), real_rect.bottom(), text);
|
p.drawText(real_rect.x(), real_rect.bottom(), text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CLEARPILOT: System health overlay — shows metrics that indicate the system
|
||||||
|
// is overburdened or behind. Toggled via ClearpilotShowHealthMetrics param.
|
||||||
|
// Metrics (top→bottom): LAG, DROP, TEMP, CPU, MEM
|
||||||
|
// LAG (ms): controlsd cumLagMs — most direct "is the loop keeping up" indicator
|
||||||
|
// DROP (%): modelV2 frameDropPerc — modeld losing frames; controlsd errors >20%
|
||||||
|
// TEMP (°C): deviceState.maxTempC — thermal throttling starts ~75, serious >88
|
||||||
|
// CPU (%): max core from deviceState.cpuUsagePercent
|
||||||
|
// MEM (%): deviceState.memoryUsagePercent
|
||||||
|
// Each value color-codes green/yellow/red by severity.
|
||||||
|
void AnnotatedCameraWidget::drawHealthMetrics(QPainter &p) {
|
||||||
|
static bool enabled = Params().getBool("ClearpilotShowHealthMetrics");
|
||||||
|
static int check_counter = 0;
|
||||||
|
// re-check the param every ~2s without a toggle signal path
|
||||||
|
if (++check_counter >= 40) {
|
||||||
|
check_counter = 0;
|
||||||
|
enabled = Params().getBool("ClearpilotShowHealthMetrics");
|
||||||
|
}
|
||||||
|
if (!enabled) return;
|
||||||
|
|
||||||
|
SubMaster &sm = *(uiState()->sm);
|
||||||
|
auto cs = sm["controlsState"].getControlsState();
|
||||||
|
auto ds = sm["deviceState"].getDeviceState();
|
||||||
|
auto mv = sm["modelV2"].getModelV2();
|
||||||
|
|
||||||
|
float lag_ms = cs.getCumLagMs();
|
||||||
|
float drop_pct = mv.getFrameDropPerc();
|
||||||
|
float temp_c = ds.getMaxTempC();
|
||||||
|
int mem_pct = ds.getMemoryUsagePercent();
|
||||||
|
int cpu_pct = 0;
|
||||||
|
for (auto v : ds.getCpuUsagePercent()) cpu_pct = std::max(cpu_pct, (int)v);
|
||||||
|
|
||||||
|
auto color_for = [](float v, float warn, float crit) {
|
||||||
|
if (v >= crit) return QColor(0xff, 0x50, 0x50); // red
|
||||||
|
if (v >= warn) return QColor(0xff, 0xd0, 0x40); // yellow
|
||||||
|
return QColor(0xff, 0xff, 0xff); // white (ok)
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Row { QString label; QString value; QColor color; };
|
||||||
|
Row rows[] = {
|
||||||
|
{"LAG", QString::number((int)lag_ms), color_for(lag_ms, 50.f, 200.f)},
|
||||||
|
{"DROP", QString::number((int)drop_pct),color_for(drop_pct, 5.f, 15.f)},
|
||||||
|
{"TEMP", QString::number((int)temp_c), color_for(temp_c, 75.f, 88.f)},
|
||||||
|
{"CPU", QString::number(cpu_pct), color_for((float)cpu_pct, 75.f, 90.f)},
|
||||||
|
{"MEM", QString::number(mem_pct), color_for((float)mem_pct, 70.f, 85.f)},
|
||||||
|
};
|
||||||
|
|
||||||
|
p.save();
|
||||||
|
p.setFont(InterFont(90, QFont::Bold));
|
||||||
|
QFontMetrics fm = p.fontMetrics();
|
||||||
|
int row_h = fm.height(); // natural line height at 90pt bold
|
||||||
|
int gap = 40; // requested 40px between values
|
||||||
|
int margin = 30; // requested 30px margin
|
||||||
|
int panel_w = 360; // fixed width — fits "TEMP 99"
|
||||||
|
int n = sizeof(rows) / sizeof(rows[0]);
|
||||||
|
int panel_h = n * row_h + (n - 1) * gap + 2 * margin;
|
||||||
|
int x = width() - panel_w - margin;
|
||||||
|
int y = height() - panel_h - margin;
|
||||||
|
|
||||||
|
// black background
|
||||||
|
p.setPen(Qt::NoPen);
|
||||||
|
p.setBrush(QColor(0, 0, 0, 200));
|
||||||
|
p.drawRoundedRect(QRect(x, y, panel_w, panel_h), 20, 20);
|
||||||
|
|
||||||
|
// rows
|
||||||
|
int text_y = y + margin + fm.ascent();
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
p.setPen(rows[i].color);
|
||||||
|
// label left, value right
|
||||||
|
p.drawText(x + margin, text_y, rows[i].label);
|
||||||
|
QRect vrect = fm.boundingRect(rows[i].value);
|
||||||
|
p.drawText(x + panel_w - margin - vrect.width(), text_y, rows[i].value);
|
||||||
|
text_y += row_h + gap;
|
||||||
|
}
|
||||||
|
p.restore();
|
||||||
|
}
|
||||||
|
|
||||||
void AnnotatedCameraWidget::initializeGL() {
|
void AnnotatedCameraWidget::initializeGL() {
|
||||||
CameraWidget::initializeGL();
|
CameraWidget::initializeGL();
|
||||||
qInfo() << "OpenGL version:" << QString((const char*)glGetString(GL_VERSION));
|
qInfo() << "OpenGL version:" << QString((const char*)glGetString(GL_VERSION));
|
||||||
@@ -867,8 +946,9 @@ void AnnotatedCameraWidget::drawLaneLines(QPainter &painter, const UIState *s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (outlineOnly) {
|
if (outlineOnly) {
|
||||||
|
// CLEARPILOT: center path (tire track) is 2x wider than other lines in nightrider
|
||||||
painter.setPen(QPen(QColor(center_lane_color.red(), center_lane_color.green(),
|
painter.setPen(QPen(QColor(center_lane_color.red(), center_lane_color.green(),
|
||||||
center_lane_color.blue(), 180), outlineWidth));
|
center_lane_color.blue(), 180), outlineWidth * 2));
|
||||||
painter.setBrush(Qt::NoBrush);
|
painter.setBrush(Qt::NoBrush);
|
||||||
} else {
|
} else {
|
||||||
painter.setPen(Qt::NoPen);
|
painter.setPen(Qt::NoPen);
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ private:
|
|||||||
void drawSpeedWidget(QPainter &p, int x, int y, const QString &title, const QString &speedLimitStr, QColor colorSpeed, int width = 176);
|
void drawSpeedWidget(QPainter &p, int x, int y, const QString &title, const QString &speedLimitStr, QColor colorSpeed, int width = 176);
|
||||||
void drawSpeedLimitSign(QPainter &p);
|
void drawSpeedLimitSign(QPainter &p);
|
||||||
void drawCruiseWarningSign(QPainter &p);
|
void drawCruiseWarningSign(QPainter &p);
|
||||||
|
void drawHealthMetrics(QPainter &p);
|
||||||
|
|
||||||
QVBoxLayout *main_layout;
|
QVBoxLayout *main_layout;
|
||||||
QPixmap dm_img;
|
QPixmap dm_img;
|
||||||
|
|||||||
Binary file not shown.
@@ -159,6 +159,7 @@ def main():
|
|||||||
params_memory = Params("/dev/shm/params")
|
params_memory = Params("/dev/shm/params")
|
||||||
last_daylight_check = 0.0
|
last_daylight_check = 0.0
|
||||||
daylight_computed = False
|
daylight_computed = False
|
||||||
|
prev_daylight = None # CLEARPILOT: gate IsDaylight write on change
|
||||||
print("gpsd: entering main loop", file=sys.stderr, flush=True)
|
print("gpsd: entering main loop", file=sys.stderr, flush=True)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
@@ -205,7 +206,10 @@ def main():
|
|||||||
last_daylight_check = now_mono
|
last_daylight_check = now_mono
|
||||||
utc_now = datetime.datetime.utcfromtimestamp(fix["timestamp_ms"] / 1000)
|
utc_now = datetime.datetime.utcfromtimestamp(fix["timestamp_ms"] / 1000)
|
||||||
daylight = is_daylight(fix["latitude"], fix["longitude"], utc_now)
|
daylight = is_daylight(fix["latitude"], fix["longitude"], utc_now)
|
||||||
|
# CLEARPILOT: gate on change — daylight flips twice a day, don't rewrite every 30s
|
||||||
|
if daylight != prev_daylight:
|
||||||
params_memory.put_bool("IsDaylight", daylight)
|
params_memory.put_bool("IsDaylight", daylight)
|
||||||
|
prev_daylight = daylight
|
||||||
|
|
||||||
if not daylight_computed:
|
if not daylight_computed:
|
||||||
daylight_computed = True
|
daylight_computed = True
|
||||||
@@ -221,7 +225,7 @@ def main():
|
|||||||
params_memory.put_int("ScreenDisplayMode", 0)
|
params_memory.put_int("ScreenDisplayMode", 0)
|
||||||
cloudlog.warning("gpsd: auto-switch to normal (sunrise)")
|
cloudlog.warning("gpsd: auto-switch to normal (sunrise)")
|
||||||
|
|
||||||
time.sleep(1.0) # 1 Hz polling
|
time.sleep(0.5) # 2 Hz polling
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
Reference in New Issue
Block a user