Fix tici powerdown and add support for forcing (#20132)

* also shutdown on tici

* force powerdown

* bump panda

* abstract out shutdown and thermal config

* add comment on tici shutdown

Co-authored-by: Comma Device <device@comma.ai>
old-commit-hash: 8ad1c793d1
commatwo_master
robbederks 4 years ago committed by GitHub
parent c1606b60fd
commit 0f73681f8d
  1. 1
      common/params_pyx.pyx
  2. 2
      panda
  3. 10
      selfdrive/hardware/base.py
  4. 8
      selfdrive/hardware/eon/hardware.py
  5. 8
      selfdrive/hardware/pc/hardware.py
  6. 9
      selfdrive/hardware/tici/hardware.py
  7. 1
      selfdrive/thermald/power_monitoring.py
  8. 20
      selfdrive/thermald/thermald.py

@ -76,6 +76,7 @@ keys = {
b"Offroad_NeosUpdate": [TxType.CLEAR_ON_MANAGER_START], b"Offroad_NeosUpdate": [TxType.CLEAR_ON_MANAGER_START],
b"Offroad_UpdateFailed": [TxType.CLEAR_ON_MANAGER_START], b"Offroad_UpdateFailed": [TxType.CLEAR_ON_MANAGER_START],
b"Offroad_HardwareUnsupported": [TxType.CLEAR_ON_MANAGER_START], b"Offroad_HardwareUnsupported": [TxType.CLEAR_ON_MANAGER_START],
b"ForcePowerDown": [TxType.CLEAR_ON_MANAGER_START],
} }
def ensure_bytes(v): def ensure_bytes(v):

@ -1 +1 @@
Subproject commit e7a5bf85412883cc49a35be6521ccac2bb9502b7 Subproject commit 0ae2be95a114269b12e039eabf0a563c1ca32ece

@ -1,5 +1,7 @@
from abc import abstractmethod from abc import abstractmethod
from collections import namedtuple
ThermalConfig = namedtuple('ThermalConfig', ['cpu', 'gpu', 'mem', 'bat', 'ambient'])
class HardwareBase: class HardwareBase:
@staticmethod @staticmethod
@ -91,3 +93,11 @@ class HardwareBase:
@abstractmethod @abstractmethod
def get_current_power_draw(self): def get_current_power_draw(self):
pass pass
@abstractmethod
def shutdown(self):
pass
@abstractmethod
def get_thermal_config(self):
pass

@ -6,7 +6,7 @@ import struct
import subprocess import subprocess
from cereal import log from cereal import log
from selfdrive.hardware.base import HardwareBase from selfdrive.hardware.base import HardwareBase, ThermalConfig
NetworkType = log.DeviceState.NetworkType NetworkType = log.DeviceState.NetworkType
NetworkStrength = log.DeviceState.NetworkStrength NetworkStrength = log.DeviceState.NetworkStrength
@ -342,3 +342,9 @@ class Android(HardwareBase):
def get_current_power_draw(self): def get_current_power_draw(self):
# We don't have a good direct way to measure this on android # We don't have a good direct way to measure this on android
return None return None
def shutdown(self):
os.system('LD_LIBRARY_PATH="" svc power shutdown')
def get_thermal_config(self):
return ThermalConfig(cpu=((5, 7, 10, 12), 10), gpu=((16,), 10), mem=(2, 10), bat=(29, 1000), ambient=(25, 1))

@ -1,7 +1,7 @@
import random import random
from cereal import log from cereal import log
from selfdrive.hardware.base import HardwareBase from selfdrive.hardware.base import HardwareBase, ThermalConfig
NetworkType = log.DeviceState.NetworkType NetworkType = log.DeviceState.NetworkType
NetworkStrength = log.DeviceState.NetworkStrength NetworkStrength = log.DeviceState.NetworkStrength
@ -70,3 +70,9 @@ class Pc(HardwareBase):
def get_current_power_draw(self): def get_current_power_draw(self):
return 0 return 0
def shutdown(self):
print("SHUTDOWN!")
def get_thermal_config(self):
return ThermalConfig(cpu=((None,), 1), gpu=((None,), 1), mem=(None, 1), bat=(None, 1), ambient=(None, 1))

@ -3,7 +3,7 @@ import subprocess
from pathlib import Path from pathlib import Path
from cereal import log from cereal import log
from selfdrive.hardware.base import HardwareBase from selfdrive.hardware.base import HardwareBase, ThermalConfig
NM = 'org.freedesktop.NetworkManager' NM = 'org.freedesktop.NetworkManager'
NM_CON_ACT = NM + '.Connection.Active' NM_CON_ACT = NM + '.Connection.Active'
@ -176,3 +176,10 @@ class Tici(HardwareBase):
def get_current_power_draw(self): def get_current_power_draw(self):
return (self.read_param_file("/sys/class/hwmon/hwmon1/power1_input", int) / 1e6) return (self.read_param_file("/sys/class/hwmon/hwmon1/power1_input", int) / 1e6)
def shutdown(self):
# Note that for this to work and have the device stay powered off, the panda needs to be in UsbPowerMode::CLIENT!
os.system("sudo poweroff")
def get_thermal_config(self):
return ThermalConfig(cpu=((1, 2, 3, 4, 5, 6, 7, 8), 1000), gpu=((48,49), 1000), mem=(15, 1000), bat=(None, 1), ambient=(70, 1000))

@ -165,6 +165,7 @@ class PowerMonitoring:
disable_charging |= (self.car_battery_capacity_uWh <= 0) disable_charging |= (self.car_battery_capacity_uWh <= 0)
disable_charging &= (not pandaState.pandaState.ignitionLine and not pandaState.pandaState.ignitionCan) disable_charging &= (not pandaState.pandaState.ignitionLine and not pandaState.pandaState.ignitionCan)
disable_charging &= (self.params.get("DisablePowerDown") != b"1") disable_charging &= (self.params.get("DisablePowerDown") != b"1")
disable_charging |= (self.params.get("ForcePowerDown") == b"1")
return disable_charging return disable_charging
# See if we need to shutdown # See if we need to shutdown

@ -2,7 +2,6 @@
import datetime import datetime
import os import os
import time import time
from collections import namedtuple
from typing import Dict, Optional, Tuple from typing import Dict, Optional, Tuple
import psutil import psutil
@ -15,15 +14,13 @@ from common.numpy_fast import clip, interp
from common.params import Params from common.params import Params
from common.realtime import DT_TRML, sec_since_boot from common.realtime import DT_TRML, sec_since_boot
from selfdrive.controls.lib.alertmanager import set_offroad_alert from selfdrive.controls.lib.alertmanager import set_offroad_alert
from selfdrive.hardware import EON, HARDWARE, TICI from selfdrive.hardware import EON, HARDWARE
from selfdrive.loggerd.config import get_available_percent from selfdrive.loggerd.config import get_available_percent
from selfdrive.pandad import get_expected_signature from selfdrive.pandad import get_expected_signature
from selfdrive.swaglog import cloudlog from selfdrive.swaglog import cloudlog
from selfdrive.thermald.power_monitoring import PowerMonitoring from selfdrive.thermald.power_monitoring import PowerMonitoring
from selfdrive.version import get_git_branch, terms_version, training_version from selfdrive.version import get_git_branch, terms_version, training_version
ThermalConfig = namedtuple('ThermalConfig', ['cpu', 'gpu', 'mem', 'bat', 'ambient'])
FW_SIGNATURE = get_expected_signature() FW_SIGNATURE = get_expected_signature()
ThermalStatus = log.DeviceState.ThermalStatus ThermalStatus = log.DeviceState.ThermalStatus
@ -40,17 +37,6 @@ prev_offroad_states: Dict[str, Tuple[bool, Optional[str]]] = {}
LEON = False LEON = False
last_eon_fan_val = None last_eon_fan_val = None
def get_thermal_config():
# (tz, scale)
if EON:
return ThermalConfig(cpu=((5, 7, 10, 12), 10), gpu=((16,), 10), mem=(2, 10), bat=(29, 1000), ambient=(25, 1))
elif TICI:
return ThermalConfig(cpu=((1, 2, 3, 4, 5, 6, 7, 8), 1000), gpu=((48,49), 1000), mem=(15, 1000), bat=(None, 1), ambient=(70, 1000))
else:
return ThermalConfig(cpu=((None,), 1), gpu=((None,), 1), mem=(None, 1), bat=(None, 1), ambient=(None, 1))
def read_tz(x): def read_tz(x):
if x is None: if x is None:
return 0 return 0
@ -198,7 +184,7 @@ def thermald_thread():
power_monitor = PowerMonitoring() power_monitor = PowerMonitoring()
no_panda_cnt = 0 no_panda_cnt = 0
thermal_config = get_thermal_config() thermal_config = HARDWARE.get_thermal_config()
while 1: while 1:
pandaState = messaging.recv_sock(pandaState_sock, wait=True) pandaState = messaging.recv_sock(pandaState_sock, wait=True)
@ -395,7 +381,7 @@ def thermald_thread():
cloudlog.info(f"shutting device down, offroad since {off_ts}") cloudlog.info(f"shutting device down, offroad since {off_ts}")
# TODO: add function for blocking cloudlog instead of sleep # TODO: add function for blocking cloudlog instead of sleep
time.sleep(10) time.sleep(10)
os.system('LD_LIBRARY_PATH="" svc power shutdown') HARDWARE.shutdown()
msg.deviceState.chargingError = current_filter.x > 0. and msg.deviceState.batteryPercent < 90 # if current is positive, then battery is being discharged msg.deviceState.chargingError = current_filter.x > 0. and msg.deviceState.batteryPercent < 90 # if current is positive, then battery is being discharged
msg.deviceState.started = started_ts is not None msg.deviceState.started = started_ts is not None

Loading…
Cancel
Save