reset to pre-modification baseline; restart feature work from clean state
Restoring the working tree to the pristine pre-Claude baseline previously preserved at /data/clearpilot (now /data/clearpilot-baseline). The prior modified-but-broken tree is snapshotted at /data/openpilot-broken-2026-05-03 and tagged here as pre-reset-2026-05-03 for reference. From here, features (UI changes, dashcam, telemetry, GPS, display modes, speed logic, standstill power saving, etc.) will be re-introduced one at a time with proper testing.
This commit is contained in:
@@ -6,11 +6,9 @@ from openpilot.common.numpy_fast import interp
|
||||
from openpilot.common.swaglog import cloudlog
|
||||
from openpilot.selfdrive.controls.lib.pid import PIDController
|
||||
|
||||
|
||||
class BaseFanController(ABC):
|
||||
@abstractmethod
|
||||
def update(self, cur_temp: float, ignition: bool, standstill: bool = False,
|
||||
is_parked: bool = True, cruise_engaged: bool = False) -> int:
|
||||
def update(self, cur_temp: float, ignition: bool) -> int:
|
||||
pass
|
||||
|
||||
|
||||
@@ -22,27 +20,9 @@ class TiciFanController(BaseFanController):
|
||||
self.last_ignition = False
|
||||
self.controller = PIDController(k_p=0, k_i=4e-3, k_f=1, rate=(1 / DT_TRML))
|
||||
|
||||
def update(self, cur_temp: float, ignition: bool, standstill: bool = False,
|
||||
is_parked: bool = True, cruise_engaged: bool = False) -> int:
|
||||
# CLEARPILOT fan range rules:
|
||||
# parked → 0-100% (full, no floor)
|
||||
# in drive + cruise engaged (any speed, inc standstill) → 30-100%
|
||||
# in drive + cruise off + standstill → 10-100%
|
||||
# in drive + cruise off + moving → 30-100%
|
||||
# In the PID output, neg_limit is how negative it can go (= max fan as %),
|
||||
# pos_limit is how positive (= negative of min fan %).
|
||||
if is_parked:
|
||||
self.controller.neg_limit = -100
|
||||
self.controller.pos_limit = 0
|
||||
elif cruise_engaged:
|
||||
self.controller.neg_limit = -100
|
||||
self.controller.pos_limit = -30
|
||||
elif standstill:
|
||||
self.controller.neg_limit = -100
|
||||
self.controller.pos_limit = -10
|
||||
else:
|
||||
self.controller.neg_limit = -100
|
||||
self.controller.pos_limit = -30
|
||||
def update(self, cur_temp: float, ignition: bool) -> int:
|
||||
self.controller.neg_limit = -(100 if ignition else 30)
|
||||
self.controller.pos_limit = -(30 if ignition else 0)
|
||||
|
||||
if ignition != self.last_ignition:
|
||||
self.controller.reset()
|
||||
|
||||
@@ -36,9 +36,12 @@ class PowerMonitoring:
|
||||
# Reset capacity if it's low
|
||||
self.car_battery_capacity_uWh = max((CAR_BATTERY_CAPACITY_uWh / 10), int(car_battery_capacity_uWh))
|
||||
|
||||
# CLEARPILOT: hardcoded 30 minute shutdown timer (not user-configurable)
|
||||
self.device_shutdown_time = 1800
|
||||
self.low_voltage_shutdown = VBATT_PAUSE_CHARGING
|
||||
# FrogPilot variables
|
||||
device_management = self.params.get_bool("DeviceManagement")
|
||||
device_shutdown_setting = self.params.get_int("DeviceShutdown") if device_management else 33
|
||||
# If the toggle is set for < 1 hour, configure by 15 minute increments
|
||||
self.device_shutdown_time = (device_shutdown_setting - 3) * 3600 if device_shutdown_setting >= 4 else device_shutdown_setting * (60 * 15)
|
||||
self.low_voltage_shutdown = self.params.get_float("LowVoltageShutdown") if device_management else VBATT_PAUSE_CHARGING
|
||||
|
||||
# Calculation tick
|
||||
def calculate(self, voltage: int | None, ignition: bool):
|
||||
@@ -122,13 +125,7 @@ class PowerMonitoring:
|
||||
offroad_time > VOLTAGE_SHUTDOWN_MIN_OFFROAD_TIME_S)
|
||||
should_shutdown |= offroad_time > self.device_shutdown_time
|
||||
should_shutdown |= low_voltage_shutdown
|
||||
# CLEARPILOT: removed `car_battery_capacity_uWh <= 0` trigger. That's a virtual
|
||||
# capacity counter floor-limited to 3e6 µWh on boot which drains in ~12 min at
|
||||
# typical device power. With a short drive that doesn't fully recharge (charges
|
||||
# at 45W, cap 30e6 µWh = 36 min to full), a quick store stop could trip shutdown
|
||||
# well before the intended 30-min idle timer. The real protection we want here
|
||||
# is the car battery voltage check (kept above) — the virtual counter is now
|
||||
# retained only for telemetry.
|
||||
should_shutdown |= (self.car_battery_capacity_uWh <= 0)
|
||||
should_shutdown &= not ignition
|
||||
should_shutdown &= (not self.params.get_bool("DisablePowerDown"))
|
||||
should_shutdown &= in_car
|
||||
|
||||
@@ -10,7 +10,7 @@ from pathlib import Path
|
||||
import psutil
|
||||
|
||||
import cereal.messaging as messaging
|
||||
from cereal import car, log
|
||||
from cereal import log
|
||||
from cereal.services import SERVICE_LIST
|
||||
from openpilot.common.dict_helpers import strip_deprecated_keys
|
||||
from openpilot.common.filter_simple import FirstOrderFilter
|
||||
@@ -164,7 +164,7 @@ def hw_state_thread(end_event, hw_queue):
|
||||
|
||||
def thermald_thread(end_event, hw_queue) -> None:
|
||||
pm = messaging.PubMaster(['deviceState', 'frogpilotDeviceState'])
|
||||
sm = messaging.SubMaster(["peripheralState", "gpsLocationExternal", "controlsState", "pandaStates", "carState"], poll="pandaStates")
|
||||
sm = messaging.SubMaster(["peripheralState", "gpsLocationExternal", "controlsState", "pandaStates"], poll="pandaStates")
|
||||
|
||||
count = 0
|
||||
|
||||
@@ -197,9 +197,7 @@ def thermald_thread(end_event, hw_queue) -> None:
|
||||
engaged_prev = False
|
||||
|
||||
params = Params()
|
||||
params_memory = Params("/dev/shm/params")
|
||||
power_monitor = PowerMonitoring()
|
||||
last_touch_reset = "0" # CLEARPILOT: track last seen touch reset value
|
||||
|
||||
HARDWARE.initialize_hardware()
|
||||
thermal_config = HARDWARE.get_thermal_config()
|
||||
@@ -292,18 +290,7 @@ def thermald_thread(end_event, hw_queue) -> None:
|
||||
msg.deviceState.maxTempC = all_comp_temp
|
||||
|
||||
if fan_controller is not None:
|
||||
# CLEARPILOT: fan rules based on gear (parked vs drive) and cruise-engaged state
|
||||
if sm.seen['carState']:
|
||||
cs = sm['carState']
|
||||
standstill = cs.standstill
|
||||
is_parked = cs.gearShifter == car.CarState.GearShifter.park
|
||||
else:
|
||||
standstill = False
|
||||
is_parked = True # default safe: assume parked, no fan floor
|
||||
cruise_engaged = sm['controlsState'].enabled if sm.seen['controlsState'] else False
|
||||
msg.deviceState.fanSpeedPercentDesired = fan_controller.update(
|
||||
all_comp_temp, onroad_conditions["ignition"], standstill,
|
||||
is_parked=is_parked, cruise_engaged=cruise_engaged)
|
||||
msg.deviceState.fanSpeedPercentDesired = fan_controller.update(all_comp_temp, onroad_conditions["ignition"])
|
||||
|
||||
is_offroad_for_5_min = (started_ts is None) and ((not started_seen) or (off_ts is None) or (time.monotonic() - off_ts > 60 * 5))
|
||||
if is_offroad_for_5_min and offroad_comp_temp > OFFROAD_DANGER_TEMP:
|
||||
@@ -421,26 +408,9 @@ def thermald_thread(end_event, hw_queue) -> None:
|
||||
statlog.sample("som_power_draw", som_power_draw)
|
||||
msg.deviceState.somPowerDrawW = som_power_draw
|
||||
|
||||
# CLEARPILOT: screen tap resets shutdown timer (off_ts) while offroad
|
||||
touch_reset = params_memory.get("ShutdownTouchReset")
|
||||
if touch_reset is not None and touch_reset != last_touch_reset and off_ts is not None:
|
||||
off_ts = time.monotonic()
|
||||
cloudlog.info("shutdown timer reset by screen touch")
|
||||
last_touch_reset = touch_reset
|
||||
|
||||
# Check if we need to shut down
|
||||
if power_monitor.should_shutdown(onroad_conditions["ignition"], in_car, off_ts, started_seen):
|
||||
cloudlog.warning(f"shutting device down, offroad since {off_ts}")
|
||||
# CLEARPILOT: signal dashcamd to close recording gracefully before power-off
|
||||
params_memory.put_bool("DashcamShutdown", True)
|
||||
deadline = time.monotonic() + 15.0
|
||||
while time.monotonic() < deadline:
|
||||
if not params_memory.get_bool("DashcamShutdown"):
|
||||
cloudlog.info("dashcamd shutdown ack received")
|
||||
break
|
||||
time.sleep(0.5)
|
||||
else:
|
||||
cloudlog.warning("dashcamd shutdown ack timeout, proceeding")
|
||||
params.put_bool("DoShutdown", True)
|
||||
|
||||
msg.deviceState.started = started_ts is not None
|
||||
|
||||
Reference in New Issue
Block a user