Thermald cleanup (#2049)

* Thermald cleanup

* no Temps, fix ui formatter

* Fix scaling

* Don't touch that

* typo

* Fix fan control

* Fix if

* change cereal

* Update comment
albatross
Willem Melching 2020-08-24 14:17:41 +02:00 committed by GitHub
parent 08d6fe1880
commit 9eb3d89ca2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 56 additions and 44 deletions

2
cereal

@ -1 +1 @@
Subproject commit b9a54adaf4c825bf2b44d9d60d8e6105eb78e9b1 Subproject commit 3f13766df1f366955338b283990334e046baffe4

View File

@ -392,8 +392,8 @@ void hardware_control_thread() {
LOGD("start hardware control thread"); LOGD("start hardware control thread");
SubMaster sm({"thermal", "frontFrame"}); SubMaster sm({"thermal", "frontFrame"});
// Only control fan speed on UNO // Other pandas don't have hardware to control
if (panda->hw_type != cereal::HealthData::HwType::UNO) return; if (panda->hw_type != cereal::HealthData::HwType::UNO && panda->hw_type != cereal::HealthData::HwType::DOS) return;
uint64_t last_front_frame_t = 0; uint64_t last_front_frame_t = 0;
uint16_t prev_fan_speed = 999; uint16_t prev_fan_speed = 999;

View File

@ -1,23 +1,32 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import os
import datetime import datetime
import psutil import os
import time import time
from collections import namedtuple
import psutil
from smbus2 import SMBus from smbus2 import SMBus
from cereal import log
from common.android import ANDROID, get_network_type, get_network_strength
from common.params import Params, put_nonblocking
from common.realtime import sec_since_boot, DT_TRML
from common.numpy_fast import clip, interp
from common.filter_simple import FirstOrderFilter
from selfdrive.version import terms_version, training_version, get_git_branch
from selfdrive.swaglog import cloudlog
import cereal.messaging as messaging import cereal.messaging as messaging
from cereal import log
from common.android import get_network_strength, get_network_type
from common.filter_simple import FirstOrderFilter
from common.numpy_fast import clip, interp
from common.params import Params, put_nonblocking
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.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.thermald.power_monitoring import PowerMonitoring, get_battery_capacity, get_battery_status, \ from selfdrive.swaglog import cloudlog
get_battery_current, get_battery_voltage, get_usb_present from selfdrive.thermald.power_monitoring import (PowerMonitoring,
get_battery_capacity,
get_battery_current,
get_battery_status,
get_battery_voltage,
get_usb_present)
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()
@ -30,35 +39,41 @@ DAYS_NO_CONNECTIVITY_MAX = 7 # do not allow to engage after a week without inte
DAYS_NO_CONNECTIVITY_PROMPT = 4 # send an offroad prompt after 4 days with no internet DAYS_NO_CONNECTIVITY_PROMPT = 4 # send an offroad prompt after 4 days with no internet
DISCONNECT_TIMEOUT = 5. # wait 5 seconds before going offroad after disconnect so you get an alert DISCONNECT_TIMEOUT = 5. # wait 5 seconds before going offroad after disconnect so you get an alert
EON = os.path.isfile('/EON')
TICI = os.path.isfile('/TICI')
LEON = False LEON = False
last_eon_fan_val = None last_eon_fan_val = None
def read_tz(x, clip=True): def get_thermal_config():
if not ANDROID: # (tz, scale)
# we don't monitor thermal on PC 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):
if x is None:
return 0 return 0
try: try:
with open("/sys/devices/virtual/thermal/thermal_zone%d/temp" % x) as f: with open("/sys/devices/virtual/thermal/thermal_zone%d/temp" % x) as f:
ret = int(f.read()) return int(f.read())
if clip:
ret = max(0, ret)
except FileNotFoundError: except FileNotFoundError:
return 0 return 0
return ret
def read_thermal(thermal_config):
def read_thermal():
dat = messaging.new_message('thermal') dat = messaging.new_message('thermal')
dat.thermal.cpu0 = read_tz(5) dat.thermal.cpu = [read_tz(z) / thermal_config.cpu[1] for z in thermal_config.cpu[0]]
dat.thermal.cpu1 = read_tz(7) dat.thermal.gpu = [read_tz(z) / thermal_config.gpu[1] for z in thermal_config.gpu[0]]
dat.thermal.cpu2 = read_tz(10) dat.thermal.mem = read_tz(thermal_config.mem[0]) / thermal_config.mem[1]
dat.thermal.cpu3 = read_tz(12) dat.thermal.ambient = read_tz(thermal_config.ambient[0]) / thermal_config.ambient[1]
dat.thermal.mem = read_tz(2) dat.thermal.bat = read_tz(thermal_config.bat[0]) / thermal_config.bat[1]
dat.thermal.gpu = read_tz(16)
dat.thermal.bat = read_tz(29)
dat.thermal.pa0 = read_tz(25)
return dat return dat
@ -183,11 +198,13 @@ def thermald_thread():
pm = PowerMonitoring() pm = PowerMonitoring()
no_panda_cnt = 0 no_panda_cnt = 0
thermal_config = get_thermal_config()
while 1: while 1:
health = messaging.recv_sock(health_sock, wait=True) health = messaging.recv_sock(health_sock, wait=True)
location = messaging.recv_sock(location_sock) location = messaging.recv_sock(location_sock)
location = location.gpsLocation if location else None location = location.gpsLocation if location else None
msg = read_thermal() msg = read_thermal(thermal_config)
if health is not None: if health is not None:
usb_power = health.health.usbPowerMode != log.HealthData.UsbPowerMode.client usb_power = health.health.usbPowerMode != log.HealthData.UsbPowerMode.client
@ -208,7 +225,7 @@ def thermald_thread():
is_uno = health.health.hwType == log.HealthData.HwType.uno is_uno = health.health.hwType == log.HealthData.HwType.uno
has_relay = health.health.hwType in [log.HealthData.HwType.blackPanda, log.HealthData.HwType.uno, log.HealthData.HwType.dos] has_relay = health.health.hwType in [log.HealthData.HwType.blackPanda, log.HealthData.HwType.uno, log.HealthData.HwType.dos]
if is_uno or not ANDROID: if (not EON) or is_uno:
cloudlog.info("Setting up UNO fan handler") cloudlog.info("Setting up UNO fan handler")
handle_fan = handle_fan_uno handle_fan = handle_fan_uno
else: else:
@ -243,7 +260,7 @@ def thermald_thread():
msg.thermal.usbOnline = get_usb_present() msg.thermal.usbOnline = get_usb_present()
# Fake battery levels on uno for frame # Fake battery levels on uno for frame
if is_uno: if (not EON) or is_uno:
msg.thermal.batteryPercent = 100 msg.thermal.batteryPercent = 100
msg.thermal.batteryStatus = "Charging" msg.thermal.batteryStatus = "Charging"
msg.thermal.bat = 0 msg.thermal.bat = 0
@ -251,14 +268,9 @@ def thermald_thread():
current_filter.update(msg.thermal.batteryCurrent / 1e6) current_filter.update(msg.thermal.batteryCurrent / 1e6)
# TODO: add car battery voltage check # TODO: add car battery voltage check
max_cpu_temp = cpu_temp_filter.update( max_cpu_temp = cpu_temp_filter.update(max(msg.thermal.cpu))
max(msg.thermal.cpu0, max_comp_temp = max(max_cpu_temp, msg.thermal.mem, max(msg.thermal.gpu))
msg.thermal.cpu1, bat_temp = msg.thermal.bat
msg.thermal.cpu2,
msg.thermal.cpu3) / 10.0)
max_comp_temp = max(max_cpu_temp, msg.thermal.mem / 10., msg.thermal.gpu / 10.)
bat_temp = msg.thermal.bat / 1000.
if handle_fan is not None: if handle_fan is not None:
fan_speed = handle_fan(max_cpu_temp, bat_temp, fan_speed, ignition) fan_speed = handle_fan(max_cpu_temp, bat_temp, fan_speed, ignition)

View File

@ -124,7 +124,7 @@ static void ui_draw_sidebar_temp_metric(UIState *s) {
char temp_value_str[32]; char temp_value_str[32];
char temp_value_unit[32]; char temp_value_unit[32];
const int temp_y_offset = 0; const int temp_y_offset = 0;
snprintf(temp_value_str, sizeof(temp_value_str), "%d", s->scene.thermal.getPa0()); snprintf(temp_value_str, sizeof(temp_value_str), "%.0f", s->scene.thermal.getAmbient());
snprintf(temp_value_unit, sizeof(temp_value_unit), "%s", "°C"); snprintf(temp_value_unit, sizeof(temp_value_unit), "%s", "°C");
snprintf(temp_label_str, sizeof(temp_label_str), "%s", "TEMP"); snprintf(temp_label_str, sizeof(temp_label_str), "%s", "TEMP");
strcat(temp_value_str, temp_value_unit); strcat(temp_value_str, temp_value_unit);