Merge remote-tracking branch 'upstream/master' into car-info

pull/23762/head
Shane Smiskol 4 years ago
commit be033312a5
  1. 7
      SConstruct
  2. 2
      cereal
  3. 2
      opendbc
  4. 33
      selfdrive/athena/athenad.py
  5. 2
      selfdrive/boardd/panda.cc
  6. 2
      selfdrive/car/ford/interface.py
  7. 1
      selfdrive/common/params.cc
  8. 7
      selfdrive/hardware/base.py
  9. 32
      selfdrive/hardware/tici/hardware.py
  10. 11
      selfdrive/loggerd/uploader.py
  11. 5
      selfdrive/monitoring/driver_monitor.py
  12. 5
      selfdrive/thermald/thermald.py
  13. 4
      selfdrive/ui/qt/onroad.cc
  14. 1
      selfdrive/ui/qt/onroad.h

@ -89,7 +89,6 @@ if arch == "aarch64" or arch == "larch64":
"/usr/local/lib", "/usr/local/lib",
"/usr/lib", "/usr/lib",
"/system/vendor/lib64", "/system/vendor/lib64",
"/system/comma/usr/lib",
f"#third_party/acados/{arch}/lib", f"#third_party/acados/{arch}/lib",
] ]
@ -306,11 +305,11 @@ if arch == "Darwin":
qt_env["FRAMEWORKS"] += [f"Qt{m}" for m in qt_modules] + ["OpenGL"] qt_env["FRAMEWORKS"] += [f"Qt{m}" for m in qt_modules] + ["OpenGL"]
qt_env.AppendENVPath('PATH', os.path.join(qt_env['QTDIR'], "bin")) qt_env.AppendENVPath('PATH', os.path.join(qt_env['QTDIR'], "bin"))
elif arch == "aarch64": elif arch == "aarch64":
qt_env['QTDIR'] = "/system/comma/usr" qt_env['QTDIR'] = "/usr"
qt_dirs = [ qt_dirs = [
f"/system/comma/usr/include/qt", f"/usr/include/qt",
] ]
qt_dirs += [f"/system/comma/usr/include/qt/Qt{m}" for m in qt_modules] qt_dirs += [f"/usr/include/qt/Qt{m}" for m in qt_modules]
qt_libs = [f"Qt5{m}" for m in qt_modules] qt_libs = [f"Qt5{m}" for m in qt_modules]
qt_libs += ['EGL', 'GLESv3', 'c++_shared'] qt_libs += ['EGL', 'GLESv3', 'c++_shared']

@ -1 +1 @@
Subproject commit 9416d75c20ba59154d647a0b14f9ea1fc62c34fa Subproject commit 7e9837f768dd24d9f56edb450926c76f7f259aa6

@ -1 +1 @@
Subproject commit 859fea7ded706516f4b963218a3c9cf543f39c2a Subproject commit eab58f6f8f41f255920365ab1fd9c75e312a6869

@ -163,8 +163,6 @@ def upload_handler(end_event: threading.Event) -> None:
sm = messaging.SubMaster(['deviceState']) sm = messaging.SubMaster(['deviceState'])
tid = threading.get_ident() tid = threading.get_ident()
cellular_unmetered = Params().get_bool("CellularUnmetered")
while not end_event.is_set(): while not end_event.is_set():
cur_upload_items[tid] = None cur_upload_items[tid] = None
@ -181,46 +179,45 @@ def upload_handler(end_event: threading.Event) -> None:
cloudlog.event("athena.upload_handler.expired", item=cur_upload_items[tid], error=True) cloudlog.event("athena.upload_handler.expired", item=cur_upload_items[tid], error=True)
continue continue
# Check if uploading over cell is allowed # Check if uploading over metered connection is allowed
sm.update(0) sm.update(0)
cell = sm['deviceState'].networkType not in [NetworkType.wifi, NetworkType.ethernet] metered = sm['deviceState'].networkMetered
if cell and (not cur_upload_items[tid].allow_cellular) and (not cellular_unmetered): network_type = sm['deviceState'].networkType.raw
if metered and (not cur_upload_items[tid].allow_cellular):
retry_upload(tid, end_event, False) retry_upload(tid, end_event, False)
continue continue
try: try:
def cb(sz, cur): def cb(sz, cur):
# Abort transfer if connection changed to cell after starting upload # Abort transfer if connection changed to metered after starting upload
sm.update(0) sm.update(0)
cell = sm['deviceState'].networkType not in [NetworkType.wifi, NetworkType.ethernet] metered = sm['deviceState'].networkMetered
if cell and (not cur_upload_items[tid].allow_cellular) and (not cellular_unmetered): if metered and (not cur_upload_items[tid].allow_cellular):
raise AbortTransferException raise AbortTransferException
cur_upload_items[tid] = cur_upload_items[tid]._replace(progress=cur / sz if sz else 1) cur_upload_items[tid] = cur_upload_items[tid]._replace(progress=cur / sz if sz else 1)
network_type = sm['deviceState'].networkType.raw
fn = cur_upload_items[tid].path fn = cur_upload_items[tid].path
try: try:
sz = os.path.getsize(fn) sz = os.path.getsize(fn)
except OSError: except OSError:
sz = -1 sz = -1
cloudlog.event("athena.upload_handler.upload_start", fn=fn, sz=sz, network_type=network_type) cloudlog.event("athena.upload_handler.upload_start", fn=fn, sz=sz, network_type=network_type, metered=metered)
response = _do_upload(cur_upload_items[tid], cb) response = _do_upload(cur_upload_items[tid], cb)
if response.status_code not in (200, 201, 403, 412): if response.status_code not in (200, 201, 403, 412):
cloudlog.event("athena.upload_handler.retry", status_code=response.status_code, fn=fn, sz=sz, network_type=network_type) cloudlog.event("athena.upload_handler.retry", status_code=response.status_code, fn=fn, sz=sz, network_type=network_type, metered=metered)
retry_upload(tid, end_event) retry_upload(tid, end_event)
else: else:
cloudlog.event("athena.upload_handler.success", fn=fn, sz=sz, network_type=network_type) cloudlog.event("athena.upload_handler.success", fn=fn, sz=sz, network_type=network_type, metered=metered)
UploadQueueCache.cache(upload_queue) UploadQueueCache.cache(upload_queue)
except (requests.exceptions.Timeout, requests.exceptions.ConnectionError, requests.exceptions.SSLError): except (requests.exceptions.Timeout, requests.exceptions.ConnectionError, requests.exceptions.SSLError):
cloudlog.event("athena.upload_handler.timeout", fn=fn, sz=sz, network_type=network_type) cloudlog.event("athena.upload_handler.timeout", fn=fn, sz=sz, network_type=network_type, metered=metered)
retry_upload(tid, end_event) retry_upload(tid, end_event)
except AbortTransferException: except AbortTransferException:
cloudlog.event("athena.upload_handler.abort", fn=fn, sz=sz, network_type=network_type) cloudlog.event("athena.upload_handler.abort", fn=fn, sz=sz, network_type=network_type, metered=metered)
retry_upload(tid, end_event, False) retry_upload(tid, end_event, False)
except queue.Empty: except queue.Empty:
@ -459,6 +456,12 @@ def getNetworkType():
return HARDWARE.get_network_type() return HARDWARE.get_network_type()
@dispatcher.add_method
def getNetworkMetered():
network_type = HARDWARE.get_network_type()
return HARDWARE.get_network_metered(network_type)
@dispatcher.add_method @dispatcher.add_method
def getNetworks(): def getNetworks():
return HARDWARE.get_networks() return HARDWARE.get_networks()

@ -338,7 +338,7 @@ void Panda::set_power_saving(bool power_saving) {
usb_write(0xe7, power_saving, 0); usb_write(0xe7, power_saving, 0);
} }
void Panda::enable_deepsleep(void) { void Panda::enable_deepsleep() {
usb_write(0xfb, 0, 0); usb_write(0xfb, 0, 0);
} }

@ -25,6 +25,8 @@ class CarInterface(CarInterfaceBase):
ret.steerRateCost = 1.0 ret.steerRateCost = 1.0
ret.centerToFront = ret.wheelbase * 0.44 ret.centerToFront = ret.wheelbase * 0.44
tire_stiffness_factor = 0.5328 tire_stiffness_factor = 0.5328
# TODO: add minSteerSpeed
ret.minEnableSpeed = 12. * CV.MPH_TO_MS
# TODO: get actual value, for now starting with reasonable value for # TODO: get actual value, for now starting with reasonable value for
# civic and scaling by mass and wheelbase # civic and scaling by mass and wheelbase

@ -91,7 +91,6 @@ std::unordered_map<std::string, uint32_t> keys = {
{"CarParams", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON}, {"CarParams", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
{"CarParamsCache", CLEAR_ON_MANAGER_START}, {"CarParamsCache", CLEAR_ON_MANAGER_START},
{"CarVin", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON}, {"CarVin", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
{"CellularUnmetered", PERSISTENT},
{"CompletedTrainingVersion", PERSISTENT}, {"CompletedTrainingVersion", PERSISTENT},
{"ControlsReady", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON}, {"ControlsReady", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
{"CurrentRoute", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON}, {"CurrentRoute", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},

@ -2,7 +2,11 @@ from abc import abstractmethod, ABC
from collections import namedtuple from collections import namedtuple
from typing import Dict from typing import Dict
from cereal import log
ThermalConfig = namedtuple('ThermalConfig', ['cpu', 'gpu', 'mem', 'bat', 'ambient', 'pmic']) ThermalConfig = namedtuple('ThermalConfig', ['cpu', 'gpu', 'mem', 'bat', 'ambient', 'pmic'])
NetworkType = log.DeviceState.NetworkType
class HardwareBase(ABC): class HardwareBase(ABC):
@staticmethod @staticmethod
@ -67,6 +71,9 @@ class HardwareBase(ABC):
def get_network_strength(self, network_type): def get_network_strength(self, network_type):
pass pass
def get_network_metered(self, network_type) -> bool:
return network_type not in (NetworkType.none, NetworkType.wifi, NetworkType.ethernet)
@staticmethod @staticmethod
def set_bandwidth_limit(upload_speed_kbps: int, download_speed_kbps: int) -> None: def set_bandwidth_limit(upload_speed_kbps: int, download_speed_kbps: int) -> None:
pass pass

@ -13,6 +13,7 @@ from selfdrive.hardware.tici.amplifier import Amplifier
NM = 'org.freedesktop.NetworkManager' NM = 'org.freedesktop.NetworkManager'
NM_CON_ACT = NM + '.Connection.Active' NM_CON_ACT = NM + '.Connection.Active'
NM_DEV = NM + '.Device'
NM_DEV_WL = NM + '.Device.Wireless' NM_DEV_WL = NM + '.Device.Wireless'
NM_AP = NM + '.AccessPoint' NM_AP = NM + '.AccessPoint'
DBUS_PROPS = 'org.freedesktop.DBus.Properties' DBUS_PROPS = 'org.freedesktop.DBus.Properties'
@ -37,6 +38,13 @@ class MM_MODEM_STATE(IntEnum):
CONNECTING = 10 CONNECTING = 10
CONNECTED = 11 CONNECTED = 11
class NMMetered(IntEnum):
NM_METERED_UNKNOWN = 0
NM_METERED_YES = 1
NM_METERED_NO = 2
NM_METERED_GUESS_YES = 3
NM_METERED_GUESS_NO = 4
TIMEOUT = 0.1 TIMEOUT = 0.1
NetworkType = log.DeviceState.NetworkType NetworkType = log.DeviceState.NetworkType
@ -91,11 +99,10 @@ class Tici(HardwareBase):
primary_connection = self.nm.Get(NM, 'PrimaryConnection', dbus_interface=DBUS_PROPS, timeout=TIMEOUT) primary_connection = self.nm.Get(NM, 'PrimaryConnection', dbus_interface=DBUS_PROPS, timeout=TIMEOUT)
primary_connection = self.bus.get_object(NM, primary_connection) primary_connection = self.bus.get_object(NM, primary_connection)
primary_type = primary_connection.Get(NM_CON_ACT, 'Type', dbus_interface=DBUS_PROPS, timeout=TIMEOUT) primary_type = primary_connection.Get(NM_CON_ACT, 'Type', dbus_interface=DBUS_PROPS, timeout=TIMEOUT)
primary_id = primary_connection.Get(NM_CON_ACT, 'Id', dbus_interface=DBUS_PROPS, timeout=TIMEOUT)
if primary_type == '802-3-ethernet': if primary_type == '802-3-ethernet':
return NetworkType.ethernet return NetworkType.ethernet
elif primary_type == '802-11-wireless' and primary_id != 'Hotspot': elif primary_type == '802-11-wireless':
return NetworkType.wifi return NetworkType.wifi
else: else:
active_connections = self.nm.Get(NM, 'ActiveConnections', dbus_interface=DBUS_PROPS, timeout=TIMEOUT) active_connections = self.nm.Get(NM, 'ActiveConnections', dbus_interface=DBUS_PROPS, timeout=TIMEOUT)
@ -218,6 +225,27 @@ class Tici(HardwareBase):
return network_strength return network_strength
def get_network_metered(self, network_type) -> bool:
try:
primary_connection = self.nm.Get(NM, 'PrimaryConnection', dbus_interface=DBUS_PROPS, timeout=TIMEOUT)
primary_connection = self.bus.get_object(NM, primary_connection)
primary_devices = primary_connection.Get(NM_CON_ACT, 'Devices', dbus_interface=DBUS_PROPS, timeout=TIMEOUT)
for dev in primary_devices:
dev_obj = self.bus.get_object(NM, str(dev))
metered_prop = dev_obj.Get(NM_DEV, 'Metered', dbus_interface=DBUS_PROPS, timeout=TIMEOUT)
if network_type == NetworkType.wifi:
if metered_prop in [NMMetered.NM_METERED_YES, NMMetered.NM_METERED_GUESS_YES]:
return True
elif network_type in [NetworkType.cell2G, NetworkType.cell3G, NetworkType.cell4G, NetworkType.cell5G]:
if metered_prop == NMMetered.NM_METERED_NO:
return False
except Exception:
pass
return super().get_network_metered(network_type)
@staticmethod @staticmethod
def set_bandwidth_limit(upload_speed_kbps: int, download_speed_kbps: int) -> None: def set_bandwidth_limit(upload_speed_kbps: int, download_speed_kbps: int) -> None:
upload_speed_kbps = int(upload_speed_kbps) # Ensure integer value upload_speed_kbps = int(upload_speed_kbps) # Ensure integer value

@ -165,14 +165,14 @@ class Uploader():
return self.last_resp return self.last_resp
def upload(self, key, fn, network_type): def upload(self, key, fn, network_type, metered):
try: try:
sz = os.path.getsize(fn) sz = os.path.getsize(fn)
except OSError: except OSError:
cloudlog.exception("upload: getsize failed") cloudlog.exception("upload: getsize failed")
return False return False
cloudlog.event("upload_start", key=key, fn=fn, sz=sz, network_type=network_type) cloudlog.event("upload_start", key=key, fn=fn, sz=sz, network_type=network_type, metered=metered)
if sz == 0: if sz == 0:
try: try:
@ -195,10 +195,10 @@ class Uploader():
self.last_time = time.monotonic() - start_time self.last_time = time.monotonic() - start_time
self.last_speed = (sz / 1e6) / self.last_time self.last_speed = (sz / 1e6) / self.last_time
success = True success = True
cloudlog.event("upload_success" if stat.status_code != 412 else "upload_ignored", key=key, fn=fn, sz=sz, network_type=network_type) cloudlog.event("upload_success" if stat.status_code != 412 else "upload_ignored", key=key, fn=fn, sz=sz, network_type=network_type, metered=metered)
else: else:
success = False success = False
cloudlog.event("upload_failed", stat=stat, exc=self.last_exc, key=key, fn=fn, sz=sz, network_type=network_type) cloudlog.event("upload_failed", stat=stat, exc=self.last_exc, key=key, fn=fn, sz=sz, network_type=network_type, metered=metered)
return success return success
@ -247,7 +247,7 @@ def uploader_fn(exit_event):
key, fn = d key, fn = d
success = uploader.upload(key, fn, sm['deviceState'].networkType.raw) success = uploader.upload(key, fn, sm['deviceState'].networkType.raw, sm['deviceState'].networkMetered)
if success: if success:
backoff = 0.1 backoff = 0.1
elif allow_sleep: elif allow_sleep:
@ -257,6 +257,7 @@ def uploader_fn(exit_event):
pm.send("uploaderState", uploader.get_msg()) pm.send("uploaderState", uploader.get_msg())
def main(): def main():
uploader_fn(threading.Event()) uploader_fn(threading.Event())

@ -18,8 +18,9 @@ EventName = car.CarEvent.EventName
class DRIVER_MONITOR_SETTINGS(): class DRIVER_MONITOR_SETTINGS():
def __init__(self, TICI=TICI, DT_DMON=DT_DMON): def __init__(self, TICI=TICI, DT_DMON=DT_DMON):
self._DT_DMON = DT_DMON self._DT_DMON = DT_DMON
self._AWARENESS_TIME = 35. # passive wheeltouch total timeout # ref (page15-16): https://eur-lex.europa.eu/legal-content/EN/TXT/PDF/?uri=CELEX:42018X1947&rid=2
self._AWARENESS_PRE_TIME_TILL_TERMINAL = 12. self._AWARENESS_TIME = 30. # passive wheeltouch total timeout
self._AWARENESS_PRE_TIME_TILL_TERMINAL = 15.
self._AWARENESS_PROMPT_TIME_TILL_TERMINAL = 6. self._AWARENESS_PROMPT_TIME_TILL_TERMINAL = 6.
self._DISTRACTED_TIME = 11. # active monitoring total timeout self._DISTRACTED_TIME = 11. # active monitoring total timeout
self._DISTRACTED_PRE_TIME_TILL_TERMINAL = 8. self._DISTRACTED_PRE_TIME_TILL_TERMINAL = 8.

@ -34,7 +34,7 @@ DISCONNECT_TIMEOUT = 5. # wait 5 seconds before going offroad after disconnect
PANDA_STATES_TIMEOUT = int(1000 * 2.5 * DT_TRML) # 2.5x the expected pandaState frequency PANDA_STATES_TIMEOUT = int(1000 * 2.5 * DT_TRML) # 2.5x the expected pandaState frequency
ThermalBand = namedtuple("ThermalBand", ['min_temp', 'max_temp']) ThermalBand = namedtuple("ThermalBand", ['min_temp', 'max_temp'])
HardwareState = namedtuple("HardwareState", ['network_type', 'network_strength', 'network_info', 'nvme_temps', 'modem_temps']) HardwareState = namedtuple("HardwareState", ['network_type', 'network_metered', 'network_strength', 'network_info', 'nvme_temps', 'modem_temps'])
# List of thermal bands. We will stay within this region as long as we are within the bounds. # List of thermal bands. We will stay within this region as long as we are within the bounds.
# When exiting the bounds, we'll jump to the lower or higher band. Bands are ordered in the dict. # When exiting the bounds, we'll jump to the lower or higher band. Bands are ordered in the dict.
@ -95,6 +95,7 @@ def hw_state_thread(end_event, hw_queue):
hw_state = HardwareState( hw_state = HardwareState(
network_type=network_type, network_type=network_type,
network_metered=HARDWARE.get_network_metered(network_type),
network_strength=HARDWARE.get_network_strength(network_type), network_strength=HARDWARE.get_network_strength(network_type),
network_info=HARDWARE.get_network_info(), network_info=HARDWARE.get_network_info(),
nvme_temps=HARDWARE.get_nvme_temperatures(), nvme_temps=HARDWARE.get_nvme_temperatures(),
@ -144,6 +145,7 @@ def thermald_thread(end_event, hw_queue):
last_hw_state = HardwareState( last_hw_state = HardwareState(
network_type=NetworkType.none, network_type=NetworkType.none,
network_metered=False,
network_strength=NetworkStrength.unknown, network_strength=NetworkStrength.unknown,
network_info=None, network_info=None,
nvme_temps=[], nvme_temps=[],
@ -205,6 +207,7 @@ def thermald_thread(end_event, hw_queue):
msg.deviceState.gpuUsagePercent = int(round(HARDWARE.get_gpu_usage_percent())) msg.deviceState.gpuUsagePercent = int(round(HARDWARE.get_gpu_usage_percent()))
msg.deviceState.networkType = last_hw_state.network_type msg.deviceState.networkType = last_hw_state.network_type
msg.deviceState.networkMetered = last_hw_state.network_metered
msg.deviceState.networkStrength = last_hw_state.network_strength msg.deviceState.networkStrength = last_hw_state.network_strength
if last_hw_state.network_info is not None: if last_hw_state.network_info is not None:
msg.deviceState.networkInfo = last_hw_state.network_info msg.deviceState.networkInfo = last_hw_state.network_info

@ -314,8 +314,8 @@ void NvgWindow::drawLaneLines(QPainter &painter, const UIScene &scene) {
} }
// paint path // paint path
QLinearGradient bg(0, height(), 0, height() / 4); QLinearGradient bg(0, height(), 0, height() / 4);
bg.setColorAt(0, scene.end_to_end ? redColor() : QColor(255, 255, 255)); bg.setColorAt(0, scene.end_to_end ? redColor() : whiteColor());
bg.setColorAt(1, scene.end_to_end ? redColor(0) : QColor(255, 255, 255, 0)); bg.setColorAt(1, scene.end_to_end ? redColor(0) : whiteColor(0));
painter.setBrush(bg); painter.setBrush(bg);
painter.drawPolygon(scene.track_vertices.v, scene.track_vertices.cnt); painter.drawPolygon(scene.track_vertices.v, scene.track_vertices.cnt);
} }

@ -76,6 +76,7 @@ protected:
void drawLaneLines(QPainter &painter, const UIScene &scene); void drawLaneLines(QPainter &painter, const UIScene &scene);
void drawLead(QPainter &painter, const cereal::ModelDataV2::LeadDataV3::Reader &lead_data, const QPointF &vd); void drawLead(QPainter &painter, const cereal::ModelDataV2::LeadDataV3::Reader &lead_data, const QPointF &vd);
inline QColor redColor(int alpha = 255) { return QColor(201, 34, 49, alpha); } inline QColor redColor(int alpha = 255) { return QColor(201, 34, 49, alpha); }
inline QColor whiteColor(int alpha = 255) { return QColor(255, 255, 255, alpha); }
double prev_draw_t = 0; double prev_draw_t = 0;
}; };

Loading…
Cancel
Save