park CPU savings + fix early shutdown on virtual battery capacity
prebuilt / build prebuilt (push) Has been cancelled
badges / create badges (push) Has been cancelled

controlsd: in park+ignition-on, run full step() only every 10th cycle.
data_sample still runs every cycle (CAN parse, button detection) and
card.controls_update still runs every cycle (CAN TX heartbeat, counter
increments). Skipped cycles re-send cached controlsState/carControl so
downstream freq_ok stays OK. Button edge handling + display-mode
transitions extracted to handle_screen_mode() and called every cycle so
debug-button presses aren't dropped. controlsd: 55% → 30% CPU in park.

dmonitoringmodeld: subscribe to carState; at standstill, skip model.run
and re-publish last inference. driverStateV2 continues flowing at 10Hz
with known-good last face data (driver can't become distracted relative
to a stopped car). ~5% CPU saved.

power_monitoring: remove the `car_battery_capacity_uWh <= 0` shutdown
trigger. That virtual capacity counter floor-limits to 3e6 µWh on boot
and drains in ~12 min at typical device power, so a short drive (that
doesn't fully recharge the 30e6 µWh virtual cap) followed by a quick
store stop would trip shutdown well before the 30-min idle timer. The
real car-battery-voltage protection (low_voltage_shutdown at 11.8V with
60s debounce) is kept.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-18 13:46:33 -05:00
parent 426382960a
commit 6a79996a14
3 changed files with 78 additions and 20 deletions
+14 -2
View File
@@ -128,10 +128,14 @@ def main():
assert vipc_client.is_connected()
cloudlog.warning(f"connected with buffer size: {vipc_client.buffer_len}")
sm = SubMaster(["liveCalibration"])
sm = SubMaster(["liveCalibration", "carState"])
pm = PubMaster(["driverStateV2"])
calib = np.zeros(CALIB_LEN, dtype=np.float32)
# CLEARPILOT: cache last model output so we can republish (not re-infer) at standstill.
# Saves ~7% CPU; downstream dmonitoringd sees a steady 10Hz stream with known-good
# last readings (driver can't become distracted relative to a stopped car).
last_model_output = None
# last = 0
while True:
@@ -143,8 +147,16 @@ def main():
if sm.updated["liveCalibration"]:
calib[:] = np.array(sm["liveCalibration"].rpyCalib)
standstill = sm["carState"].standstill
t1 = time.perf_counter()
model_output, dsp_execution_time = model.run(buf, calib)
if standstill and last_model_output is not None:
# CLEARPILOT: reuse last inference at standstill
model_output = last_model_output
dsp_execution_time = 0.0
else:
model_output, dsp_execution_time = model.run(buf, calib)
last_model_output = model_output
t2 = time.perf_counter()
pm.send("driverStateV2", get_driverstate_packet(model_output, vipc_client.frame_id, vipc_client.timestamp_sof, t2 - t1, dsp_execution_time))