5d18ad1e72
When the car is in park (ignition still on), pause everything that
isn't strictly needed and keep controlsd in a minimal-cycle keepalive
mode so the car's steering ECU keeps seeing the LFA/LKAS CAN-FD
messages and stays in tester mode (no steering fault on shift to drive).
controlsd:
- Detects park gear, writes ParkMode to /dev/shm/params.
- park_mode_tick(): publishes a do-nothing CarControl through
self.card (CarController.update unconditionally appends the
steering messages every cycle, which is the actual heartbeat).
Still runs clearpilot_state_control so the LFA/debug button +
ScreenDisplayMode keep working in park.
- After park→drive, stay in keepalive-tick mode until SubMaster
reports all services healthy (an 8s hard cap as safety net).
Avoids the burst of commIssue alerts that would otherwise fire
while modeld/plannerd/paramsd/torqued/dmonitoringd/calibrationd/
frogpilot_process spin back up from cold.
manager / process_config:
- New gating helpers _park_mode(), only_onroad_active,
driverview_active, always_run_unless_parked.
- Re-gated to only_onroad_active: modeld, sensord, soundd, locationd,
calibrationd, torqued, paramsd, plannerd, radard, speed_logicd.
- Re-gated to driverview_active: dmonitoringmodeld, dmonitoringd.
- frogpilot_process → always_run_unless_parked (preserves offroad
behavior, only pauses when ignition+parked).
- controlsd stays plain only_onroad — it's the writer + heartbeat.
- ParkMode registered in params.cc, defaulted to "0" in manager_init.
thermald + fan_controller (broken-tree rule, ported):
- thermald subscribes to carState; passes standstill, is_parked,
cruise_engaged into fan_controller.update.
- New fan range rules:
parked → 0-100% (no floor, full cooling)
cruise on → 30-100%
standstill → 10-100%
moving → 30-100%
ignition off → 0-30% (existing)
dashcamd: already park-aware via gear-driven trip lifecycle — no
change needed.
Verified: build clean. Launched on bench: park mode kicks in on
startup (gearShifter=unknown initially → eventually park),
modeld/plannerd/paramsd/torqued/calibrationd/frogpilot_process
correctly disappear from the manager process list, gpsd/dashcamd/
ui/controlsd/pandad stay alive, ParkMode=1 in /dev/shm/params.
61 lines
2.2 KiB
Python
Executable File
61 lines
2.2 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
from abc import ABC, abstractmethod
|
|
|
|
from openpilot.common.realtime import DT_TRML
|
|
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:
|
|
pass
|
|
|
|
|
|
class TiciFanController(BaseFanController):
|
|
def __init__(self) -> None:
|
|
super().__init__()
|
|
cloudlog.info("Setting up TICI fan handler")
|
|
|
|
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. neg_limit is the most-negative the PID can
|
|
# output (= max fan %); pos_limit is the inverse of the floor (= -min fan %).
|
|
# parked → 0-100% (full range, no floor)
|
|
# in drive + cruise engaged → 30-100%
|
|
# in drive + cruise off + standstill → 10-100%
|
|
# in drive + cruise off + moving → 30-100%
|
|
# ignition off → 0-30% (existing behavior)
|
|
if not ignition:
|
|
self.controller.neg_limit = -30
|
|
self.controller.pos_limit = 0
|
|
elif 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
|
|
|
|
if ignition != self.last_ignition:
|
|
self.controller.reset()
|
|
|
|
error = 70 - cur_temp
|
|
fan_pwr_out = -int(self.controller.update(
|
|
error=error,
|
|
feedforward=interp(cur_temp, [60.0, 100.0], [0, -100])
|
|
))
|
|
|
|
self.last_ignition = ignition
|
|
return fan_pwr_out
|
|
|