From 5f794fe49a1e0f2849e6a979c7bd12ca5ddb060a Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Mon, 4 Jul 2022 19:55:00 +0800 Subject: [PATCH 001/112] settings.cc: remove function network_panel (#25030) remove function network_panel --- selfdrive/ui/qt/offroad/settings.cc | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index 547ad168f1..a03af23951 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -279,10 +279,6 @@ void SoftwarePanel::updateLabels() { osVersionLbl->setText(QString::fromStdString(Hardware::get_os_version()).trimmed()); } -QWidget *network_panel(QWidget *parent) { - return new Networking(parent); -} - void SettingsWindow::showEvent(QShowEvent *event) { panel_widget->setCurrentIndex(0); nav_btns->buttons()[0]->setChecked(true); @@ -328,7 +324,7 @@ SettingsWindow::SettingsWindow(QWidget *parent) : QFrame(parent) { QList> panels = { {tr("Device"), device}, - {tr("Network"), network_panel(this)}, + {tr("Network"), new Networking(this)}, {tr("Toggles"), new TogglesPanel(this)}, {tr("Software"), new SoftwarePanel(this)}, }; From 735387d5eea7e76d1940a82b0b5dcaddf1eb264a Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Mon, 4 Jul 2022 13:57:25 +0200 Subject: [PATCH 002/112] bump opendbc --- opendbc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opendbc b/opendbc index 7fbf7c2a68..9c7248ceb2 160000 --- a/opendbc +++ b/opendbc @@ -1 +1 @@ -Subproject commit 7fbf7c2a685a90ff01e744cfb410f1a8a3c06278 +Subproject commit 9c7248ceb269928e3741103f978e9e4de2b38156 From d4cc13c88a8a9a9215777709fe2eccade1fd0ccd Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Mon, 4 Jul 2022 17:13:30 +0200 Subject: [PATCH 003/112] controlsd: avoid lag on first iteration due to get_short_branch (#25031) * controlsd: avoid lag on first iteration due to get_short_branch * always cache --- selfdrive/controls/controlsd.py | 4 ++++ selfdrive/controls/lib/events.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index 3ee47c620b..9e3af9eb63 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -12,6 +12,7 @@ import cereal.messaging as messaging from common.conversions import Conversions as CV from panda import ALTERNATIVE_EXPERIENCE from system.swaglog import cloudlog +from system.version import get_short_branch from selfdrive.boardd.boardd import can_list_to_can_capnp from selfdrive.car.car_helpers import get_car, get_startup_event, get_one_can from selfdrive.controls.lib.lane_planner import CAMERA_OFFSET @@ -62,6 +63,9 @@ class Controls: def __init__(self, sm=None, pm=None, can_sock=None, CI=None): config_realtime_process(4, Priority.CTRL_HIGH) + # Ensure the current branch is cached, otherwise the first iteration of controlsd lags + self.branch = get_short_branch("") + # Setup sockets self.pm = pm if self.pm is None: diff --git a/selfdrive/controls/lib/events.py b/selfdrive/controls/lib/events.py index cc63d4995d..95ccb7b7ec 100644 --- a/selfdrive/controls/lib/events.py +++ b/selfdrive/controls/lib/events.py @@ -222,7 +222,7 @@ def user_soft_disable_alert(alert_text_2: str) -> AlertCallbackType: return func def startup_master_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: - branch = get_short_branch("") + branch = get_short_branch("") # Ensure get_short_branch is cached to avoid lags on startup if "REPLAY" in os.environ: branch = "replay" From 39007810927faa309d06e6ad9586302341547f64 Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Tue, 5 Jul 2022 16:55:32 +0200 Subject: [PATCH 004/112] add casync support to agnos updater (#23654) * add casync option to agnos updater * open if necessary * add python implementation * last chunk can be small * check flags * cleaner check * add remote and file stores * remote caibx file * print stats * use python implementation * clean up imports * add progress * fix logging * fix duplicate chunks * add comments * json stats * cleanup tmp * normal image is still sparse * Update system/hardware/tici/agnos.py Co-authored-by: Adeeb Shihadeh * Update system/hardware/tici/agnos.py Co-authored-by: Adeeb Shihadeh * add some types * remove comment * create Chunk type * make readers a class * try agnos 5.2 * add download retries * catch all exceptions * sleep between retry * revert agnos.json changes Co-authored-by: Adeeb Shihadeh --- system/hardware/tici/agnos.py | 95 ++++++++++++---- system/hardware/tici/casync.py | 192 +++++++++++++++++++++++++++++++++ 2 files changed, 265 insertions(+), 22 deletions(-) create mode 100755 system/hardware/tici/casync.py diff --git a/system/hardware/tici/agnos.py b/system/hardware/tici/agnos.py index e664654c65..527422aca7 100755 --- a/system/hardware/tici/agnos.py +++ b/system/hardware/tici/agnos.py @@ -1,13 +1,16 @@ #!/usr/bin/env python3 +import hashlib import json import lzma -import hashlib -import requests +import os import struct import subprocess import time -import os -from typing import Dict, Generator, Union +from typing import Dict, Generator, List, Tuple, Union + +import requests + +import system.hardware.tici.casync as casync SPARSE_CHUNK_FMT = struct.Struct('H2xI4x') @@ -74,6 +77,7 @@ def unsparsify(f: StreamingDecompressor) -> Generator[bytes, None, None]: else: raise Exception("Unhandled sparse chunk type") + # noop wrapper with same API as unsparsify() for non sparse images def noop(f: StreamingDecompressor) -> Generator[bytes, None, None]: while not f.eof: @@ -99,8 +103,8 @@ def get_partition_path(target_slot_number: int, partition: dict) -> str: return path -def verify_partition(target_slot_number: int, partition: Dict[str, Union[str, int]]) -> bool: - full_check = partition['full_check'] +def verify_partition(target_slot_number: int, partition: Dict[str, Union[str, int]], force_full_check: bool = False) -> bool: + full_check = partition['full_check'] or force_full_check path = get_partition_path(target_slot_number, partition) if not isinstance(partition['size'], int): return False @@ -135,21 +139,10 @@ def clear_partition_hash(target_slot_number: int, partition: dict) -> None: os.sync() -def flash_partition(target_slot_number: int, partition: dict, cloudlog): - cloudlog.info(f"Downloading and writing {partition['name']}") - - if verify_partition(target_slot_number, partition): - cloudlog.info(f"Already flashed {partition['name']}") - return - +def extract_compressed_image(target_slot_number: int, partition: dict, cloudlog): + path = get_partition_path(target_slot_number, partition) downloader = StreamingDecompressor(partition['url']) - # Clear hash before flashing in case we get interrupted - full_check = partition['full_check'] - if not full_check: - clear_partition_hash(target_slot_number, partition) - - path = get_partition_path(target_slot_number, partition) with open(path, 'wb+') as out: # Flash partition last_p = 0 @@ -172,9 +165,67 @@ def flash_partition(target_slot_number: int, partition: dict, cloudlog): if out.tell() != partition['size']: raise Exception("Uncompressed size mismatch") - # Write hash after successfull flash os.sync() - if not full_check: + + +def extract_casync_image(target_slot_number: int, partition: dict, cloudlog): + path = get_partition_path(target_slot_number, partition) + seed_path = path[:-1] + ('b' if path[-1] == 'a' else 'a') + + target = casync.parse_caibx(partition['casync_caibx']) + + sources: List[Tuple[str, casync.ChunkReader, casync.ChunkDict]] = [] + + # First source is the current partition. Index file for current version is provided in the manifest + if 'casync_seed_caibx' in partition: + sources += [('seed', casync.FileChunkReader(seed_path), casync.build_chunk_dict(casync.parse_caibx(partition['casync_seed_caibx'])))] + + # Second source is the target partition, this allows for resuming + sources += [('target', casync.FileChunkReader(path), casync.build_chunk_dict(target))] + + # Finally we add the remote source to download any missing chunks + sources += [('remote', casync.RemoteChunkReader(partition['casync_store']), casync.build_chunk_dict(target))] + + last_p = 0 + + def progress(cur): + nonlocal last_p + p = int(cur / partition['size'] * 100) + if p != last_p: + last_p = p + print(f"Installing {partition['name']}: {p}", flush=True) + + stats = casync.extract(target, sources, path, progress) + cloudlog.error(f'casync done {json.dumps(stats)}') + + os.sync() + if not verify_partition(target_slot_number, partition, force_full_check=True): + raise Exception(f"Raw hash mismatch '{partition['hash_raw'].lower()}'") + + +def flash_partition(target_slot_number: int, partition: dict, cloudlog): + cloudlog.info(f"Downloading and writing {partition['name']}") + + if verify_partition(target_slot_number, partition): + cloudlog.info(f"Already flashed {partition['name']}") + return + + # Clear hash before flashing in case we get interrupted + full_check = partition['full_check'] + if not full_check: + clear_partition_hash(target_slot_number, partition) + + path = get_partition_path(target_slot_number, partition) + + if 'casync_caibx' in partition: + extract_casync_image(target_slot_number, partition, cloudlog) + else: + extract_compressed_image(target_slot_number, partition, cloudlog) + + # Write hash after successfull flash + if not full_check: + with open(path, 'wb+') as out: + out.seek(partition['size']) out.write(partition['hash_raw'].lower().encode()) @@ -228,8 +279,8 @@ def verify_agnos_update(manifest_path: str, target_slot_number: int) -> bool: if __name__ == "__main__": - import logging import argparse + import logging parser = argparse.ArgumentParser(description="Flash and verify AGNOS update", formatter_class=argparse.ArgumentDefaultsHelpFormatter) diff --git a/system/hardware/tici/casync.py b/system/hardware/tici/casync.py new file mode 100755 index 0000000000..e77f473636 --- /dev/null +++ b/system/hardware/tici/casync.py @@ -0,0 +1,192 @@ +#!/usr/bin/env python3 +import io +import lzma +import os +import struct +import sys +import time +from abc import ABC, abstractmethod +from collections import defaultdict, namedtuple +from typing import Callable, Dict, List, Optional, Tuple + +import requests +from Crypto.Hash import SHA512 + +CA_FORMAT_INDEX = 0x96824d9c7b129ff9 +CA_FORMAT_TABLE = 0xe75b9e112f17417d +CA_FORMAT_TABLE_TAIL_MARKER = 0xe75b9e112f17417 +FLAGS = 0xb000000000000000 + +CA_HEADER_LEN = 48 +CA_TABLE_HEADER_LEN = 16 +CA_TABLE_ENTRY_LEN = 40 +CA_TABLE_MIN_LEN = CA_TABLE_HEADER_LEN + CA_TABLE_ENTRY_LEN + +CHUNK_DOWNLOAD_TIMEOUT = 10 +CHUNK_DOWNLOAD_RETRIES = 3 + +CAIBX_DOWNLOAD_TIMEOUT = 120 + +Chunk = namedtuple('Chunk', ['sha', 'offset', 'length']) +ChunkDict = Dict[bytes, Chunk] + + +class ChunkReader(ABC): + @abstractmethod + def read(self, chunk: Chunk) -> bytes: + ... + + +class FileChunkReader(ChunkReader): + """Reads chunks from a local file""" + def __init__(self, fn: str) -> None: + + super().__init__() + self.f = open(fn, 'rb') + + def read(self, chunk: Chunk) -> bytes: + self.f.seek(chunk.offset) + return self.f.read(chunk.length) + + +class RemoteChunkReader(ChunkReader): + """Reads lzma compressed chunks from a remote store""" + + def __init__(self, url: str) -> None: + super().__init__() + self.url = url + + def read(self, chunk: Chunk) -> bytes: + sha_hex = chunk.sha.hex() + url = os.path.join(self.url, sha_hex[:4], sha_hex + ".cacnk") + + for i in range(CHUNK_DOWNLOAD_RETRIES): + try: + resp = requests.get(url, timeout=CHUNK_DOWNLOAD_TIMEOUT) + break + except Exception: + if i == CHUNK_DOWNLOAD_RETRIES - 1: + raise + time.sleep(CHUNK_DOWNLOAD_TIMEOUT) + + resp.raise_for_status() + + decompressor = lzma.LZMADecompressor(format=lzma.FORMAT_AUTO) + return decompressor.decompress(resp.content) + + +def parse_caibx(caibx_path: str) -> List[Chunk]: + """Parses the chunks from a caibx file. Can handle both local and remote files. + Returns a list of chunks with hash, offset and length""" + if os.path.isfile(caibx_path): + caibx = open(caibx_path, 'rb') + else: + resp = requests.get(caibx_path, timeout=CAIBX_DOWNLOAD_TIMEOUT) + resp.raise_for_status() + caibx = io.BytesIO(resp.content) + + caibx.seek(0, os.SEEK_END) + caibx_len = caibx.tell() + caibx.seek(0, os.SEEK_SET) + + # Parse header + length, magic, flags, min_size, _, max_size = struct.unpack("= min_size + + chunks.append(Chunk(sha, offset, length)) + offset = new_offset + + return chunks + + +def build_chunk_dict(chunks: List[Chunk]) -> ChunkDict: + """Turn a list of chunks into a dict for faster lookups based on hash""" + return {c.sha: c for c in chunks} + + +def extract(target: List[Chunk], + sources: List[Tuple[str, ChunkReader, ChunkDict]], + out_path: str, + progress: Optional[Callable[[int], None]] = None): + stats: Dict[str, int] = defaultdict(int) + + with open(out_path, 'wb') as out: + for cur_chunk in target: + + # Find source for desired chunk + for name, chunk_reader, store_chunks in sources: + if cur_chunk.sha in store_chunks: + bts = chunk_reader.read(store_chunks[cur_chunk.sha]) + + # Check length + if len(bts) != cur_chunk.length: + continue + + # Check hash + if SHA512.new(bts, truncate="256").digest() != cur_chunk.sha: + continue + + # Write to output + out.seek(cur_chunk.offset) + out.write(bts) + + stats[name] += cur_chunk.length + + if progress is not None: + progress(sum(stats.values())) + + break + else: + raise RuntimeError("Desired chunk not found in provided stores") + + return stats + + +def print_stats(stats: Dict[str, int]): + total_bytes = sum(stats.values()) + print(f"Total size: {total_bytes / 1024 / 1024:.2f} MB") + for name, total in stats.items(): + print(f" {name}: {total / 1024 / 1024:.2f} MB ({total / total_bytes * 100:.1f}%)") + + +def extract_simple(caibx_path, out_path, store_path): + # (name, callback, chunks) + target = parse_caibx(caibx_path) + sources = [ + # (store_path, RemoteChunkReader(store_path), build_chunk_dict(target)), + (store_path, FileChunkReader(store_path), build_chunk_dict(target)), + ] + + return extract(target, sources, out_path) + + +if __name__ == "__main__": + caibx = sys.argv[1] + out = sys.argv[2] + store = sys.argv[3] + + stats = extract_simple(caibx, out, store) + print_stats(stats) From 06a8ac627c0b8cf00b3bd4ea7186f5c876f71561 Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Tue, 5 Jul 2022 18:06:08 +0200 Subject: [PATCH 005/112] casync: build_chunk_dict optimize for resuming (#25038) --- system/hardware/tici/casync.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/system/hardware/tici/casync.py b/system/hardware/tici/casync.py index e77f473636..b857c04795 100755 --- a/system/hardware/tici/casync.py +++ b/system/hardware/tici/casync.py @@ -123,8 +123,13 @@ def parse_caibx(caibx_path: str) -> List[Chunk]: def build_chunk_dict(chunks: List[Chunk]) -> ChunkDict: - """Turn a list of chunks into a dict for faster lookups based on hash""" - return {c.sha: c for c in chunks} + """Turn a list of chunks into a dict for faster lookups based on hash. + Keep first chunk since it's more likely to be already downloaded.""" + r = {} + for c in chunks: + if c.sha not in r: + r[c.sha] = c + return r def extract(target: List[Chunk], From 0bf1462ad0a459f8a2cc863f58089540789922f1 Mon Sep 17 00:00:00 2001 From: martinl Date: Tue, 5 Jul 2022 20:33:20 +0300 Subject: [PATCH 006/112] Update path for github workflow hardware unit tests (#25035) * Update hardware path for github workflow unit tests * Update release/files_common Co-authored-by: Adeeb Shihadeh --- .github/workflows/selfdrive_tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/selfdrive_tests.yaml b/.github/workflows/selfdrive_tests.yaml index 0ff0092b02..35a08d4fe9 100644 --- a/.github/workflows/selfdrive_tests.yaml +++ b/.github/workflows/selfdrive_tests.yaml @@ -302,7 +302,7 @@ jobs: selfdrive/locationd/test/_test_locationd_lib.py && \ $UNIT_TEST selfdrive/athena && \ $UNIT_TEST selfdrive/thermald && \ - $UNIT_TEST selfdrive/hardware/tici && \ + $UNIT_TEST system/hardware/tici && \ $UNIT_TEST selfdrive/modeld && \ $UNIT_TEST tools/lib/tests && \ ./selfdrive/ui/tests/create_test_translations.sh && \ From d4f4809992c5c73e36ec1041445e6a11b2c68448 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 5 Jul 2022 14:28:54 -0700 Subject: [PATCH 007/112] always show avg power --- tools/zookeeper/power_monitor.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/zookeeper/power_monitor.py b/tools/zookeeper/power_monitor.py index f88741813e..fa1f442bbc 100755 --- a/tools/zookeeper/power_monitor.py +++ b/tools/zookeeper/power_monitor.py @@ -27,8 +27,10 @@ if __name__ == "__main__": while duration is None or time.monotonic() - start_time < duration: fltr.update(z.read_power()) if rk.frame % rate == 0: - print(f"{fltr.x:.2f} W") measurements.append(fltr.x) + t = datetime.timedelta(seconds=time.monotonic() - start_time) + avg = sum(measurements) / len(measurements) + print(f"Now: {fltr.x:.2f} W, Avg: {avg:.2f} W over {t}") rk.keep_time() except KeyboardInterrupt: pass From 88a30004e0bf96601e5b8fc4c084219c52a46e15 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 5 Jul 2022 16:40:47 -0700 Subject: [PATCH 008/112] Chrysler: prep for Ram port (#25040) * Chrysler: prep for Ram port * bump opendbc * opendbc master * bump panda --- opendbc | 2 +- panda | 2 +- release/files_common | 4 +--- selfdrive/car/chrysler/carstate.py | 20 ++++++++++---------- selfdrive/car/chrysler/chryslercan.py | 6 +++--- selfdrive/car/chrysler/values.py | 14 +++++++------- 6 files changed, 23 insertions(+), 25 deletions(-) diff --git a/opendbc b/opendbc index 9c7248ceb2..b2895650c7 160000 --- a/opendbc +++ b/opendbc @@ -1 +1 @@ -Subproject commit 9c7248ceb269928e3741103f978e9e4de2b38156 +Subproject commit b2895650c744e24d48cee2f13563dcd5b030a271 diff --git a/panda b/panda index 2652453892..6c0d0b43c2 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 265245389208e1e6ada86b169e879c0a2e30426c +Subproject commit 6c0d0b43c239b89baa83b4a1885d0ce21ab2335e diff --git a/release/files_common b/release/files_common index acf74e2137..e32277dfd8 100644 --- a/release/files_common +++ b/release/files_common @@ -35,7 +35,6 @@ common/filter_simple.py common/stat_live.py common/spinner.py common/text_window.py -common/SConscript common/kalman/.gitignore common/kalman/* @@ -217,7 +216,6 @@ selfdrive/locationd/generated/gps.h selfdrive/locationd/laikad.py selfdrive/locationd/laikad_helpers.py -selfdrive/locationd/locationd.cc selfdrive/locationd/locationd.h selfdrive/locationd/locationd.cc selfdrive/locationd/paramsd.py @@ -475,7 +473,7 @@ opendbc/can/parser_pyx.pyx opendbc/comma_body.dbc -opendbc/chrysler_pacifica_2017_hybrid.dbc +opendbc/chrysler_pacifica_2017_hybrid_generated.dbc opendbc/chrysler_pacifica_2017_hybrid_private_fusion.dbc opendbc/gm_global_a_powertrain_generated.dbc diff --git a/selfdrive/car/chrysler/carstate.py b/selfdrive/car/chrysler/carstate.py index 444557191a..aa46ea0d94 100644 --- a/selfdrive/car/chrysler/carstate.py +++ b/selfdrive/car/chrysler/carstate.py @@ -64,14 +64,14 @@ class CarState(CarStateBase): steer_state = cp.vl["EPS_2"]["LKAS_STATE"] ret.steerFaultPermanent = steer_state == 4 or (steer_state == 0 and ret.vEgo > self.CP.minSteerSpeed) - ret.genericToggle = bool(cp.vl["STEERING_LEVERS"]["HIGH_BEAM_FLASH"]) + ret.genericToggle = bool(cp.vl["STEERING_LEVERS"]["HIGH_BEAM_PRESSED"]) if self.CP.enableBsm: - ret.leftBlindspot = cp.vl["BLIND_SPOT_WARNINGS"]["BLIND_SPOT_LEFT"] == 1 - ret.rightBlindspot = cp.vl["BLIND_SPOT_WARNINGS"]["BLIND_SPOT_RIGHT"] == 1 + ret.leftBlindspot = cp.vl["BSM_1"]["LEFT_STATUS"] == 1 + ret.rightBlindspot = cp.vl["BSM_1"]["RIGHT_STATUS"] == 1 self.lkas_counter = cp_cam.vl["LKAS_COMMAND"]["COUNTER"] - self.lkas_car_model = cp_cam.vl["LKAS_HUD"]["CAR_MODEL"] + self.lkas_car_model = cp_cam.vl["DAS_6"]["CAR_MODEL"] self.lkas_status_ok = cp_cam.vl["LKAS_HEARTBIT"]["LKAS_STATUS_OK"] self.button_counter = cp.vl["CRUISE_BUTTONS"]["COUNTER"] @@ -100,7 +100,7 @@ class CarState(CarStateBase): ("ACC_AVAILABLE", "DAS_3"), ("ACC_ACTIVE", "DAS_3"), ("ACC_FAULTED", "DAS_3"), - ("HIGH_BEAM_FLASH", "STEERING_LEVERS"), + ("HIGH_BEAM_PRESSED", "STEERING_LEVERS"), ("ACC_SPEED_CONFIG_KPH", "DAS_4"), ("CRUISE_STATE", "DAS_4"), ("COLUMN_TORQUE", "EPS_2"), @@ -132,10 +132,10 @@ class CarState(CarStateBase): if CP.enableBsm: signals += [ - ("BLIND_SPOT_RIGHT", "BLIND_SPOT_WARNINGS"), - ("BLIND_SPOT_LEFT", "BLIND_SPOT_WARNINGS"), + ("RIGHT_STATUS", "BSM_1"), + ("LEFT_STATUS", "BSM_1"), ] - checks.append(("BLIND_SPOT_WARNINGS", 2)) + checks.append(("BSM_1", 2)) return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, 0) @@ -144,13 +144,13 @@ class CarState(CarStateBase): signals = [ # sig_name, sig_address ("COUNTER", "LKAS_COMMAND"), - ("CAR_MODEL", "LKAS_HUD"), + ("CAR_MODEL", "DAS_6"), ("LKAS_STATUS_OK", "LKAS_HEARTBIT") ] checks = [ ("LKAS_COMMAND", 100), ("LKAS_HEARTBIT", 10), - ("LKAS_HUD", 4), + ("DAS_6", 4), ] return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, 2) diff --git a/selfdrive/car/chrysler/chryslercan.py b/selfdrive/car/chrysler/chryslercan.py index 53b79cab73..adcd411d31 100644 --- a/selfdrive/car/chrysler/chryslercan.py +++ b/selfdrive/car/chrysler/chryslercan.py @@ -35,14 +35,14 @@ def create_lkas_hud(packer, gear, lkas_active, hud_alert, hud_count, lkas_car_mo "LKAS_ALERTS": alerts, # byte 3, last 4 bits } - return packer.make_can_msg("LKAS_HUD", 0, values) # 0x2a6 + return packer.make_can_msg("DAS_6", 0, values) # 0x2a6 def create_lkas_command(packer, apply_steer, moving_fast, frame): # LKAS_COMMAND 0x292 (658) Lane-keeping signal to turn the wheel. values = { - "LKAS_STEERING_TORQUE": apply_steer, - "LKAS_HIGH_TORQUE": int(moving_fast), + "STEERING_TORQUE": apply_steer, + "LKAS_CONTROL_BIT": int(moving_fast), "COUNTER": frame % 0x10, } return packer.make_can_msg("LKAS_COMMAND", 0, values) diff --git a/selfdrive/car/chrysler/values.py b/selfdrive/car/chrysler/values.py index d624bd2727..5537b383d3 100644 --- a/selfdrive/car/chrysler/values.py +++ b/selfdrive/car/chrysler/values.py @@ -101,13 +101,13 @@ FINGERPRINTS = { DBC = { - CAR.PACIFICA_2017_HYBRID: dbc_dict('chrysler_pacifica_2017_hybrid', 'chrysler_pacifica_2017_hybrid_private_fusion'), - CAR.PACIFICA_2018: dbc_dict('chrysler_pacifica_2017_hybrid', 'chrysler_pacifica_2017_hybrid_private_fusion'), - CAR.PACIFICA_2020: dbc_dict('chrysler_pacifica_2017_hybrid', 'chrysler_pacifica_2017_hybrid_private_fusion'), - CAR.PACIFICA_2018_HYBRID: dbc_dict('chrysler_pacifica_2017_hybrid', 'chrysler_pacifica_2017_hybrid_private_fusion'), - CAR.PACIFICA_2019_HYBRID: dbc_dict('chrysler_pacifica_2017_hybrid', 'chrysler_pacifica_2017_hybrid_private_fusion'), - CAR.JEEP_CHEROKEE: dbc_dict('chrysler_pacifica_2017_hybrid', 'chrysler_pacifica_2017_hybrid_private_fusion'), - CAR.JEEP_CHEROKEE_2019: dbc_dict('chrysler_pacifica_2017_hybrid', 'chrysler_pacifica_2017_hybrid_private_fusion'), + CAR.PACIFICA_2017_HYBRID: dbc_dict('chrysler_pacifica_2017_hybrid_generated', 'chrysler_pacifica_2017_hybrid_private_fusion'), + CAR.PACIFICA_2018: dbc_dict('chrysler_pacifica_2017_hybrid_generated', 'chrysler_pacifica_2017_hybrid_private_fusion'), + CAR.PACIFICA_2020: dbc_dict('chrysler_pacifica_2017_hybrid_generated', 'chrysler_pacifica_2017_hybrid_private_fusion'), + CAR.PACIFICA_2018_HYBRID: dbc_dict('chrysler_pacifica_2017_hybrid_generated', 'chrysler_pacifica_2017_hybrid_private_fusion'), + CAR.PACIFICA_2019_HYBRID: dbc_dict('chrysler_pacifica_2017_hybrid_generated', 'chrysler_pacifica_2017_hybrid_private_fusion'), + CAR.JEEP_CHEROKEE: dbc_dict('chrysler_pacifica_2017_hybrid_generated', 'chrysler_pacifica_2017_hybrid_private_fusion'), + CAR.JEEP_CHEROKEE_2019: dbc_dict('chrysler_pacifica_2017_hybrid_generated', 'chrysler_pacifica_2017_hybrid_private_fusion'), } STEER_THRESHOLD = 120 From eaa8b08510057c089520f4ba410218be261c9158 Mon Sep 17 00:00:00 2001 From: martinl Date: Wed, 6 Jul 2022 02:42:53 +0300 Subject: [PATCH 009/112] Subaru: XV is supported (#25034) * Subaru: add XV to supported models * Update docs --- docs/CARS.md | 6 ++++-- selfdrive/car/subaru/values.py | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/CARS.md b/docs/CARS.md index 25de6a2549..0cf384df18 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -71,7 +71,7 @@ How We Rate The Cars |Toyota|RAV4 2019-21|All|||||| |Toyota|RAV4 Hybrid 2019-21|All|||||| -# Silver - 67 cars +# Silver - 68 cars |Make|Model|Supported Package|openpilot ACC|Stop and Go|Steer to 0|Steering Torque|Actively Maintained| |---|---|---|:---:|:---:|:---:|:---:|:---:| @@ -120,6 +120,7 @@ How We Rate The Cars |Subaru|Crosstrek 2020-21|EyeSight|||||| |Subaru|Forester 2019-21|All|||||| |Subaru|Impreza 2020-21|EyeSight|||||| +|Subaru|XV 2020-21|EyeSight|||||| |Toyota|Alphard 2019-20|All|||||| |Toyota|Alphard Hybrid 2021|All|||||| |Toyota|Camry 2018-20|All||[4](#footnotes)|||| @@ -143,7 +144,7 @@ How We Rate The Cars |Volkswagen|Passat 2015-19[6](#footnotes)|Driver Assistance|||||| |Volkswagen|Polo 2020|Driver Assistance|||||| -# Bronze - 78 cars +# Bronze - 79 cars |Make|Model|Supported Package|openpilot ACC|Stop and Go|Steer to 0|Steering Torque|Actively Maintained| |---|---|---|:---:|:---:|:---:|:---:|:---:| @@ -199,6 +200,7 @@ How We Rate The Cars |Mazda|CX-9 2021|All|||||| |Subaru|Crosstrek 2018-19|EyeSight|||||| |Subaru|Impreza 2017-19|EyeSight|||||| +|Subaru|XV 2018-19|EyeSight|||||| |Škoda|Kamiq 2021[5](#footnotes)|Driver Assistance|||||| |Škoda|Karoq 2019|Driver Assistance|||||| |Škoda|Kodiaq 2018-19|Driver Assistance|||||| diff --git a/selfdrive/car/subaru/values.py b/selfdrive/car/subaru/values.py index 45358eb3a4..ea923b1b50 100644 --- a/selfdrive/car/subaru/values.py +++ b/selfdrive/car/subaru/values.py @@ -45,10 +45,12 @@ CAR_INFO: Dict[str, Union[SubaruCarInfo, List[SubaruCarInfo]]] = { CAR.IMPREZA: [ SubaruCarInfo("Subaru Impreza 2017-19"), SubaruCarInfo("Subaru Crosstrek 2018-19", video_link="https://youtu.be/Agww7oE1k-s?t=26"), + SubaruCarInfo("Subaru XV 2018-19", video_link="https://youtu.be/Agww7oE1k-s?t=26"), ], CAR.IMPREZA_2020: [ SubaruCarInfo("Subaru Impreza 2020-21"), SubaruCarInfo("Subaru Crosstrek 2020-21"), + SubaruCarInfo("Subaru XV 2020-21"), ], CAR.FORESTER: SubaruCarInfo("Subaru Forester 2019-21", "All"), CAR.FORESTER_PREGLOBAL: SubaruCarInfo("Subaru Forester 2017-18"), From f21b56f25af5ee0930dc8f991aac4e9c438b3cda Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Tue, 5 Jul 2022 20:04:48 -0700 Subject: [PATCH 010/112] regen migration: use Panda safety parameters (#25043) no magic numbers --- selfdrive/test/process_replay/regen.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/selfdrive/test/process_replay/regen.py b/selfdrive/test/process_replay/regen.py index d2f239c249..793e548705 100755 --- a/selfdrive/test/process_replay/regen.py +++ b/selfdrive/test/process_replay/regen.py @@ -15,6 +15,8 @@ from cereal.visionipc import VisionIpcServer, VisionStreamType from common.params import Params from common.realtime import Ratekeeper, DT_MDL, DT_DMON, sec_since_boot from common.transformations.camera import eon_f_frame_size, eon_d_frame_size, tici_f_frame_size, tici_d_frame_size +from panda.python import Panda +from selfdrive.car.toyota.values import EPS_SCALE from selfdrive.manager.process import ensure_running from selfdrive.manager.process_config import managed_processes from selfdrive.test.process_replay.process_replay import FAKEDATA, setup_env, check_enabled @@ -30,8 +32,8 @@ def replay_panda_states(s, msgs): # TODO: new safety params from flags, remove after getting new routes for Toyota safety_param_migration = { - "TOYOTA PRIUS 2017": 578, - "TOYOTA RAV4 2017": 329 + "TOYOTA PRIUS 2017": EPS_SCALE["TOYOTA PRIUS 2017"] | Panda.FLAG_TOYOTA_STOCK_LONGITUDINAL, + "TOYOTA RAV4 2017": EPS_SCALE["TOYOTA RAV4 2017"] | Panda.FLAG_TOYOTA_ALT_BRAKE, } # Migrate safety param base on carState From 972e24ee263d7c86b865632f4bb110bbde1b16ac Mon Sep 17 00:00:00 2001 From: Erich Moraga <33645296+ErichMoraga@users.noreply.github.com> Date: Wed, 6 Jul 2022 00:06:25 -0500 Subject: [PATCH 011/112] Add new LEXUS_RX_TSS2 engine f/w (#25041) `@ibby1137#8978` 2022 Lexus RX350L AWD DongleID|route abc09032f402f271|2022-07-05--17-34-41 --- selfdrive/car/toyota/values.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py index 43d923338e..283c137c91 100644 --- a/selfdrive/car/toyota/values.py +++ b/selfdrive/car/toyota/values.py @@ -1761,13 +1761,14 @@ FW_VERSIONS = { b'\x01896630EB0000\x00\x00\x00\x00', b'\x01896630EC9000\x00\x00\x00\x00', b'\x01896630ED0000\x00\x00\x00\x00', + b'\x01896630ED0100\x00\x00\x00\x00', b'\x01896630ED6000\x00\x00\x00\x00', b'\x018966348W5100\x00\x00\x00\x00', b'\x018966348W9000\x00\x00\x00\x00', b'\x01896634D12000\x00\x00\x00\x00', b'\x01896634D12100\x00\x00\x00\x00', b'\x01896634D43000\x00\x00\x00\x00', - b'\x01896630ED0100\x00\x00\x00\x00', + b'\x01896634D44000\x00\x00\x00\x00', ], (Ecu.esp, 0x7b0, None): [ b'\x01F15260E031\x00\x00\x00\x00\x00\x00', From 73a6348be7f20fd2c4e303ca7ff7490b71bff59f Mon Sep 17 00:00:00 2001 From: haram-KONA <88036668+haram-KONA@users.noreply.github.com> Date: Wed, 6 Jul 2022 14:08:36 +0900 Subject: [PATCH 012/112] car docs: add video for Hyundai Kona Hybrid 2020 (#25029) * Update values.py Added the following video link "https://www.youtube.com/watch?v=0dwpAHiZgFo" * Update values.py * Update selfdrive/car/hyundai/values.py * Update selfdrive/car/hyundai/values.py Co-authored-by: Shane Smiskol --- selfdrive/car/hyundai/values.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index 0717ed1fbe..f6efedb248 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -105,7 +105,7 @@ CAR_INFO: Dict[str, Optional[Union[HyundaiCarInfo, List[HyundaiCarInfo]]]] = { CAR.IONIQ_PHEV: HyundaiCarInfo("Hyundai Ioniq Plug-in Hybrid 2020-21", harness=Harness.hyundai_h), CAR.KONA: HyundaiCarInfo("Hyundai Kona 2020", harness=Harness.hyundai_b), CAR.KONA_EV: HyundaiCarInfo("Hyundai Kona Electric 2018-21", harness=Harness.hyundai_g), - CAR.KONA_HEV: HyundaiCarInfo("Hyundai Kona Hybrid 2020", harness=Harness.hyundai_i), + CAR.KONA_HEV: HyundaiCarInfo("Hyundai Kona Hybrid 2020", video_link="https://youtu.be/0dwpAHiZgFo", harness=Harness.hyundai_i), CAR.SANTA_FE: HyundaiCarInfo("Hyundai Santa Fe 2019-20", "All", harness=Harness.hyundai_d), CAR.SANTA_FE_2022: HyundaiCarInfo("Hyundai Santa Fe 2021-22", "All", harness=Harness.hyundai_l), CAR.SANTA_FE_HEV_2022: HyundaiCarInfo("Hyundai Santa Fe Hybrid 2022", "All", harness=Harness.hyundai_l), From 38427e6fbbe1eb09c8a335f8c9aa90460d6bbfde Mon Sep 17 00:00:00 2001 From: BirdZhang <0312birdzhang@gmail.com> Date: Wed, 6 Jul 2022 13:11:21 +0800 Subject: [PATCH 013/112] Toyota: add missing esp FW version for 2021 Toyota Corolla (#25026) 2021 Toyota Levin hybrid (aka Corolla) --- selfdrive/car/toyota/values.py | 1 + 1 file changed, 1 insertion(+) diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py index 283c137c91..86283bc48f 100644 --- a/selfdrive/car/toyota/values.py +++ b/selfdrive/car/toyota/values.py @@ -816,6 +816,7 @@ FW_VERSIONS = { b'F152676303\x00\x00\x00\x00\x00\x00', b'F152676304\x00\x00\x00\x00\x00\x00', b'F152612D00\x00\x00\x00\x00\x00\x00', + b'F152612842\x00\x00\x00\x00\x00\x00', ], (Ecu.fwdRadar, 0x750, 0xf): [ b'\x018821F3301100\x00\x00\x00\x00', From f797567ef8c574027eec8da72a2c76cfb2fdafe1 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Tue, 5 Jul 2022 22:19:20 -0700 Subject: [PATCH 014/112] long planner: run when using stock longitudinal (#25017) * Squashed commit of the following: commit e27a5b4e2bfeab4e6a47440b1d4eb180ee4acf49 Author: Shane Smiskol Date: Fri Jul 1 14:10:06 2022 -0700 remove this test remove this test commit c3c10af82222ea4641d94c53a3a07b486cca8452 Author: Shane Smiskol Date: Fri Jul 1 14:08:15 2022 -0700 only planner changes commit 50e0f1d8704c15acfce8987faf3515c99e8af4f4 Merge: e088fde67 fcc5b3d70 Author: Shane Smiskol Date: Fri Jul 1 14:05:36 2022 -0700 Merge remote-tracking branch 'upstream/master' into enable-planner2 commit e088fde67edcc32ccfeea23b4ae9e44845240429 Author: Shane Smiskol Date: Thu Jun 30 13:58:38 2022 -0700 no walrus commit b7b425e530e949b9cc427833562473cc241d1367 Merge: f8634266b c49f997be Author: Shane Smiskol Date: Thu Jun 30 13:54:30 2022 -0700 Merge remote-tracking branch 'upstream/master' into enable-planner commit f8634266b49c3f692b255e6cfac66cccc438ae20 Author: Shane Smiskol Date: Wed Jun 29 16:07:35 2022 -0700 stricter test, speeds[-1] is 0.14 when starting here commit c9e446ad2183feba9d03ee39f9801091ab791c08 Merge: e6c4106ea 879a7c320 Author: Shane Smiskol Date: Wed Jun 29 16:01:32 2022 -0700 Merge remote-tracking branch 'upstream/master' into enable-planner commit e6c4106ea185c68a6c7b3d59d5bde664df8bdc9c Author: Shane Smiskol Date: Sat Jun 25 03:28:41 2022 -0700 fix test commit 0520c7f21613b57b804e08a8e8d10950ac059074 Author: Shane Smiskol Date: Sat Jun 25 03:26:16 2022 -0700 add test for resuming commit 04db5f80bff4a002f5241765a625d7cf57b74364 Merge: e23b37d3f d8bfe2f00 Author: Shane Smiskol Date: Wed Jun 22 20:15:50 2022 -0700 Merge remote-tracking branch 'upstream/master' into enable-planner commit e23b37d3fe8dd3dd07b46a32a4f0564fabade1aa Author: Shane Smiskol Date: Tue Jun 21 12:46:04 2022 -0700 0.1 should be pretty safe commit e7dc3960da3d713753f28732f50dbd25811fad28 Author: Shane Smiskol Date: Tue Jun 21 12:39:30 2022 -0700 try 0.2 commit ff0597ec92a0d2c52915316961ec123b0183c5cf Author: Shane Smiskol Date: Tue Jun 21 11:34:00 2022 -0700 Always run planner if not opLong commit 13997c55271f79fd3ca62d6db45ec3790b09aa60 Merge: d2f51ee55 95d8517a8 Author: Shane Smiskol Date: Tue Jun 21 11:29:22 2022 -0700 Merge remote-tracking branch 'upstream/master' into enable-planner commit d2f51ee55fd3bde38275371e76714d7741bc6f6b Author: Shane Smiskol Date: Tue Jun 21 11:27:45 2022 -0700 same for non-HDA2 commit 6a63bd60f09a0abd9185049cd173100d3ef6fefa Author: Shane Smiskol Date: Mon Jun 20 23:37:07 2022 -0700 mazda: ensure no resume if cancelling commit 5771cdecab7999765d9f5203c75a67f1555cf975 Author: Shane Smiskol Date: Mon Jun 20 23:27:58 2022 -0700 maintain original button msg rate commit 6c1fe0606fd0a0819ffeaac92526e43b3110f2f4 Author: Shane Smiskol Date: Wed Jun 15 23:45:26 2022 -0700 rename to resume commit 00b1df652f1679137c769f9db61eed7dd14e1542 Author: Shane Smiskol Date: Wed Jun 15 21:57:54 2022 -0700 remove comments commit 325ea9bbd5e0dd946961ede0cdcc446ad5e5bbdb Author: Shane Smiskol Date: Wed Jun 15 21:56:20 2022 -0700 vw commit 2c9061042b36fe1d6b029a4216655be69a980849 Author: Shane Smiskol Date: Wed Jun 15 21:54:37 2022 -0700 do rest but vw commit 3dc51f663dfdd4ea1fd72d239bcd5db8c7da4b47 Author: Shane Smiskol Date: Wed Jun 15 16:34:48 2022 -0700 only spam resume when future is > vEgoStarting commit 5f32cd1fcb402bee425d866a9dc76b6feea3d241 Author: Shane Smiskol Date: Wed Jun 15 16:09:43 2022 -0700 always log leads, we hide them in ui * reset when not CS.enabled remove comment * update refs --- selfdrive/controls/lib/longitudinal_planner.py | 4 ++-- selfdrive/controls/radard.py | 16 ++++++---------- selfdrive/test/process_replay/ref_commit | 2 +- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/selfdrive/controls/lib/longitudinal_planner.py b/selfdrive/controls/lib/longitudinal_planner.py index d4a6aaef8f..cf51136770 100755 --- a/selfdrive/controls/lib/longitudinal_planner.py +++ b/selfdrive/controls/lib/longitudinal_planner.py @@ -66,11 +66,11 @@ class Planner: v_cruise_kph = min(v_cruise_kph, V_CRUISE_MAX) v_cruise = v_cruise_kph * CV.KPH_TO_MS - long_control_state = sm['controlsState'].longControlState + long_control_off = sm['controlsState'].longControlState == LongCtrlState.off force_slow_decel = sm['controlsState'].forceDecel # Reset current state when not engaged, or user is controlling the speed - reset_state = long_control_state == LongCtrlState.off + reset_state = long_control_off if self.CP.openpilotLongitudinalControl else not sm['controlsState'].enabled # No change cost when user is controlling the speed, or when standstill prev_accel_constraint = not (reset_state or sm['carState'].standstill) diff --git a/selfdrive/controls/radard.py b/selfdrive/controls/radard.py index b2c9914457..3d958139d6 100755 --- a/selfdrive/controls/radard.py +++ b/selfdrive/controls/radard.py @@ -102,7 +102,7 @@ class RadarD(): self.ready = False - def update(self, sm, rr, enable_lead): + def update(self, sm, rr): self.current_time = 1e-9*max(sm.logMonoTime.values()) if sm.updated['carState']: @@ -169,11 +169,10 @@ class RadarD(): radarState.radarErrors = list(rr.errors) radarState.carStateMonoTime = sm.logMonoTime['carState'] - if enable_lead: - leads_v3 = sm['modelV2'].leadsV3 - if len(leads_v3) > 1: - radarState.leadOne = get_lead(self.v_ego, self.ready, clusters, leads_v3[0], low_speed_override=True) - radarState.leadTwo = get_lead(self.v_ego, self.ready, clusters, leads_v3[1], low_speed_override=False) + leads_v3 = sm['modelV2'].leadsV3 + if len(leads_v3) > 1: + radarState.leadOne = get_lead(self.v_ego, self.ready, clusters, leads_v3[0], low_speed_override=True) + radarState.leadTwo = get_lead(self.v_ego, self.ready, clusters, leads_v3[1], low_speed_override=False) return dat @@ -203,9 +202,6 @@ def radard_thread(sm=None, pm=None, can_sock=None): rk = Ratekeeper(1.0 / CP.radarTimeStep, print_delay_threshold=None) RD = RadarD(CP.radarTimeStep, RI.delay) - # TODO: always log leads once we can hide them conditionally - enable_lead = CP.openpilotLongitudinalControl or not CP.radarOffCan - while 1: can_strings = messaging.drain_sock_raw(can_sock, wait_for_one=True) rr = RI.update(can_strings) @@ -215,7 +211,7 @@ def radard_thread(sm=None, pm=None, can_sock=None): sm.update(0) - dat = RD.update(sm, rr, enable_lead) + dat = RD.update(sm, rr) dat.radarState.cumLagMs = -rk.remaining*1000. pm.send('radarState', dat) diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index 90444b1fa7..999081b4df 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -806984d4206056fb132625c5dad6c0ca1835a2d6 \ No newline at end of file +a57bbbffbee434e59e08b98b667dc13b6b505f08 \ No newline at end of file From 59c28611a4c385c487d5d0c8a219fe20eaeadeaf Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 5 Jul 2022 23:01:57 -0700 Subject: [PATCH 015/112] bump opendbc --- opendbc | 2 +- selfdrive/car/chrysler/carstate.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/opendbc b/opendbc index b2895650c7..1e9693ce09 160000 --- a/opendbc +++ b/opendbc @@ -1 +1 @@ -Subproject commit b2895650c744e24d48cee2f13563dcd5b030a271 +Subproject commit 1e9693ce0916b896568dcd5558a670e67843c299 diff --git a/selfdrive/car/chrysler/carstate.py b/selfdrive/car/chrysler/carstate.py index aa46ea0d94..61fe1f7ec6 100644 --- a/selfdrive/car/chrysler/carstate.py +++ b/selfdrive/car/chrysler/carstate.py @@ -51,9 +51,9 @@ class CarState(CarStateBase): ret.cruiseState.available = cp.vl["DAS_3"]["ACC_AVAILABLE"] == 1 # ACC is white ret.cruiseState.enabled = cp.vl["DAS_3"]["ACC_ACTIVE"] == 1 # ACC is green - ret.cruiseState.speed = cp.vl["DAS_4"]["ACC_SPEED_CONFIG_KPH"] * CV.KPH_TO_MS + ret.cruiseState.speed = cp.vl["DAS_4"]["ACC_SET_SPEED_KPH"] * CV.KPH_TO_MS # CRUISE_STATE is a three bit msg, 0 is off, 1 and 2 are Non-ACC mode, 3 and 4 are ACC mode, find if there are other states too - ret.cruiseState.nonAdaptive = cp.vl["DAS_4"]["CRUISE_STATE"] in (1, 2) + ret.cruiseState.nonAdaptive = cp.vl["DAS_4"]["ACC_STATE"] in (1, 2) ret.accFaulted = cp.vl["DAS_3"]["ACC_FAULTED"] != 0 ret.steeringAngleDeg = cp.vl["STEERING"]["STEER_ANGLE"] @@ -101,8 +101,8 @@ class CarState(CarStateBase): ("ACC_ACTIVE", "DAS_3"), ("ACC_FAULTED", "DAS_3"), ("HIGH_BEAM_PRESSED", "STEERING_LEVERS"), - ("ACC_SPEED_CONFIG_KPH", "DAS_4"), - ("CRUISE_STATE", "DAS_4"), + ("ACC_SET_SPEED_KPH", "DAS_4"), + ("ACC_STATE", "DAS_4"), ("COLUMN_TORQUE", "EPS_2"), ("EPS_TORQUE_MOTOR", "EPS_2"), ("LKAS_STATE", "EPS_2"), From 50434d612ee7becc09aef762a6c8fb8d8111af6d Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Wed, 6 Jul 2022 12:08:51 +0200 Subject: [PATCH 016/112] casync: reuse requests session in RemoteChunkReader (#25045) --- system/hardware/tici/casync.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/system/hardware/tici/casync.py b/system/hardware/tici/casync.py index b857c04795..d0d0da3c6a 100755 --- a/system/hardware/tici/casync.py +++ b/system/hardware/tici/casync.py @@ -55,6 +55,7 @@ class RemoteChunkReader(ChunkReader): def __init__(self, url: str) -> None: super().__init__() self.url = url + self.session = requests.Session() def read(self, chunk: Chunk) -> bytes: sha_hex = chunk.sha.hex() @@ -62,7 +63,7 @@ class RemoteChunkReader(ChunkReader): for i in range(CHUNK_DOWNLOAD_RETRIES): try: - resp = requests.get(url, timeout=CHUNK_DOWNLOAD_TIMEOUT) + resp = self.session.get(url, timeout=CHUNK_DOWNLOAD_TIMEOUT) break except Exception: if i == CHUNK_DOWNLOAD_RETRIES - 1: From 4080f729bea6092813331fb6d92c80e2f4c4f928 Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Wed, 6 Jul 2022 13:04:25 +0200 Subject: [PATCH 017/112] casync: compute seed caibx url on the fly (#25046) * compute seed hash on the fly * more logging * partition name in url * fix comment --- system/hardware/tici/agnos.py | 41 ++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/system/hardware/tici/agnos.py b/system/hardware/tici/agnos.py index 527422aca7..bd8ce2bf02 100755 --- a/system/hardware/tici/agnos.py +++ b/system/hardware/tici/agnos.py @@ -13,6 +13,7 @@ import requests import system.hardware.tici.casync as casync SPARSE_CHUNK_FMT = struct.Struct('H2xI4x') +CAIBX_URL = "https://commadist.azureedge.net/agnosupdate/" class StreamingDecompressor: @@ -103,28 +104,37 @@ def get_partition_path(target_slot_number: int, partition: dict) -> str: return path +def get_raw_hash(path: str, partition_size: int) -> str: + raw_hash = hashlib.sha256() + pos, chunk_size = 0, 1024 * 1024 + + with open(path, 'rb+') as out: + while pos < partition_size: + n = min(chunk_size, partition_size - pos) + raw_hash.update(out.read(n)) + pos += n + + return raw_hash.hexdigest().lower() + + def verify_partition(target_slot_number: int, partition: Dict[str, Union[str, int]], force_full_check: bool = False) -> bool: full_check = partition['full_check'] or force_full_check path = get_partition_path(target_slot_number, partition) + if not isinstance(partition['size'], int): return False + partition_size: int = partition['size'] if not isinstance(partition['hash_raw'], str): return False - partition_hash: str = partition['hash_raw'] - with open(path, 'rb+') as out: - if full_check: - raw_hash = hashlib.sha256() - pos, chunk_size = 0, 1024 * 1024 - while pos < partition_size: - n = min(chunk_size, partition_size - pos) - raw_hash.update(out.read(n)) - pos += n + partition_hash: str = partition['hash_raw'] - return raw_hash.hexdigest().lower() == partition_hash.lower() - else: + if full_check: + return get_raw_hash(path, partition_size) == partition_hash.lower() + else: + with open(path, 'rb+') as out: out.seek(partition_size) return out.read(64) == partition_hash.lower().encode() @@ -177,8 +187,13 @@ def extract_casync_image(target_slot_number: int, partition: dict, cloudlog): sources: List[Tuple[str, casync.ChunkReader, casync.ChunkDict]] = [] # First source is the current partition. Index file for current version is provided in the manifest - if 'casync_seed_caibx' in partition: - sources += [('seed', casync.FileChunkReader(seed_path), casync.build_chunk_dict(casync.parse_caibx(partition['casync_seed_caibx'])))] + raw_hash = get_raw_hash(seed_path, partition['size']) + caibx_url = f"{CAIBX_URL}{partition['name']}-{raw_hash}.caibx" + try: + cloudlog.info(f"casync fetching {caibx_url}") + sources += [('seed', casync.FileChunkReader(seed_path), casync.build_chunk_dict(casync.parse_caibx(caibx_url)))] + except requests.RequestException: + cloudlog.error(f"casync failed to load {caibx_url}") # Second source is the target partition, this allows for resuming sources += [('target', casync.FileChunkReader(path), casync.build_chunk_dict(target))] From 6065871ad504f1b590d8de053b25ce1cf01f29ba Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Wed, 6 Jul 2022 14:03:31 +0200 Subject: [PATCH 018/112] add casync to release files --- release/files_common | 1 + 1 file changed, 1 insertion(+) diff --git a/release/files_common b/release/files_common index e32277dfd8..b46266fa91 100644 --- a/release/files_common +++ b/release/files_common @@ -196,6 +196,7 @@ system/hardware/tici/hardware.h system/hardware/tici/hardware.py system/hardware/tici/pins.py system/hardware/tici/agnos.py +system/hardware/tici/casync.py system/hardware/tici/agnos.json system/hardware/tici/amplifier.py system/hardware/tici/updater From e336f254b1744f87119059189711b326ce8b7884 Mon Sep 17 00:00:00 2001 From: Gijs Koning Date: Wed, 6 Jul 2022 15:50:28 +0200 Subject: [PATCH 019/112] bump laika --- laika_repo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/laika_repo b/laika_repo index 6e87f536db..828612e1b8 160000 --- a/laika_repo +++ b/laika_repo @@ -1 +1 @@ -Subproject commit 6e87f536dbe8cf80040f724c89798e66ca17cf9d +Subproject commit 828612e1b8848ccf70072d5513c0b7977f1707da From b88d7c89fae448068aeaca65706d99aa145c8a74 Mon Sep 17 00:00:00 2001 From: Gijs Koning Date: Wed, 6 Jul 2022 19:01:19 +0200 Subject: [PATCH 020/112] laikad: Filter unwanted pseudoranges (#25051) Filter unwanted pseudoranges --- selfdrive/locationd/laikad.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/selfdrive/locationd/laikad.py b/selfdrive/locationd/laikad.py index 0df48dd893..40519da7bc 100755 --- a/selfdrive/locationd/laikad.py +++ b/selfdrive/locationd/laikad.py @@ -103,6 +103,9 @@ class Laikad: self.fetch_orbits(latest_msg_t + SECS_IN_MIN, block) new_meas = read_raw_ublox(report) + # Filter measurements with unexpected pseudoranges for GPS and GLONASS satellites + new_meas = [m for m in new_meas if 1e7 < m.observables['C1C'] < 3e7] + processed_measurements = process_measurements(new_meas, self.astro_dog) est_pos = self.get_est_pos(t, processed_measurements) From 3e5e27f043bca856ff3f4aaa83355d964ca42fa5 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Wed, 6 Jul 2022 18:51:51 -0700 Subject: [PATCH 021/112] Add missing 2019 RAV4 Hybrid engine FW version (#25057) add missing engine fw --- selfdrive/car/toyota/values.py | 1 + 1 file changed, 1 insertion(+) diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py index 86283bc48f..9324e6baf5 100644 --- a/selfdrive/car/toyota/values.py +++ b/selfdrive/car/toyota/values.py @@ -1317,6 +1317,7 @@ FW_VERSIONS = { b'\x018966342X6000\x00\x00\x00\x00', b'\x01896634A25000\x00\x00\x00\x00', b'\x018966342W5000\x00\x00\x00\x00', + b'\x018966342W7000\x00\x00\x00\x00', b'\x028966342W4001\x00\x00\x00\x00897CF1203001\x00\x00\x00\x00', b'\x02896634A13000\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'\x02896634A13001\x00\x00\x00\x00897CF4801001\x00\x00\x00\x00', From ea241bf3dc1d6dec2610bec9fceb1b8659014436 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Wed, 6 Jul 2022 19:42:58 -0700 Subject: [PATCH 022/112] FW fingerprinting: log all FW versions (#25042) * get_fw_versions returns all fw versions with request's brand * keep track of everything received * debug * need to regen or write a hack in build_fw_dict * to be safe, still replace old responses within same brands (hyundai responds to two queries, can fix later) to be safe, still replace old responses within same brands (hyundai responds to two queries, can fix later) * update test_fw_query_on_routes * clean up * better name * slightly cleaner * fix test_startup unit test del * fix imports * fix test_fw_fingerprint fix test_fw_fingerprint fix * fingerprint on all FW_VERSIONS, not just brands with requests * support old routes in test_fw_query_on_routes * regen and update refs * similar function style to before * better comment * space switch name * try to exact match first * useless else * fix debug script * simpler dictionary * bump cereal to master --- cereal | 2 +- selfdrive/car/fw_versions.py | 45 ++++++++++++------- selfdrive/car/tests/test_fw_fingerprint.py | 10 ++--- selfdrive/controls/tests/test_startup.py | 23 +++++----- selfdrive/debug/test_fw_query_on_routes.py | 43 +++++++++++------- selfdrive/test/process_replay/ref_commit | 2 +- selfdrive/test/process_replay/regen.py | 16 ++++++- .../test/process_replay/test_processes.py | 26 +++++------ 8 files changed, 101 insertions(+), 66 deletions(-) diff --git a/cereal b/cereal index df08568318..cda60ec965 160000 --- a/cereal +++ b/cereal @@ -1 +1 @@ -Subproject commit df08568318da97ed6f87747caee0a5b2c30086c4 +Subproject commit cda60ec9652c05de4ccfcad1fae7936e708434a3 diff --git a/selfdrive/car/fw_versions.py b/selfdrive/car/fw_versions.py index 758485c393..b79f61d94d 100755 --- a/selfdrive/car/fw_versions.py +++ b/selfdrive/car/fw_versions.py @@ -194,12 +194,13 @@ def chunks(l, n=128): yield l[i:i + n] -def build_fw_dict(fw_versions): +def build_fw_dict(fw_versions, filter_brand=None): fw_versions_dict = {} for fw in fw_versions: - addr = fw.address - sub_addr = fw.subAddress if fw.subAddress != 0 else None - fw_versions_dict[(addr, sub_addr)] = fw.fwVersion + if filter_brand is None or fw.brand == filter_brand: + addr = fw.address + sub_addr = fw.subAddress if fw.subAddress != 0 else None + fw_versions_dict[(addr, sub_addr)] = fw.fwVersion return fw_versions_dict @@ -284,18 +285,27 @@ def match_fw_to_car_exact(fw_versions_dict): def match_fw_to_car(fw_versions, allow_fuzzy=True): - fw_versions_dict = build_fw_dict(fw_versions) - matches = match_fw_to_car_exact(fw_versions_dict) + versions = get_interface_attr('FW_VERSIONS', ignore_none=True) + + # Try exact matching first + exact_matches = [True] + if allow_fuzzy: + exact_matches.append(False) + + for exact_match in exact_matches: + # For each brand, attempt to fingerprint using FW returned from its queries + for brand in versions.keys(): + fw_versions_dict = build_fw_dict(fw_versions, filter_brand=brand) - exact_match = True - if allow_fuzzy and len(matches) == 0: - matches = match_fw_to_car_fuzzy(fw_versions_dict) + if exact_match: + matches = match_fw_to_car_exact(fw_versions_dict) + else: + matches = match_fw_to_car_fuzzy(fw_versions_dict) - # Fuzzy match found - if len(matches) == 1: - exact_match = False + if len(matches) == 1: + return exact_match, matches - return exact_match, matches + return True, [] def get_present_ecus(logcan, sendcan): @@ -372,20 +382,21 @@ def get_fw_versions(logcan, sendcan, extra=None, timeout=0.1, debug=False, progr if addrs: query = IsoTpParallelQuery(sendcan, logcan, r.bus, addrs, r.request, r.response, r.rx_offset, debug=debug) t = 2 * timeout if i == 0 else timeout - fw_versions.update({addr: (version, r.request, r.rx_offset) for addr, version in query.get_data(t).items()}) + fw_versions.update({(r.brand, addr): (version, r) for addr, version in query.get_data(t).items()}) except Exception: cloudlog.warning(f"FW query exception: {traceback.format_exc()}") # Build capnp list to put into CarParams car_fw = [] - for addr, (version, request, rx_offset) in fw_versions.items(): + for (brand, addr), (version, request) in fw_versions.items(): f = car.CarParams.CarFw.new_message() f.ecu = ecu_types[addr] f.fwVersion = version f.address = addr[0] - f.responseAddress = uds.get_rx_addr_for_tx_addr(addr[0], rx_offset) - f.request = request + f.responseAddress = uds.get_rx_addr_for_tx_addr(addr[0], request.rx_offset) + f.request = request.request + f.brand = brand if addr[1] is not None: f.subAddress = addr[1] diff --git a/selfdrive/car/tests/test_fw_fingerprint.py b/selfdrive/car/tests/test_fw_fingerprint.py index ed7e420e1a..49fa66d36d 100755 --- a/selfdrive/car/tests/test_fw_fingerprint.py +++ b/selfdrive/car/tests/test_fw_fingerprint.py @@ -12,6 +12,7 @@ CarFw = car.CarParams.CarFw Ecu = car.CarParams.Ecu ECU_NAME = {v: k for k, v in Ecu.schema.enumerants.items()} +VERSIONS = get_interface_attr("FW_VERSIONS", ignore_none=True) class TestFwFingerprint(unittest.TestCase): @@ -20,14 +21,14 @@ class TestFwFingerprint(unittest.TestCase): self.assertEqual(len(candidates), 1, f"got more than one candidate: {candidates}") self.assertEqual(candidates[0], expected) - @parameterized.expand([(k, v) for k, v in FW_VERSIONS.items()]) - def test_fw_fingerprint(self, car_model, ecus): + @parameterized.expand([(b, c, e[c]) for b, e in VERSIONS.items() for c in e]) + def test_fw_fingerprint(self, brand, car_model, ecus): CP = car.CarParams.new_message() for _ in range(200): fw = [] for ecu, fw_versions in ecus.items(): ecu_name, addr, sub_addr = ecu - fw.append({"ecu": ecu_name, "fwVersion": random.choice(fw_versions), + fw.append({"ecu": ecu_name, "fwVersion": random.choice(fw_versions), 'brand': brand, "address": addr, "subAddress": 0 if sub_addr is None else sub_addr}) CP.carFw = fw _, matches = match_fw_to_car(CP.carFw) @@ -60,10 +61,9 @@ class TestFwFingerprint(unittest.TestCase): def test_fw_request_ecu_whitelist(self): passed = True brands = set(r.brand for r in REQUESTS) - versions = get_interface_attr('FW_VERSIONS') for brand in brands: whitelisted_ecus = [ecu for r in REQUESTS for ecu in r.whitelist_ecus if r.brand == brand] - brand_ecus = set([fw[0] for car_fw in versions[brand].values() for fw in car_fw]) + brand_ecus = set([fw[0] for car_fw in VERSIONS[brand].values() for fw in car_fw]) # each ecu in brand's fw versions needs to be whitelisted at least once ecus_not_whitelisted = set(brand_ecus) - set(whitelisted_ecus) diff --git a/selfdrive/controls/tests/test_startup.py b/selfdrive/controls/tests/test_startup.py index 9d13453045..a94311c8c7 100755 --- a/selfdrive/controls/tests/test_startup.py +++ b/selfdrive/controls/tests/test_startup.py @@ -42,27 +42,27 @@ class TestStartup(unittest.TestCase): # TODO: test EventName.startup for release branches # officially supported car - (EventName.startupMaster, TOYOTA.COROLLA, COROLLA_FW_VERSIONS), - (EventName.startupMaster, TOYOTA.COROLLA, COROLLA_FW_VERSIONS), + (EventName.startupMaster, TOYOTA.COROLLA, COROLLA_FW_VERSIONS, "toyota"), + (EventName.startupMaster, TOYOTA.COROLLA, COROLLA_FW_VERSIONS, "toyota"), # dashcamOnly car - (EventName.startupNoControl, MAZDA.CX5, CX5_FW_VERSIONS), - (EventName.startupNoControl, MAZDA.CX5, CX5_FW_VERSIONS), + (EventName.startupNoControl, MAZDA.CX5, CX5_FW_VERSIONS, "mazda"), + (EventName.startupNoControl, MAZDA.CX5, CX5_FW_VERSIONS, "mazda"), # unrecognized car with no fw - (EventName.startupNoFw, None, None), - (EventName.startupNoFw, None, None), + (EventName.startupNoFw, None, None, ""), + (EventName.startupNoFw, None, None, ""), # unrecognized car - (EventName.startupNoCar, None, COROLLA_FW_VERSIONS[:1]), - (EventName.startupNoCar, None, COROLLA_FW_VERSIONS[:1]), + (EventName.startupNoCar, None, COROLLA_FW_VERSIONS[:1], "toyota"), + (EventName.startupNoCar, None, COROLLA_FW_VERSIONS[:1], "toyota"), # fuzzy match - (EventName.startupMaster, TOYOTA.COROLLA, COROLLA_FW_VERSIONS_FUZZY), - (EventName.startupMaster, TOYOTA.COROLLA, COROLLA_FW_VERSIONS_FUZZY), + (EventName.startupMaster, TOYOTA.COROLLA, COROLLA_FW_VERSIONS_FUZZY, "toyota"), + (EventName.startupMaster, TOYOTA.COROLLA, COROLLA_FW_VERSIONS_FUZZY, "toyota"), ]) @with_processes(['controlsd']) - def test_startup_alert(self, expected_event, car_model, fw_versions): + def test_startup_alert(self, expected_event, car_model, fw_versions, brand): # TODO: this should be done without any real sockets controls_sock = messaging.sub_sock("controlsState") @@ -82,6 +82,7 @@ class TestStartup(unittest.TestCase): f.ecu = ecu f.address = addr f.fwVersion = version + f.brand = brand if subaddress is not None: f.subAddress = subaddress diff --git a/selfdrive/debug/test_fw_query_on_routes.py b/selfdrive/debug/test_fw_query_on_routes.py index 011dd6c9a3..789baeca4b 100755 --- a/selfdrive/debug/test_fw_query_on_routes.py +++ b/selfdrive/debug/test_fw_query_on_routes.py @@ -8,24 +8,15 @@ import traceback from tqdm import tqdm from tools.lib.logreader import LogReader from tools.lib.route import Route +from selfdrive.car.interfaces import get_interface_attr from selfdrive.car.car_helpers import interface_names from selfdrive.car.fw_versions import match_fw_to_car_exact, match_fw_to_car_fuzzy, build_fw_dict -from selfdrive.car.toyota.values import FW_VERSIONS as TOYOTA_FW_VERSIONS -from selfdrive.car.honda.values import FW_VERSIONS as HONDA_FW_VERSIONS -from selfdrive.car.hyundai.values import FW_VERSIONS as HYUNDAI_FW_VERSIONS -from selfdrive.car.volkswagen.values import FW_VERSIONS as VW_FW_VERSIONS -from selfdrive.car.mazda.values import FW_VERSIONS as MAZDA_FW_VERSIONS -from selfdrive.car.subaru.values import FW_VERSIONS as SUBARU_FW_VERSIONS NO_API = "NO_API" in os.environ -SUPPORTED_CARS = set(interface_names['toyota']) -SUPPORTED_CARS |= set(interface_names['honda']) -SUPPORTED_CARS |= set(interface_names['hyundai']) -SUPPORTED_CARS |= set(interface_names['volkswagen']) -SUPPORTED_CARS |= set(interface_names['mazda']) -SUPPORTED_CARS |= set(interface_names['subaru']) -SUPPORTED_CARS |= set(interface_names['nissan']) +VERSIONS = get_interface_attr('FW_VERSIONS', ignore_none=True) +SUPPORTED_BRANDS = VERSIONS.keys() +SUPPORTED_CARS = [brand for brand in SUPPORTED_BRANDS for brand in interface_names[brand]] try: from xx.pipeline.c.CarState import migration @@ -97,9 +88,24 @@ if __name__ == "__main__": print("not in supported cars") break - fw_versions_dict = build_fw_dict(car_fw) - exact_matches = match_fw_to_car_exact(fw_versions_dict) - fuzzy_matches = match_fw_to_car_fuzzy(fw_versions_dict) + # Older routes only have carFw from their brand + old_route = not any([len(fw.brand) for fw in car_fw]) + brands = SUPPORTED_BRANDS if not old_route else [None] + + # Exact match + exact_matches, fuzzy_matches = [], [] + for brand in brands: + fw_versions_dict = build_fw_dict(car_fw, filter_brand=brand) + exact_matches = match_fw_to_car_exact(fw_versions_dict) + if len(exact_matches) == 1: + break + + # Fuzzy match + for brand in brands: + fw_versions_dict = build_fw_dict(car_fw, filter_brand=brand) + fuzzy_matches = match_fw_to_car_fuzzy(fw_versions_dict) + if len(fuzzy_matches) == 1: + break if (len(exact_matches) == 1) and (list(exact_matches)[0] == live_fingerprint): good_exact += 1 @@ -126,12 +132,15 @@ if __name__ == "__main__": print("Mismatches") found = False - for car_fws in [TOYOTA_FW_VERSIONS, HONDA_FW_VERSIONS, HYUNDAI_FW_VERSIONS, VW_FW_VERSIONS, MAZDA_FW_VERSIONS, SUBARU_FW_VERSIONS]: + for brand in SUPPORTED_BRANDS: + car_fws = VERSIONS[brand] if live_fingerprint in car_fws: found = True expected = car_fws[live_fingerprint] for (_, expected_addr, expected_sub_addr), v in expected.items(): for version in car_fw: + if version.brand != brand and len(version.brand): + continue sub_addr = None if version.subAddress == 0 else version.subAddress addr = version.address diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index 999081b4df..0eeae1e3e3 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -a57bbbffbee434e59e08b98b667dc13b6b505f08 \ No newline at end of file +b904e52e9de4ff7b2bd7f6af8b19abaf4957e6cc \ No newline at end of file diff --git a/selfdrive/test/process_replay/regen.py b/selfdrive/test/process_replay/regen.py index 793e548705..1a2d436f1a 100755 --- a/selfdrive/test/process_replay/regen.py +++ b/selfdrive/test/process_replay/regen.py @@ -179,8 +179,22 @@ def replay_cameras(lr, frs, disable_tqdm=False): return vs, p +def migrate_carparams(lr): + all_msgs = [] + for msg in lr: + if msg.which() == 'carParams': + CP = messaging.new_message('carParams') + CP.carParams = msg.carParams.as_builder() + for car_fw in CP.carParams.carFw: + car_fw.brand = CP.carParams.carName + msg = CP.as_reader() + all_msgs.append(msg) + + return all_msgs + + def regen_segment(lr, frs=None, outdir=FAKEDATA, disable_tqdm=False): - lr = list(lr) + lr = migrate_carparams(list(lr)) if frs is None: frs = dict() diff --git a/selfdrive/test/process_replay/test_processes.py b/selfdrive/test/process_replay/test_processes.py index 4e7ba4a6dd..9cbf4439ac 100755 --- a/selfdrive/test/process_replay/test_processes.py +++ b/selfdrive/test/process_replay/test_processes.py @@ -35,19 +35,19 @@ original_segments = [ ] segments = [ - ("BODY", "bd6a637565e91581|2022-04-04--22-05-08--0"), - ("HYUNDAI", "fakedata|2022-01-20--17-49-04--0"), - ("TOYOTA", "fakedata|2022-04-29--15-57-12--0"), - ("TOYOTA2", "fakedata|2022-04-29--16-08-01--0"), - ("TOYOTA3", "fakedata|2022-04-29--16-17-39--0"), - ("HONDA", "fakedata|2022-01-20--17-56-40--0"), - ("HONDA2", "fakedata|2022-04-29--16-31-55--0"), - ("CHRYSLER", "fakedata|2022-01-20--18-00-11--0"), - ("SUBARU", "fakedata|2022-01-20--18-01-57--0"), - ("GM", "fakedata|2022-01-20--18-03-41--0"), - ("NISSAN", "fakedata|2022-01-20--18-05-29--0"), - ("VOLKSWAGEN", "fakedata|2022-01-20--18-07-15--0"), - ("MAZDA", "fakedata|2022-01-20--18-09-32--0"), + ("BODY", "regen660D86654BA|2022-07-06--14-27-15--0"), + ("HYUNDAI", "regen657E25856BB|2022-07-06--14-26-51--0"), + ("TOYOTA", "regenBA97410FBEC|2022-07-06--14-26-49--0"), + ("TOYOTA2", "regenDEDB1D9C991|2022-07-06--14-54-08--0"), + ("TOYOTA3", "regenDDC1FE60734|2022-07-06--14-32-06--0"), + ("HONDA", "regen17B09D158B8|2022-07-06--14-31-46--0"), + ("HONDA2", "regen041739C3E9A|2022-07-06--15-08-02--0"), + ("CHRYSLER", "regenBB2F9C1425C|2022-07-06--14-31-41--0"), + ("SUBARU", "regen732B69F33B1|2022-07-06--14-36-18--0"), + ("GM", "regen01D09D915B5|2022-07-06--14-36-20--0"), + ("NISSAN", "regenEA6FB2773F5|2022-07-06--14-58-23--0"), + ("VOLKSWAGEN", "regen007098CA0EF|2022-07-06--15-01-26--0"), + ("MAZDA", "regen61BA413D53B|2022-07-06--14-39-42--0"), ] # dashcamOnly makes don't need to be tested until a full port is done From 479b66c992fb2898418d866a1c61d993a9217d3d Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Wed, 6 Jul 2022 19:57:44 -0700 Subject: [PATCH 023/112] VW FPv2: reduce number of ECU queries (#24939) * only send valid/needed queries * just do volkswagen * clean up * add parameter name clean up * add test for whitelist * rename * Update selfdrive/car/fw_versions.py Co-authored-by: Jason Young <46612682+jyoung8607@users.noreply.github.com> * fix test * log response addresses * bump cereal * handle response pending with IsoTpParallelQuery * remove response pending stuff * temporarily disregard cache for easier testing * revert this Co-authored-by: Jason Young <46612682+jyoung8607@users.noreply.github.com> --- selfdrive/car/fw_versions.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/selfdrive/car/fw_versions.py b/selfdrive/car/fw_versions.py index b79f61d94d..03dcece10c 100755 --- a/selfdrive/car/fw_versions.py +++ b/selfdrive/car/fw_versions.py @@ -148,12 +148,14 @@ REQUESTS: List[Request] = [ "volkswagen", [VOLKSWAGEN_VERSION_REQUEST_MULTI], [VOLKSWAGEN_VERSION_RESPONSE], + whitelist_ecus=[Ecu.srs, Ecu.eps, Ecu.fwdRadar], rx_offset=VOLKSWAGEN_RX_OFFSET, ), Request( "volkswagen", [VOLKSWAGEN_VERSION_REQUEST_MULTI], [VOLKSWAGEN_VERSION_RESPONSE], + whitelist_ecus=[Ecu.engine, Ecu.transmission], ), # Mazda Request( From 9b0acacf5e387593ce94dbad88000b5473511e22 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 6 Jul 2022 23:42:07 -0700 Subject: [PATCH 024/112] Ram 1500 (#24878) * RamInit * bump submodules * lil cleanup * clean up carstate formatting and platform grouping make tuple * give it a gold torque star (looks around 2.4 from rough data) * Dasm Fault * bump panda * more cleanup * cleanup car state * more cleanup * some fixes * remove more stuff * fix angle signal scaling and fix lkas control bit * bump panda * update those * same limits as pacifica * cleanup hud alert building * better fault logic * fix rate * set ahb * bring that back * update refs Co-authored-by: Jonathan Co-authored-by: Shane Smiskol Co-authored-by: Comma Device --- RELEASES.md | 1 + docs/CARS.md | 3 +- panda | 2 +- release/files_common | 1 + selfdrive/car/chrysler/carcontroller.py | 73 +++++------- selfdrive/car/chrysler/carstate.py | 135 +++++++++++++++------- selfdrive/car/chrysler/chryslercan.py | 79 +++++++------ selfdrive/car/chrysler/interface.py | 22 +++- selfdrive/car/chrysler/radar_interface.py | 9 +- selfdrive/car/chrysler/values.py | 36 +++--- selfdrive/car/tests/routes.py | 1 + selfdrive/car/torque_data/override.yaml | 3 +- selfdrive/test/process_replay/ref_commit | 2 +- 13 files changed, 226 insertions(+), 141 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index 5b71fc3375..fedff5dbff 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -19,6 +19,7 @@ Version 0.8.15 (2022-07-XX) * Honda Civic 2022 support * Hyundai Tucson 2021 support thanks to bluesforte! * Lexus NX Hybrid 2020 support thanks to AlexandreSato! +* Ram 1500 2019-21 support thanks to realfast! Version 0.8.14 (2022-06-01) ======================== diff --git a/docs/CARS.md b/docs/CARS.md index 0cf384df18..a1e89efe12 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -144,7 +144,7 @@ How We Rate The Cars |Volkswagen|Passat 2015-19[6](#footnotes)|Driver Assistance|||||| |Volkswagen|Polo 2020|Driver Assistance|||||| -# Bronze - 79 cars +# Bronze - 80 cars |Make|Model|Supported Package|openpilot ACC|Stop and Go|Steer to 0|Steering Torque|Actively Maintained| |---|---|---|:---:|:---:|:---:|:---:|:---:| @@ -198,6 +198,7 @@ How We Rate The Cars |Lexus|RX Hybrid 2016-19|All|[3](#footnotes)||||| |Mazda|CX-5 2022|All|||||| |Mazda|CX-9 2021|All|||||| +|Ram|1500 2019-21|Adaptive Cruise|||||| |Subaru|Crosstrek 2018-19|EyeSight|||||| |Subaru|Impreza 2017-19|EyeSight|||||| |Subaru|XV 2018-19|EyeSight|||||| diff --git a/panda b/panda index 6c0d0b43c2..fae3ee2e81 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 6c0d0b43c239b89baa83b4a1885d0ce21ab2335e +Subproject commit fae3ee2e8161d34a7c1939503e583db9b85e5402 diff --git a/release/files_common b/release/files_common index b46266fa91..260e37e29a 100644 --- a/release/files_common +++ b/release/files_common @@ -474,6 +474,7 @@ opendbc/can/parser_pyx.pyx opendbc/comma_body.dbc +opendbc/chrysler_ram_dt_generated.dbc opendbc/chrysler_pacifica_2017_hybrid_generated.dbc opendbc/chrysler_pacifica_2017_hybrid_private_fusion.dbc diff --git a/selfdrive/car/chrysler/carcontroller.py b/selfdrive/car/chrysler/carcontroller.py index 49525646ca..606cb51176 100644 --- a/selfdrive/car/chrysler/carcontroller.py +++ b/selfdrive/car/chrysler/carcontroller.py @@ -1,8 +1,7 @@ -from cereal import car from opendbc.can.packer import CANPacker from selfdrive.car import apply_toyota_steer_torque_limits from selfdrive.car.chrysler.chryslercan import create_lkas_hud, create_lkas_command, create_cruise_buttons -from selfdrive.car.chrysler.values import CAR, CarControllerParams +from selfdrive.car.chrysler.values import RAM_CARS, CarControllerParams class CarController: @@ -10,61 +9,51 @@ class CarController: self.CP = CP self.apply_steer_last = 0 self.frame = 0 - self.prev_lkas_frame = -1 - self.hud_count = 0 - self.car_fingerprint = CP.carFingerprint - self.gone_fast_yet = False self.steer_rate_limited = False - self.packer = CANPacker(dbc_name) - - def update(self, CC, CS): - # this seems needed to avoid steering faults and to force the sync with the EPS counter - if self.prev_lkas_frame == CS.lkas_counter: - return car.CarControl.Actuators.new_message(), [] - - actuators = CC.actuators - - # steer torque - new_steer = int(round(actuators.steer * CarControllerParams.STEER_MAX)) - apply_steer = apply_toyota_steer_torque_limits(new_steer, self.apply_steer_last, - CS.out.steeringTorqueEps, CarControllerParams) - self.steer_rate_limited = new_steer != apply_steer - - moving_fast = CS.out.vEgo > self.CP.minSteerSpeed # for status message - if CS.out.vEgo > (self.CP.minSteerSpeed - 0.5): # for command high bit - self.gone_fast_yet = True - elif self.car_fingerprint in (CAR.PACIFICA_2019_HYBRID, CAR.PACIFICA_2020, CAR.JEEP_CHEROKEE_2019): - if CS.out.vEgo < (self.CP.minSteerSpeed - 3.0): - self.gone_fast_yet = False # < 14.5m/s stock turns off this bit, but fine down to 13.5 - lkas_active = moving_fast and CC.enabled - - if not lkas_active: - apply_steer = 0 + self.hud_count = 0 + self.last_lkas_falling_edge = 0 + self.lkas_active_prev = False - self.apply_steer_last = apply_steer + self.packer = CANPacker(dbc_name) + def update(self, CC, CS, low_speed_alert): can_sends = [] + # EPS faults if LKAS re-enables too quickly + lkas_active = CC.latActive and not low_speed_alert and (self.frame - self.last_lkas_falling_edge > 200) + # *** control msgs *** if CC.cruiseControl.cancel: - can_sends.append(create_cruise_buttons(self.packer, CS.button_counter + 1, cancel=True)) + bus = 2 if self.CP.carFingerprint in RAM_CARS else 0 + can_sends.append(create_cruise_buttons(self.packer, CS.button_counter + 1, bus, cancel=True)) - # LKAS_HEARTBIT is forwarded by Panda so no need to send it here. - # frame is 100Hz (0.01s period) - if self.frame % 25 == 0: # 0.25s period + # HUD alerts + if self.frame % 25 == 0: if CS.lkas_car_model != -1: - can_sends.append(create_lkas_hud(self.packer, CS.out.gearShifter, lkas_active, - CC.hudControl.visualAlert, self.hud_count, CS.lkas_car_model)) + can_sends.append(create_lkas_hud(self.packer, self.CP, lkas_active, CC.hudControl.visualAlert, self.hud_count, CS.lkas_car_model, CS.auto_high_beam)) self.hud_count += 1 - can_sends.append(create_lkas_command(self.packer, int(apply_steer), self.gone_fast_yet, CS.lkas_counter)) + # steering + if self.frame % 2 == 0: + # steer torque + new_steer = int(round(CC.actuators.steer * CarControllerParams.STEER_MAX)) + apply_steer = apply_toyota_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorqueEps, CarControllerParams) + if not lkas_active: + apply_steer = 0 + self.steer_rate_limited = new_steer != apply_steer + self.apply_steer_last = apply_steer + + idx = self.frame // 2 + can_sends.append(create_lkas_command(self.packer, self.CP, int(apply_steer), lkas_active, idx)) self.frame += 1 - self.prev_lkas_frame = CS.lkas_counter + if not lkas_active and self.lkas_active_prev: + self.last_lkas_falling_edge = self.frame + self.lkas_active_prev = lkas_active - new_actuators = actuators.copy() - new_actuators.steer = apply_steer / CarControllerParams.STEER_MAX + new_actuators = CC.actuators.copy() + new_actuators.steer = self.apply_steer_last / CarControllerParams.STEER_MAX return new_actuators, can_sends diff --git a/selfdrive/car/chrysler/carstate.py b/selfdrive/car/chrysler/carstate.py index 61fe1f7ec6..71b7e34623 100644 --- a/selfdrive/car/chrysler/carstate.py +++ b/selfdrive/car/chrysler/carstate.py @@ -3,21 +3,29 @@ from common.conversions import Conversions as CV from opendbc.can.parser import CANParser from opendbc.can.can_define import CANDefine from selfdrive.car.interfaces import CarStateBase -from selfdrive.car.chrysler.values import DBC, STEER_THRESHOLD +from selfdrive.car.chrysler.values import DBC, STEER_THRESHOLD, RAM_CARS class CarState(CarStateBase): def __init__(self, CP): super().__init__(CP) + self.CP = CP can_define = CANDefine(DBC[CP.carFingerprint]["pt"]) - self.shifter_values = can_define.dv["GEAR"]["PRNDL"] + + self.auto_high_beam = 0 + self.button_counter = 0 + self.lkas_car_model = -1 + + if CP.carFingerprint in RAM_CARS: + self.shifter_values = can_define.dv["Transmission_Status"]["Gear_State"] + else: + self.shifter_values = can_define.dv["GEAR"]["PRNDL"] def update(self, cp, cp_cam): ret = car.CarState.new_message() - self.frame = int(cp.vl["EPS_2"]["COUNTER"]) - + # lock info ret.doorOpen = any([cp.vl["BCM_1"]["DOOR_OPEN_FL"], cp.vl["BCM_1"]["DOOR_OPEN_FR"], cp.vl["BCM_1"]["DOOR_OPEN_RL"], @@ -32,8 +40,15 @@ class CarState(CarStateBase): ret.gas = cp.vl["ECM_5"]["Accelerator_Position"] ret.gasPressed = ret.gas > 1e-5 - ret.espDisabled = (cp.vl["TRACTION_BUTTON"]["TRACTION_OFF"] == 1) - + # car speed + if self.CP.carFingerprint in RAM_CARS: + ret.vEgoRaw = cp.vl["ESP_8"]["Vehicle_Speed"] * CV.KPH_TO_MS + ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(cp.vl["Transmission_Status"]["Gear_State"], None)) + else: + ret.vEgoRaw = (cp.vl["SPEED_1"]["SPEED_LEFT"] + cp.vl["SPEED_1"]["SPEED_RIGHT"]) / 2. + ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(cp.vl["GEAR"]["PRNDL"], None)) + ret.vEgo, ret.aEgo = self.update_speed_kf(ret.vEgoRaw) + ret.standstill = not ret.vEgoRaw > 0.001 ret.wheelSpeeds = self.get_wheel_speeds( cp.vl["ESP_6"]["WHEEL_SPEED_FL"], cp.vl["ESP_6"]["WHEEL_SPEED_FR"], @@ -41,55 +56,73 @@ class CarState(CarStateBase): cp.vl["ESP_6"]["WHEEL_SPEED_RR"], unit=1, ) - ret.vEgoRaw = (cp.vl["SPEED_1"]["SPEED_LEFT"] + cp.vl["SPEED_1"]["SPEED_RIGHT"]) / 2. - ret.vEgo, ret.aEgo = self.update_speed_kf(ret.vEgoRaw) - ret.standstill = not ret.vEgoRaw > 0.001 + # button presses ret.leftBlinker = cp.vl["STEERING_LEVERS"]["TURN_SIGNALS"] == 1 ret.rightBlinker = cp.vl["STEERING_LEVERS"]["TURN_SIGNALS"] == 2 - ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(cp.vl["GEAR"]["PRNDL"], None)) - - ret.cruiseState.available = cp.vl["DAS_3"]["ACC_AVAILABLE"] == 1 # ACC is white - ret.cruiseState.enabled = cp.vl["DAS_3"]["ACC_ACTIVE"] == 1 # ACC is green - ret.cruiseState.speed = cp.vl["DAS_4"]["ACC_SET_SPEED_KPH"] * CV.KPH_TO_MS - # CRUISE_STATE is a three bit msg, 0 is off, 1 and 2 are Non-ACC mode, 3 and 4 are ACC mode, find if there are other states too - ret.cruiseState.nonAdaptive = cp.vl["DAS_4"]["ACC_STATE"] in (1, 2) - ret.accFaulted = cp.vl["DAS_3"]["ACC_FAULTED"] != 0 + ret.genericToggle = cp.vl["STEERING_LEVERS"]["HIGH_BEAM_PRESSED"] == 1 + # steering wheel ret.steeringAngleDeg = cp.vl["STEERING"]["STEER_ANGLE"] ret.steeringRateDeg = cp.vl["STEERING"]["STEERING_RATE"] ret.steeringTorque = cp.vl["EPS_2"]["COLUMN_TORQUE"] ret.steeringTorqueEps = cp.vl["EPS_2"]["EPS_TORQUE_MOTOR"] ret.steeringPressed = abs(ret.steeringTorque) > STEER_THRESHOLD - steer_state = cp.vl["EPS_2"]["LKAS_STATE"] - ret.steerFaultPermanent = steer_state == 4 or (steer_state == 0 and ret.vEgo > self.CP.minSteerSpeed) - ret.genericToggle = bool(cp.vl["STEERING_LEVERS"]["HIGH_BEAM_PRESSED"]) + # cruise state + cp_cruise = cp_cam if self.CP.carFingerprint in RAM_CARS else cp + + ret.cruiseState.available = cp_cruise.vl["DAS_3"]["ACC_AVAILABLE"] == 1 + ret.cruiseState.enabled = cp_cruise.vl["DAS_3"]["ACC_ACTIVE"] == 1 + ret.cruiseState.speed = cp_cruise.vl["DAS_4"]["ACC_SET_SPEED_KPH"] * CV.KPH_TO_MS + ret.cruiseState.nonAdaptive = cp_cruise.vl["DAS_4"]["ACC_STATE"] in (1, 2) # 1 NormalCCOn and 2 NormalCCSet + ret.cruiseState.standstill = cp_cruise.vl["DAS_3"]["ACC_STANDSTILL"] == 1 + ret.accFaulted = cp_cruise.vl["DAS_3"]["ACC_FAULTED"] != 0 + + if self.CP.carFingerprint in RAM_CARS: + self.auto_high_beam = cp_cam.vl["DAS_6"]['AUTO_HIGH_BEAM_ON'] # Auto High Beam isn't Located in this message on chrysler or jeep currently located in 729 message + ret.steerFaultTemporary = cp.vl["EPS_3"]["DASM_FAULT"] == 1 + else: + steer_state = cp.vl["EPS_2"]["LKAS_STATE"] + ret.steerFaultPermanent = steer_state == 4 or (steer_state == 0 and ret.vEgo > self.CP.minSteerSpeed) + # blindspot sensors if self.CP.enableBsm: ret.leftBlindspot = cp.vl["BSM_1"]["LEFT_STATUS"] == 1 ret.rightBlindspot = cp.vl["BSM_1"]["RIGHT_STATUS"] == 1 - self.lkas_counter = cp_cam.vl["LKAS_COMMAND"]["COUNTER"] self.lkas_car_model = cp_cam.vl["DAS_6"]["CAR_MODEL"] - self.lkas_status_ok = cp_cam.vl["LKAS_HEARTBIT"]["LKAS_STATUS_OK"] self.button_counter = cp.vl["CRUISE_BUTTONS"]["COUNTER"] return ret + @staticmethod + def get_cruise_signals(): + signals = [ + ("ACC_AVAILABLE", "DAS_3"), + ("ACC_ACTIVE", "DAS_3"), + ("ACC_FAULTED", "DAS_3"), + ("ACC_STANDSTILL", "DAS_3"), + ("COUNTER", "DAS_3"), + ("ACC_SET_SPEED_KPH", "DAS_4"), + ("ACC_STATE", "DAS_4"), + ] + checks = [ + ("DAS_3", 50), + ("DAS_4", 50), + ] + return signals, checks + @staticmethod def get_can_parser(CP): signals = [ # sig_name, sig_address - ("PRNDL", "GEAR"), ("DOOR_OPEN_FL", "BCM_1"), ("DOOR_OPEN_FR", "BCM_1"), ("DOOR_OPEN_RL", "BCM_1"), ("DOOR_OPEN_RR", "BCM_1"), ("Brake_Pedal_State", "ESP_1"), ("Accelerator_Position", "ECM_5"), - ("SPEED_LEFT", "SPEED_1"), - ("SPEED_RIGHT", "SPEED_1"), ("WHEEL_SPEED_FL", "ESP_6"), ("WHEEL_SPEED_RR", "ESP_6"), ("WHEEL_SPEED_RL", "ESP_6"), @@ -97,18 +130,12 @@ class CarState(CarStateBase): ("STEER_ANGLE", "STEERING"), ("STEERING_RATE", "STEERING"), ("TURN_SIGNALS", "STEERING_LEVERS"), - ("ACC_AVAILABLE", "DAS_3"), - ("ACC_ACTIVE", "DAS_3"), - ("ACC_FAULTED", "DAS_3"), ("HIGH_BEAM_PRESSED", "STEERING_LEVERS"), - ("ACC_SET_SPEED_KPH", "DAS_4"), - ("ACC_STATE", "DAS_4"), + ("SEATBELT_DRIVER_UNLATCHED", "ORC_1"), + ("COUNTER", "EPS_2",), ("COLUMN_TORQUE", "EPS_2"), ("EPS_TORQUE_MOTOR", "EPS_2"), ("LKAS_STATE", "EPS_2"), - ("COUNTER", "EPS_2",), - ("TRACTION_OFF", "TRACTION_BUTTON"), - ("SEATBELT_DRIVER_UNLATCHED", "ORC_1"), ("COUNTER", "CRUISE_BUTTONS"), ] @@ -116,18 +143,13 @@ class CarState(CarStateBase): # sig_address, frequency ("ESP_1", 50), ("EPS_2", 100), - ("SPEED_1", 100), ("ESP_6", 50), ("STEERING", 100), - ("DAS_3", 50), - ("GEAR", 50), ("ECM_5", 50), ("CRUISE_BUTTONS", 50), - ("DAS_4", 15), ("STEERING_LEVERS", 10), ("ORC_1", 2), ("BCM_1", 1), - ("TRACTION_BUTTON", 1), ] if CP.enableBsm: @@ -137,20 +159,47 @@ class CarState(CarStateBase): ] checks.append(("BSM_1", 2)) + if CP.carFingerprint in RAM_CARS: + signals += [ + ("DASM_FAULT", "EPS_3"), + ("Vehicle_Speed", "ESP_8"), + ("Gear_State", "Transmission_Status"), + ] + checks += [ + ("ESP_8", 50), + ("EPS_3", 50), + ("Transmission_Status", 50), + ] + else: + signals += [ + ("PRNDL", "GEAR"), + ("SPEED_LEFT", "SPEED_1"), + ("SPEED_RIGHT", "SPEED_1"), + ] + checks += [ + ("GEAR", 50), + ("SPEED_1", 100), + ] + signals += CarState.get_cruise_signals()[0] + checks += CarState.get_cruise_signals()[1] + return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, 0) @staticmethod def get_cam_can_parser(CP): signals = [ - # sig_name, sig_address - ("COUNTER", "LKAS_COMMAND"), + # sig_name, sig_address, default ("CAR_MODEL", "DAS_6"), - ("LKAS_STATUS_OK", "LKAS_HEARTBIT") ] checks = [ - ("LKAS_COMMAND", 100), - ("LKAS_HEARTBIT", 10), ("DAS_6", 4), ] + if CP.carFingerprint in RAM_CARS: + signals += [ + ("AUTO_HIGH_BEAM_ON", "DAS_6"), + ] + signals += CarState.get_cruise_signals()[0] + checks += CarState.get_cruise_signals()[1] + return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, 2) diff --git a/selfdrive/car/chrysler/chryslercan.py b/selfdrive/car/chrysler/chryslercan.py index adcd411d31..e17e5d5b2a 100644 --- a/selfdrive/car/chrysler/chryslercan.py +++ b/selfdrive/car/chrysler/chryslercan.py @@ -1,56 +1,69 @@ from cereal import car -from selfdrive.car import make_can_msg - +from selfdrive.car.chrysler.values import RAM_CARS GearShifter = car.CarState.GearShifter VisualAlert = car.CarControl.HUDControl.VisualAlert -def create_lkas_hud(packer, gear, lkas_active, hud_alert, hud_count, lkas_car_model): - # LKAS_HUD 0x2a6 (678) Controls what lane-keeping icon is displayed. +def create_lkas_hud(packer, CP, lkas_active, hud_alert, hud_count, car_model, auto_high_beam): + # LKAS_HUD - Controls what lane-keeping icon is displayed + + # == Color == + # 0 hidden? + # 1 white + # 2 green + # 3 ldw + + # == Lines == + # 03 white Lines + # 04 grey lines + # 09 left lane close + # 0A right lane close + # 0B left Lane very close + # 0C right Lane very close + # 0D left cross cross + # 0E right lane cross - if hud_alert in (VisualAlert.steerRequired, VisualAlert.ldw): - msg = b'\x00\x00\x00\x03\x00\x00\x00\x00' - return make_can_msg(0x2a6, msg, 0) + # == Alerts == + # 7 Normal + # 6 lane departure place hands on wheel - color = 1 # default values are for park or neutral in 2017 are 0 0, but trying 1 1 for 2019 - lines = 1 - alerts = 0 + color = 2 if lkas_active else 1 + lines = 3 if lkas_active else 0 + alerts = 7 if lkas_active else 0 if hud_count < (1 * 4): # first 3 seconds, 4Hz alerts = 1 - # CAR.PACIFICA_2018_HYBRID and CAR.PACIFICA_2019_HYBRID - # had color = 1 and lines = 1 but trying 2017 hybrid style for now. - if gear in (GearShifter.drive, GearShifter.reverse, GearShifter.low): - if lkas_active: - color = 2 # control active, display green. - lines = 6 - else: - color = 1 # control off, display white. - lines = 1 + + if hud_alert in (VisualAlert.ldw, VisualAlert.steerRequired): + color = 4 + lines = 0 + alerts = 6 values = { - "LKAS_ICON_COLOR": color, # byte 0, last 2 bits - "CAR_MODEL": lkas_car_model, # byte 1 - "LKAS_LANE_LINES": lines, # byte 2, last 4 bits - "LKAS_ALERTS": alerts, # byte 3, last 4 bits - } + "LKAS_ICON_COLOR": color, + "CAR_MODEL": car_model, + "LKAS_LANE_LINES": lines, + "LKAS_ALERTS": alerts, + } + + if CP.carFingerprint in RAM_CARS: + values['AUTO_HIGH_BEAM_ON'] = auto_high_beam - return packer.make_can_msg("DAS_6", 0, values) # 0x2a6 + return packer.make_can_msg("DAS_6", 0, values) -def create_lkas_command(packer, apply_steer, moving_fast, frame): - # LKAS_COMMAND 0x292 (658) Lane-keeping signal to turn the wheel. +def create_lkas_command(packer, CP, apply_steer, lat_active, frame): + # LKAS_COMMAND Lane-keeping signal to turn the wheel + enabled_val = 2 if CP.carFingerprint in RAM_CARS else 1 values = { "STEERING_TORQUE": apply_steer, - "LKAS_CONTROL_BIT": int(moving_fast), - "COUNTER": frame % 0x10, + "LKAS_CONTROL_BIT": enabled_val if lat_active else 0, } - return packer.make_can_msg("LKAS_COMMAND", 0, values) + return packer.make_can_msg("LKAS_COMMAND", 0, values, frame % 0x10) -def create_cruise_buttons(packer, frame, cancel=False): +def create_cruise_buttons(packer, frame, bus, cancel=False): values = { "ACC_Cancel": cancel, - "COUNTER": frame % 0x10, } - return packer.make_can_msg("CRUISE_BUTTONS", 0, values) + return packer.make_can_msg("CRUISE_BUTTONS", bus, values, frame % 0x10) diff --git a/selfdrive/car/chrysler/interface.py b/selfdrive/car/chrysler/interface.py index 8ebcb6b126..af202cdc46 100755 --- a/selfdrive/car/chrysler/interface.py +++ b/selfdrive/car/chrysler/interface.py @@ -1,7 +1,8 @@ #!/usr/bin/env python3 from cereal import car -from selfdrive.car.chrysler.values import CAR +from panda import Panda from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config +from selfdrive.car.chrysler.values import CAR, RAM_CARS from selfdrive.car.interfaces import CarInterfaceBase @@ -10,7 +11,9 @@ class CarInterface(CarInterfaceBase): def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None, disable_radar=False): ret = CarInterfaceBase.get_std_params(candidate, fingerprint) ret.carName = "chrysler" - ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.chrysler)] + + param = Panda.FLAG_CHRYSLER_RAM_DT if candidate in RAM_CARS else None + ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.chrysler, param)] ret.steerActuatorDelay = 0.1 ret.steerLimitTimer = 0.4 @@ -39,6 +42,15 @@ class CarInterface(CarInterfaceBase): ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.15, 0.30], [0.03, 0.05]] ret.lateralTuning.pid.kf = 0.00006 + # Ram + elif candidate == CAR.RAM_1500: + ret.wheelbase = 3.88 + ret.steerRatio = 16.3 + ret.mass = 2493. + STD_CARGO_KG + ret.maxLateralAccel = 2.4 + ret.minSteerSpeed = 14.5 + CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) + else: raise ValueError(f"Unsupported car: {candidate}") @@ -64,9 +76,9 @@ class CarInterface(CarInterfaceBase): events = self.create_common_events(ret, extra_gears=[car.CarState.GearShifter.low]) # Low speed steer alert hysteresis logic - if self.CP.minSteerSpeed > 0. and ret.vEgo < (self.CP.minSteerSpeed + 1.): + if self.CP.minSteerSpeed > 0. and ret.vEgo < (self.CP.minSteerSpeed + 0.5): self.low_speed_alert = True - elif ret.vEgo > (self.CP.minSteerSpeed + 2.): + elif ret.vEgo > (self.CP.minSteerSpeed + 1.): self.low_speed_alert = False if self.low_speed_alert: events.add(car.CarEvent.EventName.belowSteerSpeed) @@ -76,4 +88,4 @@ class CarInterface(CarInterfaceBase): return ret def apply(self, c): - return self.CC.update(c, self.CS) + return self.CC.update(c, self.CS, self.low_speed_alert) diff --git a/selfdrive/car/chrysler/radar_interface.py b/selfdrive/car/chrysler/radar_interface.py index 8882dc2d91..348e3c3632 100755 --- a/selfdrive/car/chrysler/radar_interface.py +++ b/selfdrive/car/chrysler/radar_interface.py @@ -10,6 +10,10 @@ LAST_MSG = max(RADAR_MSGS_C + RADAR_MSGS_D) NUMBER_MSGS = len(RADAR_MSGS_C) + len(RADAR_MSGS_D) def _create_radar_can_parser(car_fingerprint): + dbc = DBC[car_fingerprint]['radar'] + if dbc is None: + return None + msg_n = len(RADAR_MSGS_C) # list of [(signal name, message name or number), (...)] # [('RADAR_STATE', 1024), @@ -46,6 +50,9 @@ class RadarInterface(RadarInterfaceBase): self.trigger_msg = LAST_MSG def update(self, can_strings): + if self.rcp is None: + return super().update(None) + vls = self.rcp.update_strings(can_strings) self.updated_messages.update(vls) @@ -81,4 +88,4 @@ class RadarInterface(RadarInterfaceBase): ret.points = [x for x in self.pts.values() if x.dRel != 0] self.updated_messages.clear() - return ret + return ret \ No newline at end of file diff --git a/selfdrive/car/chrysler/values.py b/selfdrive/car/chrysler/values.py index 5537b383d3..40210e68e6 100644 --- a/selfdrive/car/chrysler/values.py +++ b/selfdrive/car/chrysler/values.py @@ -2,19 +2,12 @@ from dataclasses import dataclass from enum import Enum from typing import Dict, List, Optional, Union +from cereal import car from selfdrive.car import dbc_dict from selfdrive.car.docs_definitions import CarInfo, Harness -from cereal import car Ecu = car.CarParams.Ecu -class CarControllerParams: - STEER_MAX = 261 # 262 faults - STEER_DELTA_UP = 3 # 3 is stock. 100 is fine. 200 is too much it seems - STEER_DELTA_DOWN = 3 # no faults on the way down it seems - STEER_ERROR_MAX = 80 - - class CAR: # Chrysler PACIFICA_2017_HYBRID = "CHRYSLER PACIFICA HYBRID 2017" @@ -24,16 +17,28 @@ class CAR: PACIFICA_2020 = "CHRYSLER PACIFICA 2020" # Jeep - JEEP_CHEROKEE = "JEEP GRAND CHEROKEE V6 2018" # includes 2017 Trailhawk - JEEP_CHEROKEE_2019 = "JEEP GRAND CHEROKEE 2019" # includes 2020 Trailhawk + JEEP_CHEROKEE = "JEEP GRAND CHEROKEE V6 2018" # includes 2017 Trailhawk + JEEP_CHEROKEE_2019 = "JEEP GRAND CHEROKEE 2019" # includes 2020 Trailhawk + + # Ram + RAM_1500 = "RAM 1500 5TH GEN" + +class CarControllerParams: + STEER_MAX = 261 # higher than this faults the EPS on Chrysler/Jeep. Ram DT allows more + STEER_DELTA_UP = 3 + STEER_DELTA_DOWN = 3 + STEER_ERROR_MAX = 80 + +STEER_THRESHOLD = 120 + +RAM_CARS = {CAR.RAM_1500, } @dataclass class ChryslerCarInfo(CarInfo): package: str = "Adaptive Cruise" harness: Enum = Harness.fca - CAR_INFO: Dict[str, Optional[Union[ChryslerCarInfo, List[ChryslerCarInfo]]]] = { CAR.PACIFICA_2017_HYBRID: ChryslerCarInfo("Chrysler Pacifica Hybrid 2017-18"), CAR.PACIFICA_2018_HYBRID: None, # same platforms @@ -42,6 +47,7 @@ CAR_INFO: Dict[str, Optional[Union[ChryslerCarInfo, List[ChryslerCarInfo]]]] = { CAR.PACIFICA_2020: ChryslerCarInfo("Chrysler Pacifica 2019-20"), CAR.JEEP_CHEROKEE: ChryslerCarInfo("Jeep Grand Cherokee 2016-18", video_link="https://www.youtube.com/watch?v=eLR9o2JkuRk"), CAR.JEEP_CHEROKEE_2019: ChryslerCarInfo("Jeep Grand Cherokee 2019-20", video_link="https://www.youtube.com/watch?v=jBe4lWnRSu4"), + CAR.RAM_1500: ChryslerCarInfo("Ram 1500 2019-21"), } # Unique CAN messages: @@ -97,6 +103,11 @@ FINGERPRINTS = { # Jeep Grand Cherokee 2019, including most 2020 models 55: 8, 168: 8, 179: 8, 181: 8, 256: 4, 257: 5, 258: 8, 264: 8, 268: 8, 272: 6, 273: 6, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 292: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 341: 8, 344: 8, 352: 8, 362: 8, 368: 8, 376: 3, 384: 8, 388: 4, 416: 7, 448: 6, 456: 4, 464: 8, 500: 8, 501: 8, 512: 8, 514: 8, 520: 8, 530: 8, 532: 8, 544: 8, 557: 8, 559: 8, 560: 8, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 618: 8, 624: 8, 625: 8, 632: 8, 639: 8, 640: 1, 656: 4, 658: 6, 660: 8, 671: 8, 672: 8, 676: 8, 678: 8, 680: 8, 683: 8, 684: 8, 703: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 729: 5, 736: 8, 737: 8, 738: 8, 746: 5, 752: 2, 754: 8, 760: 8, 761: 8, 764: 8, 766: 8, 773: 8, 776: 8, 779: 8, 782: 8, 783: 8, 784: 8, 785: 8, 792: 8, 799: 8, 800: 8, 804: 8, 806: 2, 808: 8, 810: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 831: 6, 832: 8, 838: 2, 840: 8, 844: 5, 847: 1, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 882: 8, 897: 8, 906: 8, 924: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 960: 4, 968: 8, 969: 4, 970: 8, 973: 8, 974: 5, 976: 8, 977: 4, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1062: 8, 1098: 8, 1100: 8, 1216: 8, 1218: 8, 1220: 8, 1223: 8, 1225: 8, 1227: 8, 1235: 8, 1242: 8, 1250: 8, 1251: 8, 1252: 8, 1254: 8, 1264: 8, 1284: 8, 1536: 8, 1537: 8, 1543: 8, 1545: 8, 1562: 8, 1568: 8, 1570: 8, 1572: 8, 1593: 8, 1856: 8, 1858: 8, 1860: 8, 1863: 8, 1865: 8, 1867: 8, 1875: 8, 1882: 8, 1890: 8, 1891: 8, 1892: 8, 1894: 8, 1896: 8, 1904: 8, 2015: 8, 2016: 8, 2017: 8, 2024: 8, 2025: 8 }], + CAR.RAM_1500: [ + {35: 8, 37: 8, 39: 8, 41: 8, 43: 8, 47: 8, 49: 8, 53: 8, 55: 8, 113: 8, 119: 2, 121: 8, 123: 7, 125: 6, 127: 8, 129: 8, 131: 8, 133: 8, 135: 8, 137: 8, 139: 8, 141: 8, 145: 8, 147: 8, 149: 7, 153: 8, 155: 8, 157: 8, 163: 8, 164: 8, 166: 8, 167: 8, 169: 8, 171: 8, 173: 5, 177: 3, 179: 8, 181: 8, 213: 3, 221: 8, 232: 8, 250: 8, 278: 8, 289: 5, 293: 3, 295: 8, 296: 8, 297: 4, 298: 8, 299: 8, 305: 8, 307: 8, 311: 8, 315: 8, 317: 8, 319: 8, 323: 8, 333: 8, 334: 8, 341: 8, 343: 8, 345: 8, 347: 8, 409: 6, 421: 8, 448: 6, 456: 4, 464: 8, 489: 8, 491: 8, 502: 8, 503: 8, 505: 8, 507: 5, 516: 7, 517: 7, 524: 8, 526: 6, 557: 8, 560: 8, 584: 8, 601: 8, 605: 8, 607: 8, 609: 8, 611: 8, 613: 8, 623: 8, 631: 8, 633: 8, 634: 8, 635: 8, 637: 8, 641: 8, 643: 8, 645: 2, 649: 8, 650: 8, 651: 8, 656: 4, 657: 8, 659: 5, 663: 8, 664: 8, 673: 8, 676: 8, 679: 8, 685: 8, 687: 8, 689: 5, 706: 8, 709: 8, 710: 8, 711: 8, 720: 6, 752: 2, 754: 8, 773: 8, 788: 3, 792: 8, 808: 8, 818: 8, 819: 8, 822: 8, 823: 8, 825: 2, 838: 2, 840: 8, 848: 8, 856: 4, 860: 6, 862: 8, 875: 2, 897: 8, 906: 8, 910: 8, 926: 3, 929: 8, 930: 8, 931: 8, 932: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 956: 8, 961: 8, 962: 8, 969: 4, 971: 8, 972: 8, 973: 8, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1062: 8, 1098: 8, 1100: 8, 2015: 8, 2016: 8, 2017: 8, 2024: 8, 2025: 8}, + {35: 8, 37: 8, 39: 8, 43: 8, 47: 8, 49: 8, 53: 8, 55: 8, 113: 8, 119: 2, 121: 8, 123: 7, 125: 6, 127: 8, 129: 8, 131: 8, 133: 8, 135: 8, 137: 8, 139: 8, 141: 8, 145: 8, 147: 8, 149: 7, 153: 8, 155: 8, 157: 8, 163: 8, 164: 8, 166: 8, 167: 8, 169: 8, 171: 8, 173: 5, 177: 3, 179: 8, 181: 8, 213: 3, 221: 8, 232: 8, 250: 8, 276: 8, 277: 8, 278: 8, 289: 5, 293: 3, 295: 8, 296: 8, 297: 4, 299: 8, 301: 8, 302: 8, 305: 8, 307: 8, 311: 8, 317: 8, 319: 8, 323: 8, 327: 8, 333: 8, 334: 8, 341: 8, 343: 8, 345: 8, 347: 8, 421: 8, 448: 6, 456: 4, 457: 8, 464: 8, 489: 8, 491: 8, 502: 8, 503: 8, 507: 5, 516: 7, 517: 7, 524: 8, 526: 6, 557: 8, 560: 8, 584: 8, 601: 8, 605: 8, 607: 8, 609: 8, 613: 8, 623: 8, 631: 8, 633: 8, 634: 8, 635: 8, 637: 8, 641: 8, 643: 8, 645: 2, 649: 8, 650: 8, 651: 8, 656: 4, 657: 8, 663: 8, 673: 8, 676: 8, 679: 8, 685: 8, 687: 8, 689: 5, 706: 8, 709: 8, 710: 8, 711: 8, 720: 6, 738: 8, 752: 2, 754: 8, 773: 8, 792: 8, 808: 8, 812: 8, 813: 8, 814: 8, 818: 8, 819: 8, 821: 8, 822: 8, 823: 8, 825: 2, 838: 2, 840: 8, 847: 1, 848: 8, 856: 4, 860: 6, 862: 8, 874: 2, 876: 8, 897: 8, 906: 8, 910: 8, 926: 3, 929: 8, 930: 8, 931: 8, 932: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 961: 8, 962: 8, 969: 4, 971: 8, 972: 8, 973: 8, 975: 8, 976: 8, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1030: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1098: 8, 1100: 8}, + {35: 8, 37: 8, 39: 8, 43: 8, 47: 8, 49: 8, 53: 8, 55: 8, 113: 8, 119: 2, 121: 8, 123: 7, 125: 6, 127: 8, 129: 8, 131: 8, 133: 8, 135: 8, 137: 8, 139: 8, 141: 8, 145: 8, 147: 8, 149: 7, 153: 8, 155: 8, 157: 8, 163: 8, 164: 8, 166: 8, 167: 8, 169: 8, 171: 8, 173: 5, 177: 3, 179: 8, 181: 8, 213: 3, 221: 8, 232: 8, 250: 8, 289: 5, 293: 3, 295: 8, 296: 8, 297: 4, 299: 8, 301: 8, 302: 8, 305: 8, 307: 8, 311: 8, 317: 8, 319: 8, 323: 8, 334: 8, 337: 8, 343: 8, 347: 8, 409: 6, 421: 8, 448: 6, 456: 4, 464: 8, 489: 8, 491: 8, 502: 8, 503: 8, 507: 5, 516: 7, 517: 7, 524: 8, 526: 6, 557: 8, 560: 8, 584: 8, 601: 8, 605: 8, 607: 8, 609: 8, 613: 8, 623: 8, 631: 8, 633: 8, 634: 8, 635: 8, 637: 8, 641: 8, 643: 8, 645: 2, 649: 8, 650: 8, 651: 8, 656: 4, 657: 8, 659: 5, 663: 8, 664: 8, 673: 8, 676: 8, 679: 8, 685: 8, 687: 8, 689: 5, 706: 8, 709: 8, 710: 8, 711: 8, 720: 6, 752: 2, 754: 8, 773: 8, 788: 3, 792: 8, 808: 8, 812: 8, 813: 8, 814: 8, 818: 8, 819: 8, 821: 8, 822: 8, 825: 2, 838: 2, 840: 8, 847: 1, 848: 8, 856: 4, 860: 6, 862: 8, 876: 8, 897: 8, 906: 8, 910: 8, 926: 3, 929: 8, 930: 8, 931: 8, 932: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 956: 8, 961: 8, 962: 8, 969: 4, 971: 8, 972: 8, 973: 8, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1030: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1062: 8, 1098: 8, 1100: 8}, + ], } @@ -108,6 +119,5 @@ DBC = { CAR.PACIFICA_2019_HYBRID: dbc_dict('chrysler_pacifica_2017_hybrid_generated', 'chrysler_pacifica_2017_hybrid_private_fusion'), CAR.JEEP_CHEROKEE: dbc_dict('chrysler_pacifica_2017_hybrid_generated', 'chrysler_pacifica_2017_hybrid_private_fusion'), CAR.JEEP_CHEROKEE_2019: dbc_dict('chrysler_pacifica_2017_hybrid_generated', 'chrysler_pacifica_2017_hybrid_private_fusion'), + CAR.RAM_1500: dbc_dict('chrysler_ram_dt_generated', None), } - -STEER_THRESHOLD = 120 diff --git a/selfdrive/car/tests/routes.py b/selfdrive/car/tests/routes.py index 19b1a05c23..96eb5f67b9 100644 --- a/selfdrive/car/tests/routes.py +++ b/selfdrive/car/tests/routes.py @@ -38,6 +38,7 @@ routes = [ TestRoute("378472f830ee7395|2021-05-28--07-38-43", CHRYSLER.PACIFICA_2018_HYBRID), TestRoute("8190c7275a24557b|2020-01-29--08-33-58", CHRYSLER.PACIFICA_2019_HYBRID), TestRoute("3d84727705fecd04|2021-05-25--08-38-56", CHRYSLER.PACIFICA_2020), + TestRoute("221c253375af4ee9|2022-06-15--18-38-24", CHRYSLER.RAM_1500), #TestRoute("f1b4c567731f4a1b|2018-04-30--10-15-35", FORD.FUSION), diff --git a/selfdrive/car/torque_data/override.yaml b/selfdrive/car/torque_data/override.yaml index a2200926c0..be81af2606 100644 --- a/selfdrive/car/torque_data/override.yaml +++ b/selfdrive/car/torque_data/override.yaml @@ -19,8 +19,9 @@ FORD FOCUS 4TH GEN: [.nan, 1.5, .nan] # No steering wheel COMMA BODY: [.nan, 1000, .nan] -# Totally new car +# Totally new cars KIA EV6 2022: [3.0, 2.5, 0.0] +RAM 1500 5TH GEN: [2.0, 2.0, 0.05] # Dashcam or fallback configured as ideal car mock: [10.0, 10, 0.0] diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index 0eeae1e3e3..b0136da88e 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -b904e52e9de4ff7b2bd7f6af8b19abaf4957e6cc \ No newline at end of file +ebe7f1285ec60f522179606d483a198535c0e83a \ No newline at end of file From fd2de54172b4a76f2ab8ac5d8f8eca5c41739351 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Thu, 7 Jul 2022 00:24:03 -0700 Subject: [PATCH 025/112] Stock longitudinal: spam resume button when lead starts moving (#24873) * always log leads, we hide them in ui * only spam resume when future is > vEgoStarting * do rest but vw * vw * remove comments * rename to resume * maintain original button msg rate * mazda: ensure no resume if cancelling * same for non-HDA2 * Always run planner if not opLong * try 0.2 * 0.1 should be pretty safe * add test for resuming * fix test * stricter test, speeds[-1] is 0.14 when starting here * no walrus * fixup mazda cc * remove extra import --- selfdrive/car/honda/carcontroller.py | 2 +- selfdrive/car/hyundai/carcontroller.py | 4 ++-- selfdrive/car/mazda/carcontroller.py | 11 ++++------- selfdrive/car/volkswagen/carcontroller.py | 5 ++--- selfdrive/controls/controlsd.py | 4 ++++ selfdrive/test/longitudinal_maneuvers/maneuver.py | 5 +++++ selfdrive/test/longitudinal_maneuvers/plant.py | 3 +++ .../test/longitudinal_maneuvers/test_longitudinal.py | 12 ++++++++++++ 8 files changed, 33 insertions(+), 13 deletions(-) diff --git a/selfdrive/car/honda/carcontroller.py b/selfdrive/car/honda/carcontroller.py index 14049c9997..d47caaa9ad 100644 --- a/selfdrive/car/honda/carcontroller.py +++ b/selfdrive/car/honda/carcontroller.py @@ -195,7 +195,7 @@ class CarController: # If using stock ACC, spam cancel command to kill gas when OP disengages. if pcm_cancel_cmd: can_sends.append(hondacan.spam_buttons_command(self.packer, CruiseButtons.CANCEL, idx, self.CP.carFingerprint)) - elif CS.out.cruiseState.standstill: + elif CC.cruiseControl.resume: can_sends.append(hondacan.spam_buttons_command(self.packer, CruiseButtons.RES_ACCEL, idx, self.CP.carFingerprint)) else: diff --git a/selfdrive/car/hyundai/carcontroller.py b/selfdrive/car/hyundai/carcontroller.py index 4fbb5ce0e1..f3066bda03 100644 --- a/selfdrive/car/hyundai/carcontroller.py +++ b/selfdrive/car/hyundai/carcontroller.py @@ -78,7 +78,7 @@ class CarController: self.last_button_frame = self.frame # cruise standstill resume - elif CC.enabled and CS.out.cruiseState.standstill: + elif CC.cruiseControl.resume: can_sends.append(hda2can.create_buttons(self.packer, CS.buttons_counter+1, False, True)) self.last_button_frame = self.frame else: @@ -96,7 +96,7 @@ class CarController: if not self.CP.openpilotLongitudinalControl: if CC.cruiseControl.cancel: can_sends.append(hyundaican.create_clu11(self.packer, self.frame, CS.clu11, Buttons.CANCEL)) - elif CS.out.cruiseState.standstill: + elif CC.cruiseControl.resume: # send resume at a max freq of 10Hz if (self.frame - self.last_button_frame) * DT_CTRL > 0.1: # send 25 messages at a time to increases the likelihood of resume being accepted diff --git a/selfdrive/car/mazda/carcontroller.py b/selfdrive/car/mazda/carcontroller.py index 0e43a11ceb..a83cef508a 100644 --- a/selfdrive/car/mazda/carcontroller.py +++ b/selfdrive/car/mazda/carcontroller.py @@ -29,13 +29,6 @@ class CarController: CS.out.steeringTorque, CarControllerParams) self.steer_rate_limited = new_steer != apply_steer - if CC.enabled: - if CS.out.standstill and self.frame % 5 == 0: - # Mazda Stop and Go requires a RES button (or gas) press if the car stops more than 3 seconds - # Send Resume button at 20hz if we're engaged at standstill to support full stop and go! - # TODO: improve the resume trigger logic by looking at actual radar data - can_sends.append(mazdacan.create_button_cmd(self.packer, self.CP.carFingerprint, CS.crz_btns_counter, Buttons.RESUME)) - if CC.cruiseControl.cancel: # If brake is pressed, let us wait >70ms before trying to disable crz to avoid # a race condition with the stock system, where the second cancel from openpilot @@ -48,6 +41,10 @@ class CarController: can_sends.append(mazdacan.create_button_cmd(self.packer, self.CP.carFingerprint, CS.crz_btns_counter, Buttons.CANCEL)) else: self.brake_counter = 0 + if CC.cruiseControl.resume and self.frame % 5 == 0: + # Mazda Stop and Go requires a RES button (or gas) press if the car stops more than 3 seconds + # Send Resume button when planner wants car to move + can_sends.append(mazdacan.create_button_cmd(self.packer, self.CP.carFingerprint, CS.crz_btns_counter, Buttons.RESUME)) self.apply_steer_last = apply_steer diff --git a/selfdrive/car/volkswagen/carcontroller.py b/selfdrive/car/volkswagen/carcontroller.py index 4614463c6e..1643fbe9b6 100644 --- a/selfdrive/car/volkswagen/carcontroller.py +++ b/selfdrive/car/volkswagen/carcontroller.py @@ -96,9 +96,8 @@ class CarController: # Cancel ACC if it's engaged with OP disengaged. self.graButtonStatesToSend = BUTTON_STATES.copy() self.graButtonStatesToSend["cancel"] = True - elif CC.enabled and CS.out.cruiseState.standstill: - # Blip the Resume button if we're engaged at standstill. - # FIXME: This is a naive implementation, improve with visiond or radar input. + elif CC.cruiseControl.resume: + # Send Resume button when planner wants car to move self.graButtonStatesToSend = BUTTON_STATES.copy() self.graButtonStatesToSend["resumeCruise"] = True diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index 9e3af9eb63..6f0c9c2ae6 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -658,6 +658,10 @@ class Controls: if self.joystick_mode and self.sm.rcv_frame['testJoystick'] > 0 and self.sm['testJoystick'].buttons[0]: CC.cruiseControl.cancel = True + speeds = self.sm['longitudinalPlan'].speeds + if len(speeds): + CC.cruiseControl.resume = self.enabled and CS.cruiseState.standstill and speeds[-1] > 0.1 + hudControl = CC.hudControl hudControl.setSpeed = float(self.v_cruise_kph * CV.KPH_TO_MS) hudControl.speedVisible = self.enabled diff --git a/selfdrive/test/longitudinal_maneuvers/maneuver.py b/selfdrive/test/longitudinal_maneuvers/maneuver.py index 9b4d016430..0d605a5fc7 100644 --- a/selfdrive/test/longitudinal_maneuvers/maneuver.py +++ b/selfdrive/test/longitudinal_maneuvers/maneuver.py @@ -16,6 +16,7 @@ class Maneuver(): self.only_lead2 = kwargs.get("only_lead2", False) self.only_radar = kwargs.get("only_radar", False) + self.ensure_start = kwargs.get("ensure_start", False) self.duration = duration self.title = title @@ -52,5 +53,9 @@ class Maneuver(): print("Crashed!!!!") valid = False + if self.ensure_start and log['v_rel'] > 0 and log['speeds'][-1] <= 0.1: + print('Planner not starting!') + valid = False + print("maneuver end", valid) return valid, np.array(logs) diff --git a/selfdrive/test/longitudinal_maneuvers/plant.py b/selfdrive/test/longitudinal_maneuvers/plant.py index 13025a9f03..3bd50ebcfa 100755 --- a/selfdrive/test/longitudinal_maneuvers/plant.py +++ b/selfdrive/test/longitudinal_maneuvers/plant.py @@ -28,6 +28,7 @@ class Plant(): self.distance = 0. self.speed = speed self.acceleration = 0.0 + self.speeds = [] # lead car self.distance_lead = distance_lead @@ -98,6 +99,7 @@ class Plant(): self.planner.update(sm) self.speed = self.planner.v_desired_filter.x self.acceleration = self.planner.a_desired + self.speeds = self.planner.v_desired_trajectory.tolist() fcw = self.planner.fcw self.distance_lead = self.distance_lead + v_lead * self.ts @@ -129,6 +131,7 @@ class Plant(): "distance": self.distance, "speed": self.speed, "acceleration": self.acceleration, + "speeds": self.speeds, "distance_lead": self.distance_lead, "fcw": fcw, } diff --git a/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py b/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py index 698877dd3a..ec698d88fa 100755 --- a/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py +++ b/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py @@ -3,6 +3,7 @@ import os import unittest from common.params import Params +from selfdrive.controls.lib.longitudinal_mpc_lib.long_mpc import STOP_DISTANCE from selfdrive.test.longitudinal_maneuvers.maneuver import Maneuver @@ -106,6 +107,17 @@ maneuvers = [ breakpoints=[1., 1.01, 11.], cruise_values=[float("nan"), 15., 15.], ), + # controls relies on planner commanding to move for stock-ACC resume spamming + Maneuver( + "resume from a stop", + duration=20., + initial_speed=0., + lead_relevancy=True, + initial_distance_lead=STOP_DISTANCE, + speed_lead_values=[0., 0., 2.], + breakpoints=[1., 10., 15.], + ensure_start=True, + ), ] From 30cb9ac962395a86464fdfc079b5f0030c7b9b9d Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Thu, 7 Jul 2022 00:28:21 -0700 Subject: [PATCH 026/112] FW query debug script: print version brand (#25058) * test_fw_query_on_routes: print brand * dynamic paddign --- selfdrive/debug/test_fw_query_on_routes.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/selfdrive/debug/test_fw_query_on_routes.py b/selfdrive/debug/test_fw_query_on_routes.py index 789baeca4b..8c8c631c38 100755 --- a/selfdrive/debug/test_fw_query_on_routes.py +++ b/selfdrive/debug/test_fw_query_on_routes.py @@ -126,9 +126,10 @@ if __name__ == "__main__": print("New style (exact):", exact_matches) print("New style (fuzzy):", fuzzy_matches) - for version in car_fw: + padding = max([len(fw.brand) for fw in car_fw]) + for version in sorted(car_fw, key=lambda fw: fw.brand): subaddr = None if version.subAddress == 0 else hex(version.subAddress) - print(f" (Ecu.{version.ecu}, {hex(version.address)}, {subaddr}): [{version.fwVersion}],") + print(f" Brand: {version.brand:{padding}} - (Ecu.{version.ecu}, {hex(version.address)}, {subaddr}): [{version.fwVersion}],") print("Mismatches") found = False From edf170103ed0d244e0483794feee6c3b4023ccc2 Mon Sep 17 00:00:00 2001 From: Gijs Koning Date: Thu, 7 Jul 2022 11:14:31 +0200 Subject: [PATCH 027/112] Process replay: Fix subtest diff (#25054) Fix subtest diff --- selfdrive/test/process_replay/test_processes.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/selfdrive/test/process_replay/test_processes.py b/selfdrive/test/process_replay/test_processes.py index 9cbf4439ac..04bf51e2e9 100755 --- a/selfdrive/test/process_replay/test_processes.py +++ b/selfdrive/test/process_replay/test_processes.py @@ -71,7 +71,7 @@ def run_test_process(data): assert os.path.exists(cur_log_fn), f"Cannot find log to upload: {cur_log_fn}" upload_file(cur_log_fn, os.path.basename(cur_log_fn)) os.remove(cur_log_fn) - return (segment, cfg.proc_name, res) + return (segment, cfg.proc_name, cfg.subtest_name, res) def get_log_data(segment): @@ -212,9 +212,9 @@ if __name__ == "__main__": results: Any = defaultdict(dict) p2 = pool.map(run_test_process, pool_args) - for (segment, proc, result) in tqdm(p2, desc="Running Tests", total=len(pool_args)): + for (segment, proc, subtest_name, result) in tqdm(p2, desc="Running Tests", total=len(pool_args)): if isinstance(result, list): - results[segment][proc] = result + results[segment][proc + subtest_name] = result diff1, diff2, failed = format_diff(results, ref_commit) if not upload: From a3a9a0685c63ea57dc936e496cd5e6be5a71512e Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Thu, 7 Jul 2022 12:02:31 +0200 Subject: [PATCH 028/112] onroad.cc: fix mutcd sign width for metric speed limit --- selfdrive/ui/qt/onroad.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/ui/qt/onroad.cc b/selfdrive/ui/qt/onroad.cc index 604d3c09a9..ca39a89ae4 100644 --- a/selfdrive/ui/qt/onroad.cc +++ b/selfdrive/ui/qt/onroad.cc @@ -296,7 +296,7 @@ void NvgWindow::drawHud(QPainter &p) { // US/Canada (MUTCD style) sign if (has_us_speed_limit) { const int border_width = 6; - const int sign_width = (speedLimitStr.size() >= 3) ? 199 : 148; + const int sign_width = rect_width - 24; const int sign_height = 186; // White outer square From eaf7eb42784732136e52cd031035e9c5ab520e6e Mon Sep 17 00:00:00 2001 From: Gijs Koning Date: Thu, 7 Jul 2022 13:06:51 +0200 Subject: [PATCH 029/112] Laikad: Use clocks for faster fetching orbits (#25060) * Use clocks msg to for first fetch of orbits. Which is sent earlier than ublox msgs * refactor last_fetch_orbits * Add comment. Add test * increase timeout * Add clocks to process replay --- selfdrive/locationd/laikad.py | 39 ++++++++++++------- selfdrive/locationd/test/test_laikad.py | 26 ++++++++++++- .../test/process_replay/process_replay.py | 4 +- 3 files changed, 53 insertions(+), 16 deletions(-) diff --git a/selfdrive/locationd/laikad.py b/selfdrive/locationd/laikad.py index 40519da7bc..e262407e02 100755 --- a/selfdrive/locationd/laikad.py +++ b/selfdrive/locationd/laikad.py @@ -5,6 +5,7 @@ import os import time from collections import defaultdict from concurrent.futures import Future, ProcessPoolExecutor +from datetime import datetime from enum import IntEnum from typing import List, Optional @@ -13,7 +14,7 @@ import numpy as np from cereal import log, messaging from common.params import Params, put_nonblocking from laika import AstroDog -from laika.constants import SECS_IN_MIN +from laika.constants import SECS_IN_HR, SECS_IN_MIN from laika.ephemeris import Ephemeris, EphemerisType, convert_ublox_ephem from laika.gps_time import GPSTime from laika.helpers import ConstellationId @@ -30,7 +31,8 @@ CACHE_VERSION = 0.1 class Laikad: - def __init__(self, valid_const=("GPS", "GLONASS"), auto_fetch_orbits=True, auto_update=False, valid_ephem_types=(EphemerisType.ULTRA_RAPID_ORBIT, EphemerisType.NAV), + def __init__(self, valid_const=("GPS", "GLONASS"), auto_fetch_orbits=True, auto_update=False, + valid_ephem_types=(EphemerisType.ULTRA_RAPID_ORBIT, EphemerisType.NAV), save_ephemeris=False): """ valid_const: GNSS constellation which can be used @@ -47,6 +49,7 @@ class Laikad: self.orbit_fetch_future: Optional[Future] = None self.last_fetch_orbits_t = None + self.got_first_ublox_msg = False self.last_cached_t = None self.save_ephemeris = save_ephemeris self.load_cache() @@ -72,8 +75,9 @@ class Laikad: except json.decoder.JSONDecodeError: cloudlog.exception("Error parsing cache") timestamp = self.last_fetch_orbits_t.as_datetime() if self.last_fetch_orbits_t is not None else 'Nan' - cloudlog.debug(f"Loaded nav and orbits cache with timestamp: {timestamp}. Unique orbit and nav sats: {list(cache['orbits'].keys())} {list(cache['nav'].keys())} " + - f"Total: {sum([len(v) for v in cache['orbits']])} and {sum([len(v) for v in cache['nav']])}") + cloudlog.debug( + f"Loaded nav and orbits cache with timestamp: {timestamp}. Unique orbit and nav sats: {list(cache['orbits'].keys())} {list(cache['nav'].keys())} " + + f"Total: {sum([len(v) for v in cache['orbits']])} and {sum([len(v) for v in cache['nav']])}") def cache_ephemeris(self, t: GPSTime): if self.save_ephemeris and (self.last_cached_t is None or t - self.last_cached_t > SECS_IN_MIN): @@ -98,9 +102,10 @@ class Laikad: t = ublox_mono_time * 1e-9 report = ublox_msg.measurementReport if report.gpsWeek > 0: + self.got_first_ublox_msg = True latest_msg_t = GPSTime(report.gpsWeek, report.rcvTow) if self.auto_fetch_orbits: - self.fetch_orbits(latest_msg_t + SECS_IN_MIN, block) + self.fetch_orbits(latest_msg_t, block) new_meas = read_raw_ublox(report) # Filter measurements with unexpected pseudoranges for GPS and GLONASS satellites @@ -174,24 +179,26 @@ class Laikad: self.gnss_kf.init_state(x_initial, covs_diag=p_initial_diag) def fetch_orbits(self, t: GPSTime, block): - if t not in self.astro_dog.orbit_fetched_times and (self.last_fetch_orbits_t is None or t - self.last_fetch_orbits_t > SECS_IN_MIN): + # Download new orbits if 1 hour of orbits data left + if t + SECS_IN_HR not in self.astro_dog.orbit_fetched_times and (self.last_fetch_orbits_t is None or abs(t - self.last_fetch_orbits_t) > SECS_IN_MIN): astro_dog_vars = self.astro_dog.valid_const, self.astro_dog.auto_update, self.astro_dog.valid_ephem_types - ret = None - if block: + if block: # Used for testing purposes ret = get_orbit_data(t, *astro_dog_vars) elif self.orbit_fetch_future is None: self.orbit_fetch_executor = ProcessPoolExecutor(max_workers=1) self.orbit_fetch_future = self.orbit_fetch_executor.submit(get_orbit_data, t, *astro_dog_vars) elif self.orbit_fetch_future.done(): - self.last_fetch_orbits_t = t ret = self.orbit_fetch_future.result() self.orbit_fetch_executor = self.orbit_fetch_future = None if ret is not None: - self.astro_dog.orbits, self.astro_dog.orbit_fetched_times = ret - self.cache_ephemeris(t=t) + if ret[0] is None: + self.last_fetch_orbits_t = ret[2] + else: + self.astro_dog.orbits, self.astro_dog.orbit_fetched_times, self.last_fetch_orbits_t = ret + self.cache_ephemeris(t=t) def get_orbit_data(t: GPSTime, valid_const, auto_update, valid_ephem_types): @@ -201,9 +208,10 @@ def get_orbit_data(t: GPSTime, valid_const, auto_update, valid_ephem_types): try: astro_dog.get_orbit_data(t, only_predictions=True) cloudlog.info(f"Done parsing orbits. Took {time.monotonic() - start_time:.1f}s") - return astro_dog.orbits, astro_dog.orbit_fetched_times + return astro_dog.orbits, astro_dog.orbit_fetched_times, t except (RuntimeError, ValueError, IOError) as e: cloudlog.warning(f"No orbit data found or parsing failure: {e}") + return None, None, t def create_measurement_msg(meas: GNSSMeasurement): @@ -284,7 +292,7 @@ class EphemerisSourceType(IntEnum): def main(sm=None, pm=None): if sm is None: - sm = messaging.SubMaster(['ubloxGnss']) + sm = messaging.SubMaster(['ubloxGnss', 'clocks']) if pm is None: pm = messaging.PubMaster(['gnssMeasurements']) @@ -299,6 +307,11 @@ def main(sm=None, pm=None): msg = laikad.process_ublox_msg(ublox_msg, sm.logMonoTime['ubloxGnss'], block=replay) if msg is not None: pm.send('gnssMeasurements', msg) + if not laikad.got_first_ublox_msg and sm.updated['clocks']: + clocks_msg = sm['clocks'] + t = GPSTime.from_datetime(datetime.utcfromtimestamp(clocks_msg.wallTimeNanos * 1E-9)) + if laikad.auto_fetch_orbits: + laikad.fetch_orbits(t, block=replay) if __name__ == "__main__": diff --git a/selfdrive/locationd/test/test_laikad.py b/selfdrive/locationd/test/test_laikad.py index 26c1d28820..3a7c073b55 100755 --- a/selfdrive/locationd/test/test_laikad.py +++ b/selfdrive/locationd/test/test_laikad.py @@ -67,7 +67,7 @@ class TestLaikad(unittest.TestCase): gpstime = GPSTime.from_datetime(datetime(2021, month=3, day=1)) laikad = Laikad() laikad.fetch_orbits(gpstime, block=False) - laikad.orbit_fetch_future.result(5) + laikad.orbit_fetch_future.result(30) # Get results and save orbits to laikad: laikad.fetch_orbits(gpstime, block=False) @@ -75,7 +75,7 @@ class TestLaikad(unittest.TestCase): self.assertIsNotNone(ephem) laikad.fetch_orbits(gpstime+2*SECS_IN_DAY, block=False) - laikad.orbit_fetch_future.result(5) + laikad.orbit_fetch_future.result(30) # Get results and save orbits to laikad: laikad.fetch_orbits(gpstime + 2 * SECS_IN_DAY, block=False) @@ -83,6 +83,28 @@ class TestLaikad(unittest.TestCase): self.assertIsNotNone(ephem) self.assertNotEqual(ephem, ephem2) + def test_fetch_orbits_with_wrong_clocks(self): + laikad = Laikad() + + def check_has_orbits(): + self.assertGreater(len(laikad.astro_dog.orbits), 0) + ephem = laikad.astro_dog.orbits['G01'][0] + self.assertIsNotNone(ephem) + real_current_time = GPSTime.from_datetime(datetime(2021, month=3, day=1)) + wrong_future_clock_time = real_current_time + SECS_IN_DAY + + laikad.fetch_orbits(wrong_future_clock_time, block=True) + check_has_orbits() + self.assertEqual(laikad.last_fetch_orbits_t, wrong_future_clock_time) + + # Test fetching orbits with earlier time + assert real_current_time < laikad.last_fetch_orbits_t + + laikad.astro_dog.orbits = {} + laikad.fetch_orbits(real_current_time, block=True) + check_has_orbits() + self.assertEqual(laikad.last_fetch_orbits_t, real_current_time) + def test_ephemeris_source_in_msg(self): data_mock = defaultdict(str) data_mock['sv_id'] = 1 diff --git a/selfdrive/test/process_replay/process_replay.py b/selfdrive/test/process_replay/process_replay.py index 9c45281b0c..c667aa3887 100755 --- a/selfdrive/test/process_replay/process_replay.py +++ b/selfdrive/test/process_replay/process_replay.py @@ -239,7 +239,7 @@ def ublox_rcv_callback(msg): def laika_rcv_callback(msg, CP, cfg, fsm): - if msg.ubloxGnss.which() == "measurementReport": + if msg.which() == 'ubloxGnss' and msg.ubloxGnss.which() == "measurementReport": return ["gnssMeasurements"], True else: return [], True @@ -352,6 +352,7 @@ CONFIGS = [ subtest_name="Offline", pub_sub={ "ubloxGnss": ["gnssMeasurements"], + "clocks": [] }, ignore=["logMonoTime"], init_callback=get_car_params, @@ -364,6 +365,7 @@ CONFIGS = [ proc_name="laikad", pub_sub={ "ubloxGnss": ["gnssMeasurements"], + "clocks": [] }, ignore=["logMonoTime"], init_callback=get_car_params, From 356190f6712b68218237147deddf90fbe6268b6e Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Thu, 7 Jul 2022 16:13:05 +0200 Subject: [PATCH 030/112] fix MacOS buid: replay frameworks (#25061) * replay: fix macos build * here too * keep original frameworks --- tools/replay/SConscript | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tools/replay/SConscript b/tools/replay/SConscript index 4a85f46d61..d3967708fa 100644 --- a/tools/replay/SConscript +++ b/tools/replay/SConscript @@ -2,8 +2,14 @@ import os Import('env', 'qt_env', 'arch', 'common', 'messaging', 'visionipc', 'cereal', 'transformations') +base_frameworks = qt_env['FRAMEWORKS'] base_libs = [common, messaging, cereal, visionipc, transformations, 'zmq', - 'capnp', 'kj', 'm', 'OpenCL', 'ssl', 'crypto', 'pthread'] + qt_env["LIBS"] + 'capnp', 'kj', 'm', 'ssl', 'crypto', 'pthread'] + qt_env["LIBS"] + +if arch == "Darwin": + base_frameworks.append('OpenCL') +else: + base_libs.append('OpenCL') qt_libs = ['qt_util'] + base_libs if arch in ['x86_64', 'Darwin'] or GetOption('extras'): @@ -11,9 +17,9 @@ if arch in ['x86_64', 'Darwin'] or GetOption('extras'): replay_lib_src = ["replay.cc", "consoleui.cc", "camera.cc", "filereader.cc", "logreader.cc", "framereader.cc", "route.cc", "util.cc"] - replay_lib = qt_env.Library("qt_replay", replay_lib_src, LIBS=qt_libs) + replay_lib = qt_env.Library("qt_replay", replay_lib_src, LIBS=qt_libs, FRAMEWORKS=base_frameworks) replay_libs = [replay_lib, 'avutil', 'avcodec', 'avformat', 'bz2', 'curl', 'yuv', 'ncurses'] + qt_libs - qt_env.Program("replay", ["main.cc"], LIBS=replay_libs) + qt_env.Program("replay", ["main.cc"], LIBS=replay_libs, FRAMEWORKS=base_frameworks) if GetOption('test'): qt_env.Program('tests/test_replay', ['tests/test_runner.cc', 'tests/test_replay.cc'], LIBS=[replay_libs]) From 7e187426c7f02b8d63bce394f08219307e5900ca Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Thu, 7 Jul 2022 18:00:07 +0200 Subject: [PATCH 031/112] athena: skip duplicate upload requests (#25062) * athena: skip duplicate upload requests * cleanup * keep simple * just ignore --- selfdrive/athena/athenad.py | 5 +++++ selfdrive/athena/tests/test_athenad.py | 23 +++++++++++++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/selfdrive/athena/athenad.py b/selfdrive/athena/athenad.py index b0e138c495..6ccd6c3de1 100755 --- a/selfdrive/athena/athenad.py +++ b/selfdrive/athena/athenad.py @@ -364,6 +364,11 @@ def uploadFilesToUrls(files_data): failed.append(fn) continue + # Skip item if already in queue + url = file['url'].split('?')[0] + if any(url == item['url'].split('?')[0] for item in listUploadQueue()): + continue + item = UploadItem( path=path, url=file['url'], diff --git a/selfdrive/athena/tests/test_athenad.py b/selfdrive/athena/tests/test_athenad.py index 382b549c1b..7f511eecf6 100755 --- a/selfdrive/athena/tests/test_athenad.py +++ b/selfdrive/athena/tests/test_athenad.py @@ -124,7 +124,7 @@ class TestAthenadMethods(unittest.TestCase): fn = os.path.join(athenad.ROOT, 'qlog.bz2') Path(fn).touch() if fn.endswith('.bz2'): - self.assertEqual(athenad.strip_bz2_extension(fn), fn[:-4]) + self.assertEqual(athenad.strip_bz2_extension(fn), fn[:-4]) @with_http_server @@ -142,9 +142,6 @@ class TestAthenadMethods(unittest.TestCase): @with_http_server def test_uploadFileToUrl(self, host): - not_exists_resp = dispatcher["uploadFileToUrl"]("does_not_exist.bz2", "http://localhost:1238", {}) - self.assertEqual(not_exists_resp, {'enqueued': 0, 'items': [], 'failed': ['does_not_exist.bz2']}) - fn = os.path.join(athenad.ROOT, 'qlog.bz2') Path(fn).touch() @@ -155,6 +152,24 @@ class TestAthenadMethods(unittest.TestCase): self.assertIsNotNone(resp['items'][0].get('id')) self.assertEqual(athenad.upload_queue.qsize(), 1) + @with_http_server + def test_uploadFileToUrl_duplicate(self, host): + fn = os.path.join(athenad.ROOT, 'qlog.bz2') + Path(fn).touch() + + url1 = f"{host}/qlog.bz2?sig=sig1" + dispatcher["uploadFileToUrl"]("qlog.bz2", url1, {}) + + # Upload same file again, but with different signature + url2 = f"{host}/qlog.bz2?sig=sig2" + resp = dispatcher["uploadFileToUrl"]("qlog.bz2", url2, {}) + self.assertEqual(resp, {'enqueued': 0, 'items': []}) + + @with_http_server + def test_uploadFileToUrl_does_not_exist(self, host): + not_exists_resp = dispatcher["uploadFileToUrl"]("does_not_exist.bz2", "http://localhost:1238", {}) + self.assertEqual(not_exists_resp, {'enqueued': 0, 'items': [], 'failed': ['does_not_exist.bz2']}) + @with_http_server def test_upload_handler(self, host): fn = os.path.join(athenad.ROOT, 'qlog.bz2') From ea80ee0845b619cc20309228611c01ed4c717fd1 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Thu, 7 Jul 2022 09:40:04 -0700 Subject: [PATCH 032/112] Chrysler: resume from cruise standstill (#25009) * Chrysler: resume from cruise standstill * bump panda * resume isn't set yet --- panda | 2 +- selfdrive/car/chrysler/carcontroller.py | 6 ++++-- selfdrive/car/chrysler/chryslercan.py | 3 ++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/panda b/panda index fae3ee2e81..53466f0934 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit fae3ee2e8161d34a7c1939503e583db9b85e5402 +Subproject commit 53466f09344c8ff6cdce3b19df76b5bca79e1327 diff --git a/selfdrive/car/chrysler/carcontroller.py b/selfdrive/car/chrysler/carcontroller.py index 606cb51176..e0eb979e6a 100644 --- a/selfdrive/car/chrysler/carcontroller.py +++ b/selfdrive/car/chrysler/carcontroller.py @@ -25,9 +25,11 @@ class CarController: # *** control msgs *** + das_bus = 2 if self.CP.carFingerprint in RAM_CARS else 0 if CC.cruiseControl.cancel: - bus = 2 if self.CP.carFingerprint in RAM_CARS else 0 - can_sends.append(create_cruise_buttons(self.packer, CS.button_counter + 1, bus, cancel=True)) + can_sends.append(create_cruise_buttons(self.packer, CS.button_counter + 1, das_bus, cancel=True)) + elif CC.enabled and CS.out.cruiseState.standstill: + can_sends.append(create_cruise_buttons(self.packer, CS.button_counter + 1, das_bus, resume=True)) # HUD alerts if self.frame % 25 == 0: diff --git a/selfdrive/car/chrysler/chryslercan.py b/selfdrive/car/chrysler/chryslercan.py index e17e5d5b2a..632c0d2bcf 100644 --- a/selfdrive/car/chrysler/chryslercan.py +++ b/selfdrive/car/chrysler/chryslercan.py @@ -62,8 +62,9 @@ def create_lkas_command(packer, CP, apply_steer, lat_active, frame): return packer.make_can_msg("LKAS_COMMAND", 0, values, frame % 0x10) -def create_cruise_buttons(packer, frame, bus, cancel=False): +def create_cruise_buttons(packer, frame, bus, cancel=False, resume=False): values = { "ACC_Cancel": cancel, + "ACC_Resume": resume, } return packer.make_can_msg("CRUISE_BUTTONS", bus, values, frame % 0x10) From 8d98d8c6578830e28ea8f39fce3844a7e493c019 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Thu, 7 Jul 2022 10:28:55 -0700 Subject: [PATCH 033/112] process replay: add Ram route (#25063) --- selfdrive/car/chrysler/interface.py | 4 +++- selfdrive/test/process_replay/ref_commit | 2 +- selfdrive/test/process_replay/test_processes.py | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/selfdrive/car/chrysler/interface.py b/selfdrive/car/chrysler/interface.py index af202cdc46..920000b271 100755 --- a/selfdrive/car/chrysler/interface.py +++ b/selfdrive/car/chrysler/interface.py @@ -2,7 +2,7 @@ from cereal import car from panda import Panda from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config -from selfdrive.car.chrysler.values import CAR, RAM_CARS +from selfdrive.car.chrysler.values import CAR, DBC, RAM_CARS from selfdrive.car.interfaces import CarInterfaceBase @@ -12,6 +12,8 @@ class CarInterface(CarInterfaceBase): ret = CarInterfaceBase.get_std_params(candidate, fingerprint) ret.carName = "chrysler" + ret.radarOffCan = DBC[candidate]['radar'] is None + param = Panda.FLAG_CHRYSLER_RAM_DT if candidate in RAM_CARS else None ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.chrysler, param)] diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index b0136da88e..0521fd8295 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -ebe7f1285ec60f522179606d483a198535c0e83a \ No newline at end of file +cf46781e405a01c96307d30d1266d46e0fa92255 \ No newline at end of file diff --git a/selfdrive/test/process_replay/test_processes.py b/selfdrive/test/process_replay/test_processes.py index 04bf51e2e9..96d1014004 100755 --- a/selfdrive/test/process_replay/test_processes.py +++ b/selfdrive/test/process_replay/test_processes.py @@ -24,6 +24,7 @@ original_segments = [ ("HONDA", "eb140f119469d9ab|2021-06-12--10-46-24--27"), # HONDA.CIVIC (NIDEC) ("HONDA2", "7d2244f34d1bbcda|2021-06-25--12-25-37--26"), # HONDA.ACCORD (BOSCH) ("CHRYSLER", "4deb27de11bee626|2021-02-20--11-28-55--8"), # CHRYSLER.PACIFICA + ("RAM", "2f4452b03ccb98f0|2022-07-07--08-01-56--2"), # CHRYSLER.RAM_1500 ("SUBARU", "4d70bc5e608678be|2021-01-15--17-02-04--5"), # SUBARU.IMPREZA ("GM", "0c58b6a25109da2b|2021-02-23--16-35-50--11"), # GM.VOLT ("NISSAN", "35336926920f3571|2021-02-12--18-38-48--46"), # NISSAN.XTRAIL @@ -43,6 +44,7 @@ segments = [ ("HONDA", "regen17B09D158B8|2022-07-06--14-31-46--0"), ("HONDA2", "regen041739C3E9A|2022-07-06--15-08-02--0"), ("CHRYSLER", "regenBB2F9C1425C|2022-07-06--14-31-41--0"), + ("RAM", "2f4452b03ccb98f0|2022-07-07--08-01-56--2"), ("SUBARU", "regen732B69F33B1|2022-07-06--14-36-18--0"), ("GM", "regen01D09D915B5|2022-07-06--14-36-20--0"), ("NISSAN", "regenEA6FB2773F5|2022-07-06--14-58-23--0"), From 568cc0f892d650bd5906b59e1ab169158a7a6bf7 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Fri, 8 Jul 2022 01:54:56 +0800 Subject: [PATCH 034/112] loggerd: remove 'enable' from struct LogCameraInfo (#25052) remove enalbe --- selfdrive/loggerd/encoderd.cc | 6 ++---- selfdrive/loggerd/loggerd.cc | 6 ++---- selfdrive/loggerd/loggerd.h | 5 ----- 3 files changed, 4 insertions(+), 13 deletions(-) diff --git a/selfdrive/loggerd/encoderd.cc b/selfdrive/loggerd/encoderd.cc index 87cf4a492f..9bd8e2f1d4 100644 --- a/selfdrive/loggerd/encoderd.cc +++ b/selfdrive/loggerd/encoderd.cc @@ -124,10 +124,8 @@ void encoderd_thread() { std::vector encoder_threads; for (const auto &cam : cameras_logged) { - if (cam.enable) { - encoder_threads.push_back(std::thread(encoder_thread, &s, cam)); - s.max_waiting++; - } + encoder_threads.push_back(std::thread(encoder_thread, &s, cam)); + s.max_waiting++; } for (auto &t : encoder_threads) t.join(); } diff --git a/selfdrive/loggerd/loggerd.cc b/selfdrive/loggerd/loggerd.cc index a75ab2c92b..e0892e68b4 100644 --- a/selfdrive/loggerd/loggerd.cc +++ b/selfdrive/loggerd/loggerd.cc @@ -204,10 +204,8 @@ void loggerd_thread() { // init encoders s.last_camera_seen_tms = millis_since_boot(); for (const auto &cam : cameras_logged) { - if (cam.enable) { - s.max_waiting++; - if (cam.has_qcamera) { s.max_waiting++; } - } + s.max_waiting++; + if (cam.has_qcamera) { s.max_waiting++; } } uint64_t msg_count = 0, bytes_count = 0; diff --git a/selfdrive/loggerd/loggerd.h b/selfdrive/loggerd/loggerd.h index 2c4990086a..6eafbe08d0 100644 --- a/selfdrive/loggerd/loggerd.h +++ b/selfdrive/loggerd/loggerd.h @@ -50,7 +50,6 @@ struct LogCameraInfo { int bitrate; bool is_h265; bool has_qcamera; - bool enable; bool record; }; @@ -63,7 +62,6 @@ const LogCameraInfo cameras_logged[] = { .bitrate = MAIN_BITRATE, .is_h265 = true, .has_qcamera = true, - .enable = true, .record = true, .frame_width = 1928, .frame_height = 1208, @@ -76,7 +74,6 @@ const LogCameraInfo cameras_logged[] = { .bitrate = DCAM_BITRATE, .is_h265 = true, .has_qcamera = false, - .enable = true, .record = Params().getBool("RecordFront"), .frame_width = 1928, .frame_height = 1208, @@ -89,7 +86,6 @@ const LogCameraInfo cameras_logged[] = { .bitrate = MAIN_BITRATE, .is_h265 = true, .has_qcamera = false, - .enable = true, .record = true, .frame_width = 1928, .frame_height = 1208, @@ -100,7 +96,6 @@ const LogCameraInfo qcam_info = { .fps = MAIN_FPS, .bitrate = 256000, .is_h265 = false, - .enable = true, .record = true, .frame_width = 526, .frame_height = 330, From 836e2a4d98b587b7ae083bb710190ed1dfa9dccf Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Thu, 7 Jul 2022 13:20:42 -0700 Subject: [PATCH 035/112] Chrysler: fix steer fault detection (#25068) --- selfdrive/car/chrysler/carstate.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/selfdrive/car/chrysler/carstate.py b/selfdrive/car/chrysler/carstate.py index 71b7e34623..47b28f9e05 100644 --- a/selfdrive/car/chrysler/carstate.py +++ b/selfdrive/car/chrysler/carstate.py @@ -83,8 +83,7 @@ class CarState(CarStateBase): self.auto_high_beam = cp_cam.vl["DAS_6"]['AUTO_HIGH_BEAM_ON'] # Auto High Beam isn't Located in this message on chrysler or jeep currently located in 729 message ret.steerFaultTemporary = cp.vl["EPS_3"]["DASM_FAULT"] == 1 else: - steer_state = cp.vl["EPS_2"]["LKAS_STATE"] - ret.steerFaultPermanent = steer_state == 4 or (steer_state == 0 and ret.vEgo > self.CP.minSteerSpeed) + ret.steerFaultPermanent = cp.vl["EPS_2"]["LKAS_STATE"] == 4 # blindspot sensors if self.CP.enableBsm: From bd2ea158977f5c26658bed8ac683b72c2c592d06 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Thu, 7 Jul 2022 14:19:30 -0700 Subject: [PATCH 036/112] Add Chinese (traditional) translations (#25064) * Add Chinese translations * wrap these * add to languages.json * fix tests * use tmp dir for tests (doesn't change translation files in git repo) * defaultdict not used * update main_zh.ts (test outdated QM file) * test outdated QM file (prev commit tests missing) * update qm file * add sidebar translations * no need for function --- selfdrive/ui/qt/sidebar.h | 14 +- selfdrive/ui/tests/test_translations.py | 46 +- selfdrive/ui/translations/languages.json | 3 +- selfdrive/ui/translations/main_zh.qm | Bin 0 -> 17617 bytes selfdrive/ui/translations/main_zh.ts | 1212 ++++++++++++++++++++++ selfdrive/ui/update_translations.py | 4 +- 6 files changed, 1254 insertions(+), 25 deletions(-) create mode 100644 selfdrive/ui/translations/main_zh.qm create mode 100644 selfdrive/ui/translations/main_zh.ts diff --git a/selfdrive/ui/qt/sidebar.h b/selfdrive/ui/qt/sidebar.h index 98ae6564d6..4c6d8f47e5 100644 --- a/selfdrive/ui/qt/sidebar.h +++ b/selfdrive/ui/qt/sidebar.h @@ -34,13 +34,13 @@ protected: QPixmap home_img, settings_img; const QMap network_type = { - {cereal::DeviceState::NetworkType::NONE, "--"}, - {cereal::DeviceState::NetworkType::WIFI, "Wi-Fi"}, - {cereal::DeviceState::NetworkType::ETHERNET, "ETH"}, - {cereal::DeviceState::NetworkType::CELL2_G, "2G"}, - {cereal::DeviceState::NetworkType::CELL3_G, "3G"}, - {cereal::DeviceState::NetworkType::CELL4_G, "LTE"}, - {cereal::DeviceState::NetworkType::CELL5_G, "5G"} + {cereal::DeviceState::NetworkType::NONE, tr("--")}, + {cereal::DeviceState::NetworkType::WIFI, tr("Wi-Fi")}, + {cereal::DeviceState::NetworkType::ETHERNET, tr("ETH")}, + {cereal::DeviceState::NetworkType::CELL2_G, tr("2G")}, + {cereal::DeviceState::NetworkType::CELL3_G, tr("3G")}, + {cereal::DeviceState::NetworkType::CELL4_G, tr("LTE")}, + {cereal::DeviceState::NetworkType::CELL5_G, tr("5G")} }; const QRect settings_btn = QRect(50, 35, 200, 117); diff --git a/selfdrive/ui/tests/test_translations.py b/selfdrive/ui/tests/test_translations.py index ccea748e24..2dedf3d785 100755 --- a/selfdrive/ui/tests/test_translations.py +++ b/selfdrive/ui/tests/test_translations.py @@ -1,10 +1,13 @@ #!/usr/bin/env python3 import json import os +import shutil import unittest from selfdrive.ui.update_translations import TRANSLATIONS_DIR, LANGUAGES_FILE, update_translations +TMP_TRANSLATIONS_DIR = os.path.join(TRANSLATIONS_DIR, "tmp") + class TestTranslations(unittest.TestCase): @classmethod @@ -12,11 +15,25 @@ class TestTranslations(unittest.TestCase): with open(LANGUAGES_FILE, "r") as f: cls.translation_files = json.load(f) + # Set up temp directory + shutil.copytree(TRANSLATIONS_DIR, TMP_TRANSLATIONS_DIR, dirs_exist_ok=True) + + @classmethod + def tearDownClass(cls): + shutil.rmtree(TMP_TRANSLATIONS_DIR, ignore_errors=True) + + @staticmethod + def _read_translation_file(path, file, file_ext): + tr_file = os.path.join(path, f"{file}.{file_ext}") + with open(tr_file, "rb") as f: + # fix relative path depth + return f.read().replace(b"filename=\"../../", b"filename=\"../") + def test_missing_translation_files(self): for name, file in self.translation_files.items(): with self.subTest(name=name, file=file): if not len(file): - self.skipTest(f"{name} translation has no file") + self.skipTest(f"{name} translation has no defined file") self.assertTrue(os.path.exists(os.path.join(TRANSLATIONS_DIR, f"{file}.ts")), f"{name} has no XML translation file, run selfdrive/ui/update_translations.py") @@ -24,26 +41,25 @@ class TestTranslations(unittest.TestCase): f"{name} has no compiled QM translation file, run selfdrive/ui/update_translations.py --release") def test_translations_updated(self): - suffix = "_test" - update_translations(suffix=suffix) + update_translations(release=True, translations_dir=TMP_TRANSLATIONS_DIR) for name, file in self.translation_files.items(): with self.subTest(name=name, file=file): - cur_tr_file = os.path.join(TRANSLATIONS_DIR, f"{file}.ts") - new_tr_file = os.path.join(TRANSLATIONS_DIR, f"{file}{suffix}.ts") - if not len(file): - self.skipTest(f"{name} translation has no file") - elif not os.path.exists(cur_tr_file): - self.skipTest(f"{name} missing translation file") # caught by test_missing_translation_files + self.skipTest(f"{name} translation has no defined file") + + for file_ext in ["ts", "qm"]: + with self.subTest(file_ext=file_ext): + + # caught by test_missing_translation_files + if not os.path.exists(os.path.join(TRANSLATIONS_DIR, f"{file}.{file_ext}")): + self.skipTest(f"{name} missing translation file") - with open(cur_tr_file, "r") as f: - cur_translations = f.read() - with open(new_tr_file, "r") as f: - new_translations = f.read() + cur_translations = self._read_translation_file(TRANSLATIONS_DIR, file, file_ext) + new_translations = self._read_translation_file(TMP_TRANSLATIONS_DIR, file, file_ext) - self.assertEqual(cur_translations, new_translations, - f"{name} translation file out of date. Run selfdrive/ui/update_translations.py to update the translation files") + self.assertEqual(cur_translations, new_translations, + f"{file} ({name}) {file_ext.upper()} translation file out of date. Run selfdrive/ui/update_translations.py --release to update the translation files") if __name__ == "__main__": diff --git a/selfdrive/ui/translations/languages.json b/selfdrive/ui/translations/languages.json index f2f9400d64..e62de24a1e 100644 --- a/selfdrive/ui/translations/languages.json +++ b/selfdrive/ui/translations/languages.json @@ -1,3 +1,4 @@ { - "English": "" + "English": "", + "中文(简体)": "main_zh" } diff --git a/selfdrive/ui/translations/main_zh.qm b/selfdrive/ui/translations/main_zh.qm new file mode 100644 index 0000000000000000000000000000000000000000..627f6afc204dba0b2c2a87f13cad266e9edcbd4f GIT binary patch literal 17617 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 ZKPoWEh4C}~ZXVfh^r2{cIZ?p!{{qG<2A}`{ literal 0 HcmV?d00001 diff --git a/selfdrive/ui/translations/main_zh.ts b/selfdrive/ui/translations/main_zh.ts new file mode 100644 index 0000000000..7bcee2c23a --- /dev/null +++ b/selfdrive/ui/translations/main_zh.ts @@ -0,0 +1,1212 @@ + + + + + AbstractAlert + + + Close + + + + + Snooze Update + 暂停更新 + + + + Reboot and Update + 重启和更新 + + + + AdvancedNetworking + + + Back + 后退 + + + + Enable Tethering + 启用网络共享 + + + + Tethering Password + 网络共享密码 + + + + + EDIT + 编辑 + + + + Enter new tethering password + 输入新的网络共享密码 + + + + IP Address + IP地址 + + + + Enable Roaming + 启用漫游 + + + + APN Setting + APN 设置 + + + + Enter APN + 输入 APN + + + + leave blank for automatic configuration + 为自动配置留空 + + + + ConfirmationDialog + + + + Ok + 好的 + + + + Cancel + 取消 + + + + DeclinePage + + + You must accept the Terms and Conditions in order to use openpilot. + 您必须接受条款和条件才能使用 openpilot。 + + + + Back + 后退 + + + + Decline, uninstall %1 + 拒绝,卸载 %1 + + + + DevicePanel + + + Dongle ID + 加密狗 ID + + + + N/A + 不适用 + + + + Serial + 串行 + + + + Driver Camera + 司机摄像头 + + + + PREVIEW + 预习 + + + + Preview the driver facing camera to help optimize device mounting position for best driver monitoring experience. (vehicle must be off) + 预览面向驾驶员的摄像头,以帮助优化设备安装位置以获得最佳驾驶员监控体验。 (车辆必须关闭) + + + + Reset Calibration + 重置校准 + + + + RESET + 重置 + + + + Are you sure you want to reset calibration? + 您确定要重置校准吗? + + + + Review Training Guide + 查看培训指南 + + + + REVIEW + 审查 + + + + Review the rules, features, and limitations of openpilot + 查看 openpilot 的规则、功能和限制 + + + + Are you sure you want to review the training guide? + 您确定要查看培训指南吗? + + + + Regulatory + 监管 + + + + VIEW + 看法 + + + Change Language + 改变语言 + + + CHANGE + 改变 + + + Select a language + 选择语言 + + + + Reboot + 重启 + + + + Power Off + 关机 + + + + openpilot requires the device to be mounted within 4° left or right and within 5° up or 8° down. openpilot is continuously calibrating, resetting is rarely required. + openpilot 要求设备安装在左或右 4° 以内,上 5° 或下 8° 以内。 openpilot 会持续校准,很少需要重置。 + + + + Your device is pointed %1° %2 and %3° %4. + 您的设备指向 %1° %2 和 %3° %4。 + + + + down + + + + + up + 向上 + + + + left + 剩下 + + + + right + 向右 + + + + Are you sure you want to reboot? + 您确定要重新启动吗? + + + + Disengage to Reboot + 脱离以重新启动 + + + + Are you sure you want to power off? + 您确定要关闭电源吗? + + + + Disengage to Power Off + 脱离以关闭电源 + + + + DriveStats + + + Drives + 驱动器 + + + + Hours + 小时 + + + + ALL TIME + 整天 + + + + PAST WEEK + 上周 + + + + KM + 千米 + + + + Miles + 迈尔斯 + + + + DriverViewScene + + + camera starting + 相机启动 + + + + InputDialog + + + Cancel + 取消 + + + + Need at least + 需要至少 + + + + characters! + 字符! + + + + Installer + + + Installing... + 安装... + + + + Receiving objects: + 接收物体: + + + + Resolving deltas: + 解决增量: + + + + Updating files: + 更新文件: + + + + MapPanel + + + Current Destination + 当前目的地 + + + + CLEAR + CLEAR + + + + Recent Destinations + 近期目的地 + + + + Try the Navigation Beta + 试用导航测试版 + + + + Get turn-by-turn directions displayed and more with a comma +prime subscription. Sign up now: https://connect.comma.ai + 使用逗号获取显示的详细路线和更多信息 +主要订阅。 立即注册:https://connect.comma.ai + + + + No home +location set + 没有家 +位置集 + + + + No work +location set + 没有工作 +位置集 + + + + no recent destinations + 没有最近的目的地 + + + + MultiOptionDialog + + Select + 选择 + + + Cancel + 取消 + + + + Networking + + + Advanced + 先进的 + + + + Enter password + 先进的 + + + + + for " + 为了 " + + + + Wrong password + Wrong password + + + + NvgWindow + + + km/h + 公里/小时 + + + + mph + 英里/小时 + + + + + MAX + 最大限度 + + + + + SPEED + 速度 + + + + + LIMIT + 限制 + + + + OffroadHome + + + UPDATE + 更新 + + + + ALERTS + 个警报 + + + + ALERT + 个警报 + + + + PairingPopup + + + Pair your device to your comma account + 将您的设备与您的逗号账户配对 + + + + + <ol type='1' style='margin-left: 15px;'> + <li style='margin-bottom: 50px;'>Go to https://connect.comma.ai on your phone</li> + <li style='margin-bottom: 50px;'>Click "add new device" and scan the QR code on the right</li> + <li style='margin-bottom: 50px;'>Bookmark connect.comma.ai to your home screen to use it like an app</li> + </ol> + + + <ol type='1' style='margin-left: 15px;'> + <li style='margin-bottom: 50px;'>在手机上访问 https://connect.comma.ai</li> + <li style='margin-bottom: 50px;'>点击“添加新设备”,扫描右侧二维码</li> + <li style='margin-bottom: 50px;'>将 connect.comma.ai 收藏到您的主屏幕,以便像应用程序一样使用它</li> + </ol> + + + + + PrimeAdWidget + + + Upgrade Now + 现在升级 + + + + Become a comma prime member at connect.comma.ai + 成为 connect.comma.ai 的逗号主要会员 + + + + PRIME FEATURES: + 主要特点: + + + + Remote access + 远程访问 + + + + 1 year of storage + 1年存储 + + + + Developer perks + 开发者福利 + + + + PrimeUserWidget + + + ✓ SUBSCRIBED + ✓ 订阅 + + + + comma prime + 逗号素数 + + + + CONNECT.COMMA.AI + CONNECT.COMMA.AI + + + + COMMA POINTS + 逗号分 + + + + QObject + + + Reboot + 重启 + + + + Exit + 出口 + + + + dashcam + 行车记录器 + + + + openpilot + 开放式飞行员 + + + + %1 minute%2 ago + %1 分钟%2 前 + + + + %1 hour%2 ago + %1 小时%2 前 + + + + %1 day%2 ago + %1 天%2 前 + + + + Reset + + + Reset failed. Reboot to try again. + 重置失败。 重新启动以重试。 + + + + Are you sure you want to reset your device? + 您确定要重置您的设备吗? + + + + Resetting device... + 正在重置设备... + + + + System Reset + 系统重置 + + + + System reset triggered. Press confirm to erase all content and settings. Press cancel to resume boot. + 触发系统重置。 按确认删除所有内容和设置。 按取消恢复启动。 + + + + Cancel + 取消 + + + + Reboot + 重启 + + + + Confirm + 确认 + + + + Unable to mount data partition. Press confirm to reset your device. + 无法挂载数据分区。 按确认重置您的设备。 + + + + RichTextDialog + + + Ok + 好的 + + + + SettingsWindow + + + × + × + + + + Device + 设备 + + + + + Network + 网络 + + + + Toggles + 切换 + + + + Software + 软件 + + + + Navigation + 导航 + + + + Setup + + + WARNING: Low Voltage + 警告:低电压 + + + + Power your device in a car with a harness or proceed at your own risk. + 使用安全带在汽车中为您的设备供电或自行承担风险。 + + + + Power off + 关机 + + + + + + Continue + 继续 + + + + Getting Started + 入门 + + + + Before we get on the road, let’s finish installation and cover some details. + 在我们上路之前,让我们完成安装并介绍一些细节。 + + + + Connect to Wi-Fi + 连接到无线网络 + + + + + Back + 后退 + + + + Continue without Wi-Fi + 在没有 Wi-Fi 的情况下继续 + + + + Waiting for internet + 等待上网 + + + + Choose Software to Install + 选择要安装的软件 + + + + Dashcam + 行车记录器 + + + + Custom Software + 定制的软件 + + + + Enter URL + 输入网址 + + + + for Custom Software + 定制软件 + + + + Downloading... + 正在下载... + + + + Download Failed + 下载失败 + + + + Ensure the entered URL is valid, and the device’s internet connection is good. + 确保输入的 URL 有效,并且设备的互联网连接良好。 + + + + Reboot device + 重启设备 + + + + Start over + 重来 + + + + SetupWidget + + + Finish Setup + 完成设置 + + + + Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer. + 将您的设备与 comma connect (connect.comma.ai) 配对并领取您的 comma prime 优惠。 + + + + Pair device + 配对设备 + + + + Sidebar + + + + CONNECT + 连接 + + + + OFFLINE + 离线 + + + + + ONLINE + 在线的 + + + + ERROR + 错误 + + + + + + TEMP + 温度 + + + + HIGH + 高的 + + + + GOOD + 好的 + + + + OK + 好的 + + + + VEHICLE + 车辆 + + + + NO + + + + + PANDA + 熊猫 + + + + GPS + GPS + + + + SEARCH + 搜索 + + + + -- + -- + + + + Wi-Fi + Wi-Fi + + + + ETH + 以太網 + + + + 2G + 2G + + + + 3G + 3G + + + + LTE + LTE + + + + 5G + 5G + + + + SoftwarePanel + + + Git Branch + Git 分支 + + + + Git Commit + Git 提交 + + + + OS Version + 操作系统版本 + + + + Version + 版本 + + + + Last Update Check + 最后更新检查 + + + + The last time openpilot successfully checked for an update. The updater only runs while the car is off. + 上次 openpilot 成功检查更新的时间。 更新程序仅在汽车关闭时运行。 + + + + Check for Update + 检查更新 + + + + CHECKING + 正在检查 + + + + Uninstall + 卸载 + + + + UNINSTALL + 卸载 + + + + Are you sure you want to uninstall? + 您确定要卸载吗? + + + + failed to fetch update + 未能获取更新 + + + + + CHECK + 查看 + + + + SshControl + + + SSH Keys + SSH 密钥 + + + + Warning: This grants SSH access to all public keys in your GitHub settings. Never enter a GitHub username other than your own. A comma employee will NEVER ask you to add their GitHub username. + 警告:这将授予对 GitHub 设置中所有公钥的 SSH 访问权限。 切勿输入您自己以外的 GitHub 用户名。 逗号员工永远不会要求您添加他们的 GitHub 用户名。 + + + + + ADD + 添加 + + + + Enter your GitHub username + 输入你的 GitHub 用户名 + + + + LOADING + 正在加载 + + + + REMOVE + 消除 + + + + Username '%1' has no keys on GitHub + 用户名“%1”在 GitHub 上没有密钥 + + + + Request timed out + 请求超时 + + + + Username '%1' doesn't exist on GitHub + GitHub 上不存在用户名“%1” + + + + SshToggle + + + Enable SSH + 启用 SSH + + + + TermsPage + + + Terms & Conditions + 条款和条件 + + + + Decline + 衰退 + + + + Scroll to accept + 滚动接受 + + + + Agree + 同意 + + + + TogglesPanel + + + Enable openpilot + 启用 openpilot + + + + Use the openpilot system for adaptive cruise control and lane keep driver assistance. Your attention is required at all times to use this feature. Changing this setting takes effect when the car is powered off. + 使用 openpilot 系统进行自适应巡航控制和车道保持驾驶员辅助。 任何时候都需要您注意使用此功能。 更改此设置在汽车断电时生效。 + + + + Enable Lane Departure Warnings + 启用车道偏离警告 + + + + Receive alerts to steer back into the lane when your vehicle drifts over a detected lane line without a turn signal activated while driving over 31 mph (50 km/h). + 当您的车辆在以超过 31 英里/小时(50 公里/小时)的速度行驶时在检测到的车道线上漂移而没有激活转向信号时,接收提醒以返回车道。 + + + + Enable Right-Hand Drive + 启用右手驱动 + + + + Allow openpilot to obey left-hand traffic conventions and perform driver monitoring on right driver seat. + 允许 openpilot 遵守左侧交通惯例并在右侧驾驶座上执行驾驶员监控。 + + + + Use Metric System + 使用公制 + + + + Display speed in km/h instead of mph. + 以公里/小时而不是英里/小时显示速度。 + + + + Record and Upload Driver Camera + 记录和上传司机摄像头 + + + + Upload data from the driver facing camera and help improve the driver monitoring algorithm. + 从面向驾驶员的摄像头上传数据,帮助改进驾驶员监控算法。 + + + + Disengage On Accelerator Pedal + 松开加速踏板 + + + + When enabled, pressing the accelerator pedal will disengage openpilot. + 启用后,踩下油门踏板将解除 openpilot。 + + + + Show ETA in 24h format + 以 24 小时格式显示 ETA + + + + Use 24h format instead of am/pm + 使用 24 小时制代替上午/下午 + + + + openpilot Longitudinal Control + openpilot 纵向控制 + + + + openpilot will disable the car's radar and will take over control of gas and brakes. Warning: this disables AEB! + openpilot 将禁用汽车的雷达并接管油门和刹车的控制。 警告:这会禁用 AEB! + + + + Updater + + + Update Required + 需要更新 + + + + An operating system update is required. Connect your device to Wi-Fi for the fastest update experience. The download size is approximately 1GB. + 需要操作系统更新。 将您的设备连接到 Wi-Fi,以获得最快的更新体验。 下载大小约为 1GB。 + + + + Connect to Wi-Fi + 连接到无线网络 + + + + Install + 安装 + + + + Back + 后退 + + + + Loading... + 正在加载... + + + + Reboot + 重启 + + + + Update failed + 更新失败 + + + + WifiUI + + + + Scanning for networks... + 正在扫描网络... + + + + CONNECTING... + 正在连接... + + + + FORGET + 忘记 + + + + Forget Wi-Fi Network " + 忘记 Wi-Fi 网络" + + + diff --git a/selfdrive/ui/update_translations.py b/selfdrive/ui/update_translations.py index 5d57fa39d2..263eb5e670 100755 --- a/selfdrive/ui/update_translations.py +++ b/selfdrive/ui/update_translations.py @@ -10,7 +10,7 @@ TRANSLATIONS_DIR = os.path.join(UI_DIR, "translations") LANGUAGES_FILE = os.path.join(TRANSLATIONS_DIR, "languages.json") -def update_translations(release=False, suffix=""): +def update_translations(release=False, translations_dir=TRANSLATIONS_DIR): with open(LANGUAGES_FILE, "r") as f: translation_files = json.load(f) @@ -19,7 +19,7 @@ def update_translations(release=False, suffix=""): print(f"{name} has no translation file, skipping...") continue - tr_file = os.path.join(TRANSLATIONS_DIR, f"{file}{suffix}.ts") + tr_file = os.path.join(translations_dir, f"{file}.ts") ret = os.system(f"lupdate -recursive {UI_DIR} -ts {tr_file}") assert ret == 0 From b035b538ec5dc4ae837fe26ab900a34828525647 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Thu, 7 Jul 2022 14:54:14 -0700 Subject: [PATCH 037/112] chill ram tune (#25071) --- selfdrive/car/chrysler/interface.py | 5 ++++- selfdrive/test/process_replay/ref_commit | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/selfdrive/car/chrysler/interface.py b/selfdrive/car/chrysler/interface.py index 920000b271..697fb9b83a 100755 --- a/selfdrive/car/chrysler/interface.py +++ b/selfdrive/car/chrysler/interface.py @@ -51,7 +51,10 @@ class CarInterface(CarInterfaceBase): ret.mass = 2493. + STD_CARGO_KG ret.maxLateralAccel = 2.4 ret.minSteerSpeed = 14.5 - CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) + + ret.lateralTuning.pid.kpBP, ret.lateralTuning.pid.kiBP = [[0.], [0.]] + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.1], [0.02]] + ret.lateralTuning.pid.kf = 0.00003 else: raise ValueError(f"Unsupported car: {candidate}") diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index 0521fd8295..4908b86182 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -cf46781e405a01c96307d30d1266d46e0fa92255 \ No newline at end of file +bd2ea158977f5c26658bed8ac683b72c2c592d06 \ No newline at end of file From dc3d94d662654a6bb2bf40560c2a17ed2303fa80 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Fri, 8 Jul 2022 06:01:02 +0800 Subject: [PATCH 038/112] UI: fix unable to scroll on 'Regulatory' page (#25014) * fix unable to scroll on 'Regulatory' page deleteLater after hide * remove alert * override exec * set MousePressEventDelay to 0 * set to 0.01 * cleanup * check event->pos() --- selfdrive/ui/qt/widgets/controls.cc | 4 +++- selfdrive/ui/qt/widgets/controls.h | 6 +++++- selfdrive/ui/qt/widgets/scrollview.cc | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/selfdrive/ui/qt/widgets/controls.cc b/selfdrive/ui/qt/widgets/controls.cc index 89c95843fb..a86c05a3c4 100644 --- a/selfdrive/ui/qt/widgets/controls.cc +++ b/selfdrive/ui/qt/widgets/controls.cc @@ -125,7 +125,9 @@ void ElidedLabel::paintEvent(QPaintEvent *event) { ClickableWidget::ClickableWidget(QWidget *parent) : QWidget(parent) { } void ClickableWidget::mouseReleaseEvent(QMouseEvent *event) { - emit clicked(); + if (rect().contains(event->pos())) { + emit clicked(); + } } // Fix stylesheets diff --git a/selfdrive/ui/qt/widgets/controls.h b/selfdrive/ui/qt/widgets/controls.h index b6684e28b2..aed99edae8 100644 --- a/selfdrive/ui/qt/widgets/controls.h +++ b/selfdrive/ui/qt/widgets/controls.h @@ -24,7 +24,11 @@ signals: protected: void paintEvent(QPaintEvent *event) override; void resizeEvent(QResizeEvent* event) override; - void mouseReleaseEvent(QMouseEvent *event) override { emit clicked(); } + void mouseReleaseEvent(QMouseEvent *event) override { + if (rect().contains(event->pos())) { + emit clicked(); + } + } QString lastText_, elidedText_; }; diff --git a/selfdrive/ui/qt/widgets/scrollview.cc b/selfdrive/ui/qt/widgets/scrollview.cc index 1aa05b4157..bd4309d8d0 100644 --- a/selfdrive/ui/qt/widgets/scrollview.cc +++ b/selfdrive/ui/qt/widgets/scrollview.cc @@ -37,7 +37,7 @@ ScrollView::ScrollView(QWidget *w, QWidget *parent) : QScrollArea(parent) { sp.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOff)); sp.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOff)); - + sp.setScrollMetric(QScrollerProperties::MousePressEventDelay, 0.01); scroller->grabGesture(this->viewport(), QScroller::LeftMouseButtonGesture); scroller->setScrollerProperties(sp); } From ff3f6de149475ce995c21f8308da0bbc08922c54 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Thu, 7 Jul 2022 16:53:34 -0700 Subject: [PATCH 039/112] UI: fix reset calibration description --- selfdrive/ui/qt/widgets/controls.cc | 30 +++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/selfdrive/ui/qt/widgets/controls.cc b/selfdrive/ui/qt/widgets/controls.cc index a86c05a3c4..3264fd3aac 100644 --- a/selfdrive/ui/qt/widgets/controls.cc +++ b/selfdrive/ui/qt/widgets/controls.cc @@ -45,21 +45,23 @@ AbstractControl::AbstractControl(const QString &title, const QString &desc, cons main_layout->addLayout(hlayout); // description - if (!desc.isEmpty()) { - description = new QLabel(desc); - description->setContentsMargins(40, 20, 40, 20); - description->setStyleSheet("font-size: 40px; color: grey"); - description->setWordWrap(true); - description->setVisible(false); - main_layout->addWidget(description); - - connect(title_label, &QPushButton::clicked, [=]() { - if (!description->isVisible()) { - emit showDescription(); - } + description = new QLabel(desc); + description->setContentsMargins(40, 20, 40, 20); + description->setStyleSheet("font-size: 40px; color: grey"); + description->setWordWrap(true); + description->setVisible(false); + main_layout->addWidget(description); + + connect(title_label, &QPushButton::clicked, [=]() { + if (!description->isVisible()) { + emit showDescription(); + } + + if (!description->text().isEmpty()) { description->setVisible(!description->isVisible()); - }); - } + } + }); + main_layout->addStretch(); } From a4c90765813e1cc3ab7afbe58cf23b392ec8181c Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Thu, 7 Jul 2022 17:09:36 -0700 Subject: [PATCH 040/112] Hyundai: limit Kona torque (#25074) --- selfdrive/car/hyundai/values.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index f6efedb248..c55a0dc639 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -32,6 +32,12 @@ class CarControllerParams: CAR.IONIQ_EV_LTD, CAR.SANTA_FE_PHEV_2022, CAR.SONATA_LF, CAR.KIA_FORTE, CAR.KIA_NIRO_HEV, CAR.KIA_OPTIMA_H, CAR.KIA_SORENTO, CAR.KIA_STINGER): self.STEER_MAX = 255 + + # These cars have significantly more torque than most HKG. Limit to 70% of max. + elif CP.carFingerprint in (CAR.KONA, CAR.KONA_EV, CAR.KONA_HEV): + self.STEER_MAX = 270 + + # Default for most HKG else: self.STEER_MAX = 384 From bd432eb76bf4c2d99a0f66b3a1df0067adb81a1a Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Thu, 7 Jul 2022 17:27:59 -0700 Subject: [PATCH 041/112] move kona limit to car controller --- selfdrive/car/hyundai/carcontroller.py | 7 ++++++- selfdrive/car/hyundai/values.py | 4 ---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/selfdrive/car/hyundai/carcontroller.py b/selfdrive/car/hyundai/carcontroller.py index f3066bda03..73635375ad 100644 --- a/selfdrive/car/hyundai/carcontroller.py +++ b/selfdrive/car/hyundai/carcontroller.py @@ -52,7 +52,12 @@ class CarController: hud_control = CC.hudControl # Steering Torque - new_steer = int(round(actuators.steer * self.params.STEER_MAX)) + + # These cars have significantly more torque than most HKG. Limit to 70% of max. + steer = actuators.steer + if self.CP.carFingerprint in (CAR.KONA, CAR.KONA_EV, CAR.KONA_HEV): + steer = clip(steer, -0.7, 0.7) + new_steer = int(round(steer * self.params.STEER_MAX)) apply_steer = apply_std_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque, self.params) self.steer_rate_limited = new_steer != apply_steer diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index c55a0dc639..4b3acf3f27 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -33,10 +33,6 @@ class CarControllerParams: CAR.KIA_OPTIMA_H, CAR.KIA_SORENTO, CAR.KIA_STINGER): self.STEER_MAX = 255 - # These cars have significantly more torque than most HKG. Limit to 70% of max. - elif CP.carFingerprint in (CAR.KONA, CAR.KONA_EV, CAR.KONA_HEV): - self.STEER_MAX = 270 - # Default for most HKG else: self.STEER_MAX = 384 From 1382e28aa0b32923a44efa28c5b25d9b02c41d68 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Thu, 7 Jul 2022 20:02:07 -0700 Subject: [PATCH 042/112] add pandas and tabulate packages (#25076) * add pandas and tabulate packages * remove that --- Pipfile | 4 +- Pipfile.lock | 1226 ++++++++++++++++++---------------- selfdrive/debug/can_table.py | 2 +- 3 files changed, 647 insertions(+), 585 deletions(-) diff --git a/Pipfile b/Pipfile index b8545b1a21..81669e4807 100644 --- a/Pipfile +++ b/Pipfile @@ -41,6 +41,8 @@ tenacity = "*" mpld3 = "*" carla = {version = "==0.9.13", markers="platform_system != 'Darwin'"} ft4222 = "*" +pandas = "*" +tabulate = "*" [packages] atomicwrites = "*" @@ -86,8 +88,6 @@ urllib3 = "*" utm = "*" websocket_client = "*" hatanaka = "==2.4" -PyQt5 = "==5.15.4" -PyQt5-sip = "==12.9.0" [requires] python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock index cc347a60f4..0612d0ff39 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "d2629168f477b3a14f68f26e3b63ea9797b20599c066b2aa23a027bcee2ca40a" + "sha256": "c92514c0e6968af008916446514f41b4e004aa7aa4a2951cc1e9e258ac072111" }, "pipfile-spec": 6, "requires": { @@ -79,75 +79,89 @@ }, "certifi": { "hashes": [ - "sha256:9c5705e395cd70084351dd8ad5c41e65655e08ce46f2ec9cf6c2c08390f71eb7", - "sha256:f1d53542ee8cbedbe2118b5686372fb33c297fcd6379b050cca0ef13a597382a" + "sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d", + "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412" ], "markers": "python_version >= '3.6'", - "version": "==2022.5.18.1" + "version": "==2022.6.15" }, "cffi": { "hashes": [ - "sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3", - "sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2", - "sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636", - "sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20", - "sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728", - "sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27", - "sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66", - "sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443", - "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0", - "sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7", - "sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39", - "sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605", - "sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a", - "sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37", - "sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029", - "sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139", - "sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc", - "sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df", - "sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14", - "sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880", - "sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2", - "sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a", - "sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e", - "sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474", - "sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024", - "sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8", - "sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0", - "sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e", - "sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a", - "sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e", - "sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032", - "sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6", - "sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e", - "sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b", - "sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e", - "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954", - "sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962", - "sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c", - "sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4", - "sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55", - "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962", - "sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023", - "sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c", - "sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6", - "sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8", - "sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382", - "sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7", - "sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc", - "sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997", - "sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796" - ], - "index": "pypi", - "version": "==1.15.0" + "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5", + "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef", + "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104", + "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426", + "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405", + "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375", + "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a", + "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e", + "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc", + "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf", + "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185", + "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497", + "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3", + "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35", + "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c", + "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83", + "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21", + "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca", + "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984", + "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac", + "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd", + "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee", + "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a", + "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2", + "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192", + "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7", + "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585", + "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f", + "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e", + "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27", + "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b", + "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e", + "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e", + "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d", + "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c", + "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415", + "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82", + "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02", + "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314", + "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325", + "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c", + "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3", + "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914", + "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045", + "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d", + "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9", + "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5", + "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2", + "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c", + "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3", + "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2", + "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8", + "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d", + "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d", + "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9", + "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162", + "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76", + "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4", + "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e", + "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9", + "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6", + "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b", + "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01", + "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0" + ], + "index": "pypi", + "version": "==1.15.1" }, "charset-normalizer": { "hashes": [ - "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597", - "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df" + "sha256:5189b6f22b01957427f35b6a08d9a0bc45b46d3788ef5a92e978433c7a35f8a5", + "sha256:575e708016ff3a5e3681541cb9d79312c416835686d054a23accb873b254f413" ], - "markers": "python_full_version >= '3.5.0'", - "version": "==2.0.12" + "markers": "python_version >= '3.6'", + "version": "==2.1.0" }, "click": { "hashes": [ @@ -169,31 +183,31 @@ }, "cryptography": { "hashes": [ - "sha256:093cb351031656d3ee2f4fa1be579a8c69c754cf874206be1d4cf3b542042804", - "sha256:0cc20f655157d4cfc7bada909dc5cc228211b075ba8407c46467f63597c78178", - "sha256:1b9362d34363f2c71b7853f6251219298124aa4cc2075ae2932e64c91a3e2717", - "sha256:1f3bfbd611db5cb58ca82f3deb35e83af34bb8cf06043fa61500157d50a70982", - "sha256:2bd1096476aaac820426239ab534b636c77d71af66c547b9ddcd76eb9c79e004", - "sha256:31fe38d14d2e5f787e0aecef831457da6cec68e0bb09a35835b0b44ae8b988fe", - "sha256:3b8398b3d0efc420e777c40c16764d6870bcef2eb383df9c6dbb9ffe12c64452", - "sha256:3c81599befb4d4f3d7648ed3217e00d21a9341a9a688ecdd615ff72ffbed7336", - "sha256:419c57d7b63f5ec38b1199a9521d77d7d1754eb97827bbb773162073ccd8c8d4", - "sha256:46f4c544f6557a2fefa7ac8ac7d1b17bf9b647bd20b16decc8fbcab7117fbc15", - "sha256:471e0d70201c069f74c837983189949aa0d24bb2d751b57e26e3761f2f782b8d", - "sha256:59b281eab51e1b6b6afa525af2bd93c16d49358404f814fe2c2410058623928c", - "sha256:731c8abd27693323b348518ed0e0705713a36d79fdbd969ad968fbef0979a7e0", - "sha256:95e590dd70642eb2079d280420a888190aa040ad20f19ec8c6e097e38aa29e06", - "sha256:a68254dd88021f24a68b613d8c51d5c5e74d735878b9e32cc0adf19d1f10aaf9", - "sha256:a7d5137e556cc0ea418dca6186deabe9129cee318618eb1ffecbd35bee55ddc1", - "sha256:aeaba7b5e756ea52c8861c133c596afe93dd716cbcacae23b80bc238202dc023", - "sha256:dc26bb134452081859aa21d4990474ddb7e863aa39e60d1592800a8865a702de", - "sha256:e53258e69874a306fcecb88b7534d61820db8a98655662a3dd2ec7f1afd9132f", - "sha256:ef15c2df7656763b4ff20a9bc4381d8352e6640cfeb95c2972c38ef508e75181", - "sha256:f224ad253cc9cea7568f49077007d2263efa57396a2f2f78114066fd54b5c68e", - "sha256:f8ec91983e638a9bcd75b39f1396e5c0dc2330cbd9ce4accefe68717e6779e0a" - ], - "index": "pypi", - "version": "==37.0.2" + "sha256:190f82f3e87033821828f60787cfa42bff98404483577b591429ed99bed39d59", + "sha256:2be53f9f5505673eeda5f2736bea736c40f051a739bfae2f92d18aed1eb54596", + "sha256:30788e070800fec9bbcf9faa71ea6d8068f5136f60029759fd8c3efec3c9dcb3", + "sha256:3d41b965b3380f10e4611dbae366f6dc3cefc7c9ac4e8842a806b9672ae9add5", + "sha256:4c590ec31550a724ef893c50f9a97a0c14e9c851c85621c5650d699a7b88f7ab", + "sha256:549153378611c0cca1042f20fd9c5030d37a72f634c9326e225c9f666d472884", + "sha256:63f9c17c0e2474ccbebc9302ce2f07b55b3b3fcb211ded18a42d5764f5c10a82", + "sha256:6bc95ed67b6741b2607298f9ea4932ff157e570ef456ef7ff0ef4884a134cc4b", + "sha256:7099a8d55cd49b737ffc99c17de504f2257e3787e02abe6d1a6d136574873441", + "sha256:75976c217f10d48a8b5a8de3d70c454c249e4b91851f6838a4e48b8f41eb71aa", + "sha256:7bc997818309f56c0038a33b8da5c0bfbb3f1f067f315f9abd6fc07ad359398d", + "sha256:80f49023dd13ba35f7c34072fa17f604d2f19bf0989f292cedf7ab5770b87a0b", + "sha256:91ce48d35f4e3d3f1d83e29ef4a9267246e6a3be51864a5b7d2247d5086fa99a", + "sha256:a958c52505c8adf0d3822703078580d2c0456dd1d27fabfb6f76fe63d2971cd6", + "sha256:b62439d7cd1222f3da897e9a9fe53bbf5c104fff4d60893ad1355d4c14a24157", + "sha256:b7f8dd0d4c1f21759695c05a5ec8536c12f31611541f8904083f3dc582604280", + "sha256:d204833f3c8a33bbe11eda63a54b1aad7aa7456ed769a982f21ec599ba5fa282", + "sha256:e007f052ed10cc316df59bc90fbb7ff7950d7e2919c9757fd42a2b8ecf8a5f67", + "sha256:f2dcb0b3b63afb6df7fd94ec6fbddac81b5492513f7b0436210d390c14d46ee8", + "sha256:f721d1885ecae9078c3f6bbe8a88bc0786b6e749bf32ccec1ef2b18929a05046", + "sha256:f7a6de3e98771e183645181b3627e2563dcde3ce94a9e42a3f427d2255190327", + "sha256:f8c0a6e9e1dd3eb0414ba320f85da6b0dcbd543126e30fcc546e7372a7fbf3b9" + ], + "index": "pypi", + "version": "==37.0.4" }, "cython": { "hashes": [ @@ -347,31 +361,31 @@ "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff", "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d" ], - "markers": "python_full_version >= '3.5.0'", + "markers": "python_version >= '3.5'", "version": "==3.3" }, "importlib-metadata": { "hashes": [ - "sha256:5d26852efe48c0a32b0509ffbc583fda1a2266545a78d104a6f4aff3db17d700", - "sha256:c58c8eb8a762858f49e18436ff552e83914778e50e9d2f1660535ffb364552ec" + "sha256:637245b8bab2b6502fcbc752cc4b7a6f6243bb02b31c5c26156ad103d3d45670", + "sha256:7401a975809ea1fdc658c3aa4f78cc2195a0e019c5cbc4c06122884e9ae80c23" ], "markers": "python_version < '3.10'", - "version": "==4.11.4" + "version": "==4.12.0" }, "importlib-resources": { "hashes": [ - "sha256:b6062987dfc51f0fcb809187cffbd60f35df7acb4589091f154214af6d0d49d3", - "sha256:e447dc01619b1e951286f3929be820029d48c75eb25d265c28b92a16548212b8" + "sha256:568c9f16cb204f9decc8d6d24a572eeea27dacbb4cee9e6b03a8025736769751", + "sha256:7952325ffd516c05a8ad0858c74dff2c3343f136fe66a6002b2623dd1d43f223" ], "markers": "python_version >= '3.7'", - "version": "==5.7.1" + "version": "==5.8.0" }, "isort": { "hashes": [ "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7", "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951" ], - "markers": "python_version < '4.0' and python_full_version >= '3.6.1'", + "markers": "python_version < '4' and python_full_version >= '3.6.1'", "version": "==5.10.1" }, "itsdangerous": { @@ -563,62 +577,58 @@ }, "numpy": { "hashes": [ - "sha256:0791fbd1e43bf74b3502133207e378901272f3c156c4df4954cad833b1380207", - "sha256:1ce7ab2053e36c0a71e7a13a7475bd3b1f54750b4b433adc96313e127b870887", - "sha256:2d487e06ecbf1dc2f18e7efce82ded4f705f4bd0cd02677ffccfb39e5c284c7e", - "sha256:37431a77ceb9307c28382c9773da9f306435135fae6b80b62a11c53cfedd8802", - "sha256:3e1ffa4748168e1cc8d3cde93f006fe92b5421396221a02f2274aab6ac83b077", - "sha256:425b390e4619f58d8526b3dcf656dde069133ae5c240229821f01b5f44ea07af", - "sha256:43a8ca7391b626b4c4fe20aefe79fec683279e31e7c79716863b4b25021e0e74", - "sha256:4c6036521f11a731ce0648f10c18ae66d7143865f19f7299943c985cdc95afb5", - "sha256:59d55e634968b8f77d3fd674a3cf0b96e85147cd6556ec64ade018f27e9479e1", - "sha256:64f56fc53a2d18b1924abd15745e30d82a5782b2cab3429aceecc6875bd5add0", - "sha256:7228ad13744f63575b3a972d7ee4fd61815b2879998e70930d4ccf9ec721dce0", - "sha256:9ce7df0abeabe7fbd8ccbf343dc0db72f68549856b863ae3dd580255d009648e", - "sha256:a911e317e8c826ea632205e63ed8507e0dc877dcdc49744584dfc363df9ca08c", - "sha256:b89bf9b94b3d624e7bb480344e91f68c1c6c75f026ed6755955117de00917a7c", - "sha256:ba9ead61dfb5d971d77b6c131a9dbee62294a932bf6a356e48c75ae684e635b3", - "sha256:c1d937820db6e43bec43e8d016b9b3165dcb42892ea9f106c70fb13d430ffe72", - "sha256:cc7f00008eb7d3f2489fca6f334ec19ca63e31371be28fd5dad955b16ec285bd", - "sha256:d4c5d5eb2ec8da0b4f50c9a843393971f31f1d60be87e0fb0917a49133d257d6", - "sha256:e96d7f3096a36c8754207ab89d4b3282ba7b49ea140e4973591852c77d09eb76", - "sha256:f0725df166cf4785c0bc4cbfb320203182b1ecd30fee6e541c8752a92df6aa32", - "sha256:f3eb268dbd5cfaffd9448113539e44e2dd1c5ca9ce25576f7c04a5453edc26fa", - "sha256:fb7a980c81dd932381f8228a426df8aeb70d59bbcda2af075b627bbc50207cba" - ], - "index": "pypi", - "version": "==1.22.4" + "sha256:092f5e6025813e64ad6d1b52b519165d08c730d099c114a9247c9bb635a2a450", + "sha256:196cd074c3f97c4121601790955f915187736f9cf458d3ee1f1b46aff2b1ade0", + "sha256:1c29b44905af288b3919803aceb6ec7fec77406d8b08aaa2e8b9e63d0fe2f160", + "sha256:2b2da66582f3a69c8ce25ed7921dcd8010d05e59ac8d89d126a299be60421171", + "sha256:5043bcd71fcc458dfb8a0fc5509bbc979da0131b9d08e3d5f50fb0bbb36f169a", + "sha256:58bfd40eb478f54ff7a5710dd61c8097e169bc36cc68333d00a9bcd8def53b38", + "sha256:79a506cacf2be3a74ead5467aee97b81fca00c9c4c8b3ba16dbab488cd99ba10", + "sha256:94b170b4fa0168cd6be4becf37cb5b127bd12a795123984385b8cd4aca9857e5", + "sha256:97a76604d9b0e79f59baeca16593c711fddb44936e40310f78bfef79ee9a835f", + "sha256:98e8e0d8d69ff4d3fa63e6c61e8cfe2d03c29b16b58dbef1f9baa175bbed7860", + "sha256:ac86f407873b952679f5f9e6c0612687e51547af0e14ddea1eedfcb22466babd", + "sha256:ae8adff4172692ce56233db04b7ce5792186f179c415c37d539c25de7298d25d", + "sha256:bd3fa4fe2e38533d5336e1272fc4e765cabbbde144309ccee8675509d5cd7b05", + "sha256:d0d2094e8f4d760500394d77b383a1b06d3663e8892cdf5df3c592f55f3bff66", + "sha256:d54b3b828d618a19779a84c3ad952e96e2c2311b16384e973e671aa5be1f6187", + "sha256:d6ca8dabe696c2785d0c8c9b0d8a9b6e5fdbe4f922bde70d57fa1a2848134f95", + "sha256:d8cc87bed09de55477dba9da370c1679bd534df9baa171dd01accbb09687dac3", + "sha256:f0f18804df7370571fb65db9b98bf1378172bd4e962482b857e612d1fec0f53e", + "sha256:f1d88ef79e0a7fa631bb2c3dda1ea46b32b1fe614e10fedd611d3d5398447f2f", + "sha256:f9c3fc2adf67762c9fe1849c859942d23f8d3e0bee7b5ed3d4a9c3eeb50a2f07", + "sha256:fc431493df245f3c627c0c05c2bd134535e7929dbe2e602b80e42bf52ff760bc", + "sha256:fe8b9683eb26d2c4d5db32cd29b38fdcf8381324ab48313b5b69088e0e355379" + ], + "index": "pypi", + "version": "==1.23.0" }, "onnx": { "hashes": [ - "sha256:0cf47c205b376b3763beef92a6de4152f3b1552d6f640d93044938500baf5958", - "sha256:3403884c482859f8cf2e0c276da84bd9ac2235d266726f4ddc9625d3fd263218", - "sha256:43b32a2f20c94aa98866deae9e4218faf0495144ad05402e918fa279674b6df9", - "sha256:4454906de80a351de6929b0896ad605d106c324c3112c92249240e531f68fbba", - "sha256:4aa899f74acd4c5543f0efed8bfe98a3b701df75c5ffa179212e3088c51971bb", - "sha256:58d4873ec587ac14c44227d8027787edc88cd61596e646e3417f2a826a920898", - "sha256:593ca9e11f15afa26b3aaf2d170bb803d4bd86dbd560aa7be4e5f535d03f83d5", - "sha256:67c6d2654c1c203e5c839a47900b51f588fd0de71bbd497fb193d30a0b3ec1e9", - "sha256:7924d9baa13dbbf335737229f6d068f380d153679f357e495da60007b61cf56d", - "sha256:7a2f5d6998fe79aed80fad9d4522140d02c4d29513047e335d5c5355c1ebda5e", - "sha256:82221a07707b1ccf71fb18c6abb77f2566517a55d5185809775b5ff008bfb35c", - "sha256:89420e5b824d7e182846fe2aa09190ddb41162b261465c6ca928174bc2ac10b7", - "sha256:997d91ffd7b7ae7aee09c6d652a896d906be430d425865c759b51a8de5df9fe0", - "sha256:9b9f58ea01c1b20b057f55f628df4fc0403bbc160b7282a56e3bb4df5c7fb96f", - "sha256:a6e9135f1d02539ca7573f699fb0d31d3c43d10fac1d2d2239a9a1c553506c29", - "sha256:ae74bf8fa343b64e2b7fe205091b7f3728887c018ae061d161dd86ec95eb66a8", - "sha256:b2de0b117ad77689d308824a0c9eb89539ec28a799b4e2e05b3bb977b0da0b45", - "sha256:c3d3503110f2cab2c818f4a7b2bc8abc3bc79649daa39e70d5fb504b208ddb1e", - "sha256:d6581dd2122525549d1d8b431b8bf375298993c77bddb8fd0bf0d92611df76a1", - "sha256:d6ddbe89e32f885db736d36fcb132784e368331a18c3b6168ac9f561eb462057", - "sha256:df85666ab2b88fd9cf9b2504bcb551da39422eab65a143926a8db58f81b09164", - "sha256:ea06dbf57a287657b6dc4e189918e4cb451450308589d482117216194d6f83d6", - "sha256:eb46f31f12bb0bfdcfb68497d10b20447cf8fa6c4f693120c013e052645357b8", - "sha256:eca224c7c2c8ee4072a0743e4898a84a9bdf8297b5e5910a2632e4c4182ffb2a", - "sha256:f335d982b8ed201cf767459b993630acfd20c32b100529f70af9f28a26e72167" - ], - "index": "pypi", - "version": "==1.11.0" + "sha256:13b3e77d27523b9dbf4f30dfc9c959455859d5e34e921c44f712d69b8369eff9", + "sha256:213e73610173f6b2e99f99a4b0636f80b379c417312079d603806e48ada4ca8b", + "sha256:23781594bb8b7ee985de1005b3c601648d5b0568a81e01365c48f91d1f5648e4", + "sha256:2d9a7db54e75529160337232282a4816cc50667dc7dc34be178fd6f6b79d4705", + "sha256:341c7016e23273e9ffa9b6e301eee95b8c37d0f04df7cedbdb169d2c39524c96", + "sha256:3c6e6bcffc3f5c1e148df3837dc667fa4c51999788c1b76b0b8fbba607e02da8", + "sha256:5578b93dc6c918cec4dee7fb7d9dd3b09d338301ee64ca8b4f28bc217ed42dca", + "sha256:56ceb7e094c43882b723cfaa107d85ad673cfdf91faeb28d7dcadacca4f43a07", + "sha256:81a3555fd67be2518bf86096299b48fb9154652596219890abfe90bd43a9ec13", + "sha256:8a7aa61aea339bd28f310f4af4f52ce6c4b876386228760b16308efd58f95059", + "sha256:9fd2f4e23078df197bb76a59b9cd8f5a43a6ad2edc035edb3ecfb9042093e05a", + "sha256:af90427ca04c6b7b8107c2021e1273227a3ef1a7a01f3073039cae7855a59833", + "sha256:b3629e8258db15d4e2c9b7f1be91a3186719dd94661c218c6f5fde3cc7de3d4d", + "sha256:bdbd2578424c70836f4d0f9dda16c21868ddb07cc8192f9e8a176908b43d694b", + "sha256:c11162ffc487167da140f1112f49c4f82d815824f06e58bc3095407699f05863", + "sha256:c39a7a0352c856f1df30dccf527eb6cb4909052e5eaf6fa2772a637324c526aa", + "sha256:c7a9b3ea02c30efc1d2662337e280266aca491a8e86be0d8a657f874b7cccd1e", + "sha256:f66d2996e65f490a57b3ae952e4e9189b53cc9fe3f75e601d50d4db2dc1b1cd9", + "sha256:f8800f28c746ab06e51ef8449fd1215621f4ddba91be3ffc264658937d38a2af", + "sha256:fab13feb4d94342aae6d357d480f2e47d41b9f4e584367542b21ca6defda9e0a", + "sha256:fea5156a03398fe0e23248042d8651c1eaac5f6637d4dd683b4c1f1320b9f7b4" + ], + "index": "pypi", + "version": "==1.12.0" }, "onnxruntime-gpu": { "hashes": [ @@ -635,47 +645,67 @@ }, "pillow": { "hashes": [ - "sha256:088df396b047477dd1bbc7de6e22f58400dae2f21310d9e2ec2933b2ef7dfa4f", - "sha256:09e67ef6e430f90caa093528bd758b0616f8165e57ed8d8ce014ae32df6a831d", - "sha256:0b4d5ad2cd3a1f0d1df882d926b37dbb2ab6c823ae21d041b46910c8f8cd844b", - "sha256:0b525a356680022b0af53385944026d3486fc8c013638cf9900eb87c866afb4c", - "sha256:1d4331aeb12f6b3791911a6da82de72257a99ad99726ed6b63f481c0184b6fb9", - "sha256:20d514c989fa28e73a5adbddd7a171afa5824710d0ab06d4e1234195d2a2e546", - "sha256:2b291cab8a888658d72b575a03e340509b6b050b62db1f5539dd5cd18fd50578", - "sha256:3f6c1716c473ebd1649663bf3b42702d0d53e27af8b64642be0dd3598c761fb1", - "sha256:42dfefbef90eb67c10c45a73a9bc1599d4dac920f7dfcbf4ec6b80cb620757fe", - "sha256:488f3383cf5159907d48d32957ac6f9ea85ccdcc296c14eca1a4e396ecc32098", - "sha256:4d45dbe4b21a9679c3e8b3f7f4f42a45a7d3ddff8a4a16109dff0e1da30a35b2", - "sha256:53c27bd452e0f1bc4bfed07ceb235663a1df7c74df08e37fd6b03eb89454946a", - "sha256:55e74faf8359ddda43fee01bffbc5bd99d96ea508d8a08c527099e84eb708f45", - "sha256:59789a7d06c742e9d13b883d5e3569188c16acb02eeed2510fd3bfdbc1bd1530", - "sha256:5b650dbbc0969a4e226d98a0b440c2f07a850896aed9266b6fedc0f7e7834108", - "sha256:66daa16952d5bf0c9d5389c5e9df562922a59bd16d77e2a276e575d32e38afd1", - "sha256:6e760cf01259a1c0a50f3c845f9cad1af30577fd8b670339b1659c6d0e7a41dd", - "sha256:7502539939b53d7565f3d11d87c78e7ec900d3c72945d4ee0e2f250d598309a0", - "sha256:769a7f131a2f43752455cc72f9f7a093c3ff3856bf976c5fb53a59d0ccc704f6", - "sha256:7c150dbbb4a94ea4825d1e5f2c5501af7141ea95825fadd7829f9b11c97aaf6c", - "sha256:8844217cdf66eabe39567118f229e275f0727e9195635a15e0e4b9227458daaf", - "sha256:8a66fe50386162df2da701b3722781cbe90ce043e7d53c1fd6bd801bca6b48d4", - "sha256:9370d6744d379f2de5d7fa95cdbd3a4d92f0b0ef29609b4b1687f16bc197063d", - "sha256:937a54e5694684f74dcbf6e24cc453bfc5b33940216ddd8f4cd8f0f79167f765", - "sha256:9c857532c719fb30fafabd2371ce9b7031812ff3889d75273827633bca0c4602", - "sha256:a4165205a13b16a29e1ac57efeee6be2dfd5b5408122d59ef2145bc3239fa340", - "sha256:b3fe2ff1e1715d4475d7e2c3e8dabd7c025f4410f79513b4ff2de3d51ce0fa9c", - "sha256:b6617221ff08fbd3b7a811950b5c3f9367f6e941b86259843eab77c8e3d2b56b", - "sha256:b761727ed7d593e49671d1827044b942dd2f4caae6e51bab144d4accf8244a84", - "sha256:baf3be0b9446a4083cc0c5bb9f9c964034be5374b5bc09757be89f5d2fa247b8", - "sha256:c17770a62a71718a74b7548098a74cd6880be16bcfff5f937f900ead90ca8e92", - "sha256:c67db410508b9de9c4694c57ed754b65a460e4812126e87f5052ecf23a011a54", - "sha256:d78ca526a559fb84faaaf84da2dd4addef5edb109db8b81677c0bb1aad342601", - "sha256:e9ed59d1b6ee837f4515b9584f3d26cf0388b742a11ecdae0d9237a94505d03a", - "sha256:f054b020c4d7e9786ae0404278ea318768eb123403b18453e28e47cdb7a0a4bf", - "sha256:f372d0f08eff1475ef426344efe42493f71f377ec52237bf153c5713de987251", - "sha256:f3f6a6034140e9e17e9abc175fc7a266a6e63652028e157750bd98e804a8ed9a", - "sha256:ffde4c6fabb52891d81606411cbfaf77756e3b561b566efd270b3ed3791fde4e" - ], - "index": "pypi", - "version": "==9.1.1" + "sha256:0030fdbd926fb85844b8b92e2f9449ba89607231d3dd597a21ae72dc7fe26927", + "sha256:030e3460861488e249731c3e7ab59b07c7853838ff3b8e16aac9561bb345da14", + "sha256:0ed2c4ef2451de908c90436d6e8092e13a43992f1860275b4d8082667fbb2ffc", + "sha256:136659638f61a251e8ed3b331fc6ccd124590eeff539de57c5f80ef3a9594e58", + "sha256:13b725463f32df1bfeacbf3dd197fb358ae8ebcd8c5548faa75126ea425ccb60", + "sha256:1536ad017a9f789430fb6b8be8bf99d2f214c76502becc196c6f2d9a75b01b76", + "sha256:15928f824870535c85dbf949c09d6ae7d3d6ac2d6efec80f3227f73eefba741c", + "sha256:17d4cafe22f050b46d983b71c707162d63d796a1235cdf8b9d7a112e97b15bac", + "sha256:1802f34298f5ba11d55e5bb09c31997dc0c6aed919658dfdf0198a2fe75d5490", + "sha256:1cc1d2451e8a3b4bfdb9caf745b58e6c7a77d2e469159b0d527a4554d73694d1", + "sha256:1fd6f5e3c0e4697fa7eb45b6e93996299f3feee73a3175fa451f49a74d092b9f", + "sha256:254164c57bab4b459f14c64e93df11eff5ded575192c294a0c49270f22c5d93d", + "sha256:2ad0d4df0f5ef2247e27fc790d5c9b5a0af8ade9ba340db4a73bb1a4a3e5fb4f", + "sha256:2c58b24e3a63efd22554c676d81b0e57f80e0a7d3a5874a7e14ce90ec40d3069", + "sha256:2d33a11f601213dcd5718109c09a52c2a1c893e7461f0be2d6febc2879ec2402", + "sha256:337a74fd2f291c607d220c793a8135273c4c2ab001b03e601c36766005f36885", + "sha256:37ff6b522a26d0538b753f0b4e8e164fdada12db6c6f00f62145d732d8a3152e", + "sha256:3d1f14f5f691f55e1b47f824ca4fdcb4b19b4323fe43cc7bb105988cad7496be", + "sha256:408673ed75594933714482501fe97e055a42996087eeca7e5d06e33218d05aa8", + "sha256:4134d3f1ba5f15027ff5c04296f13328fecd46921424084516bdb1b2548e66ff", + "sha256:4ad2f835e0ad81d1689f1b7e3fbac7b01bb8777d5a985c8962bedee0cc6d43da", + "sha256:50dff9cc21826d2977ef2d2a205504034e3a4563ca6f5db739b0d1026658e004", + "sha256:510cef4a3f401c246cfd8227b300828715dd055463cdca6176c2e4036df8bd4f", + "sha256:5aed7dde98403cd91d86a1115c78d8145c83078e864c1de1064f52e6feb61b20", + "sha256:69bd1a15d7ba3694631e00df8de65a8cb031911ca11f44929c97fe05eb9b6c1d", + "sha256:6bf088c1ce160f50ea40764f825ec9b72ed9da25346216b91361eef8ad1b8f8c", + "sha256:6e8c66f70fb539301e064f6478d7453e820d8a2c631da948a23384865cd95544", + "sha256:727dd1389bc5cb9827cbd1f9d40d2c2a1a0c9b32dd2261db522d22a604a6eec9", + "sha256:74a04183e6e64930b667d321524e3c5361094bb4af9083db5c301db64cd341f3", + "sha256:75e636fd3e0fb872693f23ccb8a5ff2cd578801251f3a4f6854c6a5d437d3c04", + "sha256:7761afe0126d046974a01e030ae7529ed0ca6a196de3ec6937c11df0df1bc91c", + "sha256:7888310f6214f19ab2b6df90f3f06afa3df7ef7355fc025e78a3044737fab1f5", + "sha256:7b0554af24df2bf96618dac71ddada02420f946be943b181108cac55a7a2dcd4", + "sha256:7c7b502bc34f6e32ba022b4a209638f9e097d7a9098104ae420eb8186217ebbb", + "sha256:808add66ea764ed97d44dda1ac4f2cfec4c1867d9efb16a33d158be79f32b8a4", + "sha256:831e648102c82f152e14c1a0938689dbb22480c548c8d4b8b248b3e50967b88c", + "sha256:93689632949aff41199090eff5474f3990b6823404e45d66a5d44304e9cdc467", + "sha256:96b5e6874431df16aee0c1ba237574cb6dff1dcb173798faa6a9d8b399a05d0e", + "sha256:9a54614049a18a2d6fe156e68e188da02a046a4a93cf24f373bffd977e943421", + "sha256:a138441e95562b3c078746a22f8fca8ff1c22c014f856278bdbdd89ca36cff1b", + "sha256:a647c0d4478b995c5e54615a2e5360ccedd2f85e70ab57fbe817ca613d5e63b8", + "sha256:a9c9bc489f8ab30906d7a85afac4b4944a572a7432e00698a7239f44a44e6efb", + "sha256:ad2277b185ebce47a63f4dc6302e30f05762b688f8dc3de55dbae4651872cdf3", + "sha256:b6d5e92df2b77665e07ddb2e4dbd6d644b78e4c0d2e9272a852627cdba0d75cf", + "sha256:bc431b065722a5ad1dfb4df354fb9333b7a582a5ee39a90e6ffff688d72f27a1", + "sha256:bdd0de2d64688ecae88dd8935012c4a72681e5df632af903a1dca8c5e7aa871a", + "sha256:c79698d4cd9318d9481d89a77e2d3fcaeff5486be641e60a4b49f3d2ecca4e28", + "sha256:cb6259196a589123d755380b65127ddc60f4c64b21fc3bb46ce3a6ea663659b0", + "sha256:d5b87da55a08acb586bad5c3aa3b86505f559b84f39035b233d5bf844b0834b1", + "sha256:dcd7b9c7139dc8258d164b55696ecd16c04607f1cc33ba7af86613881ffe4ac8", + "sha256:dfe4c1fedfde4e2fbc009d5ad420647f7730d719786388b7de0999bf32c0d9fd", + "sha256:ea98f633d45f7e815db648fd7ff0f19e328302ac36427343e4432c84432e7ff4", + "sha256:ec52c351b35ca269cb1f8069d610fc45c5bd38c3e91f9ab4cbbf0aebc136d9c8", + "sha256:eef7592281f7c174d3d6cbfbb7ee5984a671fcd77e3fc78e973d492e9bf0eb3f", + "sha256:f07f1f00e22b231dd3d9b9208692042e29792d6bd4f6639415d2f23158a80013", + "sha256:f3fac744f9b540148fa7715a435d2283b71f68bfb6d4aae24482a890aed18b59", + "sha256:fa768eff5f9f958270b081bb33581b4b569faabf8774726b283edb06617101dc", + "sha256:fac2d65901fb0fdf20363fbd345c01958a742f2dc62a8dd4495af66e3ff502a4" + ], + "index": "pypi", + "version": "==9.2.0" }, "platformdirs": { "hashes": [ @@ -803,39 +833,39 @@ }, "pycryptodome": { "hashes": [ - "sha256:028dcbf62d128b4335b61c9fbb7dd8c376594db607ef36d5721ee659719935d5", - "sha256:12ef157eb1e01a157ca43eda275fa68f8db0dd2792bc4fe00479ab8f0e6ae075", - "sha256:2562de213960693b6d657098505fd4493c45f3429304da67efcbeb61f0edfe89", - "sha256:27e92c1293afcb8d2639baf7eb43f4baada86e4de0f1fb22312bfc989b95dae2", - "sha256:36e3242c4792e54ed906c53f5d840712793dc68b726ec6baefd8d978c5282d30", - "sha256:50a5346af703330944bea503106cd50c9c2212174cfcb9939db4deb5305a8367", - "sha256:53dedbd2a6a0b02924718b520a723e88bcf22e37076191eb9b91b79934fb2192", - "sha256:69f05aaa90c99ac2f2af72d8d7f185f729721ad7c4be89e9e3d0ab101b0ee875", - "sha256:75a3a364fee153e77ed889c957f6f94ec6d234b82e7195b117180dcc9fc16f96", - "sha256:766a8e9832128c70012e0c2b263049506cbf334fb21ff7224e2704102b6ef59e", - "sha256:7fb90a5000cc9c9ff34b4d99f7f039e9c3477700e309ff234eafca7b7471afc0", - "sha256:893f32210de74b9f8ac869ed66c97d04e7d351182d6d39ebd3b36d3db8bda65d", - "sha256:8b5c28058102e2974b9868d72ae5144128485d466ba8739abd674b77971454cc", - "sha256:924b6aad5386fb54f2645f22658cb0398b1f25bc1e714a6d1522c75d527deaa5", - "sha256:9924248d6920b59c260adcae3ee231cd5af404ac706ad30aa4cd87051bf09c50", - "sha256:9ec761a35dbac4a99dcbc5cd557e6e57432ddf3e17af8c3c86b44af9da0189c0", - "sha256:a36ab51674b014ba03da7f98b675fcb8eabd709a2d8e18219f784aba2db73b72", - "sha256:aae395f79fa549fb1f6e3dc85cf277f0351e15a22e6547250056c7f0c990d6a5", - "sha256:c880a98376939165b7dc504559f60abe234b99e294523a273847f9e7756f4132", - "sha256:ce7a875694cd6ccd8682017a7c06c6483600f151d8916f2b25cf7a439e600263", - "sha256:d1b7739b68a032ad14c5e51f7e4e1a5f92f3628bba024a2bda1f30c481fc85d8", - "sha256:dcd65355acba9a1d0fc9b923875da35ed50506e339b35436277703d7ace3e222", - "sha256:e04e40a7f8c1669195536a37979dd87da2c32dbdc73d6fe35f0077b0c17c803b", - "sha256:e0c04c41e9ade19fbc0eff6aacea40b831bfcb2c91c266137bcdfd0d7b2f33ba", - "sha256:e24d4ec4b029611359566c52f31af45c5aecde7ef90bf8f31620fd44c438efe7", - "sha256:e64738207a02a83590df35f59d708bf1e7ea0d6adce712a777be2967e5f7043c", - "sha256:ea56a35fd0d13121417d39a83f291017551fa2c62d6daa6b04af6ece7ed30d84", - "sha256:f2772af1c3ef8025c85335f8b828d0193fa1e43256621f613280e2c81bfad423", - "sha256:f403a3e297a59d94121cb3ee4b1cf41f844332940a62d71f9e4a009cc3533493", - "sha256:f572a3ff7b6029dd9b904d6be4e0ce9e309dcb847b03e3ac8698d9d23bb36525" - ], - "index": "pypi", - "version": "==3.14.1" + "sha256:045d75527241d17e6ef13636d845a12e54660aa82e823b3b3341bcf5af03fa79", + "sha256:0926f7cc3735033061ef3cf27ed16faad6544b14666410727b31fea85a5b16eb", + "sha256:092a26e78b73f2530b8bd6b3898e7453ab2f36e42fd85097d705d6aba2ec3e5e", + "sha256:1b22bcd9ec55e9c74927f6b1f69843cb256fb5a465088ce62837f793d9ffea88", + "sha256:2aa55aae81f935a08d5a3c2042eb81741a43e044bd8a81ea7239448ad751f763", + "sha256:2ea63d46157386c5053cfebcdd9bd8e0c8b7b0ac4a0507a027f5174929403884", + "sha256:2ec709b0a58b539a4f9d33fb8508264c3678d7edb33a68b8906ba914f71e8c13", + "sha256:2ffd8b31561455453ca9f62cb4c24e6b8d119d6d531087af5f14b64bee2c23e6", + "sha256:4b52cb18b0ad46087caeb37a15e08040f3b4c2d444d58371b6f5d786d95534c2", + "sha256:4c3ccad74eeb7b001f3538643c4225eac398c77d617ebb3e57571a897943c667", + "sha256:5099c9ca345b2f252f0c28e96904643153bae9258647585e5e6f649bb7a1844a", + "sha256:57f565acd2f0cf6fb3e1ba553d0cb1f33405ec1f9c5ded9b9a0a5320f2c0bd3d", + "sha256:60b4faae330c3624cc5a546ba9cfd7b8273995a15de94ee4538130d74953ec2e", + "sha256:7c9ed8aa31c146bef65d89a1b655f5f4eab5e1120f55fc297713c89c9e56ff0b", + "sha256:7e3a8f6ee405b3bd1c4da371b93c31f7027944b2bcce0697022801db93120d83", + "sha256:9135dddad504592bcc18b0d2d95ce86c3a5ea87ec6447ef25cfedea12d6018b8", + "sha256:9c772c485b27967514d0df1458b56875f4b6d025566bf27399d0c239ff1b369f", + "sha256:9eaadc058106344a566dc51d3d3a758ab07f8edde013712bc8d22032a86b264f", + "sha256:9ee40e2168f1348ae476676a2e938ca80a2f57b14a249d8fe0d3cdf803e5a676", + "sha256:a8f06611e691c2ce45ca09bbf983e2ff2f8f4f87313609d80c125aff9fad6e7f", + "sha256:b9c5b1a1977491533dfd31e01550ee36ae0249d78aae7f632590db833a5012b8", + "sha256:b9cc96e274b253e47ad33ae1fccc36ea386f5251a823ccb50593a935db47fdd2", + "sha256:c3640deff4197fa064295aaac10ab49a0d55ef3d6a54ae1499c40d646655c89f", + "sha256:c77126899c4b9c9827ddf50565e93955cb3996813c18900c16b2ea0474e130e9", + "sha256:d2a39a66057ab191e5c27211a7daf8f0737f23acbf6b3562b25a62df65ffcb7b", + "sha256:e244ab85c422260de91cda6379e8e986405b4f13dc97d2876497178707f87fc1", + "sha256:ecaaef2d21b365d9c5ca8427ffc10cebed9d9102749fd502218c23cb9a05feb5", + "sha256:fd2184aae6ee2a944aaa49113e6f5787cdc5e4db1eb8edb1aea914bd75f33a0c", + "sha256:ff287bcba9fbeb4f1cccc1f2e90a08d691480735a611ee83c80a7d74ad72b9d9", + "sha256:ff7ae90e36c1715a54446e7872b76102baa5c63aa980917f4aa45e8c78d1a3ec" + ], + "index": "pypi", + "version": "==3.15.0" }, "pyflakes": { "hashes": [ @@ -855,101 +885,54 @@ }, "pylint": { "hashes": [ - "sha256:549261e0762c3466cc001024c4419c08252cb8c8d40f5c2c6966fea690e7fe2a", - "sha256:bb71e6d169506de585edea997e48d9ff20c0dc0e2fbc1d166bad6b640120326b" + "sha256:47705453aa9dce520e123a7d51843d5f0032cbfa06870f89f00927aa1f735a4a", + "sha256:89b61867db16eefb7b3c5b84afc94081edaf11544189e2b238154677529ad69f" ], "index": "pypi", - "version": "==2.14.1" + "version": "==2.14.4" }, "pyopencl": { "hashes": [ - "sha256:01030054c201b021715deb3d6f1355844f9795429dfa0591b59b6f8000ec2d38", - "sha256:02997935ac164f519be65c371f9dd2267a2b7532247dc0a2ef43f435cf76cf4b", - "sha256:07482df440e1246cba6dc46ef70d3ebf1a6c8157a3c6456091026c7f9e4d18d2", - "sha256:0b179591c60b4446846fbea035cb3d1acd2685b0226ba91724109882dc59af2c", - "sha256:15ebc3f3eb2df1d196a7dcefd68d0e9ffa11e275f8a6c57a1145a1d0ff36c382", - "sha256:1a5fb7dc32cf24cdeab1205bc075710d7112656720c2bf9972bebe906e28ec4b", - "sha256:1b649637d608e8dabdec0e0f85392f727fdf622463b425cf7587bdd313b4d9eb", - "sha256:22eed49903178bc686287192a8319ce763129b4e5d42a9dfb5d8f763ba5d6bd6", - "sha256:2deef59d73d0bdd11ba40613ab0798c767214a669a1a5a672500787fb7da63d3", - "sha256:3736bfdc946068be66fe4b5c680926c84366b724b3c4b649b2a1940f7bd6afde", - "sha256:3dd0b5ff24d12ad4c13446d8e5439e63914496dfcf9e23a26baeaa65ec3c7039", - "sha256:5430b938e9391309be2ffaefb6269a0a3c016af5d729121cf8a5fce62a5146c2", - "sha256:5e89596e7f18824fc1f84e2cb0ae059fbfe187d1e2e3919ab0cd701cc634eb03", - "sha256:65e406603fbe47ca72298e022a3c3855b2e1732cb9d04ecbb411025050d0bc57", - "sha256:6f9f91594358af6a9728908c31c5ed4bec3fe1a0d25c6292e37e40c92903fe36", - "sha256:77a70b76789aac85566cb0e3ff6b60c4c00729bbd7f0edd24ac4b3b43e4627e2", - "sha256:799355c27463bf801260e3398643c3c9359627fa9e6ac621cfb5dc1d6e77d859", - "sha256:7ae4825562f7c5956b8926cb99882df1631c5e28aa1310d896c22a8471cf8f56", - "sha256:7b17906a4821a30aa1ce7a9d783bba2564230ea6a55ff31eb3f0e2a4aa5b80af", - "sha256:7d4bf4c858554e9e3af9e7f18b06e8d6c39b25d7a80c28db6e5dd412dc457aee", - "sha256:8981a9274796272508158b08a3cb1a5711318cf32b5f0e4829edecb1a9efcf93", - "sha256:8da3ef5a03cfd0a9859a5ebe623f3c43037e9f0dffd2b658e944bbc381beb529", - "sha256:94c744997f4aff86e68fa3a5d383dc8b5f1e529a360156b82c7583a757eddaa5", - "sha256:9a7fb5769bce7ec09a2d264a233ec9c730b15b391c830d04a381df3fc85bdaca", - "sha256:a6ce276a42caedd3a9a7be00031cfe6bf5d1796efdac40e47f1b707846c96d86", - "sha256:a84310ae508f998ed31825b6e3ab888098cb69a2c627bf5970706620a8d4b127", - "sha256:ad08e37cdeda5d38ac3ca9820400da62ce3a67aab76a5eefa5d089ef3a4877c9", - "sha256:b6e426b5fdce61051b112825da20df4cb78429967e491223bfedaf95c025273a", - "sha256:bb363f9993013b04c0b146e269a73b3d5ebef30f78d5fa542f317cc2440e15b6", - "sha256:c58f05b050ae4ac3b0584d97738ae7ac4381e611567b9d67fe7cf4210c0a7b62", - "sha256:c84ef85cf6b83dbcef4e034390fc1ed6bd8eadf5260b5ae89515d3b9744ef207", - "sha256:c9a841b80ef4c332a6133377fc295fe5376f90f8f2e7c63d36903b07b8ea7262", - "sha256:cd5871aff617d3c9d338fd94c9187382390db82452be0868055b8c519a73445d", - "sha256:cf45c232bf818ef54ee831eb41f4edbd5dfe4c67d894b1e65fc17a690a63c81e", - "sha256:e90bd1ed69cca2a750ffabafc70b4f9eb4d109299e986c3c8fdc4c40fee36ef2", - "sha256:ea5b6ef0e4ad23a3ccbdb382f7cccadbb200a47ceb6ff3e965a3c6c46360b4c2", - "sha256:f433ddd7bfd688b591ea95b6971e5e6cb00f8d5f2dc5db833e528e5ede6909d6" - ], - "index": "pypi", - "version": "==2022.1.5" - }, - "pyqt5": { - "hashes": [ - "sha256:213bebd51821ed89b4d5b35bb10dbe67564228b3568f463a351a08e8b1677025", - "sha256:2a69597e0dd11caabe75fae133feca66387819fc9bc050f547e5551bce97e5be", - "sha256:883a549382fc22d29a0568f3ef20b38c8e7ab633a59498ac4eb63a3bf36d3fd3", - "sha256:8c0848ba790a895801d5bfd171da31cad3e551dbcc4e59677a3b622de2ceca98", - "sha256:a88526a271e846e44779bb9ad7a738c6d3c4a9d01e15a128ecfc6dd4696393b7" - ], - "index": "pypi", - "version": "==5.15.4" - }, - "pyqt5-qt5": { - "hashes": [ - "sha256:1988f364ec8caf87a6ee5d5a3a5210d57539988bf8e84714c7d60972692e2f4a", - "sha256:750b78e4dba6bdf1607febedc08738e318ea09e9b10aea9ff0d73073f11f6962", - "sha256:76980cd3d7ae87e3c7a33bfebfaee84448fd650bad6840471d6cae199b56e154", - "sha256:9cc7a768b1921f4b982ebc00a318ccb38578e44e45316c7a4a850e953e1dd327" - ], - "version": "==5.15.2" - }, - "pyqt5-sip": { - "hashes": [ - "sha256:055581c6fed44ba4302b70eeb82e979ff70400037358908f251cd85cbb3dbd93", - "sha256:0fc9aefacf502696710b36cdc9fa2a61487f55ee883dbcf2c2a6477e261546f7", - "sha256:42274a501ab4806d2c31659170db14c282b8313d2255458064666d9e70d96206", - "sha256:4347bd81d30c8e3181e553b3734f91658cfbdd8f1a19f254777f906870974e6d", - "sha256:485972daff2fb0311013f471998f8ec8262ea381bded244f9d14edaad5f54271", - "sha256:4f8e05fe01d54275877c59018d8e82dcdd0bc5696053a8b830eecea3ce806121", - "sha256:69a3ad4259172e2b1aa9060de211efac39ddd734a517b1924d9c6c0cc4f55f96", - "sha256:6a8701892a01a5a2a4720872361197cc80fdd5f49c8482d488ddf38c9c84f055", - "sha256:6d5bca2fc222d58e8093ee8a81a6e3437067bb22bc3f86d06ec8be721e15e90a", - "sha256:83c3220b1ca36eb8623ba2eb3766637b19eb0ce9f42336ad8253656d32750c0a", - "sha256:a25b9843c7da6a1608f310879c38e6434331aab1dc2fe6cb65c14f1ecf33780e", - "sha256:ac57d796c78117eb39edd1d1d1aea90354651efac9d3590aac67fa4983f99f1f", - "sha256:b09f4cd36a4831229fb77c424d89635fa937d97765ec90685e2f257e56a2685a", - "sha256:c446971c360a0a1030282a69375a08c78e8a61d568bfd6dab3dcc5cf8817f644", - "sha256:c5216403d4d8d857ec4a61f631d3945e44fa248aa2415e9ee9369ab7c8a4d0c7", - "sha256:d3e4489d7c2b0ece9d203ae66e573939f7f60d4d29e089c9f11daa17cfeaae32", - "sha256:d59af63120d1475b2bf94fe8062610720a9be1e8940ea146c7f42bb449d49067", - "sha256:d85002238b5180bce4b245c13d6face848faa1a7a9e5c6e292025004f2fd619a", - "sha256:d8b2bdff7bbf45bc975c113a03b14fd669dc0c73e1327f02706666a7dd51a197", - "sha256:dd05c768c2b55ffe56a9d49ce6cc77cdf3d53dbfad935258a9e347cbfd9a5850", - "sha256:fc43f2d7c438517ee33e929e8ae77132749c15909afab6aeece5fcf4147ffdb5" - ], - "index": "pypi", - "version": "==12.9.0" + "sha256:069e7eb1a223d88c13eafa54d6ae896fa892e75ba3d56ff2135a26107ef1142b", + "sha256:1490e6cdeaecba42854013c273685d65fd9102ee6dc6bc3bcb814e9e2b8179e5", + "sha256:15f7b3d29c9359e1e440e4f52f70de031f8d0d8d0f8de53a3bc01501b89360c0", + "sha256:1a2029b7fda6709eca077f618f997372c3d6f2780ad45512632b0d056e6305f9", + "sha256:25e87b4ccc0cc53487d445bea07ce9bdb478a335725df16986aead2ff65b68a4", + "sha256:2c9ad1cbc3f540afc52038851be8e06640aacfece051c89408bc3aece605a7ee", + "sha256:2df01c95ea9ae3dd66b277f0df47144cf7535a27b48a8d49fdd98e0583e368ce", + "sha256:316f59d0c40bfce4f6c160dbaf6501883b33880370bb1819f360dad747e52dfe", + "sha256:4836bc4619be967d6c28627adac151223037fdca056c4ab54da16b591f719347", + "sha256:4b53f7f3ed85ab671c8bfc61a0bbc5476725a7a5f51a94bba5512c3962b2d609", + "sha256:5304cb336af7316ae0650abb7467c076032635bfe4710b8df191612d245dca28", + "sha256:55e9302b8f0b1964c87b0fdab7b853aa2b2f10b4188f5b4618782d4380448c11", + "sha256:6032bef8a35f6df727a0b66e3c9faedb3f560318052848b28d2f72622cfbeace", + "sha256:6ec55934057e99461f684ccd293d87db59a452f5834c13ae36b19d31dfe38599", + "sha256:7176f96728be9b43024bd71704f60849cbfcf0fafd20270181b68ea4730ceb2d", + "sha256:730901d409d8251cd6e9dc59e6c518dff5cdb20a3a0b728344bfd2c707f28b64", + "sha256:75be43c7f33fb86f9d18b7b6f8e9081d8bd5b6331a90aec0d2cad3e81e72bc8f", + "sha256:7bef8e8bcfff574b481565390113ea0a37cf33fd2587ade7f2980f15e73f7b08", + "sha256:7ca9597877e1f8bdb4a49810988230f538b2d7aac389c33418a21cf4358f2fd4", + "sha256:814389b3eb9e6930cf43b984283c94a955edf20ec286402da5acfa503d3ae790", + "sha256:8efc3467454ce8c644f09029a3308496f9cb6e93ca5e8c08f6b79e7825da72c5", + "sha256:98bad7035f27b6de5c9268f52c1e10bffe3a2874994e862468a1792b699a4884", + "sha256:9bbfe94bb6e9d0458693183334e73c973e2fcba01568f42db15b453b926fb816", + "sha256:9d112a4426f5b356641c1312bf1004247dc4019e649502589b86333557203c01", + "sha256:a845779f505ed57b83f279307ae6307d886f3e41fb24dcf7889da27daa726118", + "sha256:aca3581f1a7f6b809b8cdc78b0e66587848b38b143bf2983e91ff8fb9a41bc8f", + "sha256:af5664b98140a29966c5fb12e9d29b85b6c6310efa97d82aee58310774917e8f", + "sha256:b85fa5ba1678dd40713587fd437787b6aa940000c2ddffa360884431be21723a", + "sha256:bcabfb5217ca8f8770f9c69298f79576080bb994b1883a99494b4c2668b04836", + "sha256:c00989bed1e7e5b32ad498fec3deb1c93403ab802cd99b7c78b9c692bd0910ef", + "sha256:d0ddc3b74ad1804eb3fe238dfa3b844b997e88b1ca5164a717c16b362b4f34c3", + "sha256:d8bb2eea4e960917e0a6132dedd34c8ec0b7a384f22713f775d50dbce154263a", + "sha256:db833ebb1e756969a8f851f15486598eb9e3fb27b0535c2a8193cc1c71455016", + "sha256:dc2d78cb5da0081ada1c263aaa773fd5479b3da5e2c421547bf7f3258d3239a5", + "sha256:dd2728e59ae088c900ed68f68d953476d0ff07189f182f917b74de2ac7b3972e", + "sha256:ea4eff6b922fa4ad2077ef90b3254d78597d050ada09bfbe74c22dd22d10c6ac", + "sha256:f8887d54e654598f3854472540b2eb228ac56b56a2491b95bdfac8f15be1c943" + ], + "index": "pypi", + "version": "==2022.1.6" }, "pyserial": { "hashes": [ @@ -969,10 +952,10 @@ }, "pytools": { "hashes": [ - "sha256:3393d25029982080e3fb94c47bf627a1e553ccd174fe2edef6c1c5ec723918ff" + "sha256:4d62875e9a2ab2a24e393a9a8b799492f1a721bffa840af3807bfd42871dd1f4" ], "markers": "python_version ~= '3.6'", - "version": "==2022.1.9" + "version": "==2022.1.12" }, "pyyaml": { "hashes": [ @@ -1015,74 +998,74 @@ }, "pyzmq": { "hashes": [ - "sha256:057176dd3f5ccf5aad4abd662d76b6a39bbf799baaf2f39cd4fdaf2eab326e43", - "sha256:05ec90a8da618f2398f9d1aa20b18a9ef332992c6ac23e8c866099faad6ef0d6", - "sha256:154de02b15422af28b53d29a02de72121ba503634955017255573fc1f995143d", - "sha256:16b832adb5d8716f46051da5533c480250bf126984ce86804db6137a3a7f931b", - "sha256:1df26aa854bdd3a8341bf199064dd6aa6e240f2eaa3c9fa8d217e5d8b868c73e", - "sha256:28f9164fb2658b7b414fa0894c75b1a9c61375774cdc1bdb7298beb042a2cd87", - "sha256:2951c29b8649f3672af9dca8ff61d86310d3664d9629788b1c66422fb13b1239", - "sha256:2b08774057ae7ce8a2eb4e7d54db05358234440706ce43a85814500c5d7bd22e", - "sha256:2e2ac40f7a91c740ec68d6db07ae19ea9259c959333c68bee56ab2c799a67d66", - "sha256:312e56799410c34797417a4060a8bd37d4db1f06d1ec0c54f7c8fd81e0d90376", - "sha256:38f778a74e3889392e949326cfd0e9b2eb37dcbb2980d98fad2c51703d523db2", - "sha256:3955dd5bbbe02f454655296ee36a66c334c7102a29b8458223d168c0380edfd5", - "sha256:425ba851a6f9892bde1da2024d82e2fe6796bd77e3391fb96665c50fe9d4c6a5", - "sha256:48bbc2db041ab28eeee4a3e8ada0ed336640946dd5a8e53dbd3805f9dbdcf0dc", - "sha256:4fbcd657cda75574fd1315a4c44bd322bc2e219039fb09f146bbe6f8aef039e9", - "sha256:523ba7fd4d8fe75ad09c1e574a648892b75a97d0cfc8005727681053ac19555b", - "sha256:53b2c1326c2e484d450932d2be739f064b7cb572faabec38386098a28516a529", - "sha256:540d7146c3cdc9bbffab039ea067f494eba24d1abe5bd33eb9f963c01e3305d4", - "sha256:563d4281c4dbdf647d93114420151d33f895afc4c46b7115a67a0aa5347e6624", - "sha256:67a049bcf967a39993858beed873ed3405536019820922d4efacfe35ab3da51a", - "sha256:67ec63ae3c9c1fa2e077fcb42e77035e2121a04f987464bdf9945a28535d30ad", - "sha256:68e22c5d3be451e87d47f956b397a7823bfbde2176341bc902fba30f96831d7e", - "sha256:6ab4b6108e69f63c917cd7ef7217c5727955b1ac90600e44a13ed5312019a014", - "sha256:6bd7f18bd4cf51ea8d7e54825902cf36f9d2f35cc51ef618373988d5398b8dd0", - "sha256:6cd53e861bccc0bdc4620f68fb4a91d5bcfe9f4213cf8e200fa498044d33a6dc", - "sha256:6d346e551fa64b89d57a4ac74b9bc66703413f02f50093e089e861999ec5cccc", - "sha256:6ff8708fabc9f9bc2949f457d39b4088c9656c4c9ac15fbbbbaafce8f6d07833", - "sha256:7626e8384275a7dea6f3d1f749fb5e00299042e9c895fc3dbe24cb154909c242", - "sha256:7e7346b2b33dcd4a2171dd8a9870ae283eec8f6231dcbcf237a0f41e74751a50", - "sha256:81623c67cb71b93b5f7e06c9107f3781738ae86866db830c950223d87af2a235", - "sha256:83f1c76068faf62c32a36dd62dc4db642c2027bbbd960f8f6345b59e9d4dc472", - "sha256:8679bb1dd723ecbea03b1f96c98972815775fd8ec756c440a14f289c436c472e", - "sha256:86fb683cb9a9c0bb7476988b7957393ecdd22777d87d804442c66e62c99197f9", - "sha256:8757c62f7960cd26122f7aaaf86eda1e016fa85734c3777b8054dd334d7dea4d", - "sha256:894be7d17228e7328cc188096c0162697211ec91761f6812fff12790cbe11c66", - "sha256:8a0f240bf43c29be1bd82d77e602a61c798e9de02e5f8bb7bb414cb814f43236", - "sha256:8c3abf7eab5b76ae162c4fbb16d514a947fc57fd995b64e5ea8ef8ba3b888a69", - "sha256:93332c6972e4c91522c4810e907f3aea067424338071161b39cacded022559df", - "sha256:97d6c676dc97d593625d9fc48154f2ffeabb619a1e6fe8d2a5b53f97e3e9bdee", - "sha256:99dd85f0ca1db8d17a01a25c2bbb7784d25a2d39497c6beddbe96bff74194e04", - "sha256:9c7fb691fb07ec7ab99fd173bb0e7e0248d31bf83d484a87b917a342f63812c9", - "sha256:b3bc3cf200aab74f3d758586ac50295214eda496ac6a6636e0c881c5958d9123", - "sha256:bba54f97578943f48f621b4a7afb8eb022370da26a88b88ccc9fee9f3ef7ce45", - "sha256:bd2a13a0f8367e50347cbac87ae230ae1953935443240238f956bf10668bead6", - "sha256:cbc1184349ca6e5112898aa7fc3efa1b1bbae24ab1edc774cfd09cbfd3b091d7", - "sha256:cd82cca9c489e441574804dbda2dd8e114cf3be7935b03de11dade2c9478aea6", - "sha256:ce8ba5ed8b0a7a203922d61cff45ee6001a41a9359f04f00d055a4e988755569", - "sha256:cfee22e072a382b92ee0709dbb8203dabd52d54258051e770d9d2a81b162530b", - "sha256:d977df6f7c4109ed1d96ffb6795f6af77114be606ae4556efbfc9cac725db65d", - "sha256:da72a384a1d7e87490ca71182f3ab469ed21d847adc16b70c34faac5a3b12801", - "sha256:ddf4ad1d651e6c9234945061e1a31fe27a4be0dea21c498b87b186fadf8f5919", - "sha256:eb0ae5dfda83bbce660179d7b41c1c38fd833a54d2e6d9b258c644f3b75ef94d", - "sha256:f4c7d370badc60ac94a554bc571a46d03e39d8aacfba8006b334512e184aed59", - "sha256:f6c378b435a26fda8996579c0e324b108d2ca0d01b4661503a75634e5155559f", - "sha256:f6c9d30888503f2f5f87d6d41f016301352dd98da4a861bd10663c3a2d99d3b5", - "sha256:fab8a7877275060f7b303e1f91c218069a2814a616b6a5ee2d8a3737deb15915", - "sha256:fc32e7d7f98cac3d8d5153ed2cb583158ae3d446a6efb8e28ccb1c54a09f4169" - ], - "index": "pypi", - "version": "==23.1.0" + "sha256:004a431dfa0459123e6f4660d7e3c4ac19217d134ca38bacfffb2e78716fe944", + "sha256:057b154471e096e2dda147f7b057041acc303bb7ca4aa24c3b88c6cecdd78717", + "sha256:0e08671dc202a1880fa522f921f35ca5925ba30da8bc96228d74a8f0643ead9c", + "sha256:1b2a21f595f8cc549abd6c8de1fcd34c83441e35fb24b8a59bf161889c62a486", + "sha256:21552624ce69e69f7924f413b802b1fb554f4c0497f837810e429faa1cd4f163", + "sha256:22ac0243a41798e3eb5d5714b28c2f28e3d10792dffbc8a5fca092f975fdeceb", + "sha256:2b054525c9f7e240562185bf21671ca16d56bde92e9bd0f822c07dec7626b704", + "sha256:30c365e60c39c53f8eea042b37ea28304ffa6558fb7241cf278745095a5757da", + "sha256:3a4d87342c2737fbb9eee5c33c792db27b36b04957b4e6b7edd73a5b239a2a13", + "sha256:420b9abd1a7330687a095373b8280a20cdee04342fbc8ccb3b56d9ec8efd4e62", + "sha256:444f7d615d5f686d0ef508b9edfa8a286e6d89f449a1ba37b60ef69d869220a3", + "sha256:558f5f636e3e65f261b64925e8b190e8689e334911595394572cc7523879006d", + "sha256:5592fb4316f895922b1cacb91b04a0fa09d6f6f19bbab4442b4d0a0825177b93", + "sha256:59928dfebe93cf1e203e3cb0fd5d5dd384da56b99c8305f2e1b0a933751710f6", + "sha256:5cb642e94337b0c76c9c8cb9bfb0f8a78654575847d080d3e1504f312d691fc3", + "sha256:5d57542429df6acff02ff022067aa75b677603cee70e3abb9742787545eec966", + "sha256:5d92e7cbeab7f70b08cc0f27255b0bb2500afc30f31075bca0b1cb87735d186c", + "sha256:602835e5672ca9ca1d78e6c148fb28c4f91b748ebc41fbd2f479d8763d58bc9b", + "sha256:60746a7e8558655420a69441c0a1d47ed225ed3ac355920b96a96d0554ef7e6b", + "sha256:61b97f624da42813f74977425a3a6144d604ea21cf065616d36ea3a866d92c1c", + "sha256:693c96ae4d975eb8efa1639670e9b1fac0c3f98b7845b65c0f369141fb4bb21f", + "sha256:814e5aaf0c3be9991a59066eafb2d6e117aed6b413e3e7e9be45d4e55f5e2748", + "sha256:83005d8928f8a5cebcfb33af3bfb84b1ad65d882b899141a331cc5d07d89f093", + "sha256:831da96ba3f36cc892f0afbb4fb89b28b61b387261676e55d55a682addbd29f7", + "sha256:8355744fdbdeac5cfadfa4f38b82029b5f2b8cab7472a33453a217a7f3a9dce2", + "sha256:8496a2a5efd055c61ac2c6a18116c768a25c644b6747dcfde43e91620ab3453c", + "sha256:859059caf564f0c9398c9005278055ed3d37af4d73de6b1597821193b04ca09b", + "sha256:8c0f4d6f8c985bab83792be26ff3233940ba42e22237610ac50cbcfc10a5c235", + "sha256:8c2d8b69a2bf239ae3d987537bf3fbc2b044a405394cf4c258fc684971dd48b2", + "sha256:984b232802eddf9f0be264a4d57a10b3a1fd7319df14ee6fc7b41c6d155a3e6c", + "sha256:99cedf38eaddf263cf7e2a50e405f12c02cedf6d9df00a0d9c5d7b9417b57f76", + "sha256:a3dc339f7bc185d5fd0fd976242a5baf35de404d467e056484def8a4dd95868b", + "sha256:a51f12a8719aad9dcfb55d456022f16b90abc8dde7d3ca93ce3120b40e3fa169", + "sha256:bbabd1df23bf63ae829e81200034c0e433499275a6ed29ca1a912ea7629426d9", + "sha256:bcc6953e47bcfc9028ddf9ab2a321a3c51d7cc969db65edec092019bb837959f", + "sha256:c0a5f987d73fd9b46c3d180891f829afda714ab6bab30a1218724d4a0a63afd8", + "sha256:c223a13555444707a0a7ebc6f9ee63053147c8c082bd1a31fd1207a03e8b0500", + "sha256:c616893a577e9d6773a3836732fd7e2a729157a108b8fccd31c87512fa01671a", + "sha256:c882f1d4f96fbd807e92c334251d8ebd159a1ef89059ccd386ddea83fdb91bd8", + "sha256:c8dec8a2f3f0bb462e6439df436cd8c7ec37968e90b4209ac621e7fbc0ed3b00", + "sha256:c9638e0057e3f1a8b7c5ce33c7575349d9183a033a19b5676ad55096ae36820b", + "sha256:ce4f71e17fa849de41a06109030d3f6815fcc33338bf98dd0dde6d456d33c929", + "sha256:ced12075cdf3c7332ecc1960f77f7439d5ebb8ea20bbd3c34c8299e694f1b0a1", + "sha256:d11628212fd731b8986f1561d9bb3f8c38d9c15b330c3d8a88963519fbcd553b", + "sha256:d1610260cc672975723fcf7705c69a95f3b88802a594c9867781bedd9b13422c", + "sha256:d4651de7316ec8560afe430fb042c0782ed8ac54c0be43a515944d7c78fddac8", + "sha256:da338e2728410d74ddeb1479ec67cfba73311607037455a40f92b6f5c62bf11d", + "sha256:de727ea906033b30527b4a99498f19aca3f4d1073230a958679a5b726e2784e0", + "sha256:e2e2db5c6ef376e97c912733dfc24406f5949474d03e800d5f07b6aca4d870af", + "sha256:e669913cb2179507628419ec4f0e453e48ce6f924de5884d396f18c31836089c", + "sha256:eb4a573a8499685d62545e806d8fd143c84ac8b3439f925cd92c8763f0ed9bd7", + "sha256:f146648941cadaaaf01254a75651a23c08159d009d36c5af42a7cc200a5e53ec", + "sha256:f3ff6abde52e702397949054cb5b06c1c75b5d6542f6a2ce029e46f71ffbbbf2", + "sha256:f5aa9da520e4bb8cee8189f2f541701405e7690745094ded7a37b425d60527ea", + "sha256:f5fdb00d65ec44b10cc6b9b6318ef1363b81647a4aa3270ca39565eadb2d1201", + "sha256:f685003d836ad0e5d4f08d1e024ee3ac7816eb2f873b2266306eef858f058133", + "sha256:fee86542dc4ee8229e023003e3939b4d58cc2453922cf127778b69505fc9064b" + ], + "index": "pypi", + "version": "==23.2.0" }, "requests": { "hashes": [ - "sha256:bc7861137fbce630f17b03d3ad02ad0bf978c844f3536d0edda6499dafce2b6f", - "sha256:d568723a7ebd25875d8d1eaf5dfa068cd2fc8194b2e483d7b1f7c81918dbec6b" + "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983", + "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349" ], "index": "pypi", - "version": "==2.28.0" + "version": "==2.28.1" }, "scons": { "hashes": [ @@ -1094,11 +1077,11 @@ }, "sentry-sdk": { "hashes": [ - "sha256:259535ba66933eacf85ab46524188c84dcb4c39f40348455ce15e2c0aca68863", - "sha256:778b53f0a6c83b1ee43d3b7886318ba86d975e686cb2c7906ccc35b334360be1" + "sha256:b82ad57306d5546713f15d5d70daea0408cf7f998c7566db16e0e6257e51e561", + "sha256:ddbd191b6f4e696b7845b4d87389898ae1207981faf114f968a57363aa6be03c" ], "index": "pypi", - "version": "==1.5.12" + "version": "==1.6.0" }, "setproctitle": { "hashes": [ @@ -1179,11 +1162,11 @@ }, "setuptools": { "hashes": [ - "sha256:5a844ad6e190dccc67d6d7411d119c5152ce01f7c76be4d8a1eaa314501bba77", - "sha256:bf8a748ac98b09d32c9a64a995a6b25921c96cc5743c1efa82763ba80ff54e91" + "sha256:16923d366ced322712c71ccb97164d07472abeecd13f3a6c283f6d5d26722793", + "sha256:db3b8e2f922b2a910a29804776c643ea609badb6a32c4bcc226fd4fd902cce65" ], "markers": "python_version >= '3.7'", - "version": "==62.4.0" + "version": "==63.1.0" }, "six": { "hashes": [ @@ -1227,11 +1210,11 @@ }, "tomlkit": { "hashes": [ - "sha256:0f4050db66fd445b885778900ce4dd9aea8c90c4721141fde0d6ade893820ef1", - "sha256:71ceb10c0eefd8b8f11fe34e8a51ad07812cb1dc3de23247425fbc9ddc47b9dd" + "sha256:1c5bebdf19d5051e2e1de6cf70adfc5948d47221f097fcff7a3ffc91e953eaf5", + "sha256:61901f81ff4017951119cd0d1ed9b7af31c821d6845c8c477587bbdcd5e5854e" ], - "markers": "python_version >= '3.6' and python_version < '4.0'", - "version": "==0.11.0" + "markers": "python_version >= '3.6' and python_version < '4'", + "version": "==0.11.1" }, "tqdm": { "hashes": [ @@ -1243,19 +1226,19 @@ }, "typing-extensions": { "hashes": [ - "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708", - "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376" + "sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02", + "sha256:e6d2677a32f47fc7eb2795db1dd15c1f34eff616bcaf2cfb5e997f854fa1c4a6" ], - "markers": "python_version < '3.10'", - "version": "==4.2.0" + "markers": "python_version >= '3.7'", + "version": "==4.3.0" }, "urllib3": { "hashes": [ - "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14", - "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e" + "sha256:8298d6d56d39be0e3bc13c1c97d133f9b45d797169a0e11cdd0e0489d786f7ec", + "sha256:879ba4d1e89654d9769ce13121e0f94310ea32e8d2f8cf587b77c08bbcdb30d6" ], "index": "pypi", - "version": "==1.26.9" + "version": "==1.26.10" }, "utm": { "hashes": [ @@ -1266,11 +1249,11 @@ }, "websocket-client": { "hashes": [ - "sha256:50b21db0058f7a953d67cc0445be4b948d7fc196ecbeb8083d68d94628e4abf6", - "sha256:722b171be00f2b90e1d4fb2f2b53146a536ca38db1da8ff49c972a4e1365d0ef" + "sha256:5d55652dc1d0b3c734f044337d929aaf83f4f9138816ec680c1aefefb4dc4877", + "sha256:d58c5f284d6a9bf8379dab423259fe8f85b70d5fa5d2916d5791a84594b122b1" ], "index": "pypi", - "version": "==1.3.2" + "version": "==1.3.3" }, "werkzeug": { "hashes": [ @@ -1443,11 +1426,11 @@ }, "babel": { "hashes": [ - "sha256:7aed055f0c04c9e7f51a2f75261e41e1c804efa724cb65b60a970dd4448d469d", - "sha256:81a3beca4d0cd40a9cfb9e2adb2cf39261c2f959b92e7a74750befe5d79afd7b" + "sha256:7614553711ee97490f732126dc077f8d0ae084ebc6a96e23db1482afabdb2c51", + "sha256:ff56f4892c1c4bf0d814575ea23471c230d544203c7748e8c68f0089478d48eb" ], "markers": "python_version >= '3.6'", - "version": "==2.10.2" + "version": "==2.10.3" }, "bcrypt": { "hashes": [ @@ -1468,11 +1451,11 @@ }, "breathe": { "hashes": [ - "sha256:553aeffb00efc2cf96c4c9ed388d6ee8036ecd6d1bd9bd0c656fc25ca271bd3c", - "sha256:c4b9ff4d5298fd91518d336ede28b6a2d8cacc685d0eae17eb20e760e06bb904" + "sha256:48804dcf0e607a89fb6ad88c729ef12743a42db03ae9489be4ef8f7c4011774a", + "sha256:ac0768a5e84addad3e632028fe67749c567aba2b29088493b64c2c1634bcdba1" ], "index": "pypi", - "version": "==4.33.1" + "version": "==4.34.0" }, "carla": { "hashes": [ @@ -1490,67 +1473,81 @@ }, "certifi": { "hashes": [ - "sha256:9c5705e395cd70084351dd8ad5c41e65655e08ce46f2ec9cf6c2c08390f71eb7", - "sha256:f1d53542ee8cbedbe2118b5686372fb33c297fcd6379b050cca0ef13a597382a" + "sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d", + "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412" ], "markers": "python_version >= '3.6'", - "version": "==2022.5.18.1" + "version": "==2022.6.15" }, "cffi": { "hashes": [ - "sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3", - "sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2", - "sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636", - "sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20", - "sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728", - "sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27", - "sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66", - "sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443", - "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0", - "sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7", - "sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39", - "sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605", - "sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a", - "sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37", - "sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029", - "sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139", - "sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc", - "sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df", - "sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14", - "sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880", - "sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2", - "sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a", - "sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e", - "sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474", - "sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024", - "sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8", - "sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0", - "sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e", - "sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a", - "sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e", - "sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032", - "sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6", - "sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e", - "sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b", - "sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e", - "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954", - "sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962", - "sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c", - "sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4", - "sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55", - "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962", - "sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023", - "sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c", - "sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6", - "sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8", - "sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382", - "sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7", - "sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc", - "sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997", - "sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796" - ], - "index": "pypi", - "version": "==1.15.0" + "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5", + "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef", + "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104", + "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426", + "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405", + "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375", + "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a", + "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e", + "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc", + "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf", + "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185", + "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497", + "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3", + "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35", + "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c", + "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83", + "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21", + "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca", + "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984", + "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac", + "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd", + "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee", + "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a", + "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2", + "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192", + "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7", + "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585", + "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f", + "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e", + "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27", + "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b", + "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e", + "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e", + "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d", + "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c", + "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415", + "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82", + "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02", + "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314", + "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325", + "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c", + "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3", + "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914", + "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045", + "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d", + "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9", + "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5", + "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2", + "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c", + "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3", + "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2", + "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8", + "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d", + "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d", + "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9", + "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162", + "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76", + "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4", + "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e", + "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9", + "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6", + "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b", + "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01", + "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0" + ], + "index": "pypi", + "version": "==1.15.1" }, "cfgv": { "hashes": [ @@ -1562,11 +1559,11 @@ }, "charset-normalizer": { "hashes": [ - "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597", - "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df" + "sha256:5189b6f22b01957427f35b6a08d9a0bc45b46d3788ef5a92e978433c7a35f8a5", + "sha256:575e708016ff3a5e3681541cb9d79312c416835686d054a23accb873b254f413" ], - "markers": "python_full_version >= '3.5.0'", - "version": "==2.0.12" + "markers": "python_version >= '3.6'", + "version": "==2.1.0" }, "control": { "hashes": [ @@ -1624,31 +1621,31 @@ }, "cryptography": { "hashes": [ - "sha256:093cb351031656d3ee2f4fa1be579a8c69c754cf874206be1d4cf3b542042804", - "sha256:0cc20f655157d4cfc7bada909dc5cc228211b075ba8407c46467f63597c78178", - "sha256:1b9362d34363f2c71b7853f6251219298124aa4cc2075ae2932e64c91a3e2717", - "sha256:1f3bfbd611db5cb58ca82f3deb35e83af34bb8cf06043fa61500157d50a70982", - "sha256:2bd1096476aaac820426239ab534b636c77d71af66c547b9ddcd76eb9c79e004", - "sha256:31fe38d14d2e5f787e0aecef831457da6cec68e0bb09a35835b0b44ae8b988fe", - "sha256:3b8398b3d0efc420e777c40c16764d6870bcef2eb383df9c6dbb9ffe12c64452", - "sha256:3c81599befb4d4f3d7648ed3217e00d21a9341a9a688ecdd615ff72ffbed7336", - "sha256:419c57d7b63f5ec38b1199a9521d77d7d1754eb97827bbb773162073ccd8c8d4", - "sha256:46f4c544f6557a2fefa7ac8ac7d1b17bf9b647bd20b16decc8fbcab7117fbc15", - "sha256:471e0d70201c069f74c837983189949aa0d24bb2d751b57e26e3761f2f782b8d", - "sha256:59b281eab51e1b6b6afa525af2bd93c16d49358404f814fe2c2410058623928c", - "sha256:731c8abd27693323b348518ed0e0705713a36d79fdbd969ad968fbef0979a7e0", - "sha256:95e590dd70642eb2079d280420a888190aa040ad20f19ec8c6e097e38aa29e06", - "sha256:a68254dd88021f24a68b613d8c51d5c5e74d735878b9e32cc0adf19d1f10aaf9", - "sha256:a7d5137e556cc0ea418dca6186deabe9129cee318618eb1ffecbd35bee55ddc1", - "sha256:aeaba7b5e756ea52c8861c133c596afe93dd716cbcacae23b80bc238202dc023", - "sha256:dc26bb134452081859aa21d4990474ddb7e863aa39e60d1592800a8865a702de", - "sha256:e53258e69874a306fcecb88b7534d61820db8a98655662a3dd2ec7f1afd9132f", - "sha256:ef15c2df7656763b4ff20a9bc4381d8352e6640cfeb95c2972c38ef508e75181", - "sha256:f224ad253cc9cea7568f49077007d2263efa57396a2f2f78114066fd54b5c68e", - "sha256:f8ec91983e638a9bcd75b39f1396e5c0dc2330cbd9ce4accefe68717e6779e0a" - ], - "index": "pypi", - "version": "==37.0.2" + "sha256:190f82f3e87033821828f60787cfa42bff98404483577b591429ed99bed39d59", + "sha256:2be53f9f5505673eeda5f2736bea736c40f051a739bfae2f92d18aed1eb54596", + "sha256:30788e070800fec9bbcf9faa71ea6d8068f5136f60029759fd8c3efec3c9dcb3", + "sha256:3d41b965b3380f10e4611dbae366f6dc3cefc7c9ac4e8842a806b9672ae9add5", + "sha256:4c590ec31550a724ef893c50f9a97a0c14e9c851c85621c5650d699a7b88f7ab", + "sha256:549153378611c0cca1042f20fd9c5030d37a72f634c9326e225c9f666d472884", + "sha256:63f9c17c0e2474ccbebc9302ce2f07b55b3b3fcb211ded18a42d5764f5c10a82", + "sha256:6bc95ed67b6741b2607298f9ea4932ff157e570ef456ef7ff0ef4884a134cc4b", + "sha256:7099a8d55cd49b737ffc99c17de504f2257e3787e02abe6d1a6d136574873441", + "sha256:75976c217f10d48a8b5a8de3d70c454c249e4b91851f6838a4e48b8f41eb71aa", + "sha256:7bc997818309f56c0038a33b8da5c0bfbb3f1f067f315f9abd6fc07ad359398d", + "sha256:80f49023dd13ba35f7c34072fa17f604d2f19bf0989f292cedf7ab5770b87a0b", + "sha256:91ce48d35f4e3d3f1d83e29ef4a9267246e6a3be51864a5b7d2247d5086fa99a", + "sha256:a958c52505c8adf0d3822703078580d2c0456dd1d27fabfb6f76fe63d2971cd6", + "sha256:b62439d7cd1222f3da897e9a9fe53bbf5c104fff4d60893ad1355d4c14a24157", + "sha256:b7f8dd0d4c1f21759695c05a5ec8536c12f31611541f8904083f3dc582604280", + "sha256:d204833f3c8a33bbe11eda63a54b1aad7aa7456ed769a982f21ec599ba5fa282", + "sha256:e007f052ed10cc316df59bc90fbb7ff7950d7e2919c9757fd42a2b8ecf8a5f67", + "sha256:f2dcb0b3b63afb6df7fd94ec6fbddac81b5492513f7b0436210d390c14d46ee8", + "sha256:f721d1885ecae9078c3f6bbe8a88bc0786b6e749bf32ccec1ef2b18929a05046", + "sha256:f7a6de3e98771e183645181b3627e2563dcde3ce94a9e42a3f427d2255190327", + "sha256:f8c0a6e9e1dd3eb0414ba320f85da6b0dcbd543126e30fcc546e7372a7fbf3b9" + ], + "index": "pypi", + "version": "==37.0.4" }, "cycler": { "hashes": [ @@ -1742,11 +1739,11 @@ }, "fonttools": { "hashes": [ - "sha256:c0fdcfa8ceebd7c1b2021240bd46ef77aa8e7408cf10434be55df52384865f8e", - "sha256:f829c579a8678fa939a1d9e9894d01941db869de44390adb49ce67055a06cc2a" + "sha256:9a1c52488045cd6c6491fd07711a380f932466e317cb8e016fc4e99dc7eac2f0", + "sha256:d73f25b283cd8033367451122aa868a23de0734757a01984e4b30b18b9050c72" ], "markers": "python_version >= '3.7'", - "version": "==4.33.3" + "version": "==4.34.4" }, "ft4222": { "hashes": [ @@ -1805,24 +1802,24 @@ "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff", "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d" ], - "markers": "python_full_version >= '3.5.0'", + "markers": "python_version >= '3.5'", "version": "==3.3" }, "imagesize": { "hashes": [ - "sha256:1db2f82529e53c3e929e8926a1fa9235aa82d0bd0c580359c67ec31b2fddaa8c", - "sha256:cd1750d452385ca327479d45b64d9c7729ecf0b3969a58148298c77092261f9d" + "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b", + "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.3.0" + "version": "==1.4.1" }, "importlib-metadata": { "hashes": [ - "sha256:5d26852efe48c0a32b0509ffbc583fda1a2266545a78d104a6f4aff3db17d700", - "sha256:c58c8eb8a762858f49e18436ff552e83914778e50e9d2f1660535ffb364552ec" + "sha256:637245b8bab2b6502fcbc752cc4b7a6f6243bb02b31c5c26156ad103d3d45670", + "sha256:7401a975809ea1fdc658c3aa4f78cc2195a0e019c5cbc4c06122884e9ae80c23" ], "markers": "python_version < '3.10'", - "version": "==4.11.4" + "version": "==4.12.0" }, "iniconfig": { "hashes": [ @@ -2076,38 +2073,39 @@ }, "nodeenv": { "hashes": [ - "sha256:3ef13ff90291ba2a4a7a4ff9a979b63ffdd00a464dbe04acf0ea6471517a4c2b", - "sha256:621e6b7076565ddcacd2db0294c0381e01fd28945ab36bcf00f41c5daf63bef7" + "sha256:27083a7b96a25f2f5e1d8cb4b6317ee8aeda3bdd121394e5ac54e498028a042e", + "sha256:e0e7f7dfb85fc5394c6fe1e8fa98131a2473e04311a45afb6508f7cf1836fa2b" ], - "version": "==1.6.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", + "version": "==1.7.0" }, "numpy": { "hashes": [ - "sha256:0791fbd1e43bf74b3502133207e378901272f3c156c4df4954cad833b1380207", - "sha256:1ce7ab2053e36c0a71e7a13a7475bd3b1f54750b4b433adc96313e127b870887", - "sha256:2d487e06ecbf1dc2f18e7efce82ded4f705f4bd0cd02677ffccfb39e5c284c7e", - "sha256:37431a77ceb9307c28382c9773da9f306435135fae6b80b62a11c53cfedd8802", - "sha256:3e1ffa4748168e1cc8d3cde93f006fe92b5421396221a02f2274aab6ac83b077", - "sha256:425b390e4619f58d8526b3dcf656dde069133ae5c240229821f01b5f44ea07af", - "sha256:43a8ca7391b626b4c4fe20aefe79fec683279e31e7c79716863b4b25021e0e74", - "sha256:4c6036521f11a731ce0648f10c18ae66d7143865f19f7299943c985cdc95afb5", - "sha256:59d55e634968b8f77d3fd674a3cf0b96e85147cd6556ec64ade018f27e9479e1", - "sha256:64f56fc53a2d18b1924abd15745e30d82a5782b2cab3429aceecc6875bd5add0", - "sha256:7228ad13744f63575b3a972d7ee4fd61815b2879998e70930d4ccf9ec721dce0", - "sha256:9ce7df0abeabe7fbd8ccbf343dc0db72f68549856b863ae3dd580255d009648e", - "sha256:a911e317e8c826ea632205e63ed8507e0dc877dcdc49744584dfc363df9ca08c", - "sha256:b89bf9b94b3d624e7bb480344e91f68c1c6c75f026ed6755955117de00917a7c", - "sha256:ba9ead61dfb5d971d77b6c131a9dbee62294a932bf6a356e48c75ae684e635b3", - "sha256:c1d937820db6e43bec43e8d016b9b3165dcb42892ea9f106c70fb13d430ffe72", - "sha256:cc7f00008eb7d3f2489fca6f334ec19ca63e31371be28fd5dad955b16ec285bd", - "sha256:d4c5d5eb2ec8da0b4f50c9a843393971f31f1d60be87e0fb0917a49133d257d6", - "sha256:e96d7f3096a36c8754207ab89d4b3282ba7b49ea140e4973591852c77d09eb76", - "sha256:f0725df166cf4785c0bc4cbfb320203182b1ecd30fee6e541c8752a92df6aa32", - "sha256:f3eb268dbd5cfaffd9448113539e44e2dd1c5ca9ce25576f7c04a5453edc26fa", - "sha256:fb7a980c81dd932381f8228a426df8aeb70d59bbcda2af075b627bbc50207cba" - ], - "index": "pypi", - "version": "==1.22.4" + "sha256:092f5e6025813e64ad6d1b52b519165d08c730d099c114a9247c9bb635a2a450", + "sha256:196cd074c3f97c4121601790955f915187736f9cf458d3ee1f1b46aff2b1ade0", + "sha256:1c29b44905af288b3919803aceb6ec7fec77406d8b08aaa2e8b9e63d0fe2f160", + "sha256:2b2da66582f3a69c8ce25ed7921dcd8010d05e59ac8d89d126a299be60421171", + "sha256:5043bcd71fcc458dfb8a0fc5509bbc979da0131b9d08e3d5f50fb0bbb36f169a", + "sha256:58bfd40eb478f54ff7a5710dd61c8097e169bc36cc68333d00a9bcd8def53b38", + "sha256:79a506cacf2be3a74ead5467aee97b81fca00c9c4c8b3ba16dbab488cd99ba10", + "sha256:94b170b4fa0168cd6be4becf37cb5b127bd12a795123984385b8cd4aca9857e5", + "sha256:97a76604d9b0e79f59baeca16593c711fddb44936e40310f78bfef79ee9a835f", + "sha256:98e8e0d8d69ff4d3fa63e6c61e8cfe2d03c29b16b58dbef1f9baa175bbed7860", + "sha256:ac86f407873b952679f5f9e6c0612687e51547af0e14ddea1eedfcb22466babd", + "sha256:ae8adff4172692ce56233db04b7ce5792186f179c415c37d539c25de7298d25d", + "sha256:bd3fa4fe2e38533d5336e1272fc4e765cabbbde144309ccee8675509d5cd7b05", + "sha256:d0d2094e8f4d760500394d77b383a1b06d3663e8892cdf5df3c592f55f3bff66", + "sha256:d54b3b828d618a19779a84c3ad952e96e2c2311b16384e973e671aa5be1f6187", + "sha256:d6ca8dabe696c2785d0c8c9b0d8a9b6e5fdbe4f922bde70d57fa1a2848134f95", + "sha256:d8cc87bed09de55477dba9da370c1679bd534df9baa171dd01accbb09687dac3", + "sha256:f0f18804df7370571fb65db9b98bf1378172bd4e962482b857e612d1fec0f53e", + "sha256:f1d88ef79e0a7fa631bb2c3dda1ea46b32b1fe614e10fedd611d3d5398447f2f", + "sha256:f9c3fc2adf67762c9fe1849c859942d23f8d3e0bee7b5ed3d4a9c3eeb50a2f07", + "sha256:fc431493df245f3c627c0c05c2bd134535e7929dbe2e602b80e42bf52ff760bc", + "sha256:fe8b9683eb26d2c4d5db32cd29b38fdcf8381324ab48313b5b69088e0e355379" + ], + "index": "pypi", + "version": "==1.23.0" }, "opencv-python-headless": { "hashes": [ @@ -2130,6 +2128,33 @@ "markers": "python_version >= '3.6'", "version": "==21.3" }, + "pandas": { + "hashes": [ + "sha256:07238a58d7cbc8a004855ade7b75bbd22c0db4b0ffccc721556bab8a095515f6", + "sha256:0daf876dba6c622154b2e6741f29e87161f844e64f84801554f879d27ba63c0d", + "sha256:16ad23db55efcc93fa878f7837267973b61ea85d244fc5ff0ccbcfa5638706c5", + "sha256:1d9382f72a4f0e93909feece6fef5500e838ce1c355a581b3d8f259839f2ea76", + "sha256:24ea75f47bbd5574675dae21d51779a4948715416413b30614c1e8b480909f81", + "sha256:2893e923472a5e090c2d5e8db83e8f907364ec048572084c7d10ef93546be6d1", + "sha256:2ff7788468e75917574f080cd4681b27e1a7bf36461fe968b49a87b5a54d007c", + "sha256:41fc406e374590a3d492325b889a2686b31e7a7780bec83db2512988550dadbf", + "sha256:48350592665ea3cbcd07efc8c12ff12d89be09cd47231c7925e3b8afada9d50d", + "sha256:605d572126eb4ab2eadf5c59d5d69f0608df2bf7bcad5c5880a47a20a0699e3e", + "sha256:6dfbf16b1ea4f4d0ee11084d9c026340514d1d30270eaa82a9f1297b6c8ecbf0", + "sha256:6f803320c9da732cc79210d7e8cc5c8019aad512589c910c66529eb1b1818230", + "sha256:721a3dd2f06ef942f83a819c0f3f6a648b2830b191a72bbe9451bcd49c3bd42e", + "sha256:755679c49460bd0d2f837ab99f0a26948e68fa0718b7e42afbabd074d945bf84", + "sha256:78b00429161ccb0da252229bcda8010b445c4bf924e721265bec5a6e96a92e92", + "sha256:958a0588149190c22cdebbc0797e01972950c927a11a900fe6c2296f207b1d6f", + "sha256:a3924692160e3d847e18702bb048dc38e0e13411d2b503fecb1adf0fcf950ba4", + "sha256:d51674ed8e2551ef7773820ef5dab9322be0828629f2cbf8d1fc31a0c4fed640", + "sha256:d5ebc990bd34f4ac3c73a2724c2dcc9ee7bf1ce6cf08e87bb25c6ad33507e318", + "sha256:d6c0106415ff1a10c326c49bc5dd9ea8b9897a6ca0c8688eb9c30ddec49535ef", + "sha256:e48fbb64165cda451c06a0f9e4c7a16b534fcabd32546d531b3c240ce2844112" + ], + "index": "pypi", + "version": "==1.4.3" + }, "parameterized": { "hashes": [ "sha256:41bbff37d6186430f77f900d777e5bb6a24928a1c46fb1de692f8b52b8833b5c", @@ -2148,47 +2173,67 @@ }, "pillow": { "hashes": [ - "sha256:088df396b047477dd1bbc7de6e22f58400dae2f21310d9e2ec2933b2ef7dfa4f", - "sha256:09e67ef6e430f90caa093528bd758b0616f8165e57ed8d8ce014ae32df6a831d", - "sha256:0b4d5ad2cd3a1f0d1df882d926b37dbb2ab6c823ae21d041b46910c8f8cd844b", - "sha256:0b525a356680022b0af53385944026d3486fc8c013638cf9900eb87c866afb4c", - "sha256:1d4331aeb12f6b3791911a6da82de72257a99ad99726ed6b63f481c0184b6fb9", - "sha256:20d514c989fa28e73a5adbddd7a171afa5824710d0ab06d4e1234195d2a2e546", - "sha256:2b291cab8a888658d72b575a03e340509b6b050b62db1f5539dd5cd18fd50578", - "sha256:3f6c1716c473ebd1649663bf3b42702d0d53e27af8b64642be0dd3598c761fb1", - "sha256:42dfefbef90eb67c10c45a73a9bc1599d4dac920f7dfcbf4ec6b80cb620757fe", - "sha256:488f3383cf5159907d48d32957ac6f9ea85ccdcc296c14eca1a4e396ecc32098", - "sha256:4d45dbe4b21a9679c3e8b3f7f4f42a45a7d3ddff8a4a16109dff0e1da30a35b2", - "sha256:53c27bd452e0f1bc4bfed07ceb235663a1df7c74df08e37fd6b03eb89454946a", - "sha256:55e74faf8359ddda43fee01bffbc5bd99d96ea508d8a08c527099e84eb708f45", - "sha256:59789a7d06c742e9d13b883d5e3569188c16acb02eeed2510fd3bfdbc1bd1530", - "sha256:5b650dbbc0969a4e226d98a0b440c2f07a850896aed9266b6fedc0f7e7834108", - "sha256:66daa16952d5bf0c9d5389c5e9df562922a59bd16d77e2a276e575d32e38afd1", - "sha256:6e760cf01259a1c0a50f3c845f9cad1af30577fd8b670339b1659c6d0e7a41dd", - "sha256:7502539939b53d7565f3d11d87c78e7ec900d3c72945d4ee0e2f250d598309a0", - "sha256:769a7f131a2f43752455cc72f9f7a093c3ff3856bf976c5fb53a59d0ccc704f6", - "sha256:7c150dbbb4a94ea4825d1e5f2c5501af7141ea95825fadd7829f9b11c97aaf6c", - "sha256:8844217cdf66eabe39567118f229e275f0727e9195635a15e0e4b9227458daaf", - "sha256:8a66fe50386162df2da701b3722781cbe90ce043e7d53c1fd6bd801bca6b48d4", - "sha256:9370d6744d379f2de5d7fa95cdbd3a4d92f0b0ef29609b4b1687f16bc197063d", - "sha256:937a54e5694684f74dcbf6e24cc453bfc5b33940216ddd8f4cd8f0f79167f765", - "sha256:9c857532c719fb30fafabd2371ce9b7031812ff3889d75273827633bca0c4602", - "sha256:a4165205a13b16a29e1ac57efeee6be2dfd5b5408122d59ef2145bc3239fa340", - "sha256:b3fe2ff1e1715d4475d7e2c3e8dabd7c025f4410f79513b4ff2de3d51ce0fa9c", - "sha256:b6617221ff08fbd3b7a811950b5c3f9367f6e941b86259843eab77c8e3d2b56b", - "sha256:b761727ed7d593e49671d1827044b942dd2f4caae6e51bab144d4accf8244a84", - "sha256:baf3be0b9446a4083cc0c5bb9f9c964034be5374b5bc09757be89f5d2fa247b8", - "sha256:c17770a62a71718a74b7548098a74cd6880be16bcfff5f937f900ead90ca8e92", - "sha256:c67db410508b9de9c4694c57ed754b65a460e4812126e87f5052ecf23a011a54", - "sha256:d78ca526a559fb84faaaf84da2dd4addef5edb109db8b81677c0bb1aad342601", - "sha256:e9ed59d1b6ee837f4515b9584f3d26cf0388b742a11ecdae0d9237a94505d03a", - "sha256:f054b020c4d7e9786ae0404278ea318768eb123403b18453e28e47cdb7a0a4bf", - "sha256:f372d0f08eff1475ef426344efe42493f71f377ec52237bf153c5713de987251", - "sha256:f3f6a6034140e9e17e9abc175fc7a266a6e63652028e157750bd98e804a8ed9a", - "sha256:ffde4c6fabb52891d81606411cbfaf77756e3b561b566efd270b3ed3791fde4e" - ], - "index": "pypi", - "version": "==9.1.1" + "sha256:0030fdbd926fb85844b8b92e2f9449ba89607231d3dd597a21ae72dc7fe26927", + "sha256:030e3460861488e249731c3e7ab59b07c7853838ff3b8e16aac9561bb345da14", + "sha256:0ed2c4ef2451de908c90436d6e8092e13a43992f1860275b4d8082667fbb2ffc", + "sha256:136659638f61a251e8ed3b331fc6ccd124590eeff539de57c5f80ef3a9594e58", + "sha256:13b725463f32df1bfeacbf3dd197fb358ae8ebcd8c5548faa75126ea425ccb60", + "sha256:1536ad017a9f789430fb6b8be8bf99d2f214c76502becc196c6f2d9a75b01b76", + "sha256:15928f824870535c85dbf949c09d6ae7d3d6ac2d6efec80f3227f73eefba741c", + "sha256:17d4cafe22f050b46d983b71c707162d63d796a1235cdf8b9d7a112e97b15bac", + "sha256:1802f34298f5ba11d55e5bb09c31997dc0c6aed919658dfdf0198a2fe75d5490", + "sha256:1cc1d2451e8a3b4bfdb9caf745b58e6c7a77d2e469159b0d527a4554d73694d1", + "sha256:1fd6f5e3c0e4697fa7eb45b6e93996299f3feee73a3175fa451f49a74d092b9f", + "sha256:254164c57bab4b459f14c64e93df11eff5ded575192c294a0c49270f22c5d93d", + "sha256:2ad0d4df0f5ef2247e27fc790d5c9b5a0af8ade9ba340db4a73bb1a4a3e5fb4f", + "sha256:2c58b24e3a63efd22554c676d81b0e57f80e0a7d3a5874a7e14ce90ec40d3069", + "sha256:2d33a11f601213dcd5718109c09a52c2a1c893e7461f0be2d6febc2879ec2402", + "sha256:337a74fd2f291c607d220c793a8135273c4c2ab001b03e601c36766005f36885", + "sha256:37ff6b522a26d0538b753f0b4e8e164fdada12db6c6f00f62145d732d8a3152e", + "sha256:3d1f14f5f691f55e1b47f824ca4fdcb4b19b4323fe43cc7bb105988cad7496be", + "sha256:408673ed75594933714482501fe97e055a42996087eeca7e5d06e33218d05aa8", + "sha256:4134d3f1ba5f15027ff5c04296f13328fecd46921424084516bdb1b2548e66ff", + "sha256:4ad2f835e0ad81d1689f1b7e3fbac7b01bb8777d5a985c8962bedee0cc6d43da", + "sha256:50dff9cc21826d2977ef2d2a205504034e3a4563ca6f5db739b0d1026658e004", + "sha256:510cef4a3f401c246cfd8227b300828715dd055463cdca6176c2e4036df8bd4f", + "sha256:5aed7dde98403cd91d86a1115c78d8145c83078e864c1de1064f52e6feb61b20", + "sha256:69bd1a15d7ba3694631e00df8de65a8cb031911ca11f44929c97fe05eb9b6c1d", + "sha256:6bf088c1ce160f50ea40764f825ec9b72ed9da25346216b91361eef8ad1b8f8c", + "sha256:6e8c66f70fb539301e064f6478d7453e820d8a2c631da948a23384865cd95544", + "sha256:727dd1389bc5cb9827cbd1f9d40d2c2a1a0c9b32dd2261db522d22a604a6eec9", + "sha256:74a04183e6e64930b667d321524e3c5361094bb4af9083db5c301db64cd341f3", + "sha256:75e636fd3e0fb872693f23ccb8a5ff2cd578801251f3a4f6854c6a5d437d3c04", + "sha256:7761afe0126d046974a01e030ae7529ed0ca6a196de3ec6937c11df0df1bc91c", + "sha256:7888310f6214f19ab2b6df90f3f06afa3df7ef7355fc025e78a3044737fab1f5", + "sha256:7b0554af24df2bf96618dac71ddada02420f946be943b181108cac55a7a2dcd4", + "sha256:7c7b502bc34f6e32ba022b4a209638f9e097d7a9098104ae420eb8186217ebbb", + "sha256:808add66ea764ed97d44dda1ac4f2cfec4c1867d9efb16a33d158be79f32b8a4", + "sha256:831e648102c82f152e14c1a0938689dbb22480c548c8d4b8b248b3e50967b88c", + "sha256:93689632949aff41199090eff5474f3990b6823404e45d66a5d44304e9cdc467", + "sha256:96b5e6874431df16aee0c1ba237574cb6dff1dcb173798faa6a9d8b399a05d0e", + "sha256:9a54614049a18a2d6fe156e68e188da02a046a4a93cf24f373bffd977e943421", + "sha256:a138441e95562b3c078746a22f8fca8ff1c22c014f856278bdbdd89ca36cff1b", + "sha256:a647c0d4478b995c5e54615a2e5360ccedd2f85e70ab57fbe817ca613d5e63b8", + "sha256:a9c9bc489f8ab30906d7a85afac4b4944a572a7432e00698a7239f44a44e6efb", + "sha256:ad2277b185ebce47a63f4dc6302e30f05762b688f8dc3de55dbae4651872cdf3", + "sha256:b6d5e92df2b77665e07ddb2e4dbd6d644b78e4c0d2e9272a852627cdba0d75cf", + "sha256:bc431b065722a5ad1dfb4df354fb9333b7a582a5ee39a90e6ffff688d72f27a1", + "sha256:bdd0de2d64688ecae88dd8935012c4a72681e5df632af903a1dca8c5e7aa871a", + "sha256:c79698d4cd9318d9481d89a77e2d3fcaeff5486be641e60a4b49f3d2ecca4e28", + "sha256:cb6259196a589123d755380b65127ddc60f4c64b21fc3bb46ce3a6ea663659b0", + "sha256:d5b87da55a08acb586bad5c3aa3b86505f559b84f39035b233d5bf844b0834b1", + "sha256:dcd7b9c7139dc8258d164b55696ecd16c04607f1cc33ba7af86613881ffe4ac8", + "sha256:dfe4c1fedfde4e2fbc009d5ad420647f7730d719786388b7de0999bf32c0d9fd", + "sha256:ea98f633d45f7e815db648fd7ff0f19e328302ac36427343e4432c84432e7ff4", + "sha256:ec52c351b35ca269cb1f8069d610fc45c5bd38c3e91f9ab4cbbf0aebc136d9c8", + "sha256:eef7592281f7c174d3d6cbfbb7ee5984a671fcd77e3fc78e973d492e9bf0eb3f", + "sha256:f07f1f00e22b231dd3d9b9208692042e29792d6bd4f6639415d2f23158a80013", + "sha256:f3fac744f9b540148fa7715a435d2283b71f68bfb6d4aae24482a890aed18b59", + "sha256:fa768eff5f9f958270b081bb33581b4b569faabf8774726b283edb06617101dc", + "sha256:fac2d65901fb0fdf20363fbd345c01958a742f2dc62a8dd4495af66e3ff502a4" + ], + "index": "pypi", + "version": "==9.2.0" }, "platformdirs": { "hashes": [ @@ -2426,11 +2471,11 @@ }, "requests": { "hashes": [ - "sha256:bc7861137fbce630f17b03d3ad02ad0bf978c844f3536d0edda6499dafce2b6f", - "sha256:d568723a7ebd25875d8d1eaf5dfa068cd2fc8194b2e483d7b1f7c81918dbec6b" + "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983", + "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349" ], "index": "pypi", - "version": "==2.28.0" + "version": "==2.28.1" }, "reverse-geocoder": { "hashes": [ @@ -2468,6 +2513,14 @@ "index": "pypi", "version": "==1.8.1" }, + "setuptools": { + "hashes": [ + "sha256:16923d366ced322712c71ccb97164d07472abeecd13f3a6c283f6d5d26722793", + "sha256:db3b8e2f922b2a910a29804776c643ea609badb6a32c4bcc226fd4fd902cce65" + ], + "markers": "python_version >= '3.7'", + "version": "==63.1.0" + }, "six": { "hashes": [ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", @@ -2492,11 +2545,11 @@ }, "sphinx": { "hashes": [ - "sha256:7bf8ca9637a4ee15af412d1a1d9689fec70523a68ca9bb9127c2f3eeb344e2e6", - "sha256:ebf612653238bcc8f4359627a9b7ce44ede6fdd75d9d30f68255c7383d3a6226" + "sha256:b18e978ea7565720f26019c702cd85c84376e948370f1cd43d60265010e1c7b0", + "sha256:d3e57663eed1d7c5c50895d191fdeda0b54ded6f44d5621b50709466c338d1e8" ], "index": "pypi", - "version": "==4.5.0" + "version": "==5.0.2" }, "sphinx-rtd-theme": { "hashes": [ @@ -2570,6 +2623,15 @@ "index": "pypi", "version": "==3.5.4" }, + "tabulate": { + "hashes": [ + "sha256:0ba055423dbaa164b9e456abe7920c5e8ed33fcc16f6d1b2f2d152c8e1e8b4fc", + "sha256:436f1c768b424654fce8597290d2764def1eea6a77cfa5c33be00b1bc0f4f63d", + "sha256:6c57f3f3dd7ac2782770155f3adb2db0b1a269637e42f27599925e64b114f519" + ], + "index": "pypi", + "version": "==0.8.10" + }, "tenacity": { "hashes": [ "sha256:43242a20e3e73291a28bcbcacfd6e000b02d3857a9a9fff56b297a27afdc932f", @@ -2596,27 +2658,27 @@ }, "typing-extensions": { "hashes": [ - "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708", - "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376" + "sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02", + "sha256:e6d2677a32f47fc7eb2795db1dd15c1f34eff616bcaf2cfb5e997f854fa1c4a6" ], - "markers": "python_version < '3.10'", - "version": "==4.2.0" + "markers": "python_version >= '3.7'", + "version": "==4.3.0" }, "urllib3": { "hashes": [ - "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14", - "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e" + "sha256:8298d6d56d39be0e3bc13c1c97d133f9b45d797169a0e11cdd0e0489d786f7ec", + "sha256:879ba4d1e89654d9769ce13121e0f94310ea32e8d2f8cf587b77c08bbcdb30d6" ], "index": "pypi", - "version": "==1.26.9" + "version": "==1.26.10" }, "virtualenv": { "hashes": [ - "sha256:e617f16e25b42eb4f6e74096b9c9e37713cf10bf30168fb4a739f3fa8f898a3a", - "sha256:ef589a79795589aada0c1c5b319486797c03b67ac3984c48c669c0e4f50df3a5" + "sha256:288171134a2ff3bfb1a2f54f119e77cd1b81c29fc1265a2356f3e8d14c7d58c4", + "sha256:b30aefac647e86af6d82bfc944c556f8f1a9c90427b2fb4e3bfbf338cb82becf" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==20.14.1" + "version": "==20.15.1" }, "zipp": { "hashes": [ diff --git a/selfdrive/debug/can_table.py b/selfdrive/debug/can_table.py index e8cd084a32..11d070e708 100755 --- a/selfdrive/debug/can_table.py +++ b/selfdrive/debug/can_table.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 import argparse -import pandas as pd # pylint: disable=import-error +import pandas as pd import cereal.messaging as messaging From d8089fb94e9ad1ab54bc3baf1acbb430b305f612 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Thu, 7 Jul 2022 23:07:21 -0700 Subject: [PATCH 043/112] Add video for 2020 Lexus ES Hybrid --- selfdrive/car/toyota/values.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py index 9324e6baf5..8149bfd063 100644 --- a/selfdrive/car/toyota/values.py +++ b/selfdrive/car/toyota/values.py @@ -152,7 +152,7 @@ CAR_INFO: Dict[str, Union[ToyotaCarInfo, List[ToyotaCarInfo]]] = { CAR.LEXUS_CTH: ToyotaCarInfo("Lexus CT Hybrid 2017-18", "LSS", footnotes=[Footnote.DSU]), CAR.LEXUS_ESH: ToyotaCarInfo("Lexus ES Hybrid 2017-18", "LSS", footnotes=[Footnote.DSU]), CAR.LEXUS_ES_TSS2: ToyotaCarInfo("Lexus ES 2019-21"), - CAR.LEXUS_ESH_TSS2: ToyotaCarInfo("Lexus ES Hybrid 2019-22"), + CAR.LEXUS_ESH_TSS2: ToyotaCarInfo("Lexus ES Hybrid 2019-22", video_link="https://youtu.be/BZ29osRVJeg?t=12"), CAR.LEXUS_IS: ToyotaCarInfo("Lexus IS 2017-19"), CAR.LEXUS_NX: ToyotaCarInfo("Lexus NX 2018-19", footnotes=[Footnote.DSU]), CAR.LEXUS_NXH: ToyotaCarInfo("Lexus NX Hybrid 2018-19", footnotes=[Footnote.DSU]), From ed47032a6d51d1aeaf4cd553ae9b350e04672558 Mon Sep 17 00:00:00 2001 From: Lee Jong Mun <43285072+crwusiz@users.noreply.github.com> Date: Fri, 8 Jul 2022 16:03:57 +0900 Subject: [PATCH 044/112] Add Korean translations (#25073) * Add Korean translations Signed-off-by: crwusiz * line error fix Signed-off-by: crwusiz * space error retry Signed-off-by: crwusiz * " fix Signed-off-by: crwusiz * translation --release * main_ko.qm remove * main_ko.qm remake * Update ko and fix zh * fix Linguist warnings * commit noun Co-authored-by: Shane Smiskol --- selfdrive/ui/translations/languages.json | 3 +- selfdrive/ui/translations/main_ko.qm | Bin 0 -> 19159 bytes selfdrive/ui/translations/main_ko.ts | 1212 ++++++++++++++++++++++ 3 files changed, 1214 insertions(+), 1 deletion(-) create mode 100644 selfdrive/ui/translations/main_ko.qm create mode 100644 selfdrive/ui/translations/main_ko.ts diff --git a/selfdrive/ui/translations/languages.json b/selfdrive/ui/translations/languages.json index e62de24a1e..b8c3a50fd7 100644 --- a/selfdrive/ui/translations/languages.json +++ b/selfdrive/ui/translations/languages.json @@ -1,4 +1,5 @@ { "English": "", - "中文(简体)": "main_zh" + "中文(简体)": "main_zh", + "한국어": "main_ko" } diff --git a/selfdrive/ui/translations/main_ko.qm b/selfdrive/ui/translations/main_ko.qm new file mode 100644 index 0000000000000000000000000000000000000000..62ddb3be2b89c6c73e82458ae86c02825c925de5 GIT binary patch literal 19159 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 literal 0 HcmV?d00001 diff --git a/selfdrive/ui/translations/main_ko.ts b/selfdrive/ui/translations/main_ko.ts new file mode 100644 index 0000000000..fd643224cc --- /dev/null +++ b/selfdrive/ui/translations/main_ko.ts @@ -0,0 +1,1212 @@ + + + + + AbstractAlert + + + Close + 닫기 + + + + Snooze Update + 업데이트 일시중지 + + + + Reboot and Update + 업데이트 및 재부팅 + + + + AdvancedNetworking + + + Back + 뒤로 + + + + Enable Tethering + 테더링 사용 + + + + Tethering Password + 테더링 비밀번호 + + + + + EDIT + 편집 + + + + Enter new tethering password + 새 테더링 비밀번호 입력 + + + + IP Address + IP 주소 + + + + Enable Roaming + 로밍 사용 + + + + APN Setting + APN 설정 + + + + Enter APN + APN 입력 + + + + leave blank for automatic configuration + 자동 구성을 위해 비워둠 + + + + ConfirmationDialog + + + + Ok + 확인 + + + + Cancel + 취소 + + + + DeclinePage + + + You must accept the Terms and Conditions in order to use openpilot. + 당신은 반드시 약관에 동의해야만 openpilot을 사용할 수 있습니다. + + + + Back + 뒤로 + + + + Decline, uninstall %1 + 거절,삭제 %1 + + + + DevicePanel + + + Dongle ID + Dongle ID + + + + N/A + N/A + + + + Serial + Serial + + + + Driver Camera + 운전자 카메라 + + + + PREVIEW + 미리보기 + + + + Preview the driver facing camera to help optimize device mounting position for best driver monitoring experience. (vehicle must be off) + 운전자 카메라를 미리 보면서 최적의 운전자 모니터링 경험을 위해 기기 장착 위치를 최적화할수 있습니다. (차량은 반드시 닫아야 합니다) + + + + Reset Calibration + 캘리브레이션 재설정 + + + + RESET + 재설정 + + + + Are you sure you want to reset calibration? + 캘리브레이션을 재설정하시겠습니까? + + + + Review Training Guide + 트레이닝 가이드 다시보기 + + + + REVIEW + 다시보기 + + + + Review the rules, features, and limitations of openpilot + openpilot의 규칙, 기능, 제한 다시보기 + + + + Are you sure you want to review the training guide? + 트레이닝 가이드를 다시보시겠습니까? + + + + Regulatory + 규제 + + + + VIEW + 보기 + + + Change Language + 언어변경 + + + CHANGE + 변경 + + + Select a language + 언어선택 + + + + Reboot + 재부팅 + + + + Power Off + 전원 종료 + + + + openpilot requires the device to be mounted within 4° left or right and within 5° up or 8° down. openpilot is continuously calibrating, resetting is rarely required. + openpilot은 장치를 왼쪽 또는 오른쪽 4° 이내, 위쪽 5° 또는 아래쪽 8° 이내로 설치해야 합니다. openpilot은 지속적으로 보정되므로 리셋이 거의 필요하지 않습니다. + + + + Your device is pointed %1° %2 and %3° %4. + 사용자의 기기가 %1° %2 및 %3° %4를 가리키고 있습니다. + + + + down + 아래 + + + + up + + + + + left + 왼쪽 + + + + right + 오른쪽 + + + + Are you sure you want to reboot? + 재부팅 하시겠습니까? + + + + Disengage to Reboot + 재부팅 하려면 해제하세요 + + + + Are you sure you want to power off? + 전원을 종료하시겠습니까? + + + + Disengage to Power Off + 전원을 종료하려면 해제하세요 + + + + DriveStats + + + Drives + 주행수 + + + + Hours + 시간 + + + + ALL TIME + 전체 시간 + + + + PAST WEEK + 지난주 + + + + KM + Km + + + + Miles + Miles + + + + DriverViewScene + + + camera starting + 카메라 시작중 + + + + InputDialog + + + Cancel + 취소 + + + + Need at least + 최소 필요 + + + + characters! + 문자! + + + + Installer + + + Installing... + 설치중... + + + + Receiving objects: + 수신중: + + + + Resolving deltas: + 델타병합: + + + + Updating files: + 파일갱신: + + + + MapPanel + + + Current Destination + 현재 목적지 + + + + CLEAR + CLEAR + + + + Recent Destinations + 최근 목적지 + + + + Try the Navigation Beta + 네비게이션(베타)을 사용해보세요 + + + + Get turn-by-turn directions displayed and more with a comma +prime subscription. Sign up now: https://connect.comma.ai + 자세한 경로안내를 확인하시려면 comma prime을 구독하세요. +즉시등록:https://connect.comma.ai + + + + No home +location set + 집 +설정되지않음 + + + + No work +location set + 회사 +설정되지않음 + + + + no recent destinations + 최근 경로 없음 + + + + MultiOptionDialog + + Select + 선택 + + + Cancel + 취소 + + + + Networking + + + Advanced + 고급 + + + + Enter password + 비밀번호를 입력하세요 + + + + + for " + 하기위한 " + + + + Wrong password + 비밀번호가 틀렸습니다 + + + + NvgWindow + + + km/h + km/h + + + + mph + mph + + + + + MAX + MAX + + + + + SPEED + SPEED + + + + + LIMIT + LIMIT + + + + OffroadHome + + + UPDATE + 업데이트 + + + + ALERTS + 알림 + + + + ALERT + 알림 + + + + PairingPopup + + + Pair your device to your comma account + 장치를 콤마 계정과 페어링합니다 + + + + + <ol type='1' style='margin-left: 15px;'> + <li style='margin-bottom: 50px;'>Go to https://connect.comma.ai on your phone</li> + <li style='margin-bottom: 50px;'>Click "add new device" and scan the QR code on the right</li> + <li style='margin-bottom: 50px;'>Bookmark connect.comma.ai to your home screen to use it like an app</li> + </ol> + + + <ol type='1' style='margin-left: 15px;'> + <li style='margin-bottom: 50px;'>https://connect.comma.ai에 접속하세요</li> + <li style='margin-bottom: 50px;'>"새 장치 추가"를 클릭하고 오른쪽 QR 코드를 검색합니다.</li> + <li style='margin-bottom: 50px;'>connect.comma.ai을 앱처럼 사용하려면 홈 화면에 바로가기를 만드십시오.</li> + </ol> + + + + + PrimeAdWidget + + + Upgrade Now + 지금 업그레이드 + + + + Become a comma prime member at connect.comma.ai + connect.comma.ai에서 comma prime에 가입합니다 + + + + PRIME FEATURES: + PRIME 기능: + + + + Remote access + 원격 접속 + + + + 1 year of storage + 1년간 저장 + + + + Developer perks + 개발자 혜택 + + + + PrimeUserWidget + + + ✓ SUBSCRIBED + ✓ 구독함 + + + + comma prime + comma prime + + + + CONNECT.COMMA.AI + CONNECT.COMMA.AI + + + + COMMA POINTS + COMMA POINTS + + + + QObject + + + Reboot + 재부팅 + + + + Exit + 종료 + + + + dashcam + dashcam + + + + openpilot + openpilot + + + + %1 minute%2 ago + %1 분%2 전 + + + + %1 hour%2 ago + %1 시간%2 전 + + + + %1 day%2 ago + %1 일%2 전 + + + + Reset + + + Reset failed. Reboot to try again. + 초기화 실패. 재부팅후 다시 시도하세요. + + + + Are you sure you want to reset your device? + 장치를 초기화 하시겠습니까? + + + + Resetting device... + 장치 초기화중... + + + + System Reset + 장치 초기화 + + + + System reset triggered. Press confirm to erase all content and settings. Press cancel to resume boot. + 장치를 초기화 합니다. 확인버튼을 누르면 모든 내용과 설정이 초기화됩니다. 취소를 누르면 다시 부팅합니다. + + + + Cancel + 취소 + + + + Reboot + 재부팅 + + + + Confirm + 확인 + + + + Unable to mount data partition. Press confirm to reset your device. + 데이터 파티션을 마운트할 수 없습니다. 확인 버튼을 눌러 장치를 리셋합니다. + + + + RichTextDialog + + + Ok + 확인 + + + + SettingsWindow + + + × + × + + + + Device + 장치 + + + + + Network + 네트워크 + + + + Toggles + 토글 + + + + Software + 소프트웨어 + + + + Navigation + 네비게이션 + + + + Setup + + + WARNING: Low Voltage + 경고: 전압이 낮습니다 + + + + Power your device in a car with a harness or proceed at your own risk. + 하네스 보드에 차량의 전원을 연결하세요. + + + + Power off + 전원 종료 + + + + + + Continue + 계속 + + + + Getting Started + 시작 + + + + Before we get on the road, let’s finish installation and cover some details. + 출발하기 전에 설치를 완료하고 몇 가지 세부 사항을 살펴보겠습니다. + + + + Connect to Wi-Fi + wifi 연결 + + + + + Back + 뒤로 + + + + Continue without Wi-Fi + wifi 없이 계속 + + + + Waiting for internet + 네트워크 접속을 기다립니다 + + + + Choose Software to Install + 설치할 소프트웨어를 선택하세요 + + + + Dashcam + Dashcam + + + + Custom Software + Custom Software + + + + Enter URL + URL 입력 + + + + for Custom Software + for Custom Software + + + + Downloading... + 다운로드중... + + + + Download Failed + 다운로드 실패 + + + + Ensure the entered URL is valid, and the device’s internet connection is good. + 입력된 URL이 유효하고 장치의 인터넷 연결이 잘 되어 있는지 확인합니다. + + + + Reboot device + 재부팅 + + + + Start over + 다시 시작 + + + + SetupWidget + + + Finish Setup + 설치완료 + + + + Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer. + 장치를 (connect.comma.ai)에서 페어링하고 comma prime 오퍼를 청구합니다. + + + + Pair device + 페어링 + + + + Sidebar + + + + CONNECT + 연결 + + + + OFFLINE + 오프라인 + + + + + ONLINE + 온라인 + + + + ERROR + 오류 + + + + + + TEMP + 온도 + + + + HIGH + 높음 + + + + GOOD + 경고 + + + + OK + 좋음 + + + + VEHICLE + 차량 + + + + NO + NO + + + + PANDA + PANDA + + + + GPS + GPS + + + + SEARCH + 검색중 + + + + -- + -- + + + + Wi-Fi + Wi-Fi + + + + ETH + 이더넷 + + + + 2G + 2G + + + + 3G + 3G + + + + LTE + LTE + + + + 5G + 5G + + + + SoftwarePanel + + + Git Branch + Git 브렌치 + + + + Git Commit + Git 커밋 + + + + OS Version + OS 버전 + + + + Version + 버전 + + + + Last Update Check + 최신 업데이트 검사 + + + + The last time openpilot successfully checked for an update. The updater only runs while the car is off. + 이전에 openpilot에서 업데이트를 성공적으로 확인한 시간입니다. 업데이트 프로그램은 차량 연결이 해제되었을때만 작동합니다. + + + + Check for Update + 업데이트 확인 + + + + CHECKING + 검사중 + + + + Uninstall + 삭제 + + + + UNINSTALL + 삭제 + + + + Are you sure you want to uninstall? + 삭제하시겠습니까? + + + + failed to fetch update + 업데이트를 가져올수없습니다 + + + + + CHECK + 확인 + + + + SshControl + + + SSH Keys + SSH 키 + + + + Warning: This grants SSH access to all public keys in your GitHub settings. Never enter a GitHub username other than your own. A comma employee will NEVER ask you to add their GitHub username. + 경고:이렇게 하면 GitHub 설정의 모든 공용 키에 대한 SSH 액세스 권한이 부여됩니다. 자신의 사용자 이름이 아닌 GitHub 사용자 이름을 입력하지 마십시오. comma 직원은 GitHub 사용자 이름을 추가하도록 요청하지 않습니다. + + + + + ADD + 추가 + + + + Enter your GitHub username + GitHub 사용자 ID + + + + LOADING + 로딩 + + + + REMOVE + 제거 + + + + Username '%1' has no keys on GitHub + 사용자 이름 '%1' GitHub에 키가 없습니다 + + + + Request timed out + 요청 시간 초과 + + + + Username '%1' doesn't exist on GitHub + 사용자 이름 '%1' GitHub에 없습니다 + + + + SshToggle + + + Enable SSH + SSH 사용 + + + + TermsPage + + + Terms & Conditions + 약관 + + + + Decline + 거절 + + + + Scroll to accept + 스크롤 허용 + + + + Agree + 동의 + + + + TogglesPanel + + + Enable openpilot + openpilot 사용 + + + + Use the openpilot system for adaptive cruise control and lane keep driver assistance. Your attention is required at all times to use this feature. Changing this setting takes effect when the car is powered off. + 어댑티브 크루즈 컨트롤 및 차선 유지 운전자 보조를 위해 openpilot 시스템을 사용하십시오. 이 기능을 사용하려면 항상 주의를 기울여야 합니다. 이 설정을 변경하면 차량 전원이 꺼질 때 적용됩니다. + + + + Enable Lane Departure Warnings + 차선 이탈 경고 사용 + + + + Receive alerts to steer back into the lane when your vehicle drifts over a detected lane line without a turn signal activated while driving over 31 mph (50 km/h). + 차량이 50km/h(31mph) 이상의 속도로 주행하는 동안 방향 지시등이 활성화되지 않은 상태에서 감지된 차선 위를 주행할 경우 차선이탈 경고를 사용합니다. + + + + Enable Right-Hand Drive + 우측핸들 사용 + + + + Allow openpilot to obey left-hand traffic conventions and perform driver monitoring on right driver seat. + openpilot이 좌측 교통 규칙을 준수하고 우측 운전석에서 운전자 모니터링을 수행합니다. + + + + Use Metric System + 미터법 사용 + + + + Display speed in km/h instead of mph. + mph가 아닌 km/h로 속도 표시. + + + + Record and Upload Driver Camera + 운전자 카메라 기록 및 업로드 + + + + Upload data from the driver facing camera and help improve the driver monitoring algorithm. + 운전자 카메라에서 데이터를 업로드하고 운전자 모니터링 알고리즘을 개선합니다. + + + + Disengage On Accelerator Pedal + 가속페달 조작시 해제 + + + + When enabled, pressing the accelerator pedal will disengage openpilot. + 활성화된 경우 가속 페달을 누르면 openpilot이 해제됩니다. + + + + Show ETA in 24h format + 24시간 형식으로 ETA 표시 + + + + Use 24h format instead of am/pm + 오전/오후 대신 24시간 형식 사용 + + + + openpilot Longitudinal Control + openpilot Longitudinal Control + + + + openpilot will disable the car's radar and will take over control of gas and brakes. Warning: this disables AEB! + openpilot은 차량'의 레이더를 무력화시키고 가속페달과 브레이크의 제어를 인계받을 것이다. 경고: AEB를 비활성화합니다! + + + + Updater + + + Update Required + 업데이트 필요 + + + + An operating system update is required. Connect your device to Wi-Fi for the fastest update experience. The download size is approximately 1GB. + OS 업데이트가 필요합니다. 장치를 wifi에 연결하여 가장 빠른 업데이트 경험을 제공합니다. 다운로드 크기는 약 1GB입니다. + + + + Connect to Wi-Fi + wifi 연결 + + + + Install + 설치 + + + + Back + 뒤로 + + + + Loading... + 로딩중... + + + + Reboot + 재부팅 + + + + Update failed + 업데이트 실패 + + + + WifiUI + + + + Scanning for networks... + 네트워크 검색 중... + + + + CONNECTING... + 연결중... + + + + FORGET + 저장안함 + + + + Forget Wi-Fi Network " + wifi 네트워크 저장안함" + + + From c9fa5ef11a6d47a886b30f65b2064b2d6ae05807 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Fri, 8 Jul 2022 00:23:46 -0700 Subject: [PATCH 045/112] AGNOS 5.2 (#25011) * AGNOS 5.2 * casync manifest --- launch_env.sh | 2 +- system/hardware/tici/agnos.json | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/launch_env.sh b/launch_env.sh index 769613bc79..ac84d6dcbd 100755 --- a/launch_env.sh +++ b/launch_env.sh @@ -7,7 +7,7 @@ export OPENBLAS_NUM_THREADS=1 export VECLIB_MAXIMUM_THREADS=1 if [ -z "$AGNOS_VERSION" ]; then - export AGNOS_VERSION="5.1" + export AGNOS_VERSION="5.2" fi if [ -z "$PASSIVE" ]; then diff --git a/system/hardware/tici/agnos.json b/system/hardware/tici/agnos.json index 004a0f9dfb..853d3ab434 100644 --- a/system/hardware/tici/agnos.json +++ b/system/hardware/tici/agnos.json @@ -1,9 +1,9 @@ [ { "name": "boot", - "url": "https://commadist.azureedge.net/agnosupdate/boot-bb71f49294150c4233b89e2a10768a5a3de003203ecd02e3f845821b35cd409f.img.xz", - "hash": "bb71f49294150c4233b89e2a10768a5a3de003203ecd02e3f845821b35cd409f", - "hash_raw": "bb71f49294150c4233b89e2a10768a5a3de003203ecd02e3f845821b35cd409f", + "url": "https://commadist.azureedge.net/agnosupdate/boot-243ddbb9e2256aa7af7fed0daf8cff4017a3c838c759373a634b8539f271bfb8.img.xz", + "hash": "243ddbb9e2256aa7af7fed0daf8cff4017a3c838c759373a634b8539f271bfb8", + "hash_raw": "243ddbb9e2256aa7af7fed0daf8cff4017a3c838c759373a634b8539f271bfb8", "size": 14780416, "sparse": false, "full_check": true, @@ -41,12 +41,14 @@ }, { "name": "system", - "url": "https://commadist.azureedge.net/agnosupdate/system-11fdbc9e8a9cd27f98346d7e1039bc5b3032d0e892ff95fa1258673ff1809bca.img.xz", - "hash": "45b4719a9e580617cf840036b24fb0dcd32491edd9654d8d74c28d91ff362d36", - "hash_raw": "11fdbc9e8a9cd27f98346d7e1039bc5b3032d0e892ff95fa1258673ff1809bca", + "url": "https://commadist.azureedge.net/agnosupdate/system-59622eddd068d49f2e9df69ef5115e3f205ad369539690a5b240c8c93796dd13.img.xz", + "hash": "44da205d17b44b2be7c94854a6bb3efb2928ec9a9889fe62af8b322d2295b74f", + "hash_raw": "59622eddd068d49f2e9df69ef5115e3f205ad369539690a5b240c8c93796dd13", "size": 10737418240, "sparse": true, "full_check": false, - "has_ab": true + "has_ab": true, + "casync_caibx": "https://commadist.azureedge.net/agnosupdate/system-59622eddd068d49f2e9df69ef5115e3f205ad369539690a5b240c8c93796dd13.caibx", + "casync_store": "https://commadist.azureedge.net/agnosupdate/system-59622eddd068d49f2e9df69ef5115e3f205ad369539690a5b240c8c93796dd13" } ] From 5b4e39990ac4d098f874c8f1e378e2ab855c0036 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 8 Jul 2022 00:41:17 -0700 Subject: [PATCH 046/112] Add Japanese translations (#25078) * Add Japanese translations * test japanese * update tr file * test for unfinished translation tags * add compiled QM add compiled QM * mark as finished * remove from tests, needs some design decisions Co-authored-by: PONPC --- selfdrive/ui/tests/test_translations.py | 10 + selfdrive/ui/translations/main_ja.qm | Bin 0 -> 19159 bytes selfdrive/ui/translations/main_ja.ts | 1207 +++++++++++++++++++++++ 3 files changed, 1217 insertions(+) create mode 100644 selfdrive/ui/translations/main_ja.qm create mode 100644 selfdrive/ui/translations/main_ja.ts diff --git a/selfdrive/ui/tests/test_translations.py b/selfdrive/ui/tests/test_translations.py index 2dedf3d785..3230a99543 100755 --- a/selfdrive/ui/tests/test_translations.py +++ b/selfdrive/ui/tests/test_translations.py @@ -61,6 +61,16 @@ class TestTranslations(unittest.TestCase): self.assertEqual(cur_translations, new_translations, f"{file} ({name}) {file_ext.upper()} translation file out of date. Run selfdrive/ui/update_translations.py --release to update the translation files") + def test_unfinished_translations(self): + for name, file in self.translation_files.items(): + with self.subTest(name=name, file=file): + if not len(file): + raise self.skipTest(f"{name} translation has no defined file") + + cur_translations = self._read_translation_file(TRANSLATIONS_DIR, file, "ts") + self.assertTrue(b"" not in cur_translations, + f"{file} ({name}) translation file has unfinished translations. Finish translations or mark them as completed in Qt Linguist") + if __name__ == "__main__": unittest.main() diff --git a/selfdrive/ui/translations/main_ja.qm b/selfdrive/ui/translations/main_ja.qm new file mode 100644 index 0000000000000000000000000000000000000000..552545cf879ed5c9a4009e63d334dee10c479e33 GIT binary patch literal 19159 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 HImG`LJd!}I literal 0 HcmV?d00001 diff --git a/selfdrive/ui/translations/main_ja.ts b/selfdrive/ui/translations/main_ja.ts new file mode 100644 index 0000000000..fbb654bc4c --- /dev/null +++ b/selfdrive/ui/translations/main_ja.ts @@ -0,0 +1,1207 @@ + + + + + AbstractAlert + + + Close + 閉じる + + + + Snooze Update + 更新停止 + + + + Reboot and Update + 再起動してアップデート + + + + AdvancedNetworking + + + Back + もどる + + + + Enable Tethering + テザリングを有効化 + + + + Tethering Password + テザリングパスワード + + + + + EDIT + 編集 + + + + Enter new tethering password + 新しいテザリングパスワードを入力 + + + + IP Address + IPアドレス + + + + Enable Roaming + ローミングを有効化 + + + + APN Setting + APN 設定 + + + + Enter APN + APN 入力 + + + + leave blank for automatic configuration + 空欄で自動設定 + + + + ConfirmationDialog + + + + Ok + OK + + + + Cancel + キャンセル + + + + DeclinePage + + + You must accept the Terms and Conditions in order to use openpilot. + openpilotを利用するためには、利用規約に同意する必要があります。 + + + + Back + 戻る + + + + Decline, uninstall %1 + 拒否してアンインストール %1 + + + + DevicePanel + + + Dongle ID + ドングル ID + + + + N/A + N/A + + + + Serial + シリアル + + + + Driver Camera + ドライバーカメラ + + + + PREVIEW + プレビュー + + + + Preview the driver facing camera to help optimize device mounting position for best driver monitoring experience. (vehicle must be off) + ドライバーカメラのプレビューにより、デバイスの取り付け位置を最適化し、最高のドライバーモニタリング体験を提供します。(車両の電源を切る必要があります) + + + + Reset Calibration + キャリブレーションリセット + + + + RESET + リセット + + + + Are you sure you want to reset calibration? + 本当にキャリブレーションをリセットしますか? + + + + Review Training Guide + トレーニングガイドを見る + + + + REVIEW + レビュー + + + + Review the rules, features, and limitations of openpilot + openpilot 規約 機能 制約を見る + + + + Are you sure you want to review the training guide? + 本当にトレーニングガイドを見ますか? + + + + Regulatory + レギュレーション + + + + VIEW + ビュー + + + Change Language + 言語を変更 + + + CHANGE + 変更 + + + Select a language + 言語を選択する + + + + Reboot + 再起動 + + + + Power Off + 電源を切る + + + + openpilot requires the device to be mounted within 4° left or right and within 5° up or 8° down. openpilot is continuously calibrating, resetting is rarely required. + openpilot は、左右に4°、上に5°、下に8°の範囲に設置する必要があります。openpilot は継続的に校正されているので、手動でリセットする必要はほとんどありません。 + + + + Your device is pointed %1° %2 and %3° %4. + デバイスは %1° %2 と %3° %4を示しています。 + + + + down + + + + + up + + + + + left + + + + + right + + + + + Are you sure you want to reboot? + 本当に再起動しますか? + + + + Disengage to Reboot + 再起動するために離脱します + + + + Are you sure you want to power off? + 本当に電源を切っても良いですか? + + + + Disengage to Power Off + 電源を切るために離脱します + + + + DriveStats + + + Drives + ドライブ + + + + Hours + 時間 + + + + ALL TIME + 累計 + + + + PAST WEEK + 先週 + + + + KM + km + + + + Miles + マイル + + + + DriverViewScene + + + camera starting + カメラ起動 + + + + InputDialog + + + Cancel + キャンセル + + + + Need at least + 最低限必要なもの + + + + characters! + 記号! + + + + Installer + + + Installing... + インストール... + + + + Receiving objects: + オブジェクトを受信中: + + + + Resolving deltas: + リゾルブ解決中: + + + + Updating files: + ファイルを更新中: + + + + MapPanel + + + Current Destination + 現在の目的地 + + + + CLEAR + クリア + + + + Recent Destinations + 最近の目的地 + + + + Try the Navigation Beta + ベータ版ナビゲーション + + + + Get turn-by-turn directions displayed and more with a comma +prime subscription. Sign up now: https://connect.comma.ai + より詳細な案内や表示に関する情報を得ることができます。 詳しくはこちら:https://connect.comma.ai + + + + No home +location set + 自宅の登録なし +位置を設定 + + + + No work +location set + 職場の登録なし +位置を設定 + + + + no recent destinations + 最寄りの目的地がありません + + + + MultiOptionDialog + + Select + 選択 + + + + Networking + + + Advanced + 詳細 + + + + Enter password + パスワードを入力 + + + + + for " + のため " + + + + Wrong password + パスワードが間違っています + + + + NvgWindow + + + km/h + km/時 + + + + mph + マイル/時 + + + + + MAX + 最大 + + + + + SPEED + 速度 + + + + + LIMIT + 制限 + + + + OffroadHome + + + UPDATE + 更新 + + + + ALERTS + 警告 + + + + ALERT + 警告 + + + + PairingPopup + + + Pair your device to your comma account + デバイスとアカウントを連携する + + + + + <ol type='1' style='margin-left: 15px;'> + <li style='margin-bottom: 50px;'>Go to https://connect.comma.ai on your phone</li> + <li style='margin-bottom: 50px;'>Click "add new device" and scan the QR code on the right</li> + <li style='margin-bottom: 50px;'>Bookmark connect.comma.ai to your home screen to use it like an app</li> + </ol> + + + <ol type='1' style='margin-left: 15px;'> + <li style='margin-bottom: 50px;'>モバイルでアクセス https://connect.comma.ai</li> + <li style='margin-bottom: 50px;'>“新しいデバイスを追加”をクリックし,QRコードを読み込みます</li> + <li style='margin-bottom: 50px;'>connect.comma.aiをホーム画面にブックマークして、アプリのように使うことができます</li> + </ol> + + + + + PrimeAdWidget + + + Upgrade Now + いますぐアップグレード + + + + Become a comma prime member at connect.comma.ai + connect.comma.ai のプライムメンバーになる + + + + PRIME FEATURES: + 主な機能: + + + + Remote access + リモートアクセス + + + + 1 year of storage + 1年の保存期間 + + + + Developer perks + 開発者特典 + + + + PrimeUserWidget + + + ✓ SUBSCRIBED + ✓ 購読 + + + + comma prime + コンマプライム + + + + CONNECT.COMMA.AI + CONNECT.COMMA.AI + + + + COMMA POINTS + コンマポイント + + + + QObject + + + Reboot + 再起動 + + + + Exit + 退出 + + + + dashcam + ダッシュカム + + + + openpilot + オープンパイロット + + + + %1 minute%2 ago + %1 分%2 前 + + + + %1 hour%2 ago + %1 時間%2 前 + + + + %1 day%2 ago + %1 日%2 前 + + + + Reset + + + Reset failed. Reboot to try again. + 初期化に失敗しました。再起動後に再試行してください。 + + + + Are you sure you want to reset your device? + 本当に初期化しますか? + + + + Resetting device... + デバイスが初期化されます... + + + + System Reset + システムを初期化 + + + + System reset triggered. Press confirm to erase all content and settings. Press cancel to resume boot. + システムを初期化させます。 すべてのコンテンツと設定が削除されます。 キャンセルを押すと再起動します。 + + + + Cancel + キャンセル + + + + Reboot + 再起動 + + + + Confirm + 確認 + + + + Unable to mount data partition. Press confirm to reset your device. + dataパーティションをマウントできません。 確認を押すとデバイスが初期化されます。 + + + + RichTextDialog + + + Ok + OK + + + + SettingsWindow + + + × + × + + + + Device + デバイス + + + + + Network + ネットワーク + + + + Toggles + 切り替え + + + + Software + ソフトウェア + + + + Navigation + ナビゲーション + + + + Setup + + + WARNING: Low Voltage + 警告:低電圧 + + + + Power your device in a car with a harness or proceed at your own risk. + 自己責任でハーネスから電源を供給してください。 + + + + Power off + 電源を切る + + + + + + Continue + 続ける + + + + Getting Started + はじめに + + + + Before we get on the road, let’s finish installation and cover some details. + その前に、インストールを完了し、いくつかの詳細を説明します。 + + + + Connect to Wi-Fi + Wi-Fiに接続 + + + + + Back + 戻る + + + + Continue without Wi-Fi + Wi-Fi に未接続で続行 + + + + Waiting for internet + インターネット接続を待機中 + + + + Choose Software to Install + インストールするソフトウェアを選びます + + + + Dashcam + ダッシュカム + + + + Custom Software + カスタムソフトウェア + + + + Enter URL + URLを入力 + + + + for Custom Software + カスタムソフトウェア + + + + Downloading... + ダウンロード中... + + + + Download Failed + ダウンロード失敗 + + + + Ensure the entered URL is valid, and the device’s internet connection is good. + 入力されたURLが有効であること、デバイスがインターネットに接続されていることを確認してください。 + + + + Reboot device + デバイスを再起動 + + + + Start over + 再スタート + + + + SetupWidget + + + Finish Setup + セットアップ完了 + + + + Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer. + デバイスを comma connect (connect.comma.ai)でペアリングし comma prime 特典を申請してください。 + + + + Pair device + デバイスをペアリング + + + + Sidebar + + + + CONNECT + 接続 + + + + OFFLINE + オフライン + + + + + ONLINE + オンライン + + + + ERROR + エラー + + + + + + TEMP + 温度 + + + + HIGH + 高温 + + + + GOOD + 最適 + + + + OK + OK + + + + VEHICLE + 車両 + + + + NO + NO + + + + PANDA + パンダ + + + + GPS + GPS + + + + SEARCH + 検索 + + + + -- + -- + + + + Wi-Fi + Wi-Fi + + + + ETH + ETH + + + + 2G + 2G + + + + 3G + 3G + + + + LTE + LTE + + + + 5G + 5G + + + + SoftwarePanel + + + Git Branch + Git ブランチ + + + + Git Commit + Git コミット + + + + OS Version + OS バージョン + + + + Version + バージョン + + + + Last Update Check + 最終更新確認 + + + + The last time openpilot successfully checked for an update. The updater only runs while the car is off. + openpilotが最後にアップデートの確認に成功してからの時間です。アップデート処理は、車の電源が切れているときのみ実行されます。 + + + + Check for Update + 更新確認 + + + + CHECKING + 確認中 + + + + Uninstall + アンインストール + + + + UNINSTALL + アンインストール + + + + Are you sure you want to uninstall? + 本当にアンインストールしますか? + + + + failed to fetch update + 更新の取得に失敗しました + + + + + CHECK + 確認 + + + + SshControl + + + SSH Keys + SSH 鍵 + + + + Warning: This grants SSH access to all public keys in your GitHub settings. Never enter a GitHub username other than your own. A comma employee will NEVER ask you to add their GitHub username. + 警告: これは、GitHub の設定にあるすべての公開鍵への SSH アクセスを許可するものです。自分以外のGitHubのユーザー名を入力しないでください。コンマのスタッフがGitHubのユーザー名を追加するようお願いすることはありません。 + + + + + ADD + 追加 + + + + Enter your GitHub username + GitHubのユーザー名を入力してください + + + + LOADING + ローディング + + + + REMOVE + 削除 + + + + Username '%1' has no keys on GitHub + ユーザー名“%1”は GitHub に鍵がありません + + + + Request timed out + リクエストタイムアウト + + + + Username '%1' doesn't exist on GitHub + ユーザー名 '%1' は GitHub に存在しません + + + + SshToggle + + + Enable SSH + SSH を有効化 + + + + TermsPage + + + Terms & Conditions + 利用規約 + + + + Decline + 拒否 + + + + Scroll to accept + スクロールして同意 + + + + Agree + 同意 + + + + TogglesPanel + + + Enable openpilot + openpilot を有効化 + + + + Use the openpilot system for adaptive cruise control and lane keep driver assistance. Your attention is required at all times to use this feature. Changing this setting takes effect when the car is powered off. + アダプティブクルーズコントロールとレーンキーピングドライバーアシスト(openpilotシステム)。この機能を使用するには、常に注意が必要です。この設定を変更すると、車の電源が切れたときに有効になります。 + + + + Enable Lane Departure Warnings + 車線逸脱警報機能を有効化 + + + + Receive alerts to steer back into the lane when your vehicle drifts over a detected lane line without a turn signal activated while driving over 31 mph (50 km/h). + 時速31マイル(50km)を超えるスピードで走行中、方向指示器を作動させずに検出された車線ライン上に車両が触れた場合、車線に戻るアラートを受信します。 + + + + Enable Right-Hand Drive + 右ハンドルを有効化 + + + + Allow openpilot to obey left-hand traffic conventions and perform driver monitoring on right driver seat. + openpilotが左側通行規則を遵守し、右側の運転席でドライバーの監視を行うことを可能にします。 + + + + Use Metric System + メートル法を有効化 + + + + Display speed in km/h instead of mph. + 速度はmphではなくkm/hで表示されます。 + + + + Record and Upload Driver Camera + ドライバーカメラの録画とアップロード + + + + Upload data from the driver facing camera and help improve the driver monitoring algorithm. + ドライバーカメラからのデータをアップロードし、ドライバー監視のアルゴリズム向上に役立てます。 + + + + Disengage On Accelerator Pedal + アクセルペダルで解除する + + + + When enabled, pressing the accelerator pedal will disengage openpilot. + 有効な場合 openpilot はアクセルペダルを踏むと解除されます。 + + + + Show ETA in 24h format + 24時間表示 + + + + Use 24h format instead of am/pm + AM/PMの代わりに24時間形式を使用します + + + + openpilot Longitudinal Control + openpilot による垂直方向の制御 + + + + openpilot will disable the car's radar and will take over control of gas and brakes. Warning: this disables AEB! + openpilotは、車のレーダーを無効化し、アクセルとブレーキの制御を引き継ぎます。注意:AEBを無効にします! + + + + Updater + + + Update Required + 更新が必要です + + + + An operating system update is required. Connect your device to Wi-Fi for the fastest update experience. The download size is approximately 1GB. + OSのアップデートが必要です。Wi-Fiに接続することで、最速のアップデートを体験できます。ダウンロードサイズは約1GBです。 + + + + Connect to Wi-Fi + Wi-Fiに接続 + + + + Install + インストール + + + + Back + 戻る + + + + Loading... + 読み込み中... + + + + Reboot + 再起動 + + + + Update failed + 更新失敗 + + + + WifiUI + + + + Scanning for networks... + ネットワークをスキャン中... + + + + CONNECTING... + 接続中... + + + + FORGET + 削除 + + + + Forget Wi-Fi Network " + Wi-Fiを削除する” + + + From dccb184fbd4a2b39008471f94056f61bf7a7381d Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Fri, 8 Jul 2022 13:39:23 +0200 Subject: [PATCH 047/112] some more release notes --- RELEASES.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index fedff5dbff..d7f4a37476 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -5,17 +5,23 @@ Version 0.8.15 (2022-07-XX) * Effective feedforward that uses road roll * Simplified tuning, all car-specific parameters can be derived from data * Significantly improved control on TSS-P Prius +* New driving model + * Path planning uses end-to-end output instead of lane lines * New driver monitoring model - * takes a larger input frame - * outputs a driver state for both driver and passenger - * automatically determines which side the driver is on (soon) -* Reduced power usage: device runs cooler and fan spins less -* Minor UI updates + * Takes a larger input frame + * Outputs a driver state for both driver and passenger + * Automatically determines which side the driver is on (soon) +* Navigation improvements + * Speed limits shown while navigating + * Faster position fix by using raw GPS measurements +* UI updates * New font * Refreshed max speed design - * Speed limits shown while navigating * More consistent camera view perspective across cars +* Reduced power usage: device runs cooler and fan spins less * AGNOS 5 + * Support for delta updates to reduce data usage on future OS updates + * Support VSCode remote SSH target * Honda Civic 2022 support * Hyundai Tucson 2021 support thanks to bluesforte! * Lexus NX Hybrid 2020 support thanks to AlexandreSato! From b5399fbd3ce3a03bb900f1e8597f0afbd19fa314 Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Fri, 8 Jul 2022 13:41:42 +0200 Subject: [PATCH 048/112] add multilang to release notes --- RELEASES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASES.md b/RELEASES.md index d7f4a37476..80709e1482 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -15,6 +15,7 @@ Version 0.8.15 (2022-07-XX) * Speed limits shown while navigating * Faster position fix by using raw GPS measurements * UI updates + * Multilanguage support for settings and home screen * New font * Refreshed max speed design * More consistent camera view perspective across cars From c5e96201f30c7168e531ba5da98775fcd2d668c5 Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Fri, 8 Jul 2022 13:56:49 +0200 Subject: [PATCH 049/112] RELEASES.md: new driving model goes first --- RELEASES.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index 80709e1482..e0e75f3213 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,12 +1,12 @@ Version 0.8.15 (2022-07-XX) ======================== +* New driving model + * Path planning uses end-to-end output instead of lane lines * New lateral controller based on physical wheel torque model * Much smoother control, consistent across the speed range * Effective feedforward that uses road roll * Simplified tuning, all car-specific parameters can be derived from data * Significantly improved control on TSS-P Prius -* New driving model - * Path planning uses end-to-end output instead of lane lines * New driver monitoring model * Takes a larger input frame * Outputs a driver state for both driver and passenger From b6df0cd2422d63eb58cc6abaa9968954feff2ccb Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Fri, 8 Jul 2022 15:44:16 +0200 Subject: [PATCH 050/112] casync: handle hash failure (#25081) * casync: handle hashing failure due to IO errors * fix comment * all exceptions * fix typo * Update system/hardware/tici/agnos.py --- system/hardware/tici/agnos.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/system/hardware/tici/agnos.py b/system/hardware/tici/agnos.py index bd8ce2bf02..750aa630ae 100755 --- a/system/hardware/tici/agnos.py +++ b/system/hardware/tici/agnos.py @@ -186,14 +186,18 @@ def extract_casync_image(target_slot_number: int, partition: dict, cloudlog): sources: List[Tuple[str, casync.ChunkReader, casync.ChunkDict]] = [] - # First source is the current partition. Index file for current version is provided in the manifest - raw_hash = get_raw_hash(seed_path, partition['size']) - caibx_url = f"{CAIBX_URL}{partition['name']}-{raw_hash}.caibx" + # First source is the current partition. try: - cloudlog.info(f"casync fetching {caibx_url}") - sources += [('seed', casync.FileChunkReader(seed_path), casync.build_chunk_dict(casync.parse_caibx(caibx_url)))] - except requests.RequestException: - cloudlog.error(f"casync failed to load {caibx_url}") + raw_hash = get_raw_hash(seed_path, partition['size']) + caibx_url = f"{CAIBX_URL}{partition['name']}-{raw_hash}.caibx" + + try: + cloudlog.info(f"casync fetching {caibx_url}") + sources += [('seed', casync.FileChunkReader(seed_path), casync.build_chunk_dict(casync.parse_caibx(caibx_url)))] + except requests.RequestException: + cloudlog.error(f"casync failed to load {caibx_url}") + except Exception: + cloudlog.exception("casync failed to hash seed partition") # Second source is the target partition, this allows for resuming sources += [('target', casync.FileChunkReader(path), casync.build_chunk_dict(target))] From 7a4c33795a12eefff4c3e5c311f40eae2cf3506b Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Fri, 8 Jul 2022 18:20:16 +0200 Subject: [PATCH 051/112] laikad: add residual threshold for pos_fix (#25082) * laikad: add residual threshold for pos_fix * update ref * update test --- selfdrive/locationd/laikad.py | 5 +++-- selfdrive/locationd/test/test_laikad.py | 8 ++++---- selfdrive/test/process_replay/ref_commit | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/selfdrive/locationd/laikad.py b/selfdrive/locationd/laikad.py index e262407e02..67867e82b3 100755 --- a/selfdrive/locationd/laikad.py +++ b/selfdrive/locationd/laikad.py @@ -28,6 +28,7 @@ from system.swaglog import cloudlog MAX_TIME_GAP = 10 EPHEMERIS_CACHE = 'LaikadEphemeris' CACHE_VERSION = 0.1 +POS_FIX_RESIDUAL_THRESHOLD = 100.0 class Laikad: @@ -89,9 +90,9 @@ class Laikad: def get_est_pos(self, t, processed_measurements): if self.last_pos_fix_t is None or abs(self.last_pos_fix_t - t) >= 2: - min_measurements = 5 if any(p.constellation_id == ConstellationId.GLONASS for p in processed_measurements) else 4 + min_measurements = 6 if any(p.constellation_id == ConstellationId.GLONASS for p in processed_measurements) else 5 pos_fix, pos_fix_residual = calc_pos_fix_gauss_newton(processed_measurements, self.posfix_functions, min_measurements=min_measurements) - if len(pos_fix) > 0: + if len(pos_fix) > 0 and np.median(np.abs(pos_fix_residual)) < POS_FIX_RESIDUAL_THRESHOLD: self.last_pos_fix = pos_fix[:3] self.last_pos_residual = pos_fix_residual self.last_pos_fix_t = t diff --git a/selfdrive/locationd/test/test_laikad.py b/selfdrive/locationd/test/test_laikad.py index 3a7c073b55..c10a470d1a 100755 --- a/selfdrive/locationd/test/test_laikad.py +++ b/selfdrive/locationd/test/test_laikad.py @@ -138,7 +138,7 @@ class TestLaikad(unittest.TestCase): laikad = Laikad(auto_update=True, valid_ephem_types=EphemerisType.ULTRA_RAPID_ORBIT) correct_msgs = verify_messages(self.logs, laikad) - correct_msgs_expected = 560 + correct_msgs_expected = 555 self.assertEqual(correct_msgs_expected, len(correct_msgs)) self.assertEqual(correct_msgs_expected, len([m for m in correct_msgs if m.gnssMeasurements.positionECEF.valid])) @@ -159,7 +159,7 @@ class TestLaikad(unittest.TestCase): # Disable fetch_orbits to test NAV only laikad.fetch_orbits = Mock() correct_msgs = verify_messages(self.logs, laikad) - correct_msgs_expected = 560 + correct_msgs_expected = 559 self.assertEqual(correct_msgs_expected, len(correct_msgs)) self.assertEqual(correct_msgs_expected, len([m for m in correct_msgs if m.gnssMeasurements.positionECEF.valid])) @@ -168,8 +168,8 @@ class TestLaikad(unittest.TestCase): downloader_mock.side_effect = IOError laikad = Laikad(auto_update=False) correct_msgs = verify_messages(self.logs, laikad) - self.assertEqual(256, len(correct_msgs)) - self.assertEqual(256, len([m for m in correct_msgs if m.gnssMeasurements.positionECEF.valid])) + self.assertEqual(16, len(correct_msgs)) + self.assertEqual(16, len([m for m in correct_msgs if m.gnssMeasurements.positionECEF.valid])) def test_laika_get_orbits(self): laikad = Laikad(auto_update=False) diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index 4908b86182..7fced5ad62 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -bd2ea158977f5c26658bed8ac683b72c2c592d06 \ No newline at end of file +0da0928230d11dd4c76293b9e77b027eb4a1e291 \ No newline at end of file From a9401319dfa89fea2d2699aaddc758cbc47b6396 Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Fri, 8 Jul 2022 18:20:36 +0200 Subject: [PATCH 052/112] nav: use laikad position if locationd is not yet available (#25033) * ui: use laikad position when locationd is not ready * cleanup * same threshold as locationd * use first bearing directly * use in navd too --- selfdrive/navd/navd.py | 19 ++++++-- selfdrive/ui/qt/maps/map.cc | 71 ++++++++++++++++++++++------- selfdrive/ui/qt/maps/map.h | 3 +- selfdrive/ui/qt/maps/map_helpers.cc | 5 ++ selfdrive/ui/qt/maps/map_helpers.h | 1 + selfdrive/ui/ui.cc | 2 +- 6 files changed, 79 insertions(+), 22 deletions(-) diff --git a/selfdrive/navd/navd.py b/selfdrive/navd/navd.py index f02de43c7b..89a1c9bdfb 100755 --- a/selfdrive/navd/navd.py +++ b/selfdrive/navd/navd.py @@ -4,12 +4,14 @@ import os import threading import requests +import numpy as np import cereal.messaging as messaging from cereal import log from common.api import Api from common.params import Params from common.realtime import Ratekeeper +from common.transformations.coordinates import ecef2geodetic from selfdrive.navd.helpers import (Coordinate, coordinate_from_param, distance_along_geometry, maxspeed_to_ms, minimum_distance, @@ -18,6 +20,7 @@ from system.swaglog import cloudlog REROUTE_DISTANCE = 25 MANEUVER_TRANSITION_THRESHOLD = 10 +VALID_POS_STD = 50.0 class RouteEngine: @@ -72,13 +75,21 @@ class RouteEngine: def update_location(self): location = self.sm['liveLocationKalman'] - self.gps_ok = location.gpsOK + laikad = self.sm['gnssMeasurements'] - self.localizer_valid = (location.status == log.LiveLocationKalman.Status.valid) and location.positionGeodetic.valid + locationd_valid = (location.status == log.LiveLocationKalman.Status.valid) and location.positionGeodetic.valid + laikad_valid = laikad.positionECEF.valid and np.linalg.norm(laikad.positionECEF.std) < VALID_POS_STD - if self.localizer_valid: + self.localizer_valid = locationd_valid or laikad_valid + self.gps_ok = location.gpsOK or laikad_valid + + if locationd_valid: self.last_bearing = math.degrees(location.calibratedOrientationNED.value[2]) self.last_position = Coordinate(location.positionGeodetic.value[0], location.positionGeodetic.value[1]) + elif laikad_valid: + geodetic = ecef2geodetic(laikad.positionECEF.value) + self.last_position = Coordinate(geodetic[0], geodetic[1]) + self.last_bearing = None def recompute_route(self): if self.last_position is None: @@ -276,7 +287,7 @@ class RouteEngine: def main(sm=None, pm=None): if sm is None: - sm = messaging.SubMaster(['liveLocationKalman', 'managerState']) + sm = messaging.SubMaster(['liveLocationKalman', 'gnssMeasurements', 'managerState']) if pm is None: pm = messaging.PubMaster(['navInstruction', 'navRoute']) diff --git a/selfdrive/ui/qt/maps/map.cc b/selfdrive/ui/qt/maps/map.cc index 4c6a0a4e65..fd47f4188f 100644 --- a/selfdrive/ui/qt/maps/map.cc +++ b/selfdrive/ui/qt/maps/map.cc @@ -1,5 +1,6 @@ #include "selfdrive/ui/qt/maps/map.h" +#include #include #include @@ -7,6 +8,7 @@ #include #include "common/swaglog.h" +#include "common/transformations/coordinates.hpp" #include "selfdrive/ui/qt/maps/map_helpers.h" #include "selfdrive/ui/qt/request_repeater.h" #include "selfdrive/ui/qt/util.h" @@ -22,6 +24,8 @@ const float MAX_PITCH = 50; const float MIN_PITCH = 0; const float MAP_SCALE = 2; +const float VALID_POS_STD = 50.0; // m + const QString ICON_SUFFIX = ".png"; MapWindow::MapWindow(const QMapboxGLSettings &settings) : m_settings(settings), velocity_filter(0, 10, 0.05) { @@ -105,18 +109,53 @@ void MapWindow::updateState(const UIState &s) { update(); if (sm.updated("liveLocationKalman")) { - auto location = sm["liveLocationKalman"].getLiveLocationKalman(); - auto pos = location.getPositionGeodetic(); - auto orientation = location.getCalibratedOrientationNED(); - auto velocity = location.getVelocityCalibrated(); - - localizer_valid = (location.getStatus() == cereal::LiveLocationKalman::Status::VALID) && - pos.getValid() && orientation.getValid() && velocity.getValid(); - - if (localizer_valid) { - last_position = QMapbox::Coordinate(pos.getValue()[0], pos.getValue()[1]); - last_bearing = RAD2DEG(orientation.getValue()[2]); - velocity_filter.update(velocity.getValue()[0]); + auto locationd_location = sm["liveLocationKalman"].getLiveLocationKalman(); + auto locationd_pos = locationd_location.getPositionGeodetic(); + auto locationd_orientation = locationd_location.getCalibratedOrientationNED(); + auto locationd_velocity = locationd_location.getVelocityCalibrated(); + + locationd_valid = (locationd_location.getStatus() == cereal::LiveLocationKalman::Status::VALID) && + locationd_pos.getValid() && locationd_orientation.getValid() && locationd_velocity.getValid(); + + if (locationd_valid) { + last_position = QMapbox::Coordinate(locationd_pos.getValue()[0], locationd_pos.getValue()[1]); + last_bearing = RAD2DEG(locationd_orientation.getValue()[2]); + velocity_filter.update(locationd_velocity.getValue()[0]); + } + } + + if (sm.updated("gnssMeasurements")) { + auto laikad_location = sm["gnssMeasurements"].getGnssMeasurements(); + auto laikad_pos = laikad_location.getPositionECEF(); + auto laikad_pos_ecef = laikad_pos.getValue(); + auto laikad_pos_std = laikad_pos.getStd(); + auto laikad_velocity_ecef = laikad_location.getVelocityECEF().getValue(); + + laikad_valid = laikad_pos.getValid() && Eigen::Vector3d(laikad_pos_std[0], laikad_pos_std[1], laikad_pos_std[2]).norm() < VALID_POS_STD; + + if (laikad_valid && !locationd_valid) { + ECEF ecef = {.x = laikad_pos_ecef[0], .y = laikad_pos_ecef[1], .z = laikad_pos_ecef[2]}; + Geodetic laikad_pos_geodetic = ecef2geodetic(ecef); + last_position = QMapbox::Coordinate(laikad_pos_geodetic.lat, laikad_pos_geodetic.lon); + + // Compute NED velocity + LocalCoord converter(ecef); + ECEF next_ecef = {.x = ecef.x + laikad_velocity_ecef[0], .y = ecef.y + laikad_velocity_ecef[1], .z = ecef.z + laikad_velocity_ecef[2]}; + Eigen::VectorXd ned_vel = converter.ecef2ned(next_ecef).to_vector() - converter.ecef2ned(ecef).to_vector(); + + float velocity = ned_vel.norm(); + velocity_filter.update(velocity); + + // Convert NED velocity to angle + if (velocity > 1.0) { + float new_bearing = fmod(RAD2DEG(atan2(ned_vel[1], ned_vel[0])) + 360.0, 360.0); + if (last_bearing) { + float delta = 0.1 * angle_difference(*last_bearing, new_bearing); // Smooth heading + last_bearing = fmod(*last_bearing + delta + 360.0, 360.0); + } else { + last_bearing = new_bearing; + } + } } } @@ -142,9 +181,7 @@ void MapWindow::updateState(const UIState &s) { initLayers(); - if (!localizer_valid) { - map_instructions->showError("Waiting for GPS"); - } else { + if (locationd_valid || laikad_valid) { map_instructions->noError(); // Update current location marker @@ -154,6 +191,8 @@ void MapWindow::updateState(const UIState &s) { carPosSource["type"] = "geojson"; carPosSource["data"] = QVariant::fromValue(feature1); m_map->updateSource("carPosSource", carPosSource); + } else { + map_instructions->showError("Waiting for GPS"); } if (pan_counter == 0) { @@ -174,7 +213,7 @@ void MapWindow::updateState(const UIState &s) { auto i = sm["navInstruction"].getNavInstruction(); emit ETAChanged(i.getTimeRemaining(), i.getTimeRemainingTypical(), i.getDistanceRemaining()); - if (localizer_valid) { + if (locationd_valid || laikad_valid) { m_map->setPitch(MAX_PITCH); // TODO: smooth pitching based on maneuver distance emit distanceChanged(i.getManeuverDistance()); // TODO: combine with instructionsChanged emit instructionsChanged(i); diff --git a/selfdrive/ui/qt/maps/map.h b/selfdrive/ui/qt/maps/map.h index 7c39b24c3c..ecba867edb 100644 --- a/selfdrive/ui/qt/maps/map.h +++ b/selfdrive/ui/qt/maps/map.h @@ -104,7 +104,8 @@ private: std::optional last_position; std::optional last_bearing; FirstOrderFilter velocity_filter; - bool localizer_valid = false; + bool laikad_valid = false; + bool locationd_valid = false; MapInstructions* map_instructions; MapETA* map_eta; diff --git a/selfdrive/ui/qt/maps/map_helpers.cc b/selfdrive/ui/qt/maps/map_helpers.cc index 2b2c27418e..66acb7a25d 100644 --- a/selfdrive/ui/qt/maps/map_helpers.cc +++ b/selfdrive/ui/qt/maps/map_helpers.cc @@ -116,3 +116,8 @@ std::optional coordinate_from_param(std::string param) { return {}; } } + +double angle_difference(double angle1, double angle2) { + double diff = fmod(angle2 - angle1 + 180.0, 360.0) - 180.0; + return diff < -180.0 ? diff + 360.0 : diff; +} diff --git a/selfdrive/ui/qt/maps/map_helpers.h b/selfdrive/ui/qt/maps/map_helpers.h index 344246bb05..1c08c541c3 100644 --- a/selfdrive/ui/qt/maps/map_helpers.h +++ b/selfdrive/ui/qt/maps/map_helpers.h @@ -26,3 +26,4 @@ QMapbox::CoordinatesCollections capnp_coordinate_list_to_collection(const capnp: QMapbox::CoordinatesCollections coordinate_list_to_collection(QList coordinate_list); std::optional coordinate_from_param(std::string param); +double angle_difference(double angle1, double angle2); diff --git a/selfdrive/ui/ui.cc b/selfdrive/ui/ui.cc index f6193f97a6..6fe1d838ed 100644 --- a/selfdrive/ui/ui.cc +++ b/selfdrive/ui/ui.cc @@ -227,7 +227,7 @@ UIState::UIState(QObject *parent) : QObject(parent) { sm = std::make_unique>({ "modelV2", "controlsState", "liveCalibration", "radarState", "deviceState", "roadCameraState", "pandaStates", "carParams", "driverMonitoringState", "sensorEvents", "carState", "liveLocationKalman", - "wideRoadCameraState", "managerState", "navInstruction", "navRoute", + "wideRoadCameraState", "managerState", "navInstruction", "navRoute", "gnssMeasurements", }); Params params; From cf862b6576a8b3f66e26d38080a1c8eec00f0793 Mon Sep 17 00:00:00 2001 From: Gijs Koning Date: Fri, 8 Jul 2022 19:03:42 +0200 Subject: [PATCH 053/112] Laikad: Fix getting covariances for pos and velocity (#25084) * Fix getting covariances for pos and velocity * ref commit --- selfdrive/locationd/laikad.py | 13 +++++++------ selfdrive/test/process_replay/ref_commit | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/selfdrive/locationd/laikad.py b/selfdrive/locationd/laikad.py index 67867e82b3..0954cb4c9f 100755 --- a/selfdrive/locationd/laikad.py +++ b/selfdrive/locationd/laikad.py @@ -120,11 +120,12 @@ class Laikad: self.update_localizer(est_pos, t, corrected_measurements) kf_valid = all(self.kf_valid(t)) - ecef_pos = self.gnss_kf.x[GStates.ECEF_POS].tolist() - ecef_vel = self.gnss_kf.x[GStates.ECEF_VELOCITY].tolist() + ecef_pos = self.gnss_kf.x[GStates.ECEF_POS] + ecef_vel = self.gnss_kf.x[GStates.ECEF_VELOCITY] - pos_std = np.sqrt(abs(self.gnss_kf.P[GStates.ECEF_POS].diagonal())).tolist() - vel_std = np.sqrt(abs(self.gnss_kf.P[GStates.ECEF_VELOCITY].diagonal())).tolist() + p = self.gnss_kf.P.diagonal() + pos_std = np.sqrt(p[GStates.ECEF_POS]) + vel_std = np.sqrt(p[GStates.ECEF_VELOCITY]) meas_msgs = [create_measurement_msg(m) for m in corrected_measurements] dat = messaging.new_message("gnssMeasurements") @@ -132,8 +133,8 @@ class Laikad: dat.gnssMeasurements = { "gpsWeek": report.gpsWeek, "gpsTimeOfWeek": report.rcvTow, - "positionECEF": measurement_msg(value=ecef_pos, std=pos_std, valid=kf_valid), - "velocityECEF": measurement_msg(value=ecef_vel, std=vel_std, valid=kf_valid), + "positionECEF": measurement_msg(value=ecef_pos.tolist(), std=pos_std.tolist(), valid=kf_valid), + "velocityECEF": measurement_msg(value=ecef_vel.tolist(), std=vel_std.tolist(), valid=kf_valid), "positionFixECEF": measurement_msg(value=self.last_pos_fix, std=self.last_pos_residual, valid=self.last_pos_fix_t == t), "ubloxMonoTime": ublox_mono_time, "correctedMeasurements": meas_msgs diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index 7fced5ad62..0d61dbd735 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -0da0928230d11dd4c76293b9e77b027eb4a1e291 \ No newline at end of file +dab90772097a0dd4706677ba4fe5e84b10232099 \ No newline at end of file From c04942795bbb0a2a31f4c05322e6897e279f4ba9 Mon Sep 17 00:00:00 2001 From: HaraldSchafer Date: Fri, 8 Jul 2022 10:16:34 -0700 Subject: [PATCH 054/112] Update RELEASES.md --- RELEASES.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index e0e75f3213..392e9dc486 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,7 +1,9 @@ Version 0.8.15 (2022-07-XX) ======================== * New driving model - * Path planning uses end-to-end output instead of lane lines + * Path planning uses end-to-end output instead of lane lines at all times + * Reduced ping pong + * Improved lane centering * New lateral controller based on physical wheel torque model * Much smoother control, consistent across the speed range * Effective feedforward that uses road roll From 35c8c0e600746e092bb236dabd05491d8be1078a Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Fri, 8 Jul 2022 19:19:57 +0200 Subject: [PATCH 055/112] casync: increase chunk download timeout --- system/hardware/tici/casync.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/hardware/tici/casync.py b/system/hardware/tici/casync.py index d0d0da3c6a..9dff64239e 100755 --- a/system/hardware/tici/casync.py +++ b/system/hardware/tici/casync.py @@ -22,7 +22,7 @@ CA_TABLE_HEADER_LEN = 16 CA_TABLE_ENTRY_LEN = 40 CA_TABLE_MIN_LEN = CA_TABLE_HEADER_LEN + CA_TABLE_ENTRY_LEN -CHUNK_DOWNLOAD_TIMEOUT = 10 +CHUNK_DOWNLOAD_TIMEOUT = 60 CHUNK_DOWNLOAD_RETRIES = 3 CAIBX_DOWNLOAD_TIMEOUT = 120 From 0b6cf0481c07323ee427655a5849c90d9c623e64 Mon Sep 17 00:00:00 2001 From: eFini Date: Sat, 9 Jul 2022 03:12:14 +0800 Subject: [PATCH 056/112] Add Traditional Chinese translations (#25077) * Create main_zh-CHT * Update Co-authored-by: Shane Smiskol --- selfdrive/ui/translations/languages.json | 3 +- .../{main_zh.qm => main_zh-CHS.qm} | Bin .../{main_zh.ts => main_zh-CHS.ts} | 0 selfdrive/ui/translations/main_zh-CHT.qm | Bin 0 -> 17741 bytes selfdrive/ui/translations/main_zh-CHT.ts | 1220 +++++++++++++++++ 5 files changed, 1222 insertions(+), 1 deletion(-) rename selfdrive/ui/translations/{main_zh.qm => main_zh-CHS.qm} (100%) rename selfdrive/ui/translations/{main_zh.ts => main_zh-CHS.ts} (100%) create mode 100644 selfdrive/ui/translations/main_zh-CHT.qm create mode 100644 selfdrive/ui/translations/main_zh-CHT.ts diff --git a/selfdrive/ui/translations/languages.json b/selfdrive/ui/translations/languages.json index b8c3a50fd7..48f0948674 100644 --- a/selfdrive/ui/translations/languages.json +++ b/selfdrive/ui/translations/languages.json @@ -1,5 +1,6 @@ { "English": "", - "中文(简体)": "main_zh", + "中文(繁體)": "main_zh-CHT", + "中文(简体)": "main_zh-CHS", "한국어": "main_ko" } diff --git a/selfdrive/ui/translations/main_zh.qm b/selfdrive/ui/translations/main_zh-CHS.qm similarity index 100% rename from selfdrive/ui/translations/main_zh.qm rename to selfdrive/ui/translations/main_zh-CHS.qm diff --git a/selfdrive/ui/translations/main_zh.ts b/selfdrive/ui/translations/main_zh-CHS.ts similarity index 100% rename from selfdrive/ui/translations/main_zh.ts rename to selfdrive/ui/translations/main_zh-CHS.ts diff --git a/selfdrive/ui/translations/main_zh-CHT.qm b/selfdrive/ui/translations/main_zh-CHT.qm new file mode 100644 index 0000000000000000000000000000000000000000..8b055d665e4582f8d1461595d0d88a7eeacfbb49 GIT binary patch literal 17741 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 + + + + AbstractAlert + + + Close + 關閉 + + + + Snooze Update + 暫停更新 + + + + Reboot and Update + 重啟並更新 + + + + AdvancedNetworking + + + Back + 回上頁 + + + + Enable Tethering + 啟用網路分享 + + + + Tethering Password + 網路分享密碼 + + + + + EDIT + 編輯 + + + + Enter new tethering password + 輸入新的網路分享密碼 + + + + IP Address + IP 地址 + + + + Enable Roaming + 啟用漫遊 + + + + APN Setting + APN 設置 + + + + Enter APN + 輸入 APN + + + + leave blank for automatic configuration + 留空白將自動配置 + + + + ConfirmationDialog + + + + Ok + 確定 + + + + Cancel + 取消 + + + + DeclinePage + + + You must accept the Terms and Conditions in order to use openpilot. + 您必須先接受條款和條件才能使用 openpilot。 + + + + Back + 回上頁 + + + + Decline, uninstall %1 + 拒絕並卸載 %1 + + + + DevicePanel + + + Dongle ID + Dongle ID + + + + N/A + 無法使用 + + + + Serial + 序號 + + + + Driver Camera + 駕駛監控 + + + + PREVIEW + 預覽 + + + + Preview the driver facing camera to help optimize device mounting position for best driver monitoring experience. (vehicle must be off) + 預覽駕駛監控鏡頭畫面,方便調整設備安裝的位置,以提供更準確的駕駛監控。(車子必須保持在熄火的狀態) + + + + Reset Calibration + 重置校準 + + + + RESET + 重置 + + + + Are you sure you want to reset calibration? + 您確定要重置校準嗎? + + + + Review Training Guide + 觀看使用教學 + + + + REVIEW + 觀看 + + + + Review the rules, features, and limitations of openpilot + 觀看 openpilot 的使用規則、功能和限制 + + + + Are you sure you want to review the training guide? + 您確定要觀看使用教學嗎? + + + + Regulatory + 法規/監管 + + + + VIEW + 觀看 + + + Change Language + 更改語言 + + + CHANGE + 更改 + + + Select a language + 選擇語言 + + + + Reboot + 重新啟動 + + + + Power Off + 關機 + + + + openpilot requires the device to be mounted within 4° left or right and within 5° up or 8° down. openpilot is continuously calibrating, resetting is rarely required. + openpilot 需要將裝置固定在左右偏差 4° 以內,朝上偏差 5° 以内或朝下偏差 8° 以内。鏡頭在後台會持續自動校準,很少有需要重置的情况。 + + + + Your device is pointed %1° %2 and %3° %4. + 你的設備目前朝%2 %1° 以及朝%4 %3° 。 + + + + down + + + + + up + + + + + left + + + + + right + + + + + Are you sure you want to reboot? + 您確定要重新啟動嗎? + + + + Disengage to Reboot + 請先取消控車才能重新啟動 + + + + Are you sure you want to power off? + 您確定您要關機嗎? + + + + Disengage to Power Off + 請先取消控車才能關機 + + + + DriveStats + + + Drives + 旅程 + + + + Hours + 小時 + + + + ALL TIME + 總共 + + + + PAST WEEK + 上周 + + + + KM + 公里 + + + + Miles + 英里 + + + + DriverViewScene + + + camera starting + 開啟相機中 + + + + InputDialog + + + Cancel + 取消 + + + + Need at least + 需要至少 + + + + characters! + 個字元! + + + + Installer + + + Installing... + 安裝中… + + + + Receiving objects: + 接收對象: + + + + Resolving deltas: + 分析差異: + + + + Updating files: + 更新檔案: + + + + MapPanel + + + Current Destination + 當前目的地 + + + + CLEAR + 清除 + + + + Recent Destinations + 最近目的地 + + + + Try the Navigation Beta + 試用導航功能 + + + + Get turn-by-turn directions displayed and more with a comma +prime subscription. Sign up now: https://connect.comma.ai + 成為 comma 高級會員來使用導航功能 +立即註冊:https://connect.comma.ai + + + Get turn-by-turn directions displayed and more with a comma +prime subscription. Sign up now: https://connect.comma.ai + 成為 comma 高級會員來使用導航功能,立即註冊:https://connect.comma.ai + + + + No home +location set + 未設定 +住家位置 + + + + No work +location set + 未設定 +工作位置 + + + + no recent destinations + 沒有最近的導航記錄 + + + + MultiOptionDialog + + Select + 選擇 + + + Cancel + 取消 + + + + Networking + + + Advanced + 進階 + + + + Enter password + 輸入密碼 + + + + + for " + 給 " + + + + Wrong password + 密碼錯誤 + + + + NvgWindow + + + km/h + km/h + + + + mph + mph + + + + + MAX + 最高 + + + + + SPEED + 速度 + + + + + LIMIT + 速限 + + + + OffroadHome + + + UPDATE + 更新 + + + + ALERTS + 提醒 + + + + ALERT + 提醒 + + + + PairingPopup + + + Pair your device to your comma account + 將設備與您的 comma 帳號配對 + + + + + <ol type='1' style='margin-left: 15px;'> + <li style='margin-bottom: 50px;'>Go to https://connect.comma.ai on your phone</li> + <li style='margin-bottom: 50px;'>Click "add new device" and scan the QR code on the right</li> + <li style='margin-bottom: 50px;'>Bookmark connect.comma.ai to your home screen to use it like an app</li> + </ol> + + + <ol type='1' style='margin-left: 15px;'> + <li style='margin-bottom: 50px;'>用手機連至 https://connect.comma.ai</li> + <li style='margin-bottom: 50px;'>點選 "add new device" 後掃描右邊的二維碼</li> + <li style='margin-bottom: 50px;'>將 connect.comma.ai 加入您的主屏幕,以便像手機 App 一樣使用它</li> + </ol> + + + + + PrimeAdWidget + + + Upgrade Now + 馬上升級 + + + + Become a comma prime member at connect.comma.ai + 成為 connect.comma.ai 的高級會員 + + + + PRIME FEATURES: + 高級會員特點: + + + + Remote access + 遠程訪問 + + + + 1 year of storage + 一年的雲端行車記錄 + + + + Developer perks + 開發者福利 + + + + PrimeUserWidget + + + ✓ SUBSCRIBED + ✓ 已訂閱 + + + + comma prime + comma 高級會員 + + + + CONNECT.COMMA.AI + CONNECT.COMMA.AI + + + + COMMA POINTS + COMMA 積分 + + + + QObject + + + Reboot + 重新啟動 + + + + Exit + 離開 + + + + dashcam + 行車記錄器 + + + + openpilot + openpilot + + + + %1 minute%2 ago + we don't need %2 + %1 分鐘前 + + + + %1 hour%2 ago + we don't need %2 + %1 小時前 + + + + %1 day%2 ago + we don't need %2 + %1 天前 + + + + Reset + + + Reset failed. Reboot to try again. + 重置失敗。請重新啟動後再試。 + + + + Are you sure you want to reset your device? + 您確定要重置你的設備嗎? + + + + Resetting device... + 重置設備中… + + + + System Reset + 系統重置 + + + + System reset triggered. Press confirm to erase all content and settings. Press cancel to resume boot. + 系統重置已觸發。請按確認刪除所有內容和設置。按取消恢復啟動。 + + + + Cancel + 取消 + + + + Reboot + 重新啟動 + + + + Confirm + 確認 + + + + Unable to mount data partition. Press confirm to reset your device. + 無法掛載數據分區。請按確認重置您的設備。 + + + + RichTextDialog + + + Ok + 確定 + + + + SettingsWindow + + + × + × + + + + Device + 設備 + + + + + Network + 網路 + + + + Toggles + 設定 + + + + Software + 軟體 + + + + Navigation + 導航 + + + + Setup + + + WARNING: Low Voltage + 警告:電壓過低 + + + + Power your device in a car with a harness or proceed at your own risk. + 請使用車上 harness 提供的電源,若繼續的話您需要自擔風險。 + + + + Power off + 關機 + + + + + + Continue + 繼續 + + + + Getting Started + 入門 + + + + Before we get on the road, let’s finish installation and cover some details. + 在我們上路之前,讓我們完成安裝並介紹一些細節。 + + + + Connect to Wi-Fi + 連接到無線網絡 + + + + + Back + 回上頁 + + + + Continue without Wi-Fi + 在沒有 Wi-Fi 的情況下繼續 + + + + Waiting for internet + 連接至網路中 + + + + Choose Software to Install + 選擇要安裝的軟體 + + + + Dashcam + 行車記錄器 + + + + Custom Software + 定制的軟體 + + + + Enter URL + 輸入網址 + + + + for Custom Software + 定制的軟體 + + + + Downloading... + 下載中… + + + + Download Failed + 下載失敗 + + + + Ensure the entered URL is valid, and the device’s internet connection is good. + 請確定您輸入的是有效的安裝網址,並且確定設備的網路連線狀態良好。 + + + + Reboot device + 重新啟動 + + + + Start over + 重新開始 + + + + SetupWidget + + + Finish Setup + 完成設置 + + + + Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer. + 將您的設備與 comma connect (connect.comma.ai) 配對並領取您的 comma 高級會員優惠。 + + + + Pair device + 配對設備 + + + + Sidebar + + + + CONNECT + 雲端服務 + + + + OFFLINE + 已離線 + + + + + ONLINE + 已連線 + + + + ERROR + 錯誤 + + + + + + TEMP + 溫度 + + + + HIGH + 偏高 + + + + GOOD + 正常 + + + + OK + 一般 + + + + VEHICLE + 車輛通訊 + + + + NO + 未連線 + + + + PANDA + 車輛通訊 + + + + GPS + GPS + + + + SEARCH + 車輛通訊 + + + + -- + -- + + + + Wi-Fi + + + + + ETH + + + + + 2G + + + + + 3G + + + + + LTE + + + + + 5G + + + + + SoftwarePanel + + + Git Branch + Git 分支 + + + + Git Commit + Git 提交 + + + + OS Version + 系統版本 + + + + Version + 版本 + + + + Last Update Check + 上次檢查時間 + + + + The last time openpilot successfully checked for an update. The updater only runs while the car is off. + 上次成功檢查更新的時間。更新系統只會在車子熄火時執行。 + + + + Check for Update + 檢查更新 + + + + CHECKING + 檢查中 + + + + Uninstall + 卸載 + + + + UNINSTALL + 卸載 + + + + Are you sure you want to uninstall? + 您確定您要卸載嗎? + + + + failed to fetch update + 下載更新失敗 + + + + + CHECK + 檢查 + + + + SshControl + + + SSH Keys + SSH 密鑰 + + + + Warning: This grants SSH access to all public keys in your GitHub settings. Never enter a GitHub username other than your own. A comma employee will NEVER ask you to add their GitHub username. + 警告:這將授權給 GitHub 帳號中所有公鑰 SSH 訪問權限。切勿輸入非您自己的 GitHub 用戶名。comma 員工「永遠不會」要求您添加他們的 GitHub 用戶名。 + + + + + ADD + 新增 + + + + Enter your GitHub username + 請輸入您 GitHub 的用戶名 + + + + LOADING + 載入中 + + + + REMOVE + 移除 + + + + Username '%1' has no keys on GitHub + GitHub 用戶 '%1' 沒有設定任何密鑰 + + + + Request timed out + 請求超時 + + + + Username '%1' doesn't exist on GitHub + GitHub 用戶 '%1' 不存在 + + + + SshToggle + + + Enable SSH + 啟用 SSH 服務 + + + + TermsPage + + + Terms & Conditions + 條款和條件 + + + + Decline + 拒絕 + + + + Scroll to accept + 滑動至頁尾接受條款 + + + + Agree + 接受 + + + + TogglesPanel + + + Enable openpilot + 啟用 openpilot + + + + Use the openpilot system for adaptive cruise control and lane keep driver assistance. Your attention is required at all times to use this feature. Changing this setting takes effect when the car is powered off. + 使用 openpilot 的主動式巡航和車道保持功能,開啟後您需要持續集中注意力,設定變更在重新啟動車輛後生效。 + + + + Enable Lane Departure Warnings + 啟用車道偏離警告 + + + + Receive alerts to steer back into the lane when your vehicle drifts over a detected lane line without a turn signal activated while driving over 31 mph (50 km/h). + 車速在時速 50 公里 (31 英里) 以上且未打方向燈的情況下,如果偵測到車輛駛出目前車道線時,發出車道偏離警告。 + + + + Enable Right-Hand Drive + 啟用右駕模式 + + + + Allow openpilot to obey left-hand traffic conventions and perform driver monitoring on right driver seat. + openpilot 將對右側駕駛進行監控 (但仍遵守靠左駕的交通慣例)。 + + + + Use Metric System + 使用公制單位 + + + + Display speed in km/h instead of mph. + 啟用後,速度單位顯示將從 mp/h 改為 km/h。 + + + + Record and Upload Driver Camera + 記錄並上傳駕駛監控影像 + + + + Upload data from the driver facing camera and help improve the driver monitoring algorithm. + 上傳駕駛監控的錄像來協助我們提升駕駛監控的準確率。 + + + + Disengage On Accelerator Pedal + 油門取消控車 + + + + When enabled, pressing the accelerator pedal will disengage openpilot. + 啟用後,踩踏油門將會取消 openpilot 控制。 + + + + Show ETA in 24h format + 預計到達時間單位改用 24 小時制 + + + + Use 24h format instead of am/pm + 使用 24 小時制。(預設值為 12 小時制) + + + + openpilot Longitudinal Control + openpilot 縱向控制 + + + + openpilot will disable the car's radar and will take over control of gas and brakes. Warning: this disables AEB! + openpilot 將會關閉雷達訊號並接管油門和剎車的控制。注意:這也會關閉自動緊急煞車 (AEB) 系統! + + + + Updater + + + Update Required + 系統更新 + + + + An operating system update is required. Connect your device to Wi-Fi for the fastest update experience. The download size is approximately 1GB. + 設備的操作系統需要更新。請將您的設備連接到 Wi-Fi 以獲得最快的更新體驗。下載大小約為 1GB。 + + + + Connect to Wi-Fi + 連接到無線網絡 + + + + Install + 安裝 + + + + Back + 回上頁 + + + + Loading... + 載入中… + + + + Reboot + 重新啟動 + + + + Update failed + 更新失敗 + + + + WifiUI + + + + Scanning for networks... + 掃描無線網路中... + + + + CONNECTING... + 連線中... + + + + FORGET + 清除 + + + + Forget Wi-Fi Network " + 清除 Wi-Fi 網路 " + + + From e0f8f50baa209f0f5fc713100bcec16411cd5925 Mon Sep 17 00:00:00 2001 From: "Mr.one" <84395321+hellokitty-666@users.noreply.github.com> Date: Sat, 9 Jul 2022 03:49:04 +0800 Subject: [PATCH 057/112] Improve Chinese (Simplified) translations (#25075) * Optimize Chinese local translation * update QM Co-authored-by: Shane Smiskol --- selfdrive/ui/translations/main_zh-CHS.qm | Bin 17617 -> 17629 bytes selfdrive/ui/translations/main_zh-CHS.ts | 38 +++++++++++------------ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/selfdrive/ui/translations/main_zh-CHS.qm b/selfdrive/ui/translations/main_zh-CHS.qm index 627f6afc204dba0b2c2a87f13cad266e9edcbd4f..be6c51030617f25c54c086e107274a1b0434ea5c 100644 GIT binary patch delta 1770 zcmX9;ZB$g%8h*~1ea_4|b7oG+SD^;X0P$^JzYxI!S13>@2IbOBQ@CSkUNenbmUI0U zF~yFQijpO0S*D9g%a6*G^pb*F+VU$#eaRTuj;(S2d0bE6ZG6+ayOc_P&AWq?)r-K+h8L%G(jNSZB z0x@%d$Cd+W%vrFSc`gHwKgn}RK=EMiokipq>LIQG{D~~I;9j5(VpT1GwjkP;2QkJ9 z;;8>YZ0Z6e9inL{6DklbpA(B9&Iq7?JCrpsKvD&iJ-Yz?Yp4e<5qn{enZ*3_VNW>^ zI88ik67^7wZC(UFl5;V(XFo7_B*tko0COn{hS!h?8>q--2Zu3!jzuLBFyTiM=yw|v z-}n#rSE58d&iKnHnX!b0Q}NWUdcg4$CgpEr!9q;_;B_FY6jQ%$=Ksg=Vi~*ccLsmI z!}G=xy!UOZAIQ!`h0^_Xae()fG;AF$O6!t} zPf*U->(Z7Bj1T)=YAq2=yi&R-?*O9yBJ~bg4&0w2>%MP*_}Aq4?hYV*r<|uRAhBlo znfusq+MDvW^YI!F%#uG_OJ;-I@|XGR0QVO8`(h@J`b}CMn8$~P z+dguWUgBX};{i^KY1j@mhBKYlS|~^R-xJe!1z6;!cs`#Jn&ZT)9ixGPd&Da78!%+4 z*pz>S^OF!ncSaBg^oXtXeL(WR#QR-ktQjIcK2rlkFB6~6uBS-z#6g2<8@I)&D{YMb zC{F$KGxL8UIv)8HQ2$W$;S@1B^P1wSdWotuC}Z65lwBy3rnjw220zoXQzzZF{aYFteGCI4`Nn-<<=dtNI9y?u_YXeA5`}*>A>WHrD|4h z9{E?OV;jE!Mod?yNK`ZSq`IT;F7RNKdL(@_VDD9LjlV!MJMEq%>JqQo8={u6jhF3v z=XR37^CnyKwWyQG!g0F=qRv}ru&Se{Q7OqYOUkVgsn~1?S{T*^+p!f^g|CTBsN_?=Hod<)|>PP`5GM5 znPVM0BjT!BH>3c!l9(68xC5#7eI!|1q zA#u^pe?HN~%adS)9cAIJa+u0%d}!Sz`Mqr;0_O`e_f z^oXk|m+0+teVav3weQ^FA96I~_PV21v6=g>x;=ek*z{NKjLUooQfu6WYbi!Zg1fSo zH!ps#d)w7V>Fx~o?t11O{JT}EM(4Gd5m)Z=Hos<$>*DV8QRZAH0ZcP%=m6`yA__1Ae{?jW#mXseO=O=gEc*soo|=zSTj;m QmkxU&cA6Qe&dkyO1fHhgfdBvi delta 1804 zcmYLJYg80v7=C7UW_D+Gb|w@gNd*>AxvEKs3YJ(XXdsAXp;5}ZQD)jfsZ95jlA=j? zMhy|j62dI=#2S@ZSptQmcF_*Sp$x%G*HdPiiKnNtKl(A}+3(%&y*F-7`>S|nRt>|$UAojFuVY;9|rVS_l=K z`>RkO9-;kF6fAt2iAUhBrUtHa1^lU$TavPhwMyYxiw6kvFhv|hRhj9)2LXC31F zj0~WW9Kd0{QfMK_WS$x63{ z`liXNk`0dSetFY&rd87eI7|rO@c00xHORHkQ%ud08=mFZ2D|0`pPU8~TI7!hNR?PF zABp^e)Isj_5FV({NB+-3MEpE>MqPx^egi_`@ z^<;MrXCq(j33`+-!#-_lJYNl;qHD#UAEW$=R&ilCFl-btodF)wHk~thF4wkRr+n^h zTJ@pbEa-c!wrehzWwTa)jB?t3*Y<7LO1=iPgJWebUB33QmwvLSwQ3{y8oaBu4oTx~ z)M)1yl`_v+r_i#7_m?@N4!5BY=7uwd`^q#n{icz6nh!z3dSm8uBqPXeRP5yD#WWgq z=We6A_ZfQ|7jh>XpN^L$qq#1#914|VgtYYEn#QvQr^`$XRKZB$6R_5JX4Cy z>hCtpDwyYwiTcK&I#y*BmFH-_Jijv`+h!AUT>klEjyR+Z%c@{SrH&N7^=GF}6 REVIEW - 审查 + 重新查看 @@ -180,15 +180,15 @@ VIEW - 看法 + 查看 Change Language - 改变语言 + 切换语言 CHANGE - 改变 + 切换 Select a language @@ -227,7 +227,7 @@ left - 剩下 + 向左 @@ -270,7 +270,7 @@ ALL TIME - 整天 + 全部 @@ -285,7 +285,7 @@ Miles - 迈尔斯 + 英里 @@ -293,7 +293,7 @@ camera starting - 相机启动 + 相机启动中 @@ -324,7 +324,7 @@ Receiving objects: - 接收物体: + 正在接收: @@ -462,12 +462,12 @@ location set ALERTS - 个警报 + 警报 ALERT - 个警报 + 警报 @@ -561,7 +561,7 @@ location set Exit - 出口 + 退出 @@ -571,7 +571,7 @@ location set openpilot - 开放式飞行员 + openpilot @@ -732,7 +732,7 @@ location set Waiting for internet - 等待上网 + 等待网络连接 @@ -857,7 +857,7 @@ location set NO - + 未连接 @@ -1046,12 +1046,12 @@ location set Decline - 衰退 + 拒绝 Scroll to accept - 滚动接受 + 滑动接受 @@ -1084,7 +1084,7 @@ location set Enable Right-Hand Drive - 启用右手驱动 + 启用右舵模式 @@ -1114,7 +1114,7 @@ location set Disengage On Accelerator Pedal - 松开加速踏板 + 踩油门解除 From df251ef50ebfe5c997e14a03fca4ec932bc4c5cf Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Fri, 8 Jul 2022 13:00:43 -0700 Subject: [PATCH 058/112] Fix master-ci dirty working tree + CI test (#25087) * check * test for dirty working tree * swap order * fix diff --- .github/workflows/selfdrive_tests.yaml | 7 +++++-- .gitignore | 2 -- Jenkinsfile | 1 + rednose_repo | 2 +- release/check-dirty.sh | 11 +++++++++++ release/files_common | 3 +++ selfdrive/loggerd/.gitignore | 1 + 7 files changed, 22 insertions(+), 5 deletions(-) create mode 100755 release/check-dirty.sh diff --git a/.github/workflows/selfdrive_tests.yaml b/.github/workflows/selfdrive_tests.yaml index 35a08d4fe9..99a21b58f3 100644 --- a/.github/workflows/selfdrive_tests.yaml +++ b/.github/workflows/selfdrive_tests.yaml @@ -59,11 +59,14 @@ jobs: TARGET_DIR=$STRIPPED_DIR release/build_devel.sh cp Dockerfile.openpilot_base $STRIPPED_DIR - name: Build Docker image - run: eval "$BUILD" + run: | + eval "$BUILD" + rm $STRIPPED_DIR/Dockerfile.openpilot_base - name: Build openpilot and run checks run: | cd $STRIPPED_DIR ${{ env.RUN }} "CI=1 python selfdrive/manager/build.py && \ + release/check-dirty.sh && \ python -m unittest discover selfdrive/car" build_all: @@ -89,7 +92,7 @@ jobs: - name: Build Docker image run: eval "$BUILD" - name: Build openpilot with all flags - run: ${{ env.RUN }} "scons -j$(nproc) --extras --test" + run: ${{ env.RUN }} "scons -j$(nproc) --extras --test && release/check-dirty.sh" - name: Cleanup scons cache run: | ${{ env.RUN }} "scons -j$(nproc) --extras --test && \ diff --git a/.gitignore b/.gitignore index 0092c4dc94..e1ff5d5008 100644 --- a/.gitignore +++ b/.gitignore @@ -45,8 +45,6 @@ system/proclogd/proclogd selfdrive/ui/_ui selfdrive/test/longitudinal_maneuvers/out selfdrive/visiond/visiond -selfdrive/loggerd/loggerd -selfdrive/loggerd/bootlog selfdrive/sensord/_gpsd selfdrive/sensord/_sensord system/camerad/camerad diff --git a/Jenkinsfile b/Jenkinsfile index 0fa623fbcd..4e13717851 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -115,6 +115,7 @@ pipeline { phone_steps("tici", [ ["build master-ci", "cd $SOURCE_DIR/release && TARGET_DIR=$TEST_DIR EXTRA_FILES='tools/' ./build_devel.sh"], ["build openpilot", "cd selfdrive/manager && ./build.py"], + ["check dirty", "release/check-dirty.sh"], ["test manager", "python selfdrive/manager/test/test_manager.py"], ["onroad tests", "cd selfdrive/test/ && ./test_onroad.py"], ["test car interfaces", "cd selfdrive/car/tests/ && ./test_car_interfaces.py"], diff --git a/rednose_repo b/rednose_repo index 225dbacbaa..3b6bd703b7 160000 --- a/rednose_repo +++ b/rednose_repo @@ -1 +1 @@ -Subproject commit 225dbacbaac312f85eaaee0b97a3acc31f9c6b47 +Subproject commit 3b6bd703b7a7667e4f82d0b81ef9a454819b94bd diff --git a/release/check-dirty.sh b/release/check-dirty.sh new file mode 100755 index 0000000000..9c6389f380 --- /dev/null +++ b/release/check-dirty.sh @@ -0,0 +1,11 @@ +#!/usr/bin/bash +set -e + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" +cd $DIR + +if [ ! -z "$(git status --porcelain)" ]; then + echo "Dirty working tree after build:" + git status --porcelain + exit 1 +fi diff --git a/release/files_common b/release/files_common index 260e37e29a..fb91170561 100644 --- a/release/files_common +++ b/release/files_common @@ -231,6 +231,7 @@ selfdrive/locationd/models/gnss_helpers.py selfdrive/locationd/calibrationd.py +system/logcatd/.gitignore system/logcatd/SConscript system/logcatd/logcatd_systemd.cc @@ -239,6 +240,7 @@ system/proclogd/main.cc system/proclogd/proclog.cc system/proclogd/proclog.h +selfdrive/loggerd/.gitignore selfdrive/loggerd/SConscript selfdrive/loggerd/encoder/encoder.cc selfdrive/loggerd/encoder/encoder.h @@ -414,6 +416,7 @@ scripts/stop_updater.sh pyextra/.gitignore pyextra/acados_template/** +rednose/.gitignore rednose/** laika/** diff --git a/selfdrive/loggerd/.gitignore b/selfdrive/loggerd/.gitignore index 6437be5e38..53dc24e6f2 100644 --- a/selfdrive/loggerd/.gitignore +++ b/selfdrive/loggerd/.gitignore @@ -1,3 +1,4 @@ loggerd encoderd +bootlog tests/test_logger From 8ea982264ec4ba7aa47a3228236f943e76a911c5 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Fri, 8 Jul 2022 13:05:25 -0700 Subject: [PATCH 059/112] remove casync from agnos manifest for now --- system/hardware/tici/agnos.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/system/hardware/tici/agnos.json b/system/hardware/tici/agnos.json index 853d3ab434..7ccea95ee7 100644 --- a/system/hardware/tici/agnos.json +++ b/system/hardware/tici/agnos.json @@ -47,8 +47,6 @@ "size": 10737418240, "sparse": true, "full_check": false, - "has_ab": true, - "casync_caibx": "https://commadist.azureedge.net/agnosupdate/system-59622eddd068d49f2e9df69ef5115e3f205ad369539690a5b240c8c93796dd13.caibx", - "casync_store": "https://commadist.azureedge.net/agnosupdate/system-59622eddd068d49f2e9df69ef5115e3f205ad369539690a5b240c8c93796dd13" + "has_ab": true } ] From 1d6623c6092e312d03ce4d434077780e2287a010 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Fri, 8 Jul 2022 13:18:12 -0700 Subject: [PATCH 060/112] update release notes --- RELEASES.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index 392e9dc486..7e8f80500e 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,18 +1,18 @@ -Version 0.8.15 (2022-07-XX) +Version 0.8.15 (2022-07-20) ======================== * New driving model * Path planning uses end-to-end output instead of lane lines at all times * Reduced ping pong * Improved lane centering * New lateral controller based on physical wheel torque model - * Much smoother control, consistent across the speed range + * Much smoother control that's consistent across the speed range * Effective feedforward that uses road roll * Simplified tuning, all car-specific parameters can be derived from data + * Used on select Toyota and Hyundai models at first * Significantly improved control on TSS-P Prius * New driver monitoring model * Takes a larger input frame * Outputs a driver state for both driver and passenger - * Automatically determines which side the driver is on (soon) * Navigation improvements * Speed limits shown while navigating * Faster position fix by using raw GPS measurements @@ -23,8 +23,8 @@ Version 0.8.15 (2022-07-XX) * More consistent camera view perspective across cars * Reduced power usage: device runs cooler and fan spins less * AGNOS 5 - * Support for delta updates to reduce data usage on future OS updates * Support VSCode remote SSH target + * Support for delta updates to reduce data usage on future OS updates * Honda Civic 2022 support * Hyundai Tucson 2021 support thanks to bluesforte! * Lexus NX Hybrid 2020 support thanks to AlexandreSato! From 5f77451aec3345c80f8cf2e5cd15c0ce911d5612 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 8 Jul 2022 13:46:09 -0700 Subject: [PATCH 061/112] FW fingerprinting updates (#25088) * Print brand along with ecu * fix json decoding * fw_versions updates * add timeout handling back * keep logging the same --- selfdrive/car/car_helpers.py | 6 +++--- selfdrive/car/fw_versions.py | 22 ++++++++++------------ 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/selfdrive/car/car_helpers.py b/selfdrive/car/car_helpers.py index 7f83732153..690072cc4d 100644 --- a/selfdrive/car/car_helpers.py +++ b/selfdrive/car/car_helpers.py @@ -79,7 +79,7 @@ interfaces = load_interfaces(interface_names) def fingerprint(logcan, sendcan): fixed_fingerprint = os.environ.get('FINGERPRINT', "") skip_fw_query = os.environ.get('SKIP_FW_QUERY', False) - ecu_responses = set() + ecu_rx_addrs = set() if not fixed_fingerprint and not skip_fw_query: # Vin query only reliably works thorugh OBDII @@ -98,7 +98,7 @@ def fingerprint(logcan, sendcan): else: cloudlog.warning("Getting VIN & FW versions") _, vin = get_vin(logcan, sendcan, bus) - ecu_responses = get_present_ecus(logcan, sendcan) + ecu_rx_addrs = get_present_ecus(logcan, sendcan) car_fw = get_fw_versions(logcan, sendcan) exact_fw_match, fw_candidates = match_fw_to_car(car_fw) @@ -166,7 +166,7 @@ def fingerprint(logcan, sendcan): source = car.CarParams.FingerprintSource.fixed cloudlog.event("fingerprinted", car_fingerprint=car_fingerprint, source=source, fuzzy=not exact_match, - fw_count=len(car_fw), ecu_responses=ecu_responses, error=True) + fw_count=len(car_fw), ecu_responses=list(ecu_rx_addrs), error=True) return car_fingerprint, finger, vin, car_fw, source, exact_match diff --git a/selfdrive/car/fw_versions.py b/selfdrive/car/fw_versions.py index 03dcece10c..c51d120166 100755 --- a/selfdrive/car/fw_versions.py +++ b/selfdrive/car/fw_versions.py @@ -290,24 +290,21 @@ def match_fw_to_car(fw_versions, allow_fuzzy=True): versions = get_interface_attr('FW_VERSIONS', ignore_none=True) # Try exact matching first - exact_matches = [True] + exact_matches = [(True, match_fw_to_car_exact)] if allow_fuzzy: - exact_matches.append(False) + exact_matches.append((False, match_fw_to_car_fuzzy)) - for exact_match in exact_matches: + for exact_match, match_func in exact_matches: # For each brand, attempt to fingerprint using FW returned from its queries + matches = set() for brand in versions.keys(): fw_versions_dict = build_fw_dict(fw_versions, filter_brand=brand) + matches |= match_func(fw_versions_dict) - if exact_match: - matches = match_fw_to_car_exact(fw_versions_dict) - else: - matches = match_fw_to_car_fuzzy(fw_versions_dict) + if len(matches): + return exact_match, matches - if len(matches) == 1: - return exact_match, matches - - return True, [] + return True, set() def get_present_ecus(logcan, sendcan): @@ -448,9 +445,10 @@ if __name__ == "__main__": print() print("Found FW versions") print("{") + padding = max([len(fw.brand) for fw in fw_vers]) for version in fw_vers: subaddr = None if version.subAddress == 0 else hex(version.subAddress) - print(f" (Ecu.{version.ecu}, {hex(version.address)}, {subaddr}): [{version.fwVersion}]") + print(f" Brand: {version.brand:{padding}} - (Ecu.{version.ecu}, {hex(version.address)}, {subaddr}): [{version.fwVersion}]") print("}") print() From b5f0cb22a5aab4ea94cdc817bf0331919a265bfb Mon Sep 17 00:00:00 2001 From: realfast Date: Fri, 8 Jul 2022 16:36:02 -0500 Subject: [PATCH 062/112] Add Chrysler FPv2 requests and logging (#24460) * Chrylser FPv2 * Update fw_versions.py * formatting and remove default * fix rx offset * move to end * add fw versions * this won't be fingerprinted on as it returns from Mazda * only log FW versions * add type annotation * fix typing * Skip if FW versions are for read/request-only * Fix crash if no fw versions Fix crash if no fw versions Co-authored-by: Shane Smiskol Co-authored-by: Adeeb Shihadeh --- selfdrive/car/chrysler/values.py | 18 +++++++++++++++++- selfdrive/car/fw_versions.py | 21 ++++++++++++++++++++- selfdrive/car/tests/test_fw_fingerprint.py | 2 ++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/selfdrive/car/chrysler/values.py b/selfdrive/car/chrysler/values.py index 40210e68e6..ada4f486fc 100644 --- a/selfdrive/car/chrysler/values.py +++ b/selfdrive/car/chrysler/values.py @@ -1,6 +1,7 @@ +import capnp from dataclasses import dataclass from enum import Enum -from typing import Dict, List, Optional, Union +from typing import Dict, List, Optional, Tuple, Union from cereal import car from selfdrive.car import dbc_dict @@ -110,6 +111,21 @@ FINGERPRINTS = { ], } +FW_VERSIONS: Dict[str, Dict[Tuple[capnp.lib.capnp._EnumModule, int, Optional[int]], List[str]]] = { + CAR.RAM_1500: { + (Ecu.combinationMeter, 0x742, None): [], + (Ecu.srs, 0x744, None): [], + (Ecu.esp, 0x747, None): [], + (Ecu.fwdCamera, 0x753, None): [], + (Ecu.fwdCamera, 0x764, None): [], + (Ecu.eps, 0x761, None): [], + (Ecu.fwdRadar, 0x757, None): [], + (Ecu.eps, 0x75A, None): [], + (Ecu.engine, 0x7e0, None): [], + (Ecu.transmission, 0x7e1, None): [], + (Ecu.gateway, 0x18DACBF1, None): [], + } +} DBC = { CAR.PACIFICA_2017_HYBRID: dbc_dict('chrysler_pacifica_2017_hybrid_generated', 'chrysler_pacifica_2017_hybrid_private_fusion'), diff --git a/selfdrive/car/fw_versions.py b/selfdrive/car/fw_versions.py index c51d120166..04610b96d9 100755 --- a/selfdrive/car/fw_versions.py +++ b/selfdrive/car/fw_versions.py @@ -92,6 +92,13 @@ SUBARU_VERSION_REQUEST = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER]) + \ SUBARU_VERSION_RESPONSE = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER + 0x40]) + \ p16(uds.DATA_IDENTIFIER_TYPE.APPLICATION_DATA_IDENTIFICATION) +CHRYSLER_VERSION_REQUEST = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER]) + \ + p16(0xf132) +CHRYSLER_VERSION_RESPONSE = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER + 0x40]) + \ + p16(0xf132) + +CHRYSLER_RX_OFFSET = -0x280 + @dataclass class Request: @@ -188,6 +195,18 @@ REQUESTS: List[Request] = [ [TESTER_PRESENT_RESPONSE, UDS_VERSION_RESPONSE], bus=0, ), + # Chrysler / FCA / Stellantis + Request( + "chrysler", + [CHRYSLER_VERSION_REQUEST], + [CHRYSLER_VERSION_RESPONSE], + rx_offset=CHRYSLER_RX_OFFSET, + ), + Request( + "chrysler", + [CHRYSLER_VERSION_REQUEST], + [CHRYSLER_VERSION_RESPONSE], + ), ] @@ -445,7 +464,7 @@ if __name__ == "__main__": print() print("Found FW versions") print("{") - padding = max([len(fw.brand) for fw in fw_vers]) + padding = max([len(fw.brand) for fw in fw_vers] or [0]) for version in fw_vers: subaddr = None if version.subAddress == 0 else hex(version.subAddress) print(f" Brand: {version.brand:{padding}} - (Ecu.{version.ecu}, {hex(version.address)}, {subaddr}): [{version.fwVersion}]") diff --git a/selfdrive/car/tests/test_fw_fingerprint.py b/selfdrive/car/tests/test_fw_fingerprint.py index 49fa66d36d..cda241c73f 100755 --- a/selfdrive/car/tests/test_fw_fingerprint.py +++ b/selfdrive/car/tests/test_fw_fingerprint.py @@ -27,6 +27,8 @@ class TestFwFingerprint(unittest.TestCase): for _ in range(200): fw = [] for ecu, fw_versions in ecus.items(): + if not len(fw_versions): + raise unittest.SkipTest("Car model has no FW versions") ecu_name, addr, sub_addr = ecu fw.append({"ecu": ecu_name, "fwVersion": random.choice(fw_versions), 'brand': brand, "address": addr, "subAddress": 0 if sub_addr is None else sub_addr}) From c907a0c28aa0958fbc841019eb401a23432ef897 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Fri, 8 Jul 2022 14:42:54 -0700 Subject: [PATCH 063/112] add chrysler fw query to release notes --- RELEASES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASES.md b/RELEASES.md index 7e8f80500e..1e9a1b0423 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -25,6 +25,7 @@ Version 0.8.15 (2022-07-20) * AGNOS 5 * Support VSCode remote SSH target * Support for delta updates to reduce data usage on future OS updates +* Chrysler ECU firmware fingerprinting thanks to realfast! * Honda Civic 2022 support * Hyundai Tucson 2021 support thanks to bluesforte! * Lexus NX Hybrid 2020 support thanks to AlexandreSato! From 76dde007959b633f4140d04e79043c7faef567b9 Mon Sep 17 00:00:00 2001 From: ZwX1616 Date: Fri, 8 Jul 2022 16:57:50 -0700 Subject: [PATCH 064/112] Update RELEASES.md --- RELEASES.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index 1e9a1b0423..588b88827a 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -11,8 +11,9 @@ Version 0.8.15 (2022-07-20) * Used on select Toyota and Hyundai models at first * Significantly improved control on TSS-P Prius * New driver monitoring model - * Takes a larger input frame - * Outputs a driver state for both driver and passenger + * Bigger model, covering full interior view from driver camera + * Works with a wider variety of mounting angles + * 3x more unique comma three training data than previous * Navigation improvements * Speed limits shown while navigating * Faster position fix by using raw GPS measurements From 4c493237d52525d2effb95b5cda96b36a684303c Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 8 Jul 2022 19:36:09 -0700 Subject: [PATCH 065/112] Interleave VIN queries (#25090) Interleave the two requests --- selfdrive/car/vin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/selfdrive/car/vin.py b/selfdrive/car/vin.py index 7413c3f235..fd1ca61e66 100755 --- a/selfdrive/car/vin.py +++ b/selfdrive/car/vin.py @@ -18,8 +18,8 @@ VIN_UNKNOWN = "0" * 17 def get_vin(logcan, sendcan, bus, timeout=0.1, retry=5, debug=False): - for request, response in ((UDS_VIN_REQUEST, UDS_VIN_RESPONSE), (OBD_VIN_REQUEST, OBD_VIN_RESPONSE)): - for i in range(retry): + for i in range(retry): + for request, response in ((UDS_VIN_REQUEST, UDS_VIN_RESPONSE), (OBD_VIN_REQUEST, OBD_VIN_RESPONSE)): try: query = IsoTpParallelQuery(sendcan, logcan, bus, FUNCTIONAL_ADDRS, [request, ], [response, ], functional_addr=True, debug=debug) for addr, vin in query.get_data(timeout).items(): From 94c8717cac0cfad4603d57a8da108a124019dd73 Mon Sep 17 00:00:00 2001 From: Erich Moraga <33645296+ErichMoraga@users.noreply.github.com> Date: Fri, 8 Jul 2022 22:03:21 -0500 Subject: [PATCH 066/112] Add missing HIGHLANDERH_TSS2 ESP & engine f/w (#25066) * Add missing HIGHLANDERH_TSS2 ESP & engine f/w `@pkozlowski#5214` 2022 Highlander Hybrid (Poland) DongleID/route b2e9858e29db492b|2022-07-07--17-57-24 * Fix test_fw_query_on_routes with older routes Co-authored-by: Shane Smiskol --- selfdrive/car/toyota/values.py | 4 +++- selfdrive/debug/test_fw_query_on_routes.py | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py index 8149bfd063..2a03999342 100644 --- a/selfdrive/car/toyota/values.py +++ b/selfdrive/car/toyota/values.py @@ -954,11 +954,13 @@ FW_VERSIONS = { b'\x01F15264873500\x00\x00\x00\x00', b'\x01F152648C6300\x00\x00\x00\x00', b'\x01F152648J4000\x00\x00\x00\x00', + b'\x01F152648J6000\x00\x00\x00\x00', ], (Ecu.engine, 0x700, None): [ + b'\x01896630EE4000\x00\x00\x00\x00', + b'\x01896630EE6000\x00\x00\x00\x00', b'\x01896630E67000\x00\x00\x00\x00', b'\x01896630EA1000\x00\x00\x00\x00', - b'\x01896630EE4000\x00\x00\x00\x00', b'\x01896630EA1000\x00\x00\x00\x00897CF4801001\x00\x00\x00\x00', b'\x02896630E66000\x00\x00\x00\x00897CF4801001\x00\x00\x00\x00', b'\x02896630EB3000\x00\x00\x00\x00897CF4801001\x00\x00\x00\x00', diff --git a/selfdrive/debug/test_fw_query_on_routes.py b/selfdrive/debug/test_fw_query_on_routes.py index 8c8c631c38..9ce0ebb3f5 100755 --- a/selfdrive/debug/test_fw_query_on_routes.py +++ b/selfdrive/debug/test_fw_query_on_routes.py @@ -17,6 +17,7 @@ NO_API = "NO_API" in os.environ VERSIONS = get_interface_attr('FW_VERSIONS', ignore_none=True) SUPPORTED_BRANDS = VERSIONS.keys() SUPPORTED_CARS = [brand for brand in SUPPORTED_BRANDS for brand in interface_names[brand]] +UNKNOWN_BRAND = "unknown" try: from xx.pipeline.c.CarState import migration @@ -126,10 +127,10 @@ if __name__ == "__main__": print("New style (exact):", exact_matches) print("New style (fuzzy):", fuzzy_matches) - padding = max([len(fw.brand) for fw in car_fw]) + padding = max([len(fw.brand or UNKNOWN_BRAND) for fw in car_fw]) for version in sorted(car_fw, key=lambda fw: fw.brand): subaddr = None if version.subAddress == 0 else hex(version.subAddress) - print(f" Brand: {version.brand:{padding}} - (Ecu.{version.ecu}, {hex(version.address)}, {subaddr}): [{version.fwVersion}],") + print(f" Brand: {version.brand or UNKNOWN_BRAND:{padding}} - (Ecu.{version.ecu}, {hex(version.address)}, {subaddr}): [{version.fwVersion}],") print("Mismatches") found = False From 949de4d2b6b293d9f77d83c58212f5dee176cbf1 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 8 Jul 2022 20:25:54 -0700 Subject: [PATCH 067/112] UI: Internationalization support (#21212) * rough multiple language demo * more wrappings * stash * add some bad translations * updates * map from french to spanish still has same problem of needing to call setText on everything * add files * restart UI * use return code * relative path * more translations * don't loop restart * Toggle and prime translations * try on device * try QComboBox with readable style * stash * not yet scrollable * stash * dynamic translations (doesn't work for dynamic widget strings yet) * clean up multiple option selector * store languages in json * try transparent * Try transparent popup * see how this looks * tweaks * clean up * update names * Add Chinese (Simplified) translations * Do missing French translations * unit tests caught that :) * fix test * fix other test (on PC) * add entries to dialog to test * add cancel button, clean up a bit * just chinese * some clean up * use quotes * clean up * Just quit, set timeout to 0 * half a second * use exitcode * don't print if it's expected * this comment is outdated * update translations * Update translations * re-order input classes * Update line numbers * use enabled property for button style * Get rid of ListWidget * Update line numbers * Log failed to load language * Log failed to load language * Move to utils and fix english logging extra line * Update translations * spacing * looks a bit better * try this instead of exitcode fixes fix * only one function * comment * Update line numbers * fixup some japanese translations * clean up multi option dialog * Update line numbers --- common/params.cc | 1 + common/watchdog.cc | 5 +- common/watchdog.h | 4 +- selfdrive/ui/main.cc | 9 ++ selfdrive/ui/qt/offroad/settings.cc | 14 ++ selfdrive/ui/qt/util.cc | 16 +++ selfdrive/ui/qt/util.h | 1 + selfdrive/ui/qt/widgets/input.cc | 86 ++++++++++++ selfdrive/ui/qt/widgets/input.h | 9 ++ selfdrive/ui/tests/test_translations.cc | 1 + selfdrive/ui/translations/main_ja.ts | 6 +- selfdrive/ui/translations/main_ko.qm | Bin 19159 -> 19449 bytes selfdrive/ui/translations/main_ko.ts | 167 ++++++++++++----------- selfdrive/ui/translations/main_zh-CHS.qm | Bin 17629 -> 17919 bytes selfdrive/ui/translations/main_zh-CHS.ts | 167 ++++++++++++----------- selfdrive/ui/translations/main_zh-CHT.qm | Bin 17741 -> 18031 bytes selfdrive/ui/translations/main_zh-CHT.ts | 167 ++++++++++++----------- selfdrive/ui/ui.cc | 2 +- selfdrive/ui/update_translations.py | 2 +- 19 files changed, 404 insertions(+), 253 deletions(-) diff --git a/common/params.cc b/common/params.cc index f93c87cd98..c4f65a9e02 100644 --- a/common/params.cc +++ b/common/params.cc @@ -129,6 +129,7 @@ std::unordered_map keys = { {"IsUpdateAvailable", CLEAR_ON_MANAGER_START}, {"JoystickDebugMode", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF}, {"LaikadEphemeris", PERSISTENT | DONT_LOG}, + {"LanguageSetting", PERSISTENT}, {"LastAthenaPingTime", CLEAR_ON_MANAGER_START}, {"LastGPSPosition", PERSISTENT}, {"LastManagerExitReason", CLEAR_ON_MANAGER_START}, diff --git a/common/watchdog.cc b/common/watchdog.cc index 5a10207828..920df4030a 100644 --- a/common/watchdog.cc +++ b/common/watchdog.cc @@ -1,12 +1,9 @@ #include "common/watchdog.h" -#include "common/timing.h" #include "common/util.h" const std::string watchdog_fn_prefix = "/dev/shm/wd_"; // + -bool watchdog_kick() { +bool watchdog_kick(uint64_t ts) { static std::string fn = watchdog_fn_prefix + std::to_string(getpid()); - - uint64_t ts = nanos_since_boot(); return util::write_file(fn.c_str(), &ts, sizeof(ts), O_WRONLY | O_CREAT) > 0; } diff --git a/common/watchdog.h b/common/watchdog.h index 7ed23aa0d9..12dd2ca035 100644 --- a/common/watchdog.h +++ b/common/watchdog.h @@ -1,3 +1,5 @@ #pragma once -bool watchdog_kick(); +#include + +bool watchdog_kick(uint64_t ts); diff --git a/selfdrive/ui/main.cc b/selfdrive/ui/main.cc index 1eecd78b19..ed54d5aa19 100644 --- a/selfdrive/ui/main.cc +++ b/selfdrive/ui/main.cc @@ -1,6 +1,7 @@ #include #include +#include #include "system/hardware/hw.h" #include "selfdrive/ui/qt/qt_window.h" @@ -13,7 +14,15 @@ int main(int argc, char *argv[]) { qInstallMessageHandler(swagLogMessageHandler); initApp(argc, argv); + QTranslator translator; + QString translation_file = QString::fromStdString(Params().get("LanguageSetting")); + if (!translator.load(translation_file, "translations") && translation_file.length()) { + qCritical() << "Failed to load translation file:" << translation_file; + } + QApplication a(argc, argv); + a.installTranslator(&translator); + MainWindow w; setMainWindow(&w); a.installEventFilter(&w); diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index a03af23951..6bcdd55b0a 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -13,6 +13,7 @@ #endif #include "common/params.h" +#include "common/watchdog.h" #include "common/util.h" #include "system/hardware/hw.h" #include "selfdrive/ui/qt/widgets/controls.h" @@ -133,6 +134,19 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) { addItem(regulatoryBtn); } + auto translateBtn = new ButtonControl(tr("Change Language"), tr("CHANGE"), ""); + connect(translateBtn, &ButtonControl::clicked, [=]() { + QMap langs = getSupportedLanguages(); + QString selection = MultiOptionDialog::getSelection(tr("Select a language"), langs.keys(), this); + if (!selection.isEmpty()) { + // put language setting, exit Qt UI, and trigger fast restart + Params().put("LanguageSetting", langs[selection].toStdString()); + qApp->exit(18); + watchdog_kick(0); + } + }); + addItem(translateBtn); + QObject::connect(uiState(), &UIState::offroadTransition, [=](bool offroad) { for (auto btn : findChildren()) { btn->setEnabled(offroad); diff --git a/selfdrive/ui/qt/util.cc b/selfdrive/ui/qt/util.cc index cab7299cd6..a7d5438ae4 100644 --- a/selfdrive/ui/qt/util.cc +++ b/selfdrive/ui/qt/util.cc @@ -1,6 +1,9 @@ #include "selfdrive/ui/qt/util.h" #include +#include +#include +#include #include #include #include @@ -36,6 +39,19 @@ std::optional getDongleId() { } } +QMap getSupportedLanguages() { + QFile f("translations/languages.json"); + f.open(QIODevice::ReadOnly | QIODevice::Text); + QString val = f.readAll(); + + QJsonObject obj = QJsonDocument::fromJson(val.toUtf8()).object(); + QMap map; + for (auto key : obj.keys()) { + map[key] = obj[key].toString(); + } + return map; +} + void configFont(QPainter &p, const QString &family, int size, const QString &style) { QFont f(family); f.setPixelSize(size); diff --git a/selfdrive/ui/qt/util.h b/selfdrive/ui/qt/util.h index 9491c6798e..f0e57526c8 100644 --- a/selfdrive/ui/qt/util.h +++ b/selfdrive/ui/qt/util.h @@ -14,6 +14,7 @@ QString getBrand(); QString getBrandVersion(); QString getUserAgent(); std::optional getDongleId(); +QMap getSupportedLanguages(); void configFont(QPainter &p, const QString &family, int size, const QString &style); void clearLayout(QLayout* layout); void setQtSurfaceFormat(); diff --git a/selfdrive/ui/qt/widgets/input.cc b/selfdrive/ui/qt/widgets/input.cc index 755ccfe8c5..a130a8e935 100644 --- a/selfdrive/ui/qt/widgets/input.cc +++ b/selfdrive/ui/qt/widgets/input.cc @@ -1,6 +1,7 @@ #include "selfdrive/ui/qt/widgets/input.h" #include +#include #include "system/hardware/hw.h" #include "selfdrive/ui/qt/util.h" @@ -257,3 +258,88 @@ bool RichTextDialog::alert(const QString &prompt_text, QWidget *parent) { auto d = RichTextDialog(prompt_text, tr("Ok"), parent); return d.exec(); } + +// MultiOptionDialog + +MultiOptionDialog::MultiOptionDialog(const QString &prompt_text, QStringList l, QWidget *parent) : QDialogBase(parent) { + QFrame *container = new QFrame(this); + container->setStyleSheet(R"( + QFrame { background-color: #1B1B1B; } + #confirm_btn[enabled="false"] { background-color: #2B2B2B; } + #confirm_btn:enabled { background-color: #465BEA; } + #confirm_btn:enabled:pressed { background-color: #3049F4; } + )"); + + QVBoxLayout *main_layout = new QVBoxLayout(container); + main_layout->setContentsMargins(55, 50, 55, 50); + + QLabel *title = new QLabel(prompt_text, this); + title->setStyleSheet("font-size: 70px; font-weight: 500;"); + main_layout->addWidget(title, 0, Qt::AlignLeft | Qt::AlignTop); + main_layout->addSpacing(25); + + QWidget *listWidget = new QWidget(this); + QVBoxLayout *listLayout = new QVBoxLayout(listWidget); + listLayout->setSpacing(20); + listWidget->setStyleSheet(R"( + QPushButton { + height: 135; + padding: 0px 50px; + text-align: left; + font-size: 55px; + font-weight: 300; + border-radius: 10px; + background-color: #4F4F4F; + } + QPushButton:checked { background-color: #465BEA; } + )"); + + QButtonGroup *group = new QButtonGroup(listWidget); + group->setExclusive(true); + + QPushButton *confirm_btn = new QPushButton(tr("Select")); + confirm_btn->setObjectName("confirm_btn"); + confirm_btn->setEnabled(false); + + for (QString &s : l) { + QPushButton *selectionLabel = new QPushButton(s); + selectionLabel->setCheckable(true); + QObject::connect(selectionLabel, &QPushButton::toggled, [=](bool checked) { + if (checked) selection = s; + confirm_btn->setEnabled(true); + }); + + group->addButton(selectionLabel); + listLayout->addWidget(selectionLabel); + } + + ScrollView *scroll_view = new ScrollView(listWidget, this); + scroll_view->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); + + main_layout->addWidget(scroll_view); + main_layout->addStretch(1); + main_layout->addSpacing(35); + + // cancel + confirm buttons + QHBoxLayout *blayout = new QHBoxLayout; + main_layout->addLayout(blayout); + blayout->setSpacing(50); + + QPushButton *cancel_btn = new QPushButton(tr("Cancel")); + QObject::connect(cancel_btn, &QPushButton::clicked, this, &ConfirmationDialog::reject); + QObject::connect(confirm_btn, &QPushButton::clicked, this, &ConfirmationDialog::accept); + blayout->addWidget(cancel_btn); + blayout->addWidget(confirm_btn); + + QVBoxLayout *outer_layout = new QVBoxLayout(this); + outer_layout->setContentsMargins(50, 50, 50, 50); + outer_layout->addWidget(container); +} + +QString MultiOptionDialog::getSelection(const QString &prompt_text, const QStringList l, QWidget *parent) { + MultiOptionDialog d = MultiOptionDialog(prompt_text, l, parent); + if (d.exec()) { + return d.selection; + } + return ""; +} diff --git a/selfdrive/ui/qt/widgets/input.h b/selfdrive/ui/qt/widgets/input.h index f81211d0ee..47d8b74efd 100644 --- a/selfdrive/ui/qt/widgets/input.h +++ b/selfdrive/ui/qt/widgets/input.h @@ -68,3 +68,12 @@ public: explicit RichTextDialog(const QString &prompt_text, const QString &btn_text, QWidget* parent); static bool alert(const QString &prompt_text, QWidget *parent); }; + +class MultiOptionDialog : public QDialogBase { + Q_OBJECT + +public: + explicit MultiOptionDialog(const QString &prompt_text, const QStringList l, QWidget *parent); + static QString getSelection(const QString &prompt_text, const QStringList l, QWidget *parent); + QString selection; +}; diff --git a/selfdrive/ui/tests/test_translations.cc b/selfdrive/ui/tests/test_translations.cc index fecb9da44a..ba0612b4c0 100644 --- a/selfdrive/ui/tests/test_translations.cc +++ b/selfdrive/ui/tests/test_translations.cc @@ -41,6 +41,7 @@ void checkWidgetTrWrap(MainWindow &w) { // Tests all strings in the UI are wrapped with tr() TEST_CASE("UI: test all strings wrapped") { + Params().remove("LanguageSetting"); Params().remove("HardwareSerial"); Params().remove("DongleId"); qputenv("TICI", "1"); diff --git a/selfdrive/ui/translations/main_ja.ts b/selfdrive/ui/translations/main_ja.ts index fbb654bc4c..5c0f54a314 100644 --- a/selfdrive/ui/translations/main_ja.ts +++ b/selfdrive/ui/translations/main_ja.ts @@ -528,12 +528,12 @@ location set ✓ SUBSCRIBED - ✓ 購読 + ✓ 購読しました comma prime - コンマプライム + comma prime @@ -543,7 +543,7 @@ location set COMMA POINTS - コンマポイント + COMMA POINTS diff --git a/selfdrive/ui/translations/main_ko.qm b/selfdrive/ui/translations/main_ko.qm index 62ddb3be2b89c6c73e82458ae86c02825c925de5..f6e95b5038f984183d9d4273c581bb6ef6e4b91d 100644 GIT binary patch delta 1948 zcmZWqX;4#F7(ID;FE4p{c>!6pwrB`JMJwQ1tf2}B3RVzBbX-~&FhVJ63$?BpS6px# zT(F{b0d4En0k=}LF1X_pwkRM?;;ivrxA}5*Awdik?Yp+fD{IFmWaKHLx`goljp&pR{{ALpp^sa z8NiVU#4Z53_5l(W1Fv%Y=1?MYCU*ghvx$=cx8FnlSjYt)l*0-CNzgChA#xbRyo~^U z_Mm>h2OYT{jJ^u7umRB7AXawg{`VnXJWQ;Bcv%G6218nEBhkl@_Ut67`7j*(mbeSD zZ3NGG19GQoxS?J{xV0KE=c9ksOdzxZ{qG+Ddgft(iMRGHMnccEB*KeKi{=3#NXjap zBCliccO>9<1Vd*3#`qgZ5l(VG4=Lm4^57z*?konBSd55Y!vnoB@{?IWOc=%-ui`nc zUykTsk$E4C7%xA{4?E0*E!#NpYBqM$h--X1%%WI!FTF` zZnK0q#hpWDD}~Wsym8lbVNZo8Cfg6>A<=CDd*4 zW5T8SfJZDN}5m$@5FRulHhKc*%DW3^uRVZ1OO{J1aQj8YNi{wZn#@8&qkry)Vkfu-kknv}vncX!u!Fp-gIucPfd$4W12W<;I7_(R^>Qqb*`tFvBR?-`4 zvQ)fiA(gl1h)QhQ}F% zz!ZAybA$Fc6tL|wI3L7O!HI_crAL5Br(u+il?c9W*xvY@3NJELgl?b*O-94hr0evY zOSXqlvXH@YN$dHvz(9Fl_H7c#lphb-MhR!jPj0>hv{2X{l+Zpdz=C-80k_ z^^1!eZkvV;Y#`%uQ|f$5*zbaA)M!fH-eF2R&F%}an^vGDO;Tp6u1TcVZkcMmCj*86 zC8`tOCqurHcI6^(K2}-sAb`)nRAMC1ZjrL=o|WTolr_&;>UIZ|!iw#HZ!e|DeRCMi z>!WPG$l8m6%AUn*DB%O8JX|8Ny~+s}H%ggGrP79`y{c6DJ4vWcxj!L?5~i4S2j?(8 z)f{x}6bTJ7kE!SL;INseUK2@poq6sDzEsd+KK+O#>X2bRJBUj8-co&!@!YVMsynch z3+*1Mog=5yEa%j?7}mP)bTuJj4B-4)9T-goB4?tM_tBf z1M{hvPntG0I+iAGr7hXWw(rgGb${5|W2^lU2BX#Hx+UqGMd z*4q1<*$wlob#Z$+PRih)PRp`#gGu%iD~|0xLSxYq&7YV7QHlLy3#O=kcH^nTr}n?F zYK@sRF58uEdz0U}<6P;@VPz*RrK01X*yFYgC~K^h5yHwZEWof{~HSV10MhY delta 1717 zcmX9;eOQfW9KO#v?|VMp^MyW)9O+buR6=QmIw`^=sv&JgG?|PmOEWtxMoP2M@=<9j z+00xkADanSscg+R=3K;4h{F<^Ck%#Zc_!9;1?a7u-+VHbcWc2pd)qx&j5hTVj) zy#%Ru-*RHS_Xcoo6s5Dl0fqjl2?1|BbS4)O*(qGj(Cc>sf)WTSG~qTyAtm~&o$ zr%bl<2KV1REV~>lFz_^4y}ShIH&@m%Vja+TkX%YW3k+_Pd$u+M{$I%>r8E-Dlh5g~ zfE5p4EHA9n@WMX%(Ht`Ke<81m$_09u<=0~v*c2vjtYNQxuE?8;ofvS7!gOEc`8Nu4 z_Bd9wSg|680Y~pp>^G3G_b^4pk!ifYO>wM(=lz~+T`hODMhSDvE1CARuqcY6_P8o! zG>-)a^bs}){{n&C!uF`+bX2?@ja7DZwFm{Jub4ei*wd0k%ol#Xk_VU*ghPut3w|gbJl{m8`F$r=cTrDynRv$S8erTcHZ+om`H6TZvxW^Wv13@L z__~Y4e5WYoZn1RE5vAdg58(Q%GNdDt6^Y6T6(@iYi!wn*eLWhKC9k@vWRCK<&khnU zSH6zEK_e|unZ2mg;CNM8-%L8qKSp&h^$rQ7s2)w!OTFMhCkeZ#H?P~S@}XKtHZ?MPA86`<#VL$yGE}6k+yZS$DV&k+mDx!&~B-q zK8}v;BNf%M=YpGbVBEqXGv&=HnEvQ?>6K+39CE$h*L0HwMC*gPvN)4h^an=r zzuQ{<(R5<4PH!{sr5DolHVbi(#j3v;LNiFW3{F3maii1FcLOW#m1Qu$3I_su8%8(r zmGPTzn4Ck&dR;VR?cxx71sMwOhO(FKhM!6qIAF5j#0&P`<(}bk=vBbEpHcmo&z|bG z(J_qU8yIYKZtDg{q#7r-FphsuV`_3M74eBMZmD0-UN1N9SddC0`Nor ConfirmationDialog - - + + Ok 확인 - + Cancel 취소 @@ -108,149 +108,152 @@ DevicePanel - + Dongle ID Dongle ID - + N/A N/A - + Serial Serial - + Driver Camera 운전자 카메라 - + PREVIEW 미리보기 - + Preview the driver facing camera to help optimize device mounting position for best driver monitoring experience. (vehicle must be off) 운전자 카메라를 미리 보면서 최적의 운전자 모니터링 경험을 위해 기기 장착 위치를 최적화할수 있습니다. (차량은 반드시 닫아야 합니다) - + Reset Calibration 캘리브레이션 재설정 - + RESET 재설정 - + Are you sure you want to reset calibration? 캘리브레이션을 재설정하시겠습니까? - + Review Training Guide 트레이닝 가이드 다시보기 - + REVIEW 다시보기 - + Review the rules, features, and limitations of openpilot openpilot의 규칙, 기능, 제한 다시보기 - + Are you sure you want to review the training guide? 트레이닝 가이드를 다시보시겠습니까? - + Regulatory 규제 - + VIEW 보기 + Change Language - 언어변경 + 언어변경 + CHANGE - 변경 + 변경 + Select a language - 언어선택 + 언어선택 - + Reboot 재부팅 - + Power Off 전원 종료 - + openpilot requires the device to be mounted within 4° left or right and within 5° up or 8° down. openpilot is continuously calibrating, resetting is rarely required. openpilot은 장치를 왼쪽 또는 오른쪽 4° 이내, 위쪽 5° 또는 아래쪽 8° 이내로 설치해야 합니다. openpilot은 지속적으로 보정되므로 리셋이 거의 필요하지 않습니다. - + Your device is pointed %1° %2 and %3° %4. 사용자의 기기가 %1° %2 및 %3° %4를 가리키고 있습니다. - + down 아래 - + up - + left 왼쪽 - + right 오른쪽 - + Are you sure you want to reboot? 재부팅 하시겠습니까? - + Disengage to Reboot 재부팅 하려면 해제하세요 - + Are you sure you want to power off? 전원을 종료하시겠습니까? - + Disengage to Power Off 전원을 종료하려면 해제하세요 @@ -299,17 +302,17 @@ InputDialog - + Cancel 취소 - + Need at least 최소 필요 - + characters! 문자! @@ -389,12 +392,14 @@ location set MultiOptionDialog + Select - 선택 + 선택 + Cancel - 취소 + 취소 @@ -564,27 +569,27 @@ location set 종료 - + dashcam dashcam - + openpilot openpilot - + %1 minute%2 ago %1 분%2 전 - + %1 hour%2 ago %1 시간%2 전 - + %1 day%2 ago %1 일%2 전 @@ -640,7 +645,7 @@ location set RichTextDialog - + Ok 확인 @@ -648,33 +653,33 @@ location set SettingsWindow - + × × - + Device 장치 - - + + Network 네트워크 - + Toggles 토글 - + Software 소프트웨어 - + Navigation 네비게이션 @@ -913,68 +918,68 @@ location set SoftwarePanel - + Git Branch Git 브렌치 - + Git Commit Git 커밋 - + OS Version OS 버전 - + Version 버전 - + Last Update Check 최신 업데이트 검사 - + The last time openpilot successfully checked for an update. The updater only runs while the car is off. 이전에 openpilot에서 업데이트를 성공적으로 확인한 시간입니다. 업데이트 프로그램은 차량 연결이 해제되었을때만 작동합니다. - + Check for Update 업데이트 확인 - + CHECKING 검사중 - + Uninstall 삭제 - + UNINSTALL 삭제 - + Are you sure you want to uninstall? 삭제하시겠습니까? - + failed to fetch update 업데이트를 가져올수없습니다 - - + + CHECK 확인 @@ -1062,82 +1067,82 @@ location set TogglesPanel - + Enable openpilot openpilot 사용 - + Use the openpilot system for adaptive cruise control and lane keep driver assistance. Your attention is required at all times to use this feature. Changing this setting takes effect when the car is powered off. 어댑티브 크루즈 컨트롤 및 차선 유지 운전자 보조를 위해 openpilot 시스템을 사용하십시오. 이 기능을 사용하려면 항상 주의를 기울여야 합니다. 이 설정을 변경하면 차량 전원이 꺼질 때 적용됩니다. - + Enable Lane Departure Warnings 차선 이탈 경고 사용 - + Receive alerts to steer back into the lane when your vehicle drifts over a detected lane line without a turn signal activated while driving over 31 mph (50 km/h). 차량이 50km/h(31mph) 이상의 속도로 주행하는 동안 방향 지시등이 활성화되지 않은 상태에서 감지된 차선 위를 주행할 경우 차선이탈 경고를 사용합니다. - + Enable Right-Hand Drive 우측핸들 사용 - + Allow openpilot to obey left-hand traffic conventions and perform driver monitoring on right driver seat. openpilot이 좌측 교통 규칙을 준수하고 우측 운전석에서 운전자 모니터링을 수행합니다. - + Use Metric System 미터법 사용 - + Display speed in km/h instead of mph. mph가 아닌 km/h로 속도 표시. - + Record and Upload Driver Camera 운전자 카메라 기록 및 업로드 - + Upload data from the driver facing camera and help improve the driver monitoring algorithm. 운전자 카메라에서 데이터를 업로드하고 운전자 모니터링 알고리즘을 개선합니다. - + Disengage On Accelerator Pedal 가속페달 조작시 해제 - + When enabled, pressing the accelerator pedal will disengage openpilot. 활성화된 경우 가속 페달을 누르면 openpilot이 해제됩니다. - + Show ETA in 24h format 24시간 형식으로 ETA 표시 - + Use 24h format instead of am/pm 오전/오후 대신 24시간 형식 사용 - + openpilot Longitudinal Control openpilot Longitudinal Control - + openpilot will disable the car's radar and will take over control of gas and brakes. Warning: this disables AEB! openpilot은 차량'의 레이더를 무력화시키고 가속페달과 브레이크의 제어를 인계받을 것이다. 경고: AEB를 비활성화합니다! diff --git a/selfdrive/ui/translations/main_zh-CHS.qm b/selfdrive/ui/translations/main_zh-CHS.qm index be6c51030617f25c54c086e107274a1b0434ea5c..19eccddbc0e919fdadb32a5621f8f7474aded85a 100644 GIT binary patch delta 1961 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 ConfirmationDialog - - + + Ok 好的 - + Cancel 取消 @@ -108,149 +108,152 @@ DevicePanel - + Dongle ID 加密狗 ID - + N/A 不适用 - + Serial 串行 - + Driver Camera 司机摄像头 - + PREVIEW 预习 - + Preview the driver facing camera to help optimize device mounting position for best driver monitoring experience. (vehicle must be off) 预览面向驾驶员的摄像头,以帮助优化设备安装位置以获得最佳驾驶员监控体验。 (车辆必须关闭) - + Reset Calibration 重置校准 - + RESET 重置 - + Are you sure you want to reset calibration? 您确定要重置校准吗? - + Review Training Guide 查看培训指南 - + REVIEW 重新查看 - + Review the rules, features, and limitations of openpilot 查看 openpilot 的规则、功能和限制 - + Are you sure you want to review the training guide? 您确定要查看培训指南吗? - + Regulatory 监管 - + VIEW 查看 + Change Language - 切换语言 + 切换语言 + CHANGE - 切换 + 切换 + Select a language - 选择语言 + 选择语言 - + Reboot 重启 - + Power Off 关机 - + openpilot requires the device to be mounted within 4° left or right and within 5° up or 8° down. openpilot is continuously calibrating, resetting is rarely required. openpilot 要求设备安装在左或右 4° 以内,上 5° 或下 8° 以内。 openpilot 会持续校准,很少需要重置。 - + Your device is pointed %1° %2 and %3° %4. 您的设备指向 %1° %2 和 %3° %4。 - + down - + up 向上 - + left 向左 - + right 向右 - + Are you sure you want to reboot? 您确定要重新启动吗? - + Disengage to Reboot 脱离以重新启动 - + Are you sure you want to power off? 您确定要关闭电源吗? - + Disengage to Power Off 脱离以关闭电源 @@ -299,17 +302,17 @@ InputDialog - + Cancel 取消 - + Need at least 需要至少 - + characters! 字符! @@ -389,12 +392,14 @@ location set MultiOptionDialog + Select - 选择 + 选择 + Cancel - 取消 + 取消 @@ -564,27 +569,27 @@ location set 退出 - + dashcam 行车记录器 - + openpilot openpilot - + %1 minute%2 ago %1 分钟%2 前 - + %1 hour%2 ago %1 小时%2 前 - + %1 day%2 ago %1 天%2 前 @@ -640,7 +645,7 @@ location set RichTextDialog - + Ok 好的 @@ -648,33 +653,33 @@ location set SettingsWindow - + × × - + Device 设备 - - + + Network 网络 - + Toggles 切换 - + Software 软件 - + Navigation 导航 @@ -913,68 +918,68 @@ location set SoftwarePanel - + Git Branch Git 分支 - + Git Commit Git 提交 - + OS Version 操作系统版本 - + Version 版本 - + Last Update Check 最后更新检查 - + The last time openpilot successfully checked for an update. The updater only runs while the car is off. 上次 openpilot 成功检查更新的时间。 更新程序仅在汽车关闭时运行。 - + Check for Update 检查更新 - + CHECKING 正在检查 - + Uninstall 卸载 - + UNINSTALL 卸载 - + Are you sure you want to uninstall? 您确定要卸载吗? - + failed to fetch update 未能获取更新 - - + + CHECK 查看 @@ -1062,82 +1067,82 @@ location set TogglesPanel - + Enable openpilot 启用 openpilot - + Use the openpilot system for adaptive cruise control and lane keep driver assistance. Your attention is required at all times to use this feature. Changing this setting takes effect when the car is powered off. 使用 openpilot 系统进行自适应巡航控制和车道保持驾驶员辅助。 任何时候都需要您注意使用此功能。 更改此设置在汽车断电时生效。 - + Enable Lane Departure Warnings 启用车道偏离警告 - + Receive alerts to steer back into the lane when your vehicle drifts over a detected lane line without a turn signal activated while driving over 31 mph (50 km/h). 当您的车辆在以超过 31 英里/小时(50 公里/小时)的速度行驶时在检测到的车道线上漂移而没有激活转向信号时,接收提醒以返回车道。 - + Enable Right-Hand Drive 启用右舵模式 - + Allow openpilot to obey left-hand traffic conventions and perform driver monitoring on right driver seat. 允许 openpilot 遵守左侧交通惯例并在右侧驾驶座上执行驾驶员监控。 - + Use Metric System 使用公制 - + Display speed in km/h instead of mph. 以公里/小时而不是英里/小时显示速度。 - + Record and Upload Driver Camera 记录和上传司机摄像头 - + Upload data from the driver facing camera and help improve the driver monitoring algorithm. 从面向驾驶员的摄像头上传数据,帮助改进驾驶员监控算法。 - + Disengage On Accelerator Pedal 踩油门解除 - + When enabled, pressing the accelerator pedal will disengage openpilot. 启用后,踩下油门踏板将解除 openpilot。 - + Show ETA in 24h format 以 24 小时格式显示 ETA - + Use 24h format instead of am/pm 使用 24 小时制代替上午/下午 - + openpilot Longitudinal Control openpilot 纵向控制 - + openpilot will disable the car's radar and will take over control of gas and brakes. Warning: this disables AEB! openpilot 将禁用汽车的雷达并接管油门和刹车的控制。 警告:这会禁用 AEB! diff --git a/selfdrive/ui/translations/main_zh-CHT.qm b/selfdrive/ui/translations/main_zh-CHT.qm index 8b055d665e4582f8d1461595d0d88a7eeacfbb49..e64aabecd68c5df555b350ade44bd61fb2ea5cd9 100644 GIT binary patch delta 1961 zcmZWpdr(w$6#jPaz5BR(_bzXhKzS^_fQ1qjAEzkBcRob&t6Io~;rMVfmh zn)P0e(}1=M=${1$cH&xMK5-B6Jz@hO@?0GVND;t*Ys3-2z)0dO+PvVxfKotz3@{e~ z$|)dlA24neVA~2zTtmNT;OVKvbyec6SN`P)Z#MK`F zXmO!X;=;g7E{u5r;^ymsMuq5%qW`lH8$TzOK|Ch{{{E1P0!XwG(%zkb>22t0ejt7U zeZWlKvj+Omi*Uen1(BAEfc!BM>&Y&3BNE#W0#Ch$@y5A;+Z;?BvWY~PNPZkI@I+G9 z23ACi@Auk} z8&~P~y*5F1#cNyY+4Hb1 z+SW2}2CNnQ@3K{X5Q2(FGou(GFNN_2=Lox15+0}*Dr=JI-!2@gq`mDq!P)P1>g~L6 z&f^cZZkf>G$lJlfhKl2E9RNIX#20r~0p60BIf0+utm4wEqk!JOi?7ZlL0y5kTKo-& z`a#@0;V{K#bD_n@g&q%G*gH%tt>_@p0pj-S>BKZ~&$&%Nz)7+Cd1tXIsb8!wZcok^D{zC?Y{0G6!peEkmJmCSILet-5g5=hqHo3fpOAL)N@>cxuH>i@XS3JEp( zMSB4LFGoHs#!@(QDoPXapje0Ye zh@Zn4Tx#GL#T#RPwbP;8IDOJ}wj$CvV9(=HcM_DV@$8(81@}*T#FtQ$%n>^ z&66p*L&g^OMO;Q-%CVtbR61Wd{d^-cPnHXB`Ewt2FiSL+oJFL8Kg*n3iI}(X859@Li zvL}LhZxjszdYC`UCk`z$JA*!^7GllLIATbgxnU%=AZMuFyLK=Wlj^&g8M_};gF51Y zL1s0&m5V9-j5?`=6?1>6=ERMoh;3@&2b}+Yp6b?{W2l8O>ZcWqKPXW>@{k&M0_xdW zW6o3Mvn_^SxH9!M7Oz;&byP2lPupWIplZwb>kJr?W68GPVDDB~);ATf=L;-bGO|f1 z%yM+`U%>DVOH2DUCh)7JHDMp$Q!^=;x2g{53U%J%{0AAsC@e~%`xiexc5>pl4Q`5e zkfHmeXj>8fJ+;IyNXxco1U$|Eyfk|T&3vlHniEBoRwrsuK5g`VIGkd&apxlb4m7nY1`Jb5Zu#%(SdUc8x#+Vt1f_FVwk$=y~ve`zr5V H(P4iBk~aPp delta 1718 zcmX9;X;4#F7(ID;?j9}Z(DM;-5D*+qOy`*?F7(?A7%BntbN(&? z{wILptAMb5K++oC8w`wopSThj-tG0} z<9ayySnJ?`IvgXamjb=EVZ_6eK;Jx!RHgw|Cz7H!kq8sWCCQ#$Fm}!cDlr4&ej@=7 zA52*Og6C_IB3$79Nu*3;cEKx~9A@X#_KrV5!qR`VSj=4ROd_dl?> z{e^>aRpaZ+*MQhVD9xD+^jHC>$5_DU30evlF|eo3YhWl4uu0c>R}c{7qwBYh7KPh% z<1YpSw*Ie=-woBZ)xJaCLux1A+cYD zj1Jk%IILROS*P$qsc^cO%z7sY=MvWe+FhY`JOleA3JultI%K!dxThlnI`zI!B<{<4 zThS0^6t7=2o&lqB^+z=l4z}n^PmQC3WAx>vJRde?!*ZdU!|k>>^=Nqs zi};=StpP*CEBEVJdcoqA$4?pmvDh@^1Yq!%)ac1{dQhrlDOv#ZYn9@)?&O&!rA?*q zk+USbdX6PATbdQLp8}1MX1y&PWeBmA0ZvLwK3dH4hoz-a8Xx#iD*B2Lp% zOI;Z2E$#T6j;l3N$?AM2JU}{rsgX{HK|0?~L4_jeLcmQ5oFLUVkcj^z>0Vwn9sb#c zF-6j=b`lG9mxX{7X84}0JqxE&`{bBM34ok0k0?D0^gl1B>nO0zP2Sh`2Iw|Tt_a@> z7%lRvvA0-B$p%|6mFhmnu;1H}$IOl!j?cSC0^kKdNbOAa98CoAx8T~24 z>p>4#39-ibU?;o(sWD04NGaWn*}uQ0#0|#J7HtE%Tr%!H%6M)&jVD_Ixh_@=7ES`6 zd?j#)kv);94Exj01QliCsAdwruB1BhDBa-EN_qyR4opz8F2<4BP-PuDu^4tMb@gLd zLX}E`+kB3c@6}-;95=GJnsuXwnWw62ANjJo7Z78aak*Obz{>S4b>ka)Y->@sRP1Bz zcT#uUnMkWz)m=4{nb2$X*qV)0FjsYy_mRl#hA(F(mX{eKUFNxC-V(B# zH@}+109EGFFW6K*r_I%Ss90Ep`D#5efYS%*0LeE?~xPKANp99*FSJ z1~hWagx=If6;m>|3~lXpc5#m`+Rg_<>E!|KNC^W+Bx`5?ruW{mc5UblR`)ck@j2(7 zVWQP@7~40}&+2vm4W~%Cb!0Q+gy&l4*;}}_6 ConfirmationDialog - - + + Ok 確定 - + Cancel 取消 @@ -108,149 +108,152 @@ DevicePanel - + Dongle ID Dongle ID - + N/A 無法使用 - + Serial 序號 - + Driver Camera 駕駛監控 - + PREVIEW 預覽 - + Preview the driver facing camera to help optimize device mounting position for best driver monitoring experience. (vehicle must be off) 預覽駕駛監控鏡頭畫面,方便調整設備安裝的位置,以提供更準確的駕駛監控。(車子必須保持在熄火的狀態) - + Reset Calibration 重置校準 - + RESET 重置 - + Are you sure you want to reset calibration? 您確定要重置校準嗎? - + Review Training Guide 觀看使用教學 - + REVIEW 觀看 - + Review the rules, features, and limitations of openpilot 觀看 openpilot 的使用規則、功能和限制 - + Are you sure you want to review the training guide? 您確定要觀看使用教學嗎? - + Regulatory 法規/監管 - + VIEW 觀看 + Change Language - 更改語言 + 更改語言 + CHANGE - 更改 + 更改 + Select a language - 選擇語言 + 選擇語言 - + Reboot 重新啟動 - + Power Off 關機 - + openpilot requires the device to be mounted within 4° left or right and within 5° up or 8° down. openpilot is continuously calibrating, resetting is rarely required. openpilot 需要將裝置固定在左右偏差 4° 以內,朝上偏差 5° 以内或朝下偏差 8° 以内。鏡頭在後台會持續自動校準,很少有需要重置的情况。 - + Your device is pointed %1° %2 and %3° %4. 你的設備目前朝%2 %1° 以及朝%4 %3° 。 - + down - + up - + left - + right - + Are you sure you want to reboot? 您確定要重新啟動嗎? - + Disengage to Reboot 請先取消控車才能重新啟動 - + Are you sure you want to power off? 您確定您要關機嗎? - + Disengage to Power Off 請先取消控車才能關機 @@ -299,17 +302,17 @@ InputDialog - + Cancel 取消 - + Need at least 需要至少 - + characters! 個字元! @@ -394,12 +397,14 @@ location set MultiOptionDialog + Select - 選擇 + 選擇 + Cancel - 取消 + 取消 @@ -569,29 +574,29 @@ location set 離開 - + dashcam 行車記錄器 - + openpilot openpilot - + %1 minute%2 ago we don't need %2 %1 分鐘前 - + %1 hour%2 ago we don't need %2 %1 小時前 - + %1 day%2 ago we don't need %2 %1 天前 @@ -648,7 +653,7 @@ location set RichTextDialog - + Ok 確定 @@ -656,33 +661,33 @@ location set SettingsWindow - + × × - + Device 設備 - - + + Network 網路 - + Toggles 設定 - + Software 軟體 - + Navigation 導航 @@ -921,68 +926,68 @@ location set SoftwarePanel - + Git Branch Git 分支 - + Git Commit Git 提交 - + OS Version 系統版本 - + Version 版本 - + Last Update Check 上次檢查時間 - + The last time openpilot successfully checked for an update. The updater only runs while the car is off. 上次成功檢查更新的時間。更新系統只會在車子熄火時執行。 - + Check for Update 檢查更新 - + CHECKING 檢查中 - + Uninstall 卸載 - + UNINSTALL 卸載 - + Are you sure you want to uninstall? 您確定您要卸載嗎? - + failed to fetch update 下載更新失敗 - - + + CHECK 檢查 @@ -1070,82 +1075,82 @@ location set TogglesPanel - + Enable openpilot 啟用 openpilot - + Use the openpilot system for adaptive cruise control and lane keep driver assistance. Your attention is required at all times to use this feature. Changing this setting takes effect when the car is powered off. 使用 openpilot 的主動式巡航和車道保持功能,開啟後您需要持續集中注意力,設定變更在重新啟動車輛後生效。 - + Enable Lane Departure Warnings 啟用車道偏離警告 - + Receive alerts to steer back into the lane when your vehicle drifts over a detected lane line without a turn signal activated while driving over 31 mph (50 km/h). 車速在時速 50 公里 (31 英里) 以上且未打方向燈的情況下,如果偵測到車輛駛出目前車道線時,發出車道偏離警告。 - + Enable Right-Hand Drive 啟用右駕模式 - + Allow openpilot to obey left-hand traffic conventions and perform driver monitoring on right driver seat. openpilot 將對右側駕駛進行監控 (但仍遵守靠左駕的交通慣例)。 - + Use Metric System 使用公制單位 - + Display speed in km/h instead of mph. 啟用後,速度單位顯示將從 mp/h 改為 km/h。 - + Record and Upload Driver Camera 記錄並上傳駕駛監控影像 - + Upload data from the driver facing camera and help improve the driver monitoring algorithm. 上傳駕駛監控的錄像來協助我們提升駕駛監控的準確率。 - + Disengage On Accelerator Pedal 油門取消控車 - + When enabled, pressing the accelerator pedal will disengage openpilot. 啟用後,踩踏油門將會取消 openpilot 控制。 - + Show ETA in 24h format 預計到達時間單位改用 24 小時制 - + Use 24h format instead of am/pm 使用 24 小時制。(預設值為 12 小時制) - + openpilot Longitudinal Control openpilot 縱向控制 - + openpilot will disable the car's radar and will take over control of gas and brakes. Warning: this disables AEB! openpilot 將會關閉雷達訊號並接管油門和剎車的控制。注意:這也會關閉自動緊急煞車 (AEB) 系統! diff --git a/selfdrive/ui/ui.cc b/selfdrive/ui/ui.cc index 6fe1d838ed..7922714c17 100644 --- a/selfdrive/ui/ui.cc +++ b/selfdrive/ui/ui.cc @@ -246,7 +246,7 @@ void UIState::update() { updateStatus(); if (sm->frame % UI_FREQ == 0) { - watchdog_kick(); + watchdog_kick(nanos_since_boot()); } emit uiUpdate(*this); } diff --git a/selfdrive/ui/update_translations.py b/selfdrive/ui/update_translations.py index 263eb5e670..d872be0d86 100755 --- a/selfdrive/ui/update_translations.py +++ b/selfdrive/ui/update_translations.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 import argparse -import os import json +import os from common.basedir import BASEDIR From cbff8fcbd02b262860b3540a3dba7108237d2b46 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 8 Jul 2022 21:17:00 -0700 Subject: [PATCH 068/112] Nav: wrap strings (#25089) * Wrap nav strings and translate * Update QM * Update QM --- selfdrive/ui/qt/maps/map.cc | 22 ++++---- selfdrive/ui/translations/main_ko.qm | Bin 19449 -> 19997 bytes selfdrive/ui/translations/main_ko.ts | 64 +++++++++++++++++++++++ selfdrive/ui/translations/main_zh-CHS.qm | Bin 17919 -> 18457 bytes selfdrive/ui/translations/main_zh-CHS.ts | 64 +++++++++++++++++++++++ selfdrive/ui/translations/main_zh-CHT.qm | Bin 18031 -> 18569 bytes selfdrive/ui/translations/main_zh-CHT.ts | 64 +++++++++++++++++++++++ 7 files changed, 203 insertions(+), 11 deletions(-) diff --git a/selfdrive/ui/qt/maps/map.cc b/selfdrive/ui/qt/maps/map.cc index fd47f4188f..a486110a73 100644 --- a/selfdrive/ui/qt/maps/map.cc +++ b/selfdrive/ui/qt/maps/map.cc @@ -175,7 +175,7 @@ void MapWindow::updateState(const UIState &s) { loaded_once = loaded_once || m_map->isFullyLoaded(); if (!loaded_once) { - map_instructions->showError("Map Loading"); + map_instructions->showError(tr("Map Loading")); return; } @@ -192,7 +192,7 @@ void MapWindow::updateState(const UIState &s) { carPosSource["data"] = QVariant::fromValue(feature1); m_map->updateSource("carPosSource", carPosSource); } else { - map_instructions->showError("Waiting for GPS"); + map_instructions->showError(tr("Waiting for GPS")); } if (pan_counter == 0) { @@ -418,10 +418,10 @@ void MapInstructions::updateDistance(float d) { if (uiState()->scene.is_metric) { if (d > 500) { distance_str.setNum(d / 1000, 'f', 1); - distance_str += " km"; + distance_str += tr(" km"); } else { distance_str.setNum(50 * int(d / 50)); - distance_str += " m"; + distance_str += tr(" m"); } } else { float miles = d * METER_TO_MILE; @@ -429,10 +429,10 @@ void MapInstructions::updateDistance(float d) { if (feet > 500) { distance_str.setNum(miles, 'f', 1); - distance_str += " mi"; + distance_str += tr(" mi"); } else { distance_str.setNum(50 * int(feet / 50)); - distance_str += " ft"; + distance_str += tr(" ft"); } } @@ -615,7 +615,7 @@ void MapETA::updateETA(float s, float s_typical, float d) { auto eta_time = QDateTime::currentDateTime().addSecs(s).time(); if (params.getBool("NavSettingTime24h")) { eta->setText(eta_time.toString("HH:mm")); - eta_unit->setText("eta"); + eta_unit->setText(tr("eta")); } else { auto t = eta_time.toString("h:mm a").split(' '); eta->setText(t[0]); @@ -625,11 +625,11 @@ void MapETA::updateETA(float s, float s_typical, float d) { // Remaining time if (s < 3600) { time->setText(QString::number(int(s / 60))); - time_unit->setText("min"); + time_unit->setText(tr("min")); } else { int hours = int(s) / 3600; time->setText(QString::number(hours) + ":" + QString::number(int((s - hours * 3600) / 60)).rightJustified(2, '0')); - time_unit->setText("hr"); + time_unit->setText(tr("hr")); } QString color; @@ -649,10 +649,10 @@ void MapETA::updateETA(float s, float s_typical, float d) { float num = 0; if (uiState()->scene.is_metric) { num = d / 1000.0; - distance_unit->setText("km"); + distance_unit->setText(tr("km")); } else { num = d * METER_TO_MILE; - distance_unit->setText("mi"); + distance_unit->setText(tr("mi")); } distance_str.setNum(num, 'f', num < 100 ? 1 : 0); diff --git a/selfdrive/ui/translations/main_ko.qm b/selfdrive/ui/translations/main_ko.qm index f6e95b5038f984183d9d4273c581bb6ef6e4b91d..60966cdde587ebf4a43deb8ad255f374d32ca7c8 100644 GIT binary patch delta 2328 zcmZuxeNa@_9X73 zlxjOlH3{0N5N$=%0YN30pg}C87!z^g43b#Ds2LNJ*fds)?ZKT9C-IM+v+v$>?>+bY z&i(yok7{3q%02Z|j$hl|it_fr;U6wKaHcCB&?;uLn0qQ*BGGY;N8*vY@ z8W1^e$p)nHK=`M`DZuyu;(T&SJQ#c*(EI>+w{UNN;!R>S_tyb#Z4+Q_0E`!akwf|G z;6w^Aio`*05c`SkK;jm_ZUAO(TF zDB$9}pB?H_iHDDeSn@W2@8N#@M}5LGFfz`A)AvE#+Y6`^h|P9x7z?re6mcuWPeefZ z9?~|2H+>({vBMO<8JhYph(~E&77vo44dX?Oml0th8p@E|x*mwwisV~$z@&7{(9^X+ z58RkJv7AbHu_9VO?nlgdeHSgAjJf}$fFY$w+xRaoID`!0BaW9KBYP7MUWUxWyq%ng ztd!m4b>WpG8-VE#vG8mw57M9@$HwuOv9^!v%{y_R?IK;ggBsVXz}Or#51zw|xa)Ca z+ZqzSP+6nL(r#as-~M1Av{N-<2WxHLqDpO{eWNa@-nzo^nDwfQ86r2fs;&ym$B2=t z+fiG9;ok^y-gzLbS_rw(4NRCJB*`v1F<)5V#T(lrg?$}*@}0uTG76i}D14Bz14#2~ z6fUQ7V?`@;wK6o3<-+xMd;$MVwHQ7G@cm5fe}^?2aZYX99?P3Ws@J4)<0-GHkD4hw z{GPg|elBYru5PH|x~P-8HVOf5-)M2s;aZ+wB05s&u6Mq;uKRhw_NBNXn|id8SR&p7 zCO3cxdC)q;gEpO5QOW#928joIbBGJY>QBmnkU;Uo@=72{5l>1s?SG;WdA|n(eLZMP^*= z-vsnJ&4W2tn6)UaEtHmp4cAr;-OSPt(Z1*Gp@4kt-L!+WFh%?0)#rf0+1j7JrbFs$ z+J{rvA_8vf5<;8#CNAn`swv#-o^I(k4{3Fs?)Pin;(USb&qukRPoJ*tMi9Rv^jgzv zOj3eA$X&tSGHHZ9?uR@s=+VD4tCxx!^qHG!VbWgx`~|dp^mqE4mUv*yxB4Am)KIJM z=$y@H9np7r7qVyh%W+}sYnn1S=Mr0xZLC~+n{6pDh8V;3Y4Y})7JgUByC1RCqc_QW z8xJwEJ7ssp)t6YaFXjF1ti2d0AKSW{7S_oP5fX*{T0WP@g;KuUEC;a7d@46vr}EKN z%eR)eXrW?I)&GWkn<1#_JOw>xSlG?35OT+`^0G)LvkjZx@S%eyL(3hOXv_q|-(RFt z)+0urCY~G7<2DA?aANc+qY%zoz5xB1$`{%78Ia~d=8Tk~Hl zc}}#q`OLqWg@C`AFHXAz%=7EE=)Pm4)WutT;`qKNt1Q;99sv{WmKnX=(Eho_nRkN@ z87zOeTFlz7vb?#}NvG~xK3wr%Ag;~Qb!$H@pKZCGbe!MA91KoRZMWu#w_7}a=~5E| z#%S=TUg}z`?f?Jc;uVP*aVjgex&8YTNZhvYSNAFp=|CB554Z2uudn0rP+zL@d5*)(~-SMAJB+4{#}P z71m^qp}h-{{3?-HO(ZlDIV>g$+(k6Qk0@j}kqgF?K3#?%C>lPUNUKizfX)DMXG?K( z8p$p^1(uQACJNQ&lHBwfCaO2YT25=(Cv z1Ce8}WL%*G(G-nj<~|rQ?^7GRk{^ocFQ z$K4=u>R=qZJBd6}nIJw9#P&0*O>pBGYng(FN~|wpF6Mxk$7`l8cps5T4f7xzb*+7v z_9kCA>(<0{9JfHhEUES-T-Uyn+GWE{*R|55a1``DC@mAgc-mxX#f2r1&{bMpf%Vg0 z9Bg5%4Q9{Sn9@p|`zyO47_yqivnic(iEPc-)HUEC=h#g44UyL%n;%?*AVrR$Nz@pc zr;eeGjx`n!g3b!Is4EtDfIV|Jm&krOd;ZH}2pPd%7Df%xu(zJKVg53EtN$-JXnK$B z^gEBB$vJ)&l=jc()Y%CTE{qEh9l<-1i;960URhimUx$bcaq$i%5U7)jAB_^f8TcOi zPjM;hwqSiDx6M;Tvh%p?!yv*Jj^V`MF|qhZ4P9 zd1D6z%HggJLusajyKZ|Q$~$mv?I2|Tf_s+M1cwX8Q2&uWoa)hRj3Pt|;wEnt zYhMjP>MF(Fq@zR=PAGmXLp`%nMOC*w#<5Dd`g24mS!r)DD$p#;l>UFmVZ$@!^3X0Y zu2x2-LBjdBm8(`m^2rX$*akg_*(vvt6+%*}eAu=a(R!k6H~kuqla}{)#-k(4;bZT$ z;N~&>o<1$QJ^|>92PK2g?$KcU2Y+Y;R!^$p^J`8*d2ileY+a75n(>7#@Se5h&+a}1 z3H$hJcMinP@z>(8k&EZ+d22i`_xXBD9SC*sy# zIM}EX9E`n0#PXzO;IM>a}AlO#m!=#tOG~X12rCA6H zfY>4!q^lqs7o1C}tKbCg=kZ;&I}h zW9ag!9%4byJY->~_;WGp&khu8-ys7Ny2Ly4?h#p8Y80>WE`}-e8gqa2wbx9IkL WBvzGk6d diff --git a/selfdrive/ui/translations/main_ko.ts b/selfdrive/ui/translations/main_ko.ts index 91685383f7..ad35a37fa1 100644 --- a/selfdrive/ui/translations/main_ko.ts +++ b/selfdrive/ui/translations/main_ko.ts @@ -340,6 +340,57 @@ 파일갱신: + + MapETA + + + eta + 에타 + + + + min + + + + + hr + 시간 + + + + km + km + + + + mi + mi + + + + MapInstructions + + + km + km + + + + m + m + + + + mi + mi + + + + ft + ft + + MapPanel @@ -389,6 +440,19 @@ location set 최근 경로 없음 + + MapWindow + + + Map Loading + 지도 로딩 + + + + Waiting for GPS + GPS를 기다리는 중 + + MultiOptionDialog diff --git a/selfdrive/ui/translations/main_zh-CHS.qm b/selfdrive/ui/translations/main_zh-CHS.qm index 19eccddbc0e919fdadb32a5621f8f7474aded85a..b96acb89d99ed8207dd34740c51714706e771040 100644 GIT binary patch delta 2290 zcmZuxeNh6su&m3bEY$c`E+nrLX6ZtQX>7bVeC*}7}GBrp~nGj0r4ua6d0ip-zG)? zBJa&TfD{RYO(%{c)(~@OF3F5j-fJTPc63vGWL2Ubof%*Tm2n4K$ z^a@o99}Q{8Ho%kv-5x$}Dx-MWd?*6?FeYMZK$J?9T}WzOO8b5!_3Q>l-@qfr*-Xsk zMoLT-nJ}?ZN^-1&8&;H_R0ii)}URK&cHEewC`I;JgijP zxF-!z-_?HHNWaLh*DMzT+&*i>S=*ZU{+~r>GSyYP#3fzvfXyi`n@v8tQgNmDPlkyX z*Cp>~uMYE|<*WyNU-ID4da=6x7BI3(+EQWB@#NL-;f8mu*p;x0y*X2oW2pG}?UK22J_XE`CRswryIIPf#fpqMD;3BG*(ztG zxxrg0)G2B1KuZ~2#GCZLE-lGl%)HIg(r623WWH4SClWDk_F%vP4-Wm#g9-Db>acn@ zg=>_mUuR30MoINAms5$aq@AB$pg=E3hx;hFP%a$_Jj0f%kvcj_$bM3~Sk}r)r+P5{ zOR2Yy1S6K|guqO;&RaUmwFoNct&6)dg$lOok{S;H5BckIG!#C#Ot~RPS_-&G98dpnx$?5g^CWp~KT93rkk{?s zLPF;A%h(HCN0I54)K{sT&tS{^#L4u#WvO_F(>}b=vhnf+miD&gy?VYA zz1wo&NA`mMOO{g;J_j848C1g$T$K8^RNsl5?=cms-#7ih?_<V^{SsdcbiJ(tDQYHlzg6gVakWVxYJHH&eu&{I-8eObR5afWP`Ca z_|wjDA@-ziBMe z_#XPUJM@3kl3_z|Zz@`wCzoGZH}&~72y+aMsI2~s+Sixg&CEoywy7n#dCua30rE!v wcQ}jlN=on0R+c6|T~0PhNW=8IPO2l<>7s)zzhr?eDQ)`yJ2utb|5W&Y0j3r(R{#J2 delta 1749 zcmX9;XHZmE7(M&;y)AFwzC{INVUeXNg4jS&!2%H}Dq_$OODsW&L`|5%HflDCh>A5r z1jLRKTbu#GGN`DCqGE|Uk`Nq%1$8u7Vsua-hhhJmz3<-pedjyh`EK@RO-s7Q9&|Fk z)76ID%u1W{x#@e()Pw-KD}c}h^w0s?1Y!^3B4Q+Q8*wfma^L(Eka`2&TZlu5e-S71 z%$IHG8Vl%4dG2#SxeVB510z=felvi`HH`Bo;5GUSUUUay`tooE@ms*rnV8D&OqATZ z&f4N~#^crH;BS0fVEc0iW7KoK6c{&{8O%ZUu4{4n%&@&0r(R{!(8M@*J z#1!aV;}~r&^gegFK8QXRqMVFT6-xo1AdGri1oZ2VaN|tC!5NVQGST{rToeL3dK4jg z?pD@QigACFK!Q2e-tEt4Rm)vS%+vAl7q+V7H~gN({Yfm9dH||>9o@W z@VKN2*vN+XJa`1E7%;%1J*<+kcagTBcpL*9(4H>fc|YscO2Nh6euy|d zzmRzw#5oa^)lw%esT&Hoxp^Ph zu{+}4NAaX(5|7->1YDPk$G^*?kcr|cg$*%hir1c0^Lw>;?fF0KphLJ=H|#i#HdT@b zQ0XC0By)Nah1(^Cs-EQCEX7S{C;T0x1oQ5e827fJ^T#%H@oB^0LsG6!9y{3nm6W@QRxtII@>Zt;PR`P?%e6qS zv(kkoDlMc+7j3s`rJYiB4GGzd(!-Prc6evU1Rh;TA@bo=1s}Gpx@smg%!@z zADjP>1V-x{#_y$soAmFhI&%nC>fb-7LfRwxk3;H#F7FMY-enxRjfO}qiCg9vX1)AK z!U2X23v#%hYS?v{@!D$)MUUONjx_4c)9B^yMt6Iz0qEOe9PuWB7iJhIL_MOE&c=x; zlyGR3aq<*O?*7RbUmgN@Rv95fPx2b)$bbmYBvrt%kTk!NSql`&MRgRA0L%Dg_=cEwh}4fk@TSMU;=<+>6U%3cp{ zQ6dAU0s|YBs1Pa;n4wI}WI*d!W!~6ULSHG{8u_I9Bq#-2IBd?-l#1O{tk)~$dNt8^ zrBYo^V&ZDEZodZ;jxqPP-Y1bk=0QzsIjk4WNBz0q&3@B-ViErg3^$j#9iSJi=CTl? z#~bt2AbLUWuR0yvPv!^JE@`Z|-3rz1LnxIwr3TjeGT|mQYCRQeSE?q3jO6(b>e}s` za<7Bxj{4zj=_mD29^?0WtDgCf9_Ui4-WYz1CJ(b1Uh!Rw*8gmA9KpHnf7#OUNi*M> zWJ~xX2J9VRnV;~O$_%t@u1aOkXIrvo&8I?*mUBORqC$C=nx{KC$A>JnVZU*0o&yZC Y77o_CIusUk$`iK6%bg4V=sMi@e-;zY9{>OV diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts index 1bcb30142c..c3e1954f1e 100644 --- a/selfdrive/ui/translations/main_zh-CHS.ts +++ b/selfdrive/ui/translations/main_zh-CHS.ts @@ -340,6 +340,57 @@ 更新文件: + + MapETA + + + eta + 埃塔 + + + + min + 分钟 + + + + hr + 小时 + + + + km + km + + + + mi + mi + + + + MapInstructions + + + km + km + + + + m + m + + + + mi + mi + + + + ft + ft + + MapPanel @@ -389,6 +440,19 @@ location set 没有最近的目的地 + + MapWindow + + + Map Loading + 地图加载 + + + + Waiting for GPS + 等待 GPS + + MultiOptionDialog diff --git a/selfdrive/ui/translations/main_zh-CHT.qm b/selfdrive/ui/translations/main_zh-CHT.qm index e64aabecd68c5df555b350ade44bd61fb2ea5cd9..208f29c0ec9dd45424301c70cdaf64c2e9a901bc 100644 GIT binary patch delta 2307 zcmZuxdsLKl8h+-x%*^-A?8i3by};+e-a zz{z`GC&XgL)*peic@KbgxE}lwOWg;-JKY!^2x-@KKxc*2Jdpv1LTWuu%!G770{lOR zyoD-_ErWdc0ASh%ef?G9`xGyOi4tK5V>(G95#VH+;%CT(S}Bd+RF&Wz^yx4PYzcpjSQYZl-PhiueOy^p)4;tfhUnyndpUZ{!2H-p%_>#y1Wzo>!Uiy{=$>&r}Q+ZV3Mv zCD>JAd<}au7>?o zUQt~YSDseR|s_FlZF9)5KPE1jU8h>%GvM{UZbqdZ7$R{gnV8r5dsC=z-{?Ox(! zqOVQ5`WN|{51N8cp5~17m=<($D+I@yR(vW^$t=^xHQx05(RAi3wrFIS=`T-HDW4%` z?~}|s?oTdrU@b2~|85>PbsdN0j(J8Ldp*_1oH%6xd*)%D6-xykZ!pg-XTX4G&H1zY z2<4i0-c4tKjpo{Id~E)!%q>+^Ec~|luWdy8Zgbli5|e&!(bt49VVou0?=p!@wM6z7 z^Uhs4Mp0`?u zZD!?O7HiO*I4X3(I;Df_DEu|+tWqlHHQTx(b~=aIZY|!!*FNf!b??n-oQY}Hx2u_F zl45QA4`*R`llAXv=XN@-VIs=ZMpgD58s8F2t zyDLTP{Zj4qYzK*r)jnGO6A*PmYwxb)dp@dl%y^gI0eKvpq`FT15)W7Usf;wv7bk;1 zG26M=(D(o8#mlFs#pp!-m*#6ZvHcdp(v`n3z%t}NG+37ZOM`smJv7MA8(`pa=SbD> z7}9Sc=I1#Em^`r1!-gC;^>tm-!&$Vs%hN&Sj(8Vh9T z0sL(b`2UJ&pG34AP>N`C*Yf|yb0al5Aa*L^?qw`2bY71Am0 delta 1749 zcmX9;c~p&Q9DeS1zwa*J{qA?8g{Y?6f^=OWghDln%&6=$vd6X0bPkhk=1zxfS;k;& zAqrz`N60cNOQKAegOQVHEXg(vGe{<9o=*3l=f2 zY!mus0{XLnc?Fp_k{s%J{!V63xLEP9k1#k-|rt^CdFuQS_ zyY{7z(|QZy(yc(mScsb*0U8xzQ7Bi9fLL~tm<92g2zYx#TH#ANWsnZ;1x#z9%ezNB z1-}R+y?G9PsGmBt3dBv$eld~XgeQ8uJM3ZH6E{+!}&uRj~+HB;I~H8a(e&} z=&tFynuc`r(j*oK0sfsdTW;}t_gKxxJa?@3W1Lw zaNk`aMxIS#cZ4Jtc5J^OY`baX`UAp=l_VDOsZcP0rd#F;HxgObD_W>5iJ-H#%|ca{ zI|~+QyjL(F%?E7cVYp1*kI*B%MlhmJVO40y@-7 z=NqWBkRe^L{>~^>NfnhOWKEPFE-In(H<~aaU8-*&!48T}unuLXy>)7>oeFN#g+Gm< zg4Md%+M!uy+a*>xX*Pm*+J?9R<(K1)|0e~TH5)%yievNn_TyIU<{hx_!0 zXFVi=1byw`T`c@T|EAoN78U5C4M$@xF%D^Zp5LT}Y-@t<2o0OS@8VNa+jrAi~pis$O%gg3y9brkOi>-zJd=bB~7Qv_NY<7|MBHXAAR*RQ~CnWiImD!z@Iai=v2u zQRdQcWViy-4%77;Oc^0=w-s@0Li%0cGzB9)x z{U5Pl#}vyf$76bxX8EB!ot{szY@RfWglv|=um1yj)>$fRwzGrRma3RT9FLyLz^ppj XQ$NvV-R)TOQNeSCaP)2Kb+-QjngYwa diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts index 2aff3334d9..f6e36081fa 100644 --- a/selfdrive/ui/translations/main_zh-CHT.ts +++ b/selfdrive/ui/translations/main_zh-CHT.ts @@ -340,6 +340,57 @@ 更新檔案: + + MapETA + + + eta + 埃塔 + + + + min + 分鐘 + + + + hr + 小時 + + + + km + km + + + + mi + mi + + + + MapInstructions + + + km + km + + + + m + m + + + + mi + mi + + + + ft + ft + + MapPanel @@ -394,6 +445,19 @@ location set 沒有最近的導航記錄 + + MapWindow + + + Map Loading + 地圖加載 + + + + Waiting for GPS + 等待 GPS + + MultiOptionDialog From f261b8a8c29fb2c9c5fee3b382e12e7887d50269 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Fri, 8 Jul 2022 22:09:37 -0700 Subject: [PATCH 069/112] EV6: supress LFA (#25094) * EV6: supress LFA * bump panda --- opendbc | 2 +- panda | 2 +- selfdrive/car/hyundai/carcontroller.py | 3 +++ selfdrive/car/hyundai/carstate.py | 5 ++++- selfdrive/car/hyundai/hda2can.py | 5 +++++ 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/opendbc b/opendbc index 1e9693ce09..9fc90a9f58 160000 --- a/opendbc +++ b/opendbc @@ -1 +1 @@ -Subproject commit 1e9693ce0916b896568dcd5558a670e67843c299 +Subproject commit 9fc90a9f5816ed82e0f25f2eaf7ad4af3d45733e diff --git a/panda b/panda index 53466f0934..ca927fe931 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 53466f09344c8ff6cdce3b19df76b5bca79e1327 +Subproject commit ca927fe9312651a16f13aaddca8b46af5315ede6 diff --git a/selfdrive/car/hyundai/carcontroller.py b/selfdrive/car/hyundai/carcontroller.py index 73635375ad..a878ad3274 100644 --- a/selfdrive/car/hyundai/carcontroller.py +++ b/selfdrive/car/hyundai/carcontroller.py @@ -75,6 +75,9 @@ class CarController: # steering control can_sends.append(hda2can.create_lkas(self.packer, CC.enabled, self.frame, CC.latActive, apply_steer)) + if self.frame % 5 == 0: + can_sends.append(hda2can.create_cam_0x2a4(self.packer, self.frame, CS.cam_0x2a4)) + # cruise cancel if (self.frame - self.last_button_frame) * DT_CTRL > 0.25: if CC.cruiseControl.cancel: diff --git a/selfdrive/car/hyundai/carstate.py b/selfdrive/car/hyundai/carstate.py index 6c82c33856..a10cdadbca 100644 --- a/selfdrive/car/hyundai/carstate.py +++ b/selfdrive/car/hyundai/carstate.py @@ -172,6 +172,7 @@ class CarState(CarStateBase): ret.cruiseState.speed = cp.vl["CRUISE_INFO"]["SET_SPEED"] * speed_factor self.buttons_counter = cp.vl["CRUISE_BUTTONS"]["_COUNTER"] + self.cam_0x2a4 = copy.copy(cp_cam.vl["CAM_0x2a4"]) return ret @@ -313,7 +314,9 @@ class CarState(CarStateBase): @staticmethod def get_cam_can_parser(CP): if CP.carFingerprint in HDA2_CAR: - return None + signals = [(f"BYTE{i}", "CAM_0x2a4") for i in range(3, 24)] + checks = [("CAM_0x2a4", 20)] + return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, 6) signals = [ # signal_name, signal_address diff --git a/selfdrive/car/hyundai/hda2can.py b/selfdrive/car/hyundai/hda2can.py index e4c658c1a9..437f5cf538 100644 --- a/selfdrive/car/hyundai/hda2can.py +++ b/selfdrive/car/hyundai/hda2can.py @@ -12,6 +12,11 @@ def create_lkas(packer, enabled, frame, lat_active, apply_steer): } return packer.make_can_msg("LKAS", 4, values, frame % 255) +def create_cam_0x2a4(packer, frame, camera_values): + camera_values.update({ + "BYTE7": 0, + }) + return packer.make_can_msg("CAM_0x2a4", 4, camera_values, frame % 255) def create_buttons(packer, cnt, cancel, resume): values = { From 825acfae98543c915c18d3b19a9c5d2503e431a6 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Fri, 8 Jul 2022 22:09:58 -0700 Subject: [PATCH 070/112] Improve EV6 tune (#25085) --- selfdrive/car/torque_data/override.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/car/torque_data/override.yaml b/selfdrive/car/torque_data/override.yaml index be81af2606..476313df2b 100644 --- a/selfdrive/car/torque_data/override.yaml +++ b/selfdrive/car/torque_data/override.yaml @@ -20,7 +20,7 @@ FORD FOCUS 4TH GEN: [.nan, 1.5, .nan] COMMA BODY: [.nan, 1000, .nan] # Totally new cars -KIA EV6 2022: [3.0, 2.5, 0.0] +KIA EV6 2022: [3.5, 2.5, 0.0] RAM 1500 5TH GEN: [2.0, 2.0, 0.05] # Dashcam or fallback configured as ideal car From d08a23177495c778fe628dc97728f5bbfee8b0f1 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Fri, 8 Jul 2022 22:46:20 -0700 Subject: [PATCH 071/112] Ship EV6 (#25095) * Ship EV6 * bump opendbc --- RELEASES.md | 1 + docs/CARS.md | 3 ++- opendbc | 2 +- selfdrive/car/hyundai/interface.py | 2 +- selfdrive/test/process_replay/ref_commit | 2 +- selfdrive/test/process_replay/test_processes.py | 1 + 6 files changed, 7 insertions(+), 4 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index 588b88827a..b87bd2ee7d 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -29,6 +29,7 @@ Version 0.8.15 (2022-07-20) * Chrysler ECU firmware fingerprinting thanks to realfast! * Honda Civic 2022 support * Hyundai Tucson 2021 support thanks to bluesforte! +* Kia EV6 2022 support * Lexus NX Hybrid 2020 support thanks to AlexandreSato! * Ram 1500 2019-21 support thanks to realfast! diff --git a/docs/CARS.md b/docs/CARS.md index a1e89efe12..eb570faa7e 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -71,7 +71,7 @@ How We Rate The Cars |Toyota|RAV4 2019-21|All|||||| |Toyota|RAV4 Hybrid 2019-21|All|||||| -# Silver - 68 cars +# Silver - 69 cars |Make|Model|Supported Package|openpilot ACC|Stop and Go|Steer to 0|Steering Torque|Actively Maintained| |---|---|---|:---:|:---:|:---:|:---:|:---:| @@ -95,6 +95,7 @@ How We Rate The Cars |Hyundai|Santa Fe Plug-in Hybrid 2022|All|||||| |Hyundai|Tucson Diesel 2019|SCC + LKAS|||||| |Kia|Ceed 2019|SCC + LKAS|||||| +|Kia|EV6 2022|All|||||| |Kia|Forte 2018|SCC + LKAS|||||| |Kia|Forte 2019-21|SCC + LKAS|||||| |Kia|K5 2021-22|SCC|||||| diff --git a/opendbc b/opendbc index 9fc90a9f58..81148db67f 160000 --- a/opendbc +++ b/opendbc @@ -1 +1 @@ -Subproject commit 9fc90a9f5816ed82e0f25f2eaf7ad4af3d45733e +Subproject commit 81148db67fd00d4e2a107b5b8269c532436edf2b diff --git a/selfdrive/car/hyundai/interface.py b/selfdrive/car/hyundai/interface.py index 97119c77b7..069b0e74e5 100644 --- a/selfdrive/car/hyundai/interface.py +++ b/selfdrive/car/hyundai/interface.py @@ -36,7 +36,7 @@ class CarInterface(CarInterfaceBase): # These cars have been put into dashcam only due to both a lack of users and test coverage. # These cars likely still work fine. Once a user confirms each car works and a test route is # added to selfdrive/car/tests/routes.py, we can remove it from this list. - ret.dashcamOnly = candidate in {CAR.KIA_OPTIMA_H, CAR.ELANTRA_GT_I30} or candidate in HDA2_CAR + ret.dashcamOnly = candidate in {CAR.KIA_OPTIMA_H, CAR.ELANTRA_GT_I30} ret.steerActuatorDelay = 0.1 # Default delay ret.steerLimitTimer = 0.4 diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index 0d61dbd735..65ecbb4be3 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -dab90772097a0dd4706677ba4fe5e84b10232099 \ No newline at end of file +825acfae98543c915c18d3b19a9c5d2503e431a6 \ No newline at end of file diff --git a/selfdrive/test/process_replay/test_processes.py b/selfdrive/test/process_replay/test_processes.py index 96d1014004..652c49db3d 100755 --- a/selfdrive/test/process_replay/test_processes.py +++ b/selfdrive/test/process_replay/test_processes.py @@ -18,6 +18,7 @@ from tools.lib.logreader import LogReader original_segments = [ ("BODY", "937ccb7243511b65|2022-05-24--16-03-09--1"), # COMMA.BODY ("HYUNDAI", "02c45f73a2e5c6e9|2021-01-01--19-08-22--1"), # HYUNDAI.SONATA + ("HYUNDAI", "d824e27e8c60172c|2022-07-08--21-21-15--1"), # HYUNDAI.KIA_EV6 ("TOYOTA", "0982d79ebb0de295|2021-01-04--17-13-21--13"), # TOYOTA.PRIUS (INDI) ("TOYOTA2", "0982d79ebb0de295|2021-01-03--20-03-36--6"), # TOYOTA.RAV4 (LQR) ("TOYOTA3", "f7d7e3538cda1a2a|2021-08-16--08-55-34--6"), # TOYOTA.COROLLA_TSS2 From 89d1d9f6df6e1fbe65609fa8f93702479620a50e Mon Sep 17 00:00:00 2001 From: Greg Hogan Date: Sat, 9 Jul 2022 00:55:40 -0700 Subject: [PATCH 072/112] firmware fingerprinting: order brand requests (#23311) Co-authored-by: Shane Smiskol --- selfdrive/car/car_helpers.py | 4 +- selfdrive/car/fw_versions.py | 75 ++++++++++++++++++++++++++++-------- 2 files changed, 62 insertions(+), 17 deletions(-) diff --git a/selfdrive/car/car_helpers.py b/selfdrive/car/car_helpers.py index 690072cc4d..b6bdece676 100644 --- a/selfdrive/car/car_helpers.py +++ b/selfdrive/car/car_helpers.py @@ -8,7 +8,7 @@ from system.version import is_comma_remote, is_tested_branch from selfdrive.car.interfaces import get_interface_attr from selfdrive.car.fingerprints import eliminate_incompatible_cars, all_legacy_fingerprint_cars from selfdrive.car.vin import get_vin, VIN_UNKNOWN -from selfdrive.car.fw_versions import get_fw_versions, match_fw_to_car, get_present_ecus +from selfdrive.car.fw_versions import get_fw_versions_ordered, match_fw_to_car, get_present_ecus from system.swaglog import cloudlog import cereal.messaging as messaging from selfdrive.car import gen_empty_fingerprint @@ -99,7 +99,7 @@ def fingerprint(logcan, sendcan): cloudlog.warning("Getting VIN & FW versions") _, vin = get_vin(logcan, sendcan, bus) ecu_rx_addrs = get_present_ecus(logcan, sendcan) - car_fw = get_fw_versions(logcan, sendcan) + car_fw = get_fw_versions_ordered(logcan, sendcan, ecu_rx_addrs) exact_fw_match, fw_candidates = match_fw_to_car(car_fw) else: diff --git a/selfdrive/car/fw_versions.py b/selfdrive/car/fw_versions.py index 04610b96d9..c4b158aebb 100755 --- a/selfdrive/car/fw_versions.py +++ b/selfdrive/car/fw_versions.py @@ -225,6 +225,15 @@ def build_fw_dict(fw_versions, filter_brand=None): return fw_versions_dict +def get_brand_addrs(): + versions = get_interface_attr('FW_VERSIONS', ignore_none=True) + brand_addrs = defaultdict(set) + for brand, cars in versions.items(): + for fw in cars.values(): + brand_addrs[brand] |= {(addr, sub_addr) for _, addr, sub_addr in fw.keys()} + return brand_addrs + + def match_fw_to_car_fuzzy(fw_versions_dict, log=True, exclude=None): """Do a fuzzy FW match. This function will return a match, and the number of firmware version that were matched uniquely to that specific car. If multiple ECUs uniquely match to different cars @@ -236,7 +245,7 @@ def match_fw_to_car_fuzzy(fw_versions_dict, log=True, exclude=None): # time and only one is in our database. exclude_types = [Ecu.fwdCamera, Ecu.fwdRadar, Ecu.eps, Ecu.debug] - # Build lookup table from (addr, subaddr, fw) to list of candidate cars + # Build lookup table from (addr, sub_addr, fw) to list of candidate cars all_fw_versions = defaultdict(list) for candidate, fw_by_addr in FW_VERSIONS.items(): if candidate == exclude: @@ -361,24 +370,59 @@ def get_present_ecus(logcan, sendcan): return ecu_responses -def get_fw_versions(logcan, sendcan, extra=None, timeout=0.1, debug=False, progress=False): - ecu_types = {} +def get_brand_ecu_matches(ecu_rx_addrs): + """Returns dictionary of brands and matches with ECUs in their FW versions""" - # Extract ECU addresses to query from fingerprints - # ECUs using a subaddress need be queried one by one, the rest can be done in parallel - addrs = [] - parallel_addrs = [] + brand_addrs = get_brand_addrs() + brand_matches = {r.brand: set() for r in REQUESTS} + + brand_rx_offsets = set((r.brand, r.rx_offset) for r in REQUESTS) + for addr, sub_addr, _ in ecu_rx_addrs: + # Since we can't know what request an ecu responded to, add matches for all possible rx offsets + for brand, rx_offset in brand_rx_offsets: + a = (uds.get_rx_addr_for_tx_addr(addr, -rx_offset), sub_addr) + if a in brand_addrs[brand]: + brand_matches[brand].add(a) + + return brand_matches + + +def get_fw_versions_ordered(logcan, sendcan, ecu_rx_addrs, timeout=0.1, debug=False, progress=False): + """Queries for FW versions ordering brands by likelihood, breaks when exact match is found""" + all_car_fw = [] + brand_matches = get_brand_ecu_matches(ecu_rx_addrs) + + for brand in sorted(brand_matches, key=lambda b: len(brand_matches[b]), reverse=True): + car_fw = get_fw_versions(logcan, sendcan, brand=brand, timeout=timeout, debug=debug, progress=progress) + all_car_fw.extend(car_fw) + matches = match_fw_to_car_exact(build_fw_dict(car_fw)) + if len(matches) == 1: + break + + return all_car_fw + + +def get_fw_versions(logcan, sendcan, brand=None, extra=None, timeout=0.1, debug=False, progress=False): versions = get_interface_attr('FW_VERSIONS', ignore_none=True) + if brand is not None: + versions = {brand: versions[brand]} + if extra is not None: versions.update(extra) + # Extract ECU addresses to query from fingerprints + # ECUs using a subaddress need be queried one by one, the rest can be done in parallel + addrs = [] + parallel_addrs = [] + ecu_types = {} + for brand, brand_versions in versions.items(): for c in brand_versions.values(): for ecu_type, addr, sub_addr in c.keys(): a = (brand, addr, sub_addr) if a not in ecu_types: - ecu_types[(addr, sub_addr)] = ecu_type + ecu_types[a] = ecu_type if sub_addr is None: if a not in parallel_addrs: @@ -390,17 +434,17 @@ def get_fw_versions(logcan, sendcan, extra=None, timeout=0.1, debug=False, progr addrs.insert(0, parallel_addrs) fw_versions = {} - for i, addr in enumerate(tqdm(addrs, disable=not progress)): + requests = [r for r in REQUESTS if brand is None or r.brand == brand] + for addr in tqdm(addrs, disable=not progress): for addr_chunk in chunks(addr): - for r in REQUESTS: + for r in requests: try: addrs = [(a, s) for (b, a, s) in addr_chunk if b in (r.brand, 'any') and - (len(r.whitelist_ecus) == 0 or ecu_types[(a, s)] in r.whitelist_ecus)] + (len(r.whitelist_ecus) == 0 or ecu_types[(b, a, s)] in r.whitelist_ecus)] if addrs: query = IsoTpParallelQuery(sendcan, logcan, r.bus, addrs, r.request, r.response, r.rx_offset, debug=debug) - t = 2 * timeout if i == 0 else timeout - fw_versions.update({(r.brand, addr): (version, r) for addr, version in query.get_data(t).items()}) + fw_versions.update({(r.brand, addr): (version, r) for addr, version in query.get_data(timeout).items()}) except Exception: cloudlog.warning(f"FW query exception: {traceback.format_exc()}") @@ -409,7 +453,7 @@ def get_fw_versions(logcan, sendcan, extra=None, timeout=0.1, debug=False, progr for (brand, addr), (version, request) in fw_versions.items(): f = car.CarParams.CarFw.new_message() - f.ecu = ecu_types[addr] + f.ecu = ecu_types[(brand, addr[0], addr[1])] f.fwVersion = version f.address = addr[0] f.responseAddress = uds.get_rx_addr_for_tx_addr(addr[0], request.rx_offset) @@ -433,6 +477,7 @@ if __name__ == "__main__": parser = argparse.ArgumentParser(description='Get firmware version of ECUs') parser.add_argument('--scan', action='store_true') parser.add_argument('--debug', action='store_true') + parser.add_argument('--brand', help='Only query addresses/with requests for this brand') args = parser.parse_args() logcan = messaging.sub_sock('can') @@ -458,7 +503,7 @@ if __name__ == "__main__": print() t = time.time() - fw_vers = get_fw_versions(logcan, sendcan, extra=extra, debug=args.debug, progress=True) + fw_vers = get_fw_versions(logcan, sendcan, brand=args.brand, extra=extra, debug=args.debug, progress=True) _, candidates = match_fw_to_car(fw_vers) print() From eb17291ca13035b40d653da107653d4420517aaa Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Sat, 9 Jul 2022 16:47:10 +0800 Subject: [PATCH 073/112] Display the current language in MultiOptionDialog (#25098) * check the selected language in lange select dialog * disable if user selects current option * update line numbers Co-authored-by: Shane Smiskol --- selfdrive/ui/qt/offroad/settings.cc | 3 +- selfdrive/ui/qt/widgets/input.cc | 15 +++-- selfdrive/ui/qt/widgets/input.h | 4 +- selfdrive/ui/translations/main_ko.ts | 70 ++++++++++++------------ selfdrive/ui/translations/main_zh-CHS.ts | 70 ++++++++++++------------ selfdrive/ui/translations/main_zh-CHT.ts | 70 ++++++++++++------------ 6 files changed, 119 insertions(+), 113 deletions(-) diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index 6bcdd55b0a..d5b8d4bbd1 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -137,7 +137,8 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) { auto translateBtn = new ButtonControl(tr("Change Language"), tr("CHANGE"), ""); connect(translateBtn, &ButtonControl::clicked, [=]() { QMap langs = getSupportedLanguages(); - QString selection = MultiOptionDialog::getSelection(tr("Select a language"), langs.keys(), this); + QString currentLang = QString::fromStdString(Params().get("LanguageSetting")); + QString selection = MultiOptionDialog::getSelection(tr("Select a language"), langs.keys(), langs.key(currentLang), this); if (!selection.isEmpty()) { // put language setting, exit Qt UI, and trigger fast restart Params().put("LanguageSetting", langs[selection].toStdString()); diff --git a/selfdrive/ui/qt/widgets/input.cc b/selfdrive/ui/qt/widgets/input.cc index a130a8e935..b0facfce83 100644 --- a/selfdrive/ui/qt/widgets/input.cc +++ b/selfdrive/ui/qt/widgets/input.cc @@ -261,7 +261,7 @@ bool RichTextDialog::alert(const QString &prompt_text, QWidget *parent) { // MultiOptionDialog -MultiOptionDialog::MultiOptionDialog(const QString &prompt_text, QStringList l, QWidget *parent) : QDialogBase(parent) { +MultiOptionDialog::MultiOptionDialog(const QString &prompt_text, const QStringList &l, const QString ¤t, QWidget *parent) : QDialogBase(parent) { QFrame *container = new QFrame(this); container->setStyleSheet(R"( QFrame { background-color: #1B1B1B; } @@ -301,12 +301,17 @@ MultiOptionDialog::MultiOptionDialog(const QString &prompt_text, QStringList l, confirm_btn->setObjectName("confirm_btn"); confirm_btn->setEnabled(false); - for (QString &s : l) { + for (const QString &s : l) { QPushButton *selectionLabel = new QPushButton(s); selectionLabel->setCheckable(true); + selectionLabel->setChecked(s == current); QObject::connect(selectionLabel, &QPushButton::toggled, [=](bool checked) { if (checked) selection = s; - confirm_btn->setEnabled(true); + if (selection != current) { + confirm_btn->setEnabled(true); + } else { + confirm_btn->setEnabled(false); + } }); group->addButton(selectionLabel); @@ -336,8 +341,8 @@ MultiOptionDialog::MultiOptionDialog(const QString &prompt_text, QStringList l, outer_layout->addWidget(container); } -QString MultiOptionDialog::getSelection(const QString &prompt_text, const QStringList l, QWidget *parent) { - MultiOptionDialog d = MultiOptionDialog(prompt_text, l, parent); +QString MultiOptionDialog::getSelection(const QString &prompt_text, const QStringList &l, const QString ¤t, QWidget *parent) { + MultiOptionDialog d = MultiOptionDialog(prompt_text, l, current, parent); if (d.exec()) { return d.selection; } diff --git a/selfdrive/ui/qt/widgets/input.h b/selfdrive/ui/qt/widgets/input.h index 47d8b74efd..6c47a31d87 100644 --- a/selfdrive/ui/qt/widgets/input.h +++ b/selfdrive/ui/qt/widgets/input.h @@ -73,7 +73,7 @@ class MultiOptionDialog : public QDialogBase { Q_OBJECT public: - explicit MultiOptionDialog(const QString &prompt_text, const QStringList l, QWidget *parent); - static QString getSelection(const QString &prompt_text, const QStringList l, QWidget *parent); + explicit MultiOptionDialog(const QString &prompt_text, const QStringList &l, const QString ¤t, QWidget *parent); + static QString getSelection(const QString &prompt_text, const QStringList &l, const QString ¤t, QWidget *parent); QString selection; }; diff --git a/selfdrive/ui/translations/main_ko.ts b/selfdrive/ui/translations/main_ko.ts index ad35a37fa1..5a8f21d7a7 100644 --- a/selfdrive/ui/translations/main_ko.ts +++ b/selfdrive/ui/translations/main_ko.ts @@ -193,67 +193,67 @@ 변경 - + Select a language 언어선택 - + Reboot 재부팅 - + Power Off 전원 종료 - + openpilot requires the device to be mounted within 4° left or right and within 5° up or 8° down. openpilot is continuously calibrating, resetting is rarely required. openpilot은 장치를 왼쪽 또는 오른쪽 4° 이내, 위쪽 5° 또는 아래쪽 8° 이내로 설치해야 합니다. openpilot은 지속적으로 보정되므로 리셋이 거의 필요하지 않습니다. - + Your device is pointed %1° %2 and %3° %4. 사용자의 기기가 %1° %2 및 %3° %4를 가리키고 있습니다. - + down 아래 - + up - + left 왼쪽 - + right 오른쪽 - + Are you sure you want to reboot? 재부팅 하시겠습니까? - + Disengage to Reboot 재부팅 하려면 해제하세요 - + Are you sure you want to power off? 전원을 종료하시겠습니까? - + Disengage to Power Off 전원을 종료하려면 해제하세요 @@ -461,7 +461,7 @@ location set 선택 - + Cancel 취소 @@ -717,33 +717,33 @@ location set SettingsWindow - + × × - + Device 장치 - - + + Network 네트워크 - + Toggles 토글 - + Software 소프트웨어 - + Navigation 네비게이션 @@ -982,68 +982,68 @@ location set SoftwarePanel - + Git Branch Git 브렌치 - + Git Commit Git 커밋 - + OS Version OS 버전 - + Version 버전 - + Last Update Check 최신 업데이트 검사 - + The last time openpilot successfully checked for an update. The updater only runs while the car is off. 이전에 openpilot에서 업데이트를 성공적으로 확인한 시간입니다. 업데이트 프로그램은 차량 연결이 해제되었을때만 작동합니다. - + Check for Update 업데이트 확인 - + CHECKING 검사중 - + Uninstall 삭제 - + UNINSTALL 삭제 - + Are you sure you want to uninstall? 삭제하시겠습니까? - + failed to fetch update 업데이트를 가져올수없습니다 - - + + CHECK 확인 diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts index c3e1954f1e..dbbde36394 100644 --- a/selfdrive/ui/translations/main_zh-CHS.ts +++ b/selfdrive/ui/translations/main_zh-CHS.ts @@ -193,67 +193,67 @@ 切换 - + Select a language 选择语言 - + Reboot 重启 - + Power Off 关机 - + openpilot requires the device to be mounted within 4° left or right and within 5° up or 8° down. openpilot is continuously calibrating, resetting is rarely required. openpilot 要求设备安装在左或右 4° 以内,上 5° 或下 8° 以内。 openpilot 会持续校准,很少需要重置。 - + Your device is pointed %1° %2 and %3° %4. 您的设备指向 %1° %2 和 %3° %4。 - + down - + up 向上 - + left 向左 - + right 向右 - + Are you sure you want to reboot? 您确定要重新启动吗? - + Disengage to Reboot 脱离以重新启动 - + Are you sure you want to power off? 您确定要关闭电源吗? - + Disengage to Power Off 脱离以关闭电源 @@ -461,7 +461,7 @@ location set 选择 - + Cancel 取消 @@ -717,33 +717,33 @@ location set SettingsWindow - + × × - + Device 设备 - - + + Network 网络 - + Toggles 切换 - + Software 软件 - + Navigation 导航 @@ -982,68 +982,68 @@ location set SoftwarePanel - + Git Branch Git 分支 - + Git Commit Git 提交 - + OS Version 操作系统版本 - + Version 版本 - + Last Update Check 最后更新检查 - + The last time openpilot successfully checked for an update. The updater only runs while the car is off. 上次 openpilot 成功检查更新的时间。 更新程序仅在汽车关闭时运行。 - + Check for Update 检查更新 - + CHECKING 正在检查 - + Uninstall 卸载 - + UNINSTALL 卸载 - + Are you sure you want to uninstall? 您确定要卸载吗? - + failed to fetch update 未能获取更新 - - + + CHECK 查看 diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts index f6e36081fa..2920916ece 100644 --- a/selfdrive/ui/translations/main_zh-CHT.ts +++ b/selfdrive/ui/translations/main_zh-CHT.ts @@ -193,67 +193,67 @@ 更改 - + Select a language 選擇語言 - + Reboot 重新啟動 - + Power Off 關機 - + openpilot requires the device to be mounted within 4° left or right and within 5° up or 8° down. openpilot is continuously calibrating, resetting is rarely required. openpilot 需要將裝置固定在左右偏差 4° 以內,朝上偏差 5° 以内或朝下偏差 8° 以内。鏡頭在後台會持續自動校準,很少有需要重置的情况。 - + Your device is pointed %1° %2 and %3° %4. 你的設備目前朝%2 %1° 以及朝%4 %3° 。 - + down - + up - + left - + right - + Are you sure you want to reboot? 您確定要重新啟動嗎? - + Disengage to Reboot 請先取消控車才能重新啟動 - + Are you sure you want to power off? 您確定您要關機嗎? - + Disengage to Power Off 請先取消控車才能關機 @@ -466,7 +466,7 @@ location set 選擇 - + Cancel 取消 @@ -725,33 +725,33 @@ location set SettingsWindow - + × × - + Device 設備 - - + + Network 網路 - + Toggles 設定 - + Software 軟體 - + Navigation 導航 @@ -990,68 +990,68 @@ location set SoftwarePanel - + Git Branch Git 分支 - + Git Commit Git 提交 - + OS Version 系統版本 - + Version 版本 - + Last Update Check 上次檢查時間 - + The last time openpilot successfully checked for an update. The updater only runs while the car is off. 上次成功檢查更新的時間。更新系統只會在車子熄火時執行。 - + Check for Update 檢查更新 - + CHECKING 檢查中 - + Uninstall 卸載 - + UNINSTALL 卸載 - + Are you sure you want to uninstall? 您確定您要卸載嗎? - + failed to fetch update 下載更新失敗 - - + + CHECK 檢查 From be7f7041681ab088f03c075a8a836e538378a7a8 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Mon, 11 Jul 2022 12:52:03 -0700 Subject: [PATCH 074/112] Fix new steer saturated warning with joystick mode (#25113) Fix steer sat warning with joystick mode --- selfdrive/controls/controlsd.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index 6f0c9c2ae6..117509f1e6 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -602,14 +602,14 @@ class Controls: lac_log.saturated = abs(actuators.steer) >= 0.9 # Send a "steering required alert" if saturation count has reached the limit - if lac_log.active and not CS.steeringPressed and self.CP.lateralTuning.which() == 'torque': + if lac_log.active and not CS.steeringPressed and self.CP.lateralTuning.which() == 'torque' and not self.joystick_mode: undershooting = abs(lac_log.desiredLateralAccel) / abs(1e-3 + lac_log.actualLateralAccel) > 1.2 turning = abs(lac_log.desiredLateralAccel) > 1.0 good_speed = CS.vEgo > 5 max_torque = abs(self.last_actuators.steer) > 0.99 if undershooting and turning and good_speed and max_torque: self.events.add(EventName.steerSaturated) - elif lac_log.active and lac_log.saturated and not CS.steeringPressed: + elif lac_log.active and not CS.steeringPressed and lac_log.saturated: dpath_points = lat_plan.dPathPoints if len(dpath_points): # Check if we deviated from the path From 5e896ce2f134b9f17d466bf1aec694142bcb5ed3 Mon Sep 17 00:00:00 2001 From: ZwX1616 Date: Mon, 11 Jul 2022 13:22:13 -0700 Subject: [PATCH 075/112] Improve Simplified Chinese translations (#25091) * 1 * shane told me to do this * 1.5 * 2 * 3 * 4 * Update main_zh-CHS.ts * release * some minor improvements * build * remove state Co-authored-by: Shane Smiskol --- selfdrive/ui/translations/main_zh-CHS.qm | Bin 18457 -> 18507 bytes selfdrive/ui/translations/main_zh-CHS.ts | 272 +++++++++++------------ 2 files changed, 135 insertions(+), 137 deletions(-) diff --git a/selfdrive/ui/translations/main_zh-CHS.qm b/selfdrive/ui/translations/main_zh-CHS.qm index b96acb89d99ed8207dd34740c51714706e771040..59487d263a7a7524f15a239bb7ace144137f31b0 100644 GIT binary patch delta 4896 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 TUT|gA<)_(O-J$pM_^AH}{k-)m delta 4941 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 Close - + 关闭 @@ -16,7 +16,7 @@ Reboot and Update - 重启和更新 + 重启并更新 @@ -24,17 +24,17 @@ Back - 后退 + 返回 Enable Tethering - 启用网络共享 + 启用WiFi热点 Tethering Password - 网络共享密码 + WiFi热点密码 @@ -45,7 +45,7 @@ Enter new tethering password - 输入新的网络共享密码 + 输入新的WiFi热点密码 @@ -55,22 +55,22 @@ Enable Roaming - 启用漫游 + 启用数据漫游 APN Setting - APN 设置 + APN设置 Enter APN - 输入 APN + 输入APN leave blank for automatic configuration - 为自动配置留空 + 留空以自动配置 @@ -92,17 +92,17 @@ You must accept the Terms and Conditions in order to use openpilot. - 您必须接受条款和条件才能使用 openpilot。 + 您必须接受条款和条件以使用openpilot。 Back - 后退 + 返回 Decline, uninstall %1 - 拒绝,卸载 %1 + 拒绝并卸载%1 @@ -110,37 +110,37 @@ Dongle ID - 加密狗 ID + 设备ID(Dongle ID) N/A - 不适用 + N/A Serial - 串行 + 序列号 Driver Camera - 司机摄像头 + 驾驶员摄像头 PREVIEW - 预习 + 预览 Preview the driver facing camera to help optimize device mounting position for best driver monitoring experience. (vehicle must be off) - 预览面向驾驶员的摄像头,以帮助优化设备安装位置以获得最佳驾驶员监控体验。 (车辆必须关闭) + 打开并预览驾驶员摄像头,用于调整安装角度以获得最优驾驶员监控体验。仅熄火时可用。 Reset Calibration - 重置校准 + 重置设备校准 @@ -150,32 +150,32 @@ Are you sure you want to reset calibration? - 您确定要重置校准吗? + 您确定要重置设备校准吗? Review Training Guide - 查看培训指南 + 新手指南 REVIEW - 重新查看 + 查看 Review the rules, features, and limitations of openpilot - 查看 openpilot 的规则、功能和限制 + 查看openpilot的使用规则,以及其功能和限制。 Are you sure you want to review the training guide? - 您确定要查看培训指南吗? + 您确定要查看新手指南吗? Regulatory - 监管 + 监管信息 @@ -210,32 +210,32 @@ openpilot requires the device to be mounted within 4° left or right and within 5° up or 8° down. openpilot is continuously calibrating, resetting is rarely required. - openpilot 要求设备安装在左或右 4° 以内,上 5° 或下 8° 以内。 openpilot 会持续校准,很少需要重置。 + openpilot要求设备安装的偏航角在左4°和右4°之间,俯仰角在上5°和下8°之间。一般来说,openpilot会持续更新校准,很少需要重置。 Your device is pointed %1° %2 and %3° %4. - 您的设备指向 %1° %2 和 %3° %4。 + 您的设备校准为%1° %2、%3° %4。 down - + 朝下 up - 向上 + 朝上 left - 向左 + 朝左 right - 向右 + 朝右 @@ -245,17 +245,17 @@ Disengage to Reboot - 脱离以重新启动 + 取消openpilot以重新启动 Are you sure you want to power off? - 您确定要关闭电源吗? + 您确定要关机吗? Disengage to Power Off - 脱离以关闭电源 + 取消openpilot以关机 @@ -263,7 +263,7 @@ Drives - 驱动器 + 旅程数 @@ -278,12 +278,12 @@ PAST WEEK - 上周 + 过去一周 KM - 千米 + 公里 @@ -296,7 +296,7 @@ camera starting - 相机启动中 + 正在启动相机 @@ -309,12 +309,12 @@ Need at least - 需要至少 + 至少需要 characters! - 字符! + 个字符! @@ -322,7 +322,7 @@ Installing... - 安装... + 正在安装…… @@ -332,12 +332,12 @@ Resolving deltas: - 解决增量: + 正在处理: Updating files: - 更新文件: + 正在更新文件: @@ -401,12 +401,12 @@ CLEAR - CLEAR + 清空 Recent Destinations - 近期目的地 + 最近目的地 @@ -417,27 +417,25 @@ Get turn-by-turn directions displayed and more with a comma prime subscription. Sign up now: https://connect.comma.ai - 使用逗号获取显示的详细路线和更多信息 -主要订阅。 立即注册:https://connect.comma.ai + 订阅comma prime以获取导航。 +立即注册:https://connect.comma.ai No home location set - 没有家 -位置集 + 家:未设定 No work location set - 没有工作 -位置集 + 工作:未设定 no recent destinations - 没有最近的目的地 + 无最近目的地 @@ -445,7 +443,7 @@ location set Map Loading - 地图加载 + 地图加载中 @@ -471,23 +469,23 @@ location set Advanced - 先进的 + 高级 Enter password - 先进的 + 输入密码 for " - 为了 " + 网络名称:" Wrong password - Wrong password + 密码错误 @@ -495,30 +493,30 @@ location set km/h - 公里/小时 + km/h mph - 英里/小时 + mph MAX - 最大限度 + 最高定速 SPEED - 速度 + SPEED LIMIT - 限制 + LIMIT @@ -544,7 +542,7 @@ location set Pair your device to your comma account - 将您的设备与您的逗号账户配对 + 将您的设备与comma账号配对 @@ -574,12 +572,12 @@ location set Become a comma prime member at connect.comma.ai - 成为 connect.comma.ai 的逗号主要会员 + 打开connect.comma.ai以注册comma prime会员 PRIME FEATURES: - 主要特点: + comma prime特权: @@ -589,7 +587,7 @@ location set 1 year of storage - 1年存储 + 1年数据存储 @@ -602,12 +600,12 @@ location set ✓ SUBSCRIBED - ✓ 订阅 + ✓ 已订阅 comma prime - 逗号素数 + comma prime @@ -617,7 +615,7 @@ location set COMMA POINTS - 逗号分 + COMMA POINTS点数 @@ -635,7 +633,7 @@ location set dashcam - 行车记录器 + 行车记录仪 @@ -673,17 +671,17 @@ location set Resetting device... - 正在重置设备... + 正在重置设备…… System Reset - 系统重置 + 恢复出厂设置 System reset triggered. Press confirm to erase all content and settings. Press cancel to resume boot. - 触发系统重置。 按确认删除所有内容和设置。 按取消恢复启动。 + 已触发系统重置:确认以删除所有内容和设置。取消以正常启动设备。 @@ -703,7 +701,7 @@ location set Unable to mount data partition. Press confirm to reset your device. - 无法挂载数据分区。 按确认重置您的设备。 + 无法挂载数据分区。 确认以重置您的设备。 @@ -735,7 +733,7 @@ location set Toggles - 切换 + 设定 @@ -758,7 +756,7 @@ location set Power your device in a car with a harness or proceed at your own risk. - 使用安全带在汽车中为您的设备供电或自行承担风险。 + 请使用car harness线束为您的设备供电,或自行承担风险。 @@ -775,28 +773,28 @@ location set Getting Started - 入门 + 开始设置 Before we get on the road, let’s finish installation and cover some details. - 在我们上路之前,让我们完成安装并介绍一些细节。 + 开始旅程之前,让我们完成安装并介绍一些细节。 Connect to Wi-Fi - 连接到无线网络 + 连接到WiFi Back - 后退 + 返回 Continue without Wi-Fi - 在没有 Wi-Fi 的情况下继续 + 不连接WiFi并继续 @@ -811,12 +809,12 @@ location set Dashcam - 行车记录器 + Dashcam(行车记录仪) Custom Software - 定制的软件 + 自定义软件 @@ -826,12 +824,12 @@ location set for Custom Software - 定制软件 + 以下载自定义软件 Downloading... - 正在下载... + 正在下载…… @@ -841,7 +839,7 @@ location set Ensure the entered URL is valid, and the device’s internet connection is good. - 确保输入的 URL 有效,并且设备的互联网连接良好。 + 请确保互联网连接良好且输入的URL有效。 @@ -864,7 +862,7 @@ location set Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer. - 将您的设备与 comma connect (connect.comma.ai) 配对并领取您的 comma prime 优惠。 + 将您的设备与comma connect(connect.comma.ai)配对并领取您的comma prime优惠。 @@ -878,7 +876,7 @@ location set CONNECT - 连接 + CONNECT @@ -889,49 +887,49 @@ location set ONLINE - 在线的 + 在线 ERROR - 错误 + 连接出错 TEMP - 温度 + 设备温度 HIGH - 高的 + 过热 GOOD - 好的 + 良好 OK - 好的 + 一般 VEHICLE - 车辆 + 车辆连接 NO - 未连接 + PANDA - 熊猫 + PANDA @@ -941,7 +939,7 @@ location set SEARCH - 搜索 + 搜索中 @@ -956,7 +954,7 @@ location set ETH - 以太網 + 以太网 @@ -984,32 +982,32 @@ location set Git Branch - Git 分支 + Git Branch Git Commit - Git 提交 + Git Commit OS Version - 操作系统版本 + 系统版本 Version - 版本 + 软件版本 Last Update Check - 最后更新检查 + 上次检查更新 The last time openpilot successfully checked for an update. The updater only runs while the car is off. - 上次 openpilot 成功检查更新的时间。 更新程序仅在汽车关闭时运行。 + 上一次成功检查更新的时间。更新程序仅在汽车熄火时运行。 @@ -1019,7 +1017,7 @@ location set CHECKING - 正在检查 + 正在检查更新 @@ -1039,7 +1037,7 @@ location set failed to fetch update - 未能获取更新 + 获取更新失败 @@ -1053,12 +1051,12 @@ location set SSH Keys - SSH 密钥 + SSH密钥 Warning: This grants SSH access to all public keys in your GitHub settings. Never enter a GitHub username other than your own. A comma employee will NEVER ask you to add their GitHub username. - 警告:这将授予对 GitHub 设置中所有公钥的 SSH 访问权限。 切勿输入您自己以外的 GitHub 用户名。 逗号员工永远不会要求您添加他们的 GitHub 用户名。 + 警告:这将授予SSH访问权限给您GitHub设置中的所有公钥。切勿输入您自己以外的GitHub用户名。comma员工永远不会要求您添加他们的GitHub用户名。 @@ -1069,7 +1067,7 @@ location set Enter your GitHub username - 输入你的 GitHub 用户名 + 输入您的GitHub用户名 @@ -1079,12 +1077,12 @@ location set REMOVE - 消除 + 删除 Username '%1' has no keys on GitHub - 用户名“%1”在 GitHub 上没有密钥 + 用户名“%1”在GitHub上没有密钥 @@ -1094,7 +1092,7 @@ location set Username '%1' doesn't exist on GitHub - GitHub 上不存在用户名“%1” + GitHub上不存在用户名“%1” @@ -1102,7 +1100,7 @@ location set Enable SSH - 启用 SSH + 启用SSH @@ -1120,7 +1118,7 @@ location set Scroll to accept - 滑动接受 + 滑动以接受 @@ -1133,12 +1131,12 @@ location set Enable openpilot - 启用 openpilot + 启用openpilot Use the openpilot system for adaptive cruise control and lane keep driver assistance. Your attention is required at all times to use this feature. Changing this setting takes effect when the car is powered off. - 使用 openpilot 系统进行自适应巡航控制和车道保持驾驶员辅助。 任何时候都需要您注意使用此功能。 更改此设置在汽车断电时生效。 + 使用openpilot进行自适应巡航和车道保持辅助。使用此功能时您必须时刻保持注意力。该设置的更改在熄火时生效。 @@ -1148,7 +1146,7 @@ location set Receive alerts to steer back into the lane when your vehicle drifts over a detected lane line without a turn signal activated while driving over 31 mph (50 km/h). - 当您的车辆在以超过 31 英里/小时(50 公里/小时)的速度行驶时在检测到的车道线上漂移而没有激活转向信号时,接收提醒以返回车道。 + 车速超过31mph(50km/h)时,若检测到车辆越过车道线且未打转向灯,系统将发出警告以提醒您返回车道。 @@ -1158,57 +1156,57 @@ location set Allow openpilot to obey left-hand traffic conventions and perform driver monitoring on right driver seat. - 允许 openpilot 遵守左侧交通惯例并在右侧驾驶座上执行驾驶员监控。 + 允许openpilot遵守左侧交通惯例并在右侧驾驶座上执行驾驶员监控。 Use Metric System - 使用公制 + 使用公制单位 Display speed in km/h instead of mph. - 以公里/小时而不是英里/小时显示速度。 + 显示车速时,以km/h代替mph。 Record and Upload Driver Camera - 记录和上传司机摄像头 + 录制并上传驾驶员摄像头 Upload data from the driver facing camera and help improve the driver monitoring algorithm. - 从面向驾驶员的摄像头上传数据,帮助改进驾驶员监控算法。 + 上传驾驶员摄像头的数据,帮助改进驾驶员监控算法。 Disengage On Accelerator Pedal - 踩油门解除 + 踩油门时取消控制 When enabled, pressing the accelerator pedal will disengage openpilot. - 启用后,踩下油门踏板将解除 openpilot。 + 启用后,踩下油门踏板将取消openpilot。 Show ETA in 24h format - 以 24 小时格式显示 ETA + 以24小时格式显示预计到达时间 Use 24h format instead of am/pm - 使用 24 小时制代替上午/下午 + 使用24小时制代替am/pm openpilot Longitudinal Control - openpilot 纵向控制 + openpilot纵向控制 openpilot will disable the car's radar and will take over control of gas and brakes. Warning: this disables AEB! - openpilot 将禁用汽车的雷达并接管油门和刹车的控制。 警告:这会禁用 AEB! + openpilot将禁用车辆的雷达并接管油门和刹车的控制。警告:AEB将被禁用! @@ -1221,12 +1219,12 @@ location set An operating system update is required. Connect your device to Wi-Fi for the fastest update experience. The download size is approximately 1GB. - 需要操作系统更新。 将您的设备连接到 Wi-Fi,以获得最快的更新体验。 下载大小约为 1GB。 + 操作系统需要更新。请将您的设备连接到WiFi以获取更快的更新体验。下载大小约为1GB。 Connect to Wi-Fi - 连接到无线网络 + 连接到WiFi @@ -1236,12 +1234,12 @@ location set Back - 后退 + 返回 Loading... - 正在加载... + 正在加载…… @@ -1260,12 +1258,12 @@ location set Scanning for networks... - 正在扫描网络... + 正在扫描网络…… CONNECTING... - 正在连接... + 正在连接…… @@ -1275,7 +1273,7 @@ location set Forget Wi-Fi Network " - 忘记 Wi-Fi 网络" + 忘记WiFi网络" From c181d475c52798462c5b2a2cf2237eebde0fa26d Mon Sep 17 00:00:00 2001 From: ZwX1616 Date: Mon, 11 Jul 2022 13:41:55 -0700 Subject: [PATCH 076/112] fix a translation line break --- selfdrive/ui/translations/main_zh-CHS.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts index 9dade34701..9ac35994e6 100644 --- a/selfdrive/ui/translations/main_zh-CHS.ts +++ b/selfdrive/ui/translations/main_zh-CHS.ts @@ -862,7 +862,7 @@ location set Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer. - 将您的设备与comma connect(connect.comma.ai)配对并领取您的comma prime优惠。 + 将您的设备与comma connect (connect.comma.ai)配对并领取您的comma prime优惠。 From 30d88d6892f11bf2472d97d79e9f68bef9e01b3c Mon Sep 17 00:00:00 2001 From: ZwX1616 Date: Mon, 11 Jul 2022 13:45:45 -0700 Subject: [PATCH 077/112] update main_zh-CHS.qm --- selfdrive/ui/translations/main_zh-CHS.qm | Bin 18507 -> 18509 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/selfdrive/ui/translations/main_zh-CHS.qm b/selfdrive/ui/translations/main_zh-CHS.qm index 59487d263a7a7524f15a239bb7ace144137f31b0..63c17d76b7f0f99e5180d400a8143d17cbbdde55 100644 GIT binary patch delta 774 zcmWksX-HI27(MsBcW0XEIpYvI_@l;sGM5=e)U?43T&AKlHOUMy(XteROpQ=%0jUh- zDu$4#n6_DCIDeEEx89xuK{Nx{fqKS%hOQVeO~V<}hX0?lI)zw9 z(ZtM|ZsbUlWF;3l#SO%*LtcL`psPlHW-H*GfJ3*=0f|{Cd_Dz)2cn|HAMhGR&H5VP zaTMLtGeAyn{wkt;wOZM#_Z!(2U`-U)oyjF%Rqf)tM5J%Mr;U&#>UQy z3Qep|YlvG6qa5GGfX2#_#k|I1G8w(UZqRmSj2TPhD6(B}t;Ku9xUk$w&3-d3rrig2 b1sn&Gw+zK=Plm8FqTe1Y!FR}IuQUGxC?Cv+ delta 771 zcmWlXZAep59LAq>?>)1vyUl%=!wpD3Huh zj*s>j1(c*!|^D;7EvwlERZ>_M}W*J(<0d&ihj&*H7ueXDx7` zS9)=W%wj90>72WO@uu{tfMh{Y(#l*Z5IrTjB&+R&+)zO3gtPKvLjy(B%VQJyH2qti z95a(!yYNX_Y*v_Md!SnxTB{^woAP9dmJOa!o?oVQQmaIfY){+b`p&CBqK{`7!pNzZ zmt3Im@#VZ)Hw~y-UK9EVh^gf@qaG?@fVczfJH%V6nrYr6rer%C5#MDi3ldzho6P*r zE;%?|8p&2jH7yFaVqrH#k>WJ@{GMI;21vzzo2P~-L#OCdtn91sDhVu4Y|z}I;M~dv zL>SKs+|fPsmDBy$)s1%a(lpaex;P!*u(-wT+Q$7MujyhWn1z=+9kOa0qrZmxt5NP2 z%DJs(W_$$PMm0CF3`h!9^U`Ubq-mkoSOR_OSWgPII;hSK7^ts&b>Ry!`mbY zX%e*DkhmI2du)nPjh&^4WsTKjGzR?GqtjV1X0K7Am_EV%tN|0omGy_z?3Qsg^C@uD Yb_qx`jVJllI#|8%xWdPmT-PlB0NsGh%m4rY From bdfaa1d1eee77d1f9fb5b9b2632c9988caba02e3 Mon Sep 17 00:00:00 2001 From: HaraldSchafer Date: Mon, 11 Jul 2022 15:19:55 -0700 Subject: [PATCH 078/112] Ram 1500 torque tune (#25117) * torque control again * 3mss per s * no bad sensors * tweaks * Need more checks before we can do this * update refs * only ram for now Co-authored-by: Adeeb Shihadeh --- panda | 2 +- selfdrive/car/chrysler/carcontroller.py | 7 ++++--- selfdrive/car/chrysler/interface.py | 6 +++--- selfdrive/car/chrysler/values.py | 14 ++++++++++---- selfdrive/car/interfaces.py | 4 ++-- selfdrive/car/torque_data/override.yaml | 2 +- selfdrive/test/process_replay/ref_commit | 2 +- 7 files changed, 22 insertions(+), 15 deletions(-) diff --git a/panda b/panda index ca927fe931..baecd2ecc6 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit ca927fe9312651a16f13aaddca8b46af5315ede6 +Subproject commit baecd2ecc6a2a608e1305601f6f697feca69fe88 diff --git a/selfdrive/car/chrysler/carcontroller.py b/selfdrive/car/chrysler/carcontroller.py index e0eb979e6a..a7f2d007f1 100644 --- a/selfdrive/car/chrysler/carcontroller.py +++ b/selfdrive/car/chrysler/carcontroller.py @@ -16,6 +16,7 @@ class CarController: self.lkas_active_prev = False self.packer = CANPacker(dbc_name) + self.params = CarControllerParams(CP) def update(self, CC, CS, low_speed_alert): can_sends = [] @@ -40,8 +41,8 @@ class CarController: # steering if self.frame % 2 == 0: # steer torque - new_steer = int(round(CC.actuators.steer * CarControllerParams.STEER_MAX)) - apply_steer = apply_toyota_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorqueEps, CarControllerParams) + new_steer = int(round(CC.actuators.steer * self.params.STEER_MAX)) + apply_steer = apply_toyota_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorqueEps, self.params) if not lkas_active: apply_steer = 0 self.steer_rate_limited = new_steer != apply_steer @@ -56,6 +57,6 @@ class CarController: self.lkas_active_prev = lkas_active new_actuators = CC.actuators.copy() - new_actuators.steer = self.apply_steer_last / CarControllerParams.STEER_MAX + new_actuators.steer = self.apply_steer_last / self.params.STEER_MAX return new_actuators, can_sends diff --git a/selfdrive/car/chrysler/interface.py b/selfdrive/car/chrysler/interface.py index 697fb9b83a..8826a92523 100755 --- a/selfdrive/car/chrysler/interface.py +++ b/selfdrive/car/chrysler/interface.py @@ -46,15 +46,15 @@ class CarInterface(CarInterfaceBase): # Ram elif candidate == CAR.RAM_1500: + ret.steerActuatorDelay = 0.2 + ret.wheelbase = 3.88 ret.steerRatio = 16.3 ret.mass = 2493. + STD_CARGO_KG ret.maxLateralAccel = 2.4 ret.minSteerSpeed = 14.5 + CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) - ret.lateralTuning.pid.kpBP, ret.lateralTuning.pid.kiBP = [[0.], [0.]] - ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.1], [0.02]] - ret.lateralTuning.pid.kf = 0.00003 else: raise ValueError(f"Unsupported car: {candidate}") diff --git a/selfdrive/car/chrysler/values.py b/selfdrive/car/chrysler/values.py index ada4f486fc..f7531792fb 100644 --- a/selfdrive/car/chrysler/values.py +++ b/selfdrive/car/chrysler/values.py @@ -26,10 +26,16 @@ class CAR: class CarControllerParams: - STEER_MAX = 261 # higher than this faults the EPS on Chrysler/Jeep. Ram DT allows more - STEER_DELTA_UP = 3 - STEER_DELTA_DOWN = 3 - STEER_ERROR_MAX = 80 + def __init__(self, CP): + self.STEER_MAX = 261 # higher than this faults the EPS on Chrysler/Jeep. Ram DT allows more + self.STEER_ERROR_MAX = 80 + + if CP.carFingerprint in RAM_CARS: + self.STEER_DELTA_UP = 5 + self.STEER_DELTA_DOWN = 5 + else: + self.STEER_DELTA_UP = 3 + self.STEER_DELTA_DOWN = 3 STEER_THRESHOLD = 120 diff --git a/selfdrive/car/interfaces.py b/selfdrive/car/interfaces.py index 136337c5a4..4c7ea97dff 100644 --- a/selfdrive/car/interfaces.py +++ b/selfdrive/car/interfaces.py @@ -135,11 +135,11 @@ class CarInterfaceBase(ABC): return ret @staticmethod - def configure_torque_tune(candidate, tune, steering_angle_deadzone_deg=0.0): + def configure_torque_tune(candidate, tune, steering_angle_deadzone_deg=0.0, use_steering_angle=True): params = get_torque_params(candidate) tune.init('torque') - tune.torque.useSteeringAngle = True + tune.torque.useSteeringAngle = use_steering_angle tune.torque.kp = 1.0 / params['LAT_ACCEL_FACTOR'] tune.torque.kf = 1.0 / params['LAT_ACCEL_FACTOR'] tune.torque.ki = 0.1 / params['LAT_ACCEL_FACTOR'] diff --git a/selfdrive/car/torque_data/override.yaml b/selfdrive/car/torque_data/override.yaml index 476313df2b..8e6f62c4e7 100644 --- a/selfdrive/car/torque_data/override.yaml +++ b/selfdrive/car/torque_data/override.yaml @@ -21,7 +21,7 @@ COMMA BODY: [.nan, 1000, .nan] # Totally new cars KIA EV6 2022: [3.5, 2.5, 0.0] -RAM 1500 5TH GEN: [2.0, 2.0, 0.05] +RAM 1500 5TH GEN: [2.0, 2.0, 0.0] # Dashcam or fallback configured as ideal car mock: [10.0, 10, 0.0] diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index 65ecbb4be3..fc5f83c32a 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -825acfae98543c915c18d3b19a9c5d2503e431a6 \ No newline at end of file +d583bbd9643000e7f817171c583d31ae3141a652 \ No newline at end of file From 903bb405286295b48d5192cb2a7b2c01029193e3 Mon Sep 17 00:00:00 2001 From: Lee Jong Mun <43285072+crwusiz@users.noreply.github.com> Date: Tue, 12 Jul 2022 08:51:03 +0900 Subject: [PATCH 079/112] Improve Korean translations (#25105) * kor translations fix update_translations --release qm * space * qm * map setting tr space remove * ts update fix ko_update ch_update * qm release * Update QM * Fix this translation Co-authored-by: Shane Smiskol --- selfdrive/ui/qt/maps/map_settings.cc | 2 +- selfdrive/ui/translations/main_ko.qm | Bin 19997 -> 20040 bytes selfdrive/ui/translations/main_ko.ts | 96 +++++++++++------------ selfdrive/ui/translations/main_zh-CHS.qm | Bin 18509 -> 18508 bytes selfdrive/ui/translations/main_zh-CHS.ts | 2 +- selfdrive/ui/translations/main_zh-CHT.qm | Bin 18569 -> 18568 bytes selfdrive/ui/translations/main_zh-CHT.ts | 7 +- 7 files changed, 51 insertions(+), 56 deletions(-) diff --git a/selfdrive/ui/qt/maps/map_settings.cc b/selfdrive/ui/qt/maps/map_settings.cc index eaa8b1f703..d143b44e70 100644 --- a/selfdrive/ui/qt/maps/map_settings.cc +++ b/selfdrive/ui/qt/maps/map_settings.cc @@ -104,7 +104,7 @@ MapPanel::MapPanel(QWidget* parent) : QWidget(parent) { screenshot->setPixmap(pm.scaledToWidth(1080, Qt::SmoothTransformation)); no_prime_layout->addWidget(screenshot, 0, Qt::AlignHCenter); - QLabel *signup = new QLabel(tr("Get turn-by-turn directions displayed and more with a comma \nprime subscription. Sign up now: https://connect.comma.ai")); + QLabel *signup = new QLabel(tr("Get turn-by-turn directions displayed and more with a comma\nprime subscription. Sign up now: https://connect.comma.ai")); signup->setStyleSheet(R"(font-size: 45px; color: white; font-weight:300;)"); signup->setAlignment(Qt::AlignCenter); diff --git a/selfdrive/ui/translations/main_ko.qm b/selfdrive/ui/translations/main_ko.qm index 60966cdde587ebf4a43deb8ad255f374d32ca7c8..c5c66d1e73491c2ff09d91b6fdd5200002b2a6da 100644 GIT binary patch delta 2731 zcmYLJX;c(v7Jb!S)l2opt_J}NnpG4;!61vQf`Y~+XgCT<#?c^(xCEn~s3hYCijGT zc6t;x5h(_UMlB^$<^XpAR{CuOAd1YQN!oct&K{IDZZC)+uT_bN??uz{L@1g`)BoOE zh>Xf;=DL64Km}zeu4AE`GUk1Ti+9oN6J9*q12i856Oi z5Va03XJ%M}u+YOC=)^+oVdiEA6c`f5+*KSW8lJ#B9=nmqQ={N>;FsW5h2O&-qKI5Y z3SR&vK2~HoAmi|vibEZ!`|x7Lr4kT}XjfdDyo1Q$f#UWI#1(uLUCr=J*fmA>5m&@p zu4D^Ch7h^-DLsEg&4za=eYV9RvpLF@GY~lX56aUtWny%3Ds)iI^SA7c0vla4A~VeyZq0|QaiEs_B;1Inv!2`bIf(ETcJv-?N1r@9 zPF%;827{Q}cCPe~@QQvhSGIW*l(@y6wRS_fHC)4hFO;j~u6yGpITR*x_qxEy?;GyB z4bAYtMmr`y;a(1a;h1QZ!aD<|D_0r&Lm=U9Rm|fQNSLomt-4AS7p9uapd#YD3Tyv<|A5(>h_o*=nC4C>9*6E_dGmPeiKE=6?qQE7binkKz5NtWZCH0%?>_ z)vu!a-~m>X6x4{u^IVgr1Y<{6&4Pctg2cBq+gBbS@+#8&=`;elI%qCDG-I5uRU6)i zx!%*7OEq{!f!c&$a*!FLot54Tq7B;F8=zdub?w|NC>^BJ&bK6jkV(6PhT#2^r0ux( zHq6$d?Q%pHRGImNV01dwZhn4SD>6>yiyxy?d1nG+i2|4K+xkox*YSJapvHlv{QlbG zAasl`y*mr$)$oT~QFAteuPoXF$a}%G?R=wK4DJuI@{fLB z0O_K2%*FLMkghY=HGxo!F6BWn%(PyY-GheVuhuQU&4T#`-De-WKthAg@*_$#Vz$mU z6^glC)w|SzK$u?dU4{9;+xk(lYv7f;`jjNpIx%0L7MV>np+%pb2qof{>SymQL_qIi z{gSt3X07^tFW*H5_w`k~@C=2|_02~h-PqIm8~1=?IQ=~f2(o`OsLFkD;ZsAX=Uxh$RlwL+hDM(+Vd5@BVbY!k=^K2W7CZ3C6Lgi)wn!yBHSEkEIx=nFj6oc>WfE>PZ>{@ z;iB;&#;ecZ39lC8&GG@ z<8nO-*OF_gw&+ge<+UVOH`VxcX4Xeq_J|*9Eq=b%ozl1UzBX5DG6|iTHNIC0NT~Q% zZJ0HtCX0mX>4Q5{`P3W^i2>)(~Z!!U1m zP_TH?kRp$MHmp_iO*Ku`IK0Bx!7!y_s>39ee9oFFiVh(zO+Qtfv&JK0fz6|OXj8Sd zsHs|NclbBMj1ya&%u1owB=$SyI6KKvWEtv(wyyum@V@g_wW=xk(*Bw(@u{;}tFe{b z^p?{X-CWGfO)<*F%SoOh;i5y;9uh3)upBQgatTyeDotF(EDN$%OqTJfm6i^|g0nb~k({K|c#*zX?4tQ13sMN5l^4QCXW z*NP<`2?nRutjgCUTsdiDn(L&y9!5sTS9G7zB4t!r`oXi=#LCr{YDWD|spjQLsOlbO zR{S;)6UT7vsnJt zRQAp+>uTxQTXPugW|@gxaB+IPo49&_PUYKP}Y`LGv8iO>1o`T%%~7r0!J=H z4%E;M*Dl65loraauHP;-$|mT@YPfGNf%KPzvkLb7nmZX{esa3EKaHVqq{otQ$F-r$ d{ubn-STr_Qd0y&BmNbkY7ESfUf7#SE{{dW0I-~#q delta 2737 zcmZuzX;c(v7Jb!S)l2n;$R=yCi3qZUhGCH?JMLo8Aqt~|7}Thv8BmNU$*2Rk=ad=~ z(YS!i*r=gE!Jq>jpuxCcfT#yh#wBW^CdSEVRAg?;oH_Gje$=^D-}1iu?z`{nZY^W> zlrh^}iw+XW`iVv*6UlRd^MNaX8-SkzO++l_4cSCoFj3GIU<^^PJ8%}(6c3`$b0Wnr zL_=DLly1O#z$hYH6|jLwe}+hFAsX(CrxWAji2Sgw$aXnitP3v^C9NYeYKX>{;2UD6byG z;czK3_$meHaKJUUr>?-C`IuvkpV6MsF50Bx@gRpf(u8(AVZZlDUN#=X^7EySr zESb-P60>BPHpti*D%;bk#`-0))0;pnyk2&0+!i96dRa#r;tEPxZyP)lxmd1=Dr^ipEpPH$ z1LHoHU$%Wl#B7m2&#!>M0c_HPFA*<_opV?Mv0`??I1CS2$gaHgHj&p&wlEt+l^k2l zJ|&87VvBZ-tA~qcuy4>NV-Ouu2hmH#mX*WVq2BC)J2}8C)^vFXk*_CP{eC%7vcT49 zttB(C-+bSV@%8LCKRhNHI-I>VrW&SIa(o0zk&wgbHZFs*E?k1%7o{D`Wz0dTqGuFw zx%@ep=q0z%2N@WTa|^9zU(+aRz|`O~xm=>Oz#%3rSygJjvt zXFot9d5`jC3@#7%2dV`BCbY{X)p$9W+dNgxd-M`g*Qhq}mdxvllA!uW_~jJ7Y%? z0(vgdE}m>5;`az3X{$a#8w#tmZTlcu*aq!|ZeVDSwz~zy*iN0I!UqR-=z`s@ zB7rHosQyy)^A2655%WGNy3;FwvES;Nybi&{UAm@t;7FD3{AhSV6RYdYKzllHdi$cI z6_{w$I~OB!yOnyc=LwLgS0CAjn<~s-KVcK3vpb_-7M}z+JLyYz;~oeY(C@i77M}Qv z{%_?tC~AoQ?7!dz_mlcdW82~OTL#t7xItC%2D>=4cQj*g`2ICfgwc?C2l0$o4NG$G zLLrSIaND)@sQm|q&*m+GRL>26U;2tD?!2M*{$5Bv+0d7K9N#Vr;GEl1v~q~d#krxC zgew!J^twh8&L!4UeaUx`Bv{th`ie``EiTTMZPIlTDi<||S`snNcI8>uwOpv4BfiUb z46!jSZB-3u8!B5}Ng!Ve6~}0d-czf7Gxu4>l2Gqd-DB<{p?P&BHMf%>UAJU(d)9^$dzd5aIVM(uzH8UYT* zBZ!RNMNHAfTIb#T{lycyWb5lQT_LAxu5GTCKGb(I%uaENP3mB*JvKo$|I4T9$L2)o zrp<2*V-&C3dNYCIfNie&&E7_#y;od0bOXmWC!XFV@^;=F+fsP`tQcYE&0G*?+PT|W zKk-XsQ?;Fh7N5ETOm46nAywPOFiORL2AV#O4P;Yvm8 ztFBVBlk|auo>8kv_$tz}ZGaI)$LSjF#mvS{By=UVY?mH6Ix%c>dwYYV9+t*vcuJs& zltghfO`PqV<+0APtueAIlLXV*+RWzElht*FBz!mBQqYxQ?y2<=uQ~_vZKdX(>L;~X z1J2@OA%y?0g3HAOml#Hn*0^{uGE1WPg=?I~=3-{$tHEf}BUe4cv8KM`YDwYVW?(O6 z)D=n{qy8voSScpdTgIsxeJ*8)^TL7|g|s_ND`QP(O?~3A@NV&NxK0uy6pXFa6ILpw zedd~~*5ec3)N(0n`l!Jqc|^`+xGk2vR#sdS<$xp`UB#VI9%^J`Rmrkmtc|+DS|f;? zqXXW&NcGV_GL9iuzgV`xD|vP6;5a|4=g3bKV!g$#(b1zK{{K8yrqBY)qg2YLY^xL7 z%S|MO#GaAqwC3{mMYTB)y|v}2q#1jN@f$&lX(`RezcQgYvFZYLzmJh%nqLcojhm$= z5;`-@J<^T16EYaAHcR{@ae|9LZ;{bTA7!vN_gY3 Enter new tethering password - 새 테더링 비밀번호 입력 + 새 테더링 비밀번호를 입력하세요 @@ -70,7 +70,7 @@ leave blank for automatic configuration - 자동 구성을 위해 비워둠 + 자동설정을 하려면 공백으로 두세요 @@ -92,7 +92,7 @@ You must accept the Terms and Conditions in order to use openpilot. - 당신은 반드시 약관에 동의해야만 openpilot을 사용할 수 있습니다. + openpilot을 사용하려면 이용 약관에 동의해야 합니다. @@ -102,7 +102,7 @@ Decline, uninstall %1 - 거절,삭제 %1 + 거절, %1 제거 @@ -135,7 +135,7 @@ Preview the driver facing camera to help optimize device mounting position for best driver monitoring experience. (vehicle must be off) - 운전자 카메라를 미리 보면서 최적의 운전자 모니터링 경험을 위해 기기 장착 위치를 최적화할수 있습니다. (차량은 반드시 닫아야 합니다) + 운전자 카메라를 미리 보면서 최적의 운전자 모니터링 경험을 위해 장치의 장착 위치를 최적화할수 있습니다. (차량연결은 해제되어있어야 합니다) @@ -150,7 +150,7 @@ Are you sure you want to reset calibration? - 캘리브레이션을 재설정하시겠습니까? + 캘리브레이션을 재설정하시겠습니까? @@ -165,12 +165,12 @@ Review the rules, features, and limitations of openpilot - openpilot의 규칙, 기능, 제한 다시보기 + openpilot의 규칙, 기능 및 제한 다시보기 Are you sure you want to review the training guide? - 트레이닝 가이드를 다시보시겠습니까? + 트레이닝 가이드를 다시보시겠습니까? @@ -185,7 +185,7 @@ Change Language - 언어변경 + 언어 변경 @@ -195,7 +195,7 @@ Select a language - 언어선택 + 언어를 선택하세요 @@ -210,37 +210,37 @@ openpilot requires the device to be mounted within 4° left or right and within 5° up or 8° down. openpilot is continuously calibrating, resetting is rarely required. - openpilot은 장치를 왼쪽 또는 오른쪽 4° 이내, 위쪽 5° 또는 아래쪽 8° 이내로 설치해야 합니다. openpilot은 지속적으로 보정되므로 리셋이 거의 필요하지 않습니다. + openpilot은 장치를 좌측 또는 우측은 4° 이내, 위쪽 5° 또는 아래쪽은 8° 이내로 설치해야 합니다. openpilot은 지속적으로 보정되므로 리셋이 거의 필요하지 않습니다. Your device is pointed %1° %2 and %3° %4. - 사용자의 기기가 %1° %2 및 %3° %4를 가리키고 있습니다. + 사용자의 장치가 %1° %2 및 %3° %4를 가리키고 있습니다. down - 아래 + 아래로 up - + 위로 left - 왼쪽 + 좌측으로 right - 오른쪽 + 우측으로 Are you sure you want to reboot? - 재부팅 하시겠습니까? + 재부팅 하시겠습니까? @@ -250,7 +250,7 @@ Are you sure you want to power off? - 전원을 종료하시겠습니까? + 전원을 종료하시겠습니까? @@ -263,7 +263,7 @@ Drives - 주행수 + 주행 @@ -273,7 +273,7 @@ ALL TIME - 전체 시간 + 전체 @@ -309,12 +309,12 @@ Need at least - 최소 필요 + 최소 characters! - 문자! + 자가 필요합니다! @@ -345,7 +345,7 @@ eta - 에타 + 도착 @@ -401,7 +401,7 @@ CLEAR - CLEAR + 삭제 @@ -411,14 +411,14 @@ Try the Navigation Beta - 네비게이션(베타)을 사용해보세요 + 네비게이션(베타)를 사용해보세요 - Get turn-by-turn directions displayed and more with a comma + Get turn-by-turn directions displayed and more with a comma prime subscription. Sign up now: https://connect.comma.ai - 자세한 경로안내를 확인하시려면 comma prime을 구독하세요. -즉시등록:https://connect.comma.ai + 자세한 경로안내를 원하시면 comma prime을 구독하세요. +등록:https://connect.comma.ai @@ -437,7 +437,7 @@ location set no recent destinations - 최근 경로 없음 + 최근 목적지 없음 @@ -471,7 +471,7 @@ location set Advanced - 고급 + 고급 설정 @@ -775,12 +775,12 @@ location set Getting Started - 시작 + 설정 시작 Before we get on the road, let’s finish installation and cover some details. - 출발하기 전에 설치를 완료하고 몇 가지 세부 사항을 살펴보겠습니다. + 출발하기 전에 설정을 완료하고 몇 가지 세부 사항을 살펴보겠습니다. @@ -859,7 +859,7 @@ location set Finish Setup - 설치완료 + 설정 완료 @@ -869,7 +869,7 @@ location set Pair device - 페어링 + 장치 페어링 @@ -911,12 +911,12 @@ location set GOOD - 경고 + 좋음 OK - 좋음 + 경고 @@ -1009,7 +1009,7 @@ location set The last time openpilot successfully checked for an update. The updater only runs while the car is off. - 이전에 openpilot에서 업데이트를 성공적으로 확인한 시간입니다. 업데이트 프로그램은 차량 연결이 해제되었을때만 작동합니다. + 최근에 openpilot이 업데이트를 성공적으로 확인했습니다. 업데이트 프로그램은 차량 연결이 해제되었을때만 작동합니다. @@ -1019,22 +1019,22 @@ location set CHECKING - 검사중 + 확인중 Uninstall - 삭제 + 제거 UNINSTALL - 삭제 + 제거 Are you sure you want to uninstall? - 삭제하시겠습니까? + 제거하시겠습니까? @@ -1084,7 +1084,7 @@ location set Username '%1' has no keys on GitHub - 사용자 이름 '%1' GitHub에 키가 없습니다 + '%1'의 키가 GitHub에 없습니다 @@ -1094,7 +1094,7 @@ location set Username '%1' doesn't exist on GitHub - 사용자 이름 '%1' GitHub에 없습니다 + '%1'은 GitHub에 없습니다 @@ -1120,7 +1120,7 @@ location set Scroll to accept - 스크롤 허용 + 허용하려면 아래로 스크롤하세요 @@ -1168,12 +1168,12 @@ location set Display speed in km/h instead of mph. - mph가 아닌 km/h로 속도 표시. + mph 대신 km/h로 속도를 표시합니다. Record and Upload Driver Camera - 운전자 카메라 기록 및 업로드 + 운전자 카메라 녹화 및 업로드 @@ -1193,7 +1193,7 @@ location set Show ETA in 24h format - 24시간 형식으로 ETA 표시 + 24시간 형식으로 도착예정시간 표시 @@ -1275,7 +1275,7 @@ location set Forget Wi-Fi Network " - wifi 네트워크 저장안함" + wifi 네트워크 저장안함 " diff --git a/selfdrive/ui/translations/main_zh-CHS.qm b/selfdrive/ui/translations/main_zh-CHS.qm index 63c17d76b7f0f99e5180d400a8143d17cbbdde55..45fae52b4286bb3e57938bf6c7c4ad53d3bd3ba1 100644 GIT binary patch delta 1686 zcmX9;2~1R16g@NZ|15uI{(uZ%Q3M8%MP#XfvdNZ$pal^W<5G=6QL8q#S|l!`ts9~U z!Ch1ka4EGWxYm6^EGW2PG$j~R5H(t;HI-<<9>XM)lmGsI_nmvrxv#NEajQsC2XL?@uH||?FuxqI`2qN`kN6%~{P}%x@f(+*dl1&|0Y<-tu(KUd zNDyj+xoH}N#xuk!2)6~mWgx_juB3CPBue3E&4FfEGoXKhKoe0aLt_0hV0Z-*Uz`Mj zS7MBA7GT?eKD6^Gn#I7UQ4rH2Zc;Sn-bEHz7lLjq4MUF>5tXS%FE1 zDgj+CCMRtr)o@HXyc~!gkLg#~j&-;@7Gzmi-~^WTvVd_m${U)1m=UO1{0-ofgIc>( zU`Pu(HZI}&8ihlcAKs#;-~~lUA=M9xR;1PW0G_^z-4D1P=AmfH5Lnl$c%-ZV zoD&rwxz)rDw-eSP}F|nIJ7Dvop$RHtaa?wQ_H>jvGppr#F$M1FpH;P9D@*Pw2U+h4GY=gngLYwV5(Tyi7V@5s23%hV%V&|1 zI!{ zOFctys~@8s#1FkB7!agZx@9n3x7Bi&KNT!eN4`v;f`6$KYc2rctJPB#)ZSB2SM>A& zZkg)y{=2MXzDoTe^#Ristg-k|GVfGPmD4Zmut{@l;WHALr0JS)fD&%fynjVyRA)6G zBRXmJ0ByWaEoZ(}o2(*X(>ZPSn~x;ALc4j%ZeVbsc7HYN*zMGw>~QCEx=v%9!4S>S zxtD4=F5`5uZ%eubv-P%a>NH9_G+vig$NBR1(iMWK!hT(IOA1p|u4}dZo)<^86gw<{ z9m!JGokn(;DCNI&=2XujMzOPUsi4!u=Q?R?A1(EKEbTmB!E~CX(nk|%O^>v%kru0Z zrK20RvLU5(Hc(^+f~%yfIov1;Qmr(E*T)s9)*+IF9!M`{FQ!zUdc~=glr~rIe)&2H zIp`A}=K}+L_0ym7B5+@!Uvys}@qGR2pUm98Wc$BvpEN0{B zTw++BvDR{s)~6e5;|?+dUO~o&NO~{LHa1V@IGWeV_D8C?-XlA$rvi4avZW^;2vN(U z+IRy6bjxEmQ9`?^@}jt}7+ya)e-8)T2lC#|7-nId{A(o-3W<>~{KpIoZjqZ}?l9aD zCT%ybMopc`9LsSIwJ|w7x9{Uk(`Xvg&VoVPO$&26=-t8+qsGzUw5j#QKJxA|wI%!x bL|Wzou>+2WYf1+wmXtjFBI3B6Q@H>CHZ-~4 delta 1659 zcmX9;dsK{R9Dcr;@0)3E-_UK=CDnAN`=(W-(rzRqk}T~yNU_*sH`2Nc8yj+|ovd3( zigjt7le^>6u0)|YSe=bsBIK}ImlaO!KF-WP&zblA-rxKDp6B_!mkWg}g+ifcY$~A4 z1o|!@<`B0KHxf?)VkaO615yys?>TWG;2%z$$Zs-iXx>tk;UgR-E5_oj|v5fN#5qZ-DF%`#%;va}Bu;F@GyC_$9c?jC}TL~SXC)-41A$}#lu5g^Qh zVVWsG_j(Ku-+⋘WIj-X^$kEw7^t%hQvarE6yaW z1B}ZR*OOVePk`c19c>IetGHY0#DYteVxS3dOi{W#m3Z#4(p(Tt1(THXl3DkYiOT&l ziTfLsRYym&PKWYj70(6dDQkR|Sg$F1S+0wd_Z%XFR&hoG1@0Cm=C%w5+}gxNQ^-h_ zE9Q$Yf$)psrUZsd8D>MH*@lkQHgxk8OUgUQELtpkFpX#t4>WE7%;&_zUzJnREb)Y% z-WcwPmmW3)9`53$Cx6p}?(Jer^kL@BB5A{^dDIKZP%sx5&?v>pUZkETrA?+M;gh9I z?HNF?k!E^UQ1dy`%*s79x0J{%+WAVk(>V?Pd!>b8GB0>775qdZntB_$M%mD9whg2A zNhSTt>49UrRI;9_&}B&FKdb;u_R_%%cd3z^^jjx2SFD%LxnERr-Jrmer)>_^FbN2@D(=CQ*@^}#v!Ng!4Id`uZ7T&sTF)B~{ZtA6u@ z3Mo&j-w%95(;e*M{AxJ+e_AU=(}eYQJNEOm!)Ci9tsX${6ph;OC8IM#<56PAAsMNO zeZiMQuGEZ6d_dj(HK}>jE9R>AG%B(JuDPfp) zRhtV3c`7lA&6H^i9vS)ng0{GeE_(f?-E?Xf1L>qKX&Og2-fFjBp{vSHZRN^h-lEi= z43@}Zw{@{(viz=nJT;qAca_RXieS91(i|Vc)J|Laad+QU2u(!x+ zed-3*b1l@*9!1s`X}o^pyYZZtMtxNg=cdn2eO)QV2p*%q+)NDY(l^(Vn7GcMs_^86 ziH0DTTO<-;i0E9!`8#W<4CB7p$#5)(81bE<#=M)Bjy2Q_A^LIczM?Nq~!G)|dg zzU;KOg6nVPp844fpM$$>?uY~WtK|WA`LYE4BPXt*P7aggxkElzt1p?>yel7TS$><9`7LdCUM}9S%jROYDXD)>}OW M3T}t&dqxKS50wtHa{vGU diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts index 9ac35994e6..04bd2415f0 100644 --- a/selfdrive/ui/translations/main_zh-CHS.ts +++ b/selfdrive/ui/translations/main_zh-CHS.ts @@ -415,7 +415,7 @@ - Get turn-by-turn directions displayed and more with a comma + Get turn-by-turn directions displayed and more with a comma prime subscription. Sign up now: https://connect.comma.ai 订阅comma prime以获取导航。 立即注册:https://connect.comma.ai diff --git a/selfdrive/ui/translations/main_zh-CHT.qm b/selfdrive/ui/translations/main_zh-CHT.qm index 208f29c0ec9dd45424301c70cdaf64c2e9a901bc..130bcfc92670cff84c6c6fcf359be599e4941e3e 100644 GIT binary patch delta 1686 zcmX9;3sg;M7~SXGbME8Zd(V|_H=@_Atco_OWJPd^Q z#Q?*2z@;3C5v%e3mzWhts%h`G6I72WX?6zKi&@PKV4i?&7ixf*2`HP%JiA1~=}LvY zN^x&lCinLXwq8Mif3nbSvp>-3hR~yc>W9<|DV1Hg{zBMro$I~yLd{T#akGS*;ts$w zSa|foBA|m!R5H#1oi~XA_iiHxp_{~bWhR+z5J$IR#vzNuO|=GIm?9ooPGVuQcru{? zu*?##r7*CUB-U54jE<3F!&Wy2%+W{=cfdMG@FO4ldNCuVC!~_c5#$TF!yD#8VF3lNFM%u;F zQt2fSu|-;!P(cGZTG3)_MeC7P^lp@jOPW}_$I|w@X=G@Z_Fi5M*q2C$zAB-lYo((m z*2essbn$*2*Y8RfA3tRcT>g-5M<1f!vSlTLn)h{)&H2-To@H`BHGrwO$|J_ICJ_O0 zhH?@x$?_!soj|BTp0ux&#obDL1?X+^>@Q~Ve43mct^$6?wA^1YLM&dNyx9Qd}m=5 zi@mB9qvPc_%_Qik){4GE>8^KL^_hbTj?wmc6i)^3Yx|d-0D8~WjuNQ7|0V5?rWU~0 zQ(NI!pF`$TwQrKH(`|a4y$dDl9H`srv5*-~(jAz3hXj&!&xUNLgcZ71kEx8NT=zEe z0no8Y->-|4?XX*)s3Bp?9({V_TN2IEugKiM{crVK_AriXf&TD4KYsT&=*;YYuNZ@0 zv7YTB8Dd`)J(sLGI>V^Zl(v&#NULOj1->;DfUd$8Lv7t)x+vRF?=p>pne88oqDDC<}j9~Oxaw`5^LTn z`*K$?p)loGh)fTJrz>YNcu{VvI2A9Bj}wa1#yQk!kMeNBOg{9?D3s5mw53MBQ|IV~ zr^fhOc|cp6G4(bFfnTg~`ZbBlO)xI_#>)Gzjg?PWlEALU^Mk06o4d(+iUfjxGWnKq zJ>aS-IBGV%(PWD6ca(IG@OxqzrnPTAWq|pn zvO@Nk*Vm@1ttvgzXu4EKbgVbkRg$3ey;-}{pAW{FyLmYS{+($I8L(SXB2Jc*}Zh8KT9KN3CeV+I2c|V>v`V#ssMS80tqV#oEib;lW32A9U z5*3CxD`FPM2#b{&hSSg}@-ZB2zE<0{)AP@Dp5J}nzx(=K*Y9`d77BTV!Y0oM3!q5_ z28<(S64QuVi0c8V6Ho^LvOnNkMI1qVNlfIP8QthUy)eaF_@Z!wO9UfvxjgwE81pH2 zh5`wJfbI!#4q(?s%w~KouwWNpJsnugnDu=io$L1Lg@3vPZh@4u9SC!SRMG|rDx`+N zJmd(e={PY7(q##7z6*JsD=@I2C{%FBii6Jg8eq7K05eg)2QiJy0l!Iz={O1u4#OxV z3FuLWxS(SE|HWlSlInHDFDPP>BF6o}+w5*&{L0tdUw{eXS;pfrA!#*l3Bjbjm4K3o z$+4SB)dN%Ztsu+QnD%2MkTviQ7ACthK{b|kGJ$Cpc3o@+!jn;x&N};tpur}dwD+NX z-4d=J66}Kq0-gy%uQE@d-wk2NMyelhM@Tr|pYd11w(E=sD?;-GiFua_H^mCT$s#-& z^cB#@LDZ+71ANLvul9S$LSUH~txqSj?c!8xRveHm?zpD#K$>`LJ&Ap!6;H)(1k6jt zs|if(EQ_}rX`>}kY%RBA!Y?(F#R0G#t8scN^V}JYdwv)z|5vjlfq91x(i~7p+_zCv zQ^!^@cW6%3@LWJ2O@sHUqAOybtVU_(-dZxaAkB@Xz}BA9vU?)|*JIL(Br?)wOF7aj zAgEj_iLGY?S-R0|-;K7%yV2#DR9g9#-aV0awfjr7KJ zOS<%+h4FUj(&K0JpvUjhy|5$fx8<@vh?a0mEwLDAkLl*vgY<(vzTma;p9m zV3g%~o>f4gUY=LIm*$oe-vCzj^0L`Wxj#i-K3D}jevtFOAra+bH@axL(RFAyhW#d& z`c~2d+YY(3fL&ool`Gd~Q;FB|;R~&Rf4zLBlbVb9@>#bl?5b9|r>y+0-M@zGWFUc(CK>kg;gCxLOg=i_%X@k!lZHyweV_PRHZsgR~l z_hH0Cpzk}YsQwKci~U8_lEdd~tacvYX`2G8qwOAC9i`|@oN?y}#iP`ULn12?FZpt) z70SfXZPYzLnY4y_MOZ0`Q>kx1QAs`@33&gbYy?{iJC$oKW7$e8ikxJJ*q-{lM^1o? zACWJGSB5_Sp_%`M`psQ*(QB8!q`ra;spv~@PNW;P`m!dvs`;R=&fUx!2I)@($Ye3Q zXr=6sbx_|iE1gokFbH+4IGFnk9;eUI>*t1P_c-7lk%mQAB`T6^Se;?ZXXTyY{8LKp z?Q8hy6IN{3%V>L=xA=W$bgN<9>sO;+=rVf#))*Z{%R=ppal@ujdTZn8NY*yI-Z-h4 z`CO(L7mg+CEIHM<<^5+&u-aHt$hmP|Y-}v282-^Y6|Ym4s!uUpo6IS*%~I{Y ztzx`M?VXd(=Cd)W?r)>0$7OX`D_<7>4eIFi)X8S7x+wBvHl;<)+s?uDxvuVb7|sC> zSNB))q9KZU@^8A__l(*c{tMvXY_@vACr?*rwvFJJ4rwvlKj`8El3^az#(aT;%xS6Z zR4B^4>1H-vonzjbl2+uXGuWRn-|i^mKpru-Mjrw~T;{SF;%kTNa(fCHMQ0sH2(GnV Ij_WM{0lCk!tN;K2 diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts index 2920916ece..806dd54ad3 100644 --- a/selfdrive/ui/translations/main_zh-CHT.ts +++ b/selfdrive/ui/translations/main_zh-CHT.ts @@ -415,16 +415,11 @@ - Get turn-by-turn directions displayed and more with a comma + Get turn-by-turn directions displayed and more with a comma prime subscription. Sign up now: https://connect.comma.ai 成為 comma 高級會員來使用導航功能 立即註冊:https://connect.comma.ai - - Get turn-by-turn directions displayed and more with a comma -prime subscription. Sign up now: https://connect.comma.ai - 成為 comma 高級會員來使用導航功能,立即註冊:https://connect.comma.ai - No home From 2ae52e9b2218c23d4c80b36fb0b50387b6ecdd8f Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Mon, 11 Jul 2022 17:20:56 -0700 Subject: [PATCH 080/112] process replay: ensure enabled for significant amount of time (#25121) * process replay: ensure enabled for significant amount of time * update refs * 10s is reasonable --- selfdrive/controls/controlsd.py | 3 ++- selfdrive/test/process_replay/process_replay.py | 11 +++++++++-- selfdrive/test/process_replay/ref_commit | 2 +- selfdrive/test/process_replay/test_processes.py | 16 ++++++++-------- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index 117509f1e6..b344705f9d 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -406,7 +406,8 @@ class Controls: if not self.initialized: all_valid = CS.canValid and self.sm.all_checks() - if all_valid or self.sm.frame * DT_CTRL > 3.5 or SIMULATION: + timed_out = self.sm.frame * DT_CTRL > (6. if REPLAY else 3.5) + if all_valid or timed_out or SIMULATION: if not self.read_only: self.CI.init(self.CP, self.can_sock, self.pm.sock['sendcan']) self.initialized = True diff --git a/selfdrive/test/process_replay/process_replay.py b/selfdrive/test/process_replay/process_replay.py index c667aa3887..bea7dc46ee 100755 --- a/selfdrive/test/process_replay/process_replay.py +++ b/selfdrive/test/process_replay/process_replay.py @@ -14,6 +14,7 @@ from cereal import car, log from cereal.services import service_list from common.params import Params from common.timeout import Timeout +from common.realtime import DT_CTRL from panda.python import ALTERNATIVE_EXPERIENCE from selfdrive.car.car_helpers import get_car, interfaces from selfdrive.test.process_replay.helpers import OpenpilotPrefix @@ -548,11 +549,17 @@ def cpp_replay_process(cfg, lr, fingerprint=None): def check_enabled(msgs): + cur_enabled_count = 0 + max_enabled_count = 0 for msg in msgs: if msg.which() == "carParams": if msg.carParams.notCar: return True elif msg.which() == "controlsState": if msg.controlsState.active: - return True - return False + cur_enabled_count += 1 + else: + cur_enabled_count = 0 + max_enabled_count = max(max_enabled_count, cur_enabled_count) + + return max_enabled_count > int(10. / DT_CTRL) diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index fc5f83c32a..bef6956ec3 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -d583bbd9643000e7f817171c583d31ae3141a652 \ No newline at end of file +998b457e0d38e3639814ed81cb2d32e92d9bed8c \ No newline at end of file diff --git a/selfdrive/test/process_replay/test_processes.py b/selfdrive/test/process_replay/test_processes.py index 652c49db3d..91cc40f5ce 100755 --- a/selfdrive/test/process_replay/test_processes.py +++ b/selfdrive/test/process_replay/test_processes.py @@ -18,14 +18,14 @@ from tools.lib.logreader import LogReader original_segments = [ ("BODY", "937ccb7243511b65|2022-05-24--16-03-09--1"), # COMMA.BODY ("HYUNDAI", "02c45f73a2e5c6e9|2021-01-01--19-08-22--1"), # HYUNDAI.SONATA - ("HYUNDAI", "d824e27e8c60172c|2022-07-08--21-21-15--1"), # HYUNDAI.KIA_EV6 + ("HYUNDAI", "d824e27e8c60172c|2022-07-08--21-21-15--0"), # HYUNDAI.KIA_EV6 ("TOYOTA", "0982d79ebb0de295|2021-01-04--17-13-21--13"), # TOYOTA.PRIUS (INDI) ("TOYOTA2", "0982d79ebb0de295|2021-01-03--20-03-36--6"), # TOYOTA.RAV4 (LQR) ("TOYOTA3", "f7d7e3538cda1a2a|2021-08-16--08-55-34--6"), # TOYOTA.COROLLA_TSS2 ("HONDA", "eb140f119469d9ab|2021-06-12--10-46-24--27"), # HONDA.CIVIC (NIDEC) ("HONDA2", "7d2244f34d1bbcda|2021-06-25--12-25-37--26"), # HONDA.ACCORD (BOSCH) ("CHRYSLER", "4deb27de11bee626|2021-02-20--11-28-55--8"), # CHRYSLER.PACIFICA - ("RAM", "2f4452b03ccb98f0|2022-07-07--08-01-56--2"), # CHRYSLER.RAM_1500 + ("RAM", "2f4452b03ccb98f0|2022-07-07--08-01-56--3"), # CHRYSLER.RAM_1500 ("SUBARU", "4d70bc5e608678be|2021-01-15--17-02-04--5"), # SUBARU.IMPREZA ("GM", "0c58b6a25109da2b|2021-02-23--16-35-50--11"), # GM.VOLT ("NISSAN", "35336926920f3571|2021-02-12--18-38-48--46"), # NISSAN.XTRAIL @@ -39,13 +39,14 @@ original_segments = [ segments = [ ("BODY", "regen660D86654BA|2022-07-06--14-27-15--0"), ("HYUNDAI", "regen657E25856BB|2022-07-06--14-26-51--0"), + ("HYUNDAI", "d824e27e8c60172c|2022-07-08--21-21-15--0"), ("TOYOTA", "regenBA97410FBEC|2022-07-06--14-26-49--0"), ("TOYOTA2", "regenDEDB1D9C991|2022-07-06--14-54-08--0"), ("TOYOTA3", "regenDDC1FE60734|2022-07-06--14-32-06--0"), ("HONDA", "regen17B09D158B8|2022-07-06--14-31-46--0"), ("HONDA2", "regen041739C3E9A|2022-07-06--15-08-02--0"), ("CHRYSLER", "regenBB2F9C1425C|2022-07-06--14-31-41--0"), - ("RAM", "2f4452b03ccb98f0|2022-07-07--08-01-56--2"), + ("RAM", "2f4452b03ccb98f0|2022-07-07--08-01-56--3"), ("SUBARU", "regen732B69F33B1|2022-07-06--14-36-18--0"), ("GM", "regen01D09D915B5|2022-07-06--14-36-20--0"), ("NISSAN", "regenEA6FB2773F5|2022-07-06--14-58-23--0"), @@ -65,7 +66,7 @@ def run_test_process(data): res = None if not args.upload_only: lr = LogReader.from_bytes(lr_dat) - res, log_msgs = test_process(cfg, lr, ref_log_path, args.ignore_fields, args.ignore_msgs) + res, log_msgs = test_process(cfg, lr, ref_log_path, cur_log_fn, args.ignore_fields, args.ignore_msgs) # save logs so we can upload when updating refs save_log(cur_log_fn, log_msgs) @@ -83,7 +84,7 @@ def get_log_data(segment): return (segment, f.read()) -def test_process(cfg, lr, ref_log_path, ignore_fields=None, ignore_msgs=None): +def test_process(cfg, lr, ref_log_path, new_log_path, ignore_fields=None, ignore_msgs=None): if ignore_fields is None: ignore_fields = [] if ignore_msgs is None: @@ -96,7 +97,7 @@ def test_process(cfg, lr, ref_log_path, ignore_fields=None, ignore_msgs=None): # check to make sure openpilot is engaged in the route if cfg.proc_name == "controlsd": if not check_enabled(log_msgs): - raise Exception(f"Route never enabled: {ref_log_path}") + return f"Route did not enable at all or for long enough: {new_log_path}", log_msgs try: return compare_logs(ref_log_msgs, log_msgs, ignore_fields + cfg.ignore, ignore_msgs, cfg.tolerance), log_msgs @@ -216,8 +217,7 @@ if __name__ == "__main__": results: Any = defaultdict(dict) p2 = pool.map(run_test_process, pool_args) for (segment, proc, subtest_name, result) in tqdm(p2, desc="Running Tests", total=len(pool_args)): - if isinstance(result, list): - results[segment][proc + subtest_name] = result + results[segment][proc + subtest_name] = result diff1, diff2, failed = format_diff(results, ref_commit) if not upload: From 29c8e5d227eacae36dbc4357bf5328f22668d5ef Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Mon, 11 Jul 2022 17:26:59 -0700 Subject: [PATCH 081/112] Chrysler: increase Ram torque rate limit --- selfdrive/car/chrysler/values.py | 4 ++-- selfdrive/test/process_replay/ref_commit | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/selfdrive/car/chrysler/values.py b/selfdrive/car/chrysler/values.py index f7531792fb..69dade4b64 100644 --- a/selfdrive/car/chrysler/values.py +++ b/selfdrive/car/chrysler/values.py @@ -31,8 +31,8 @@ class CarControllerParams: self.STEER_ERROR_MAX = 80 if CP.carFingerprint in RAM_CARS: - self.STEER_DELTA_UP = 5 - self.STEER_DELTA_DOWN = 5 + self.STEER_DELTA_UP = 6 + self.STEER_DELTA_DOWN = 6 else: self.STEER_DELTA_UP = 3 self.STEER_DELTA_DOWN = 3 diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index bef6956ec3..d98ae96516 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -998b457e0d38e3639814ed81cb2d32e92d9bed8c \ No newline at end of file +2ae52e9b2218c23d4c80b36fb0b50387b6ecdd8f \ No newline at end of file From 045c881e1ffeb5e7bcb8e1ee78d4a42caee1be4d Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Mon, 11 Jul 2022 21:11:12 -0700 Subject: [PATCH 082/112] couple more stinger MYs supported --- docs/CARS.md | 2 +- selfdrive/car/hyundai/values.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/CARS.md b/docs/CARS.md index eb570faa7e..5e185ed278 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -105,7 +105,7 @@ How We Rate The Cars |Kia|Seltos 2021|SCC + LKAS|||||| |Kia|Sorento 2018|SCC + LKAS|||||| |Kia|Sorento 2019|SCC + LKAS|||||| -|Kia|Stinger 2018|SCC + LKAS|||||| +|Kia|Stinger 2018-20|SCC + LKAS|||||| |Lexus|CT Hybrid 2017-18|LSS|[3](#footnotes)||||| |Lexus|ES Hybrid 2017-18|LSS|[3](#footnotes)||||| |Lexus|NX 2018-19|All|[3](#footnotes)||||| diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index 4b3acf3f27..2e6a2017ea 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -151,7 +151,7 @@ CAR_INFO: Dict[str, Optional[Union[HyundaiCarInfo, List[HyundaiCarInfo]]]] = { HyundaiCarInfo("Kia Sorento 2018", video_link="https://www.youtube.com/watch?v=Fkh3s6WHJz8", harness=Harness.hyundai_c), HyundaiCarInfo("Kia Sorento 2019", video_link="https://www.youtube.com/watch?v=Fkh3s6WHJz8", harness=Harness.hyundai_e), ], - CAR.KIA_STINGER: HyundaiCarInfo("Kia Stinger 2018", video_link="https://www.youtube.com/watch?v=MJ94qoofYw0", harness=Harness.hyundai_c), + CAR.KIA_STINGER: HyundaiCarInfo("Kia Stinger 2018-20", video_link="https://www.youtube.com/watch?v=MJ94qoofYw0", harness=Harness.hyundai_c), CAR.KIA_CEED: HyundaiCarInfo("Kia Ceed 2019", harness=Harness.hyundai_e), CAR.KIA_EV6: HyundaiCarInfo("Kia EV6 2022", "All", harness=Harness.hyundai_p), From 614b3a01f89eabfa9ea26ed2a367592939f78e11 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Mon, 11 Jul 2022 22:10:06 -0700 Subject: [PATCH 083/112] Chrysler: limit buttons to 20Hz (#25125) * Chrysler: limit buttons to 10Hz * cleanup * 20hz --- selfdrive/car/chrysler/carcontroller.py | 20 +++++++++++++++----- selfdrive/test/process_replay/ref_commit | 2 +- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/selfdrive/car/chrysler/carcontroller.py b/selfdrive/car/chrysler/carcontroller.py index a7f2d007f1..8156e7841e 100644 --- a/selfdrive/car/chrysler/carcontroller.py +++ b/selfdrive/car/chrysler/carcontroller.py @@ -1,4 +1,5 @@ from opendbc.can.packer import CANPacker +from common.realtime import DT_CTRL from selfdrive.car import apply_toyota_steer_torque_limits from selfdrive.car.chrysler.chryslercan import create_lkas_hud, create_lkas_command, create_cruise_buttons from selfdrive.car.chrysler.values import RAM_CARS, CarControllerParams @@ -14,6 +15,7 @@ class CarController: self.hud_count = 0 self.last_lkas_falling_edge = 0 self.lkas_active_prev = False + self.last_button_frame = 0 self.packer = CANPacker(dbc_name) self.params = CarControllerParams(CP) @@ -26,11 +28,19 @@ class CarController: # *** control msgs *** - das_bus = 2 if self.CP.carFingerprint in RAM_CARS else 0 - if CC.cruiseControl.cancel: - can_sends.append(create_cruise_buttons(self.packer, CS.button_counter + 1, das_bus, cancel=True)) - elif CC.enabled and CS.out.cruiseState.standstill: - can_sends.append(create_cruise_buttons(self.packer, CS.button_counter + 1, das_bus, resume=True)) + # cruise buttons + if (self.frame - self.last_button_frame)*DT_CTRL > 0.05: + das_bus = 2 if self.CP.carFingerprint in RAM_CARS else 0 + + # ACC cancellation + if CC.cruiseControl.cancel: + self.last_button_frame = self.frame + can_sends.append(create_cruise_buttons(self.packer, CS.button_counter + 1, das_bus, cancel=True)) + + # ACC resume from standstill + elif CC.cruiseControl.resume: + self.last_button_frame = self.frame + can_sends.append(create_cruise_buttons(self.packer, CS.button_counter + 1, das_bus, resume=True)) # HUD alerts if self.frame % 25 == 0: diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index d98ae96516..b165b163ba 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -2ae52e9b2218c23d4c80b36fb0b50387b6ecdd8f \ No newline at end of file +11e721366f1c177a84e6cb8b48171113ac3b54f9 \ No newline at end of file From 4d7b7483d70a61cf0fb938107df55c24f27da1b0 Mon Sep 17 00:00:00 2001 From: Gijs Koning Date: Tue, 12 Jul 2022 12:36:57 +0200 Subject: [PATCH 084/112] Replay: tolerances per field (#25116) * tolerances per field in replay * refactor * Remove laikad parameters * Small comment change --- selfdrive/test/process_replay/compare_logs.py | 22 ++++++++++++++++--- .../test/process_replay/process_replay.py | 2 +- .../test/process_replay/test_processes.py | 2 +- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/selfdrive/test/process_replay/compare_logs.py b/selfdrive/test/process_replay/compare_logs.py index 057e46cd9c..bf6daf5fed 100755 --- a/selfdrive/test/process_replay/compare_logs.py +++ b/selfdrive/test/process_replay/compare_logs.py @@ -46,11 +46,25 @@ def remove_ignored_fields(msg, ignore): return msg.as_reader() -def compare_logs(log1, log2, ignore_fields=None, ignore_msgs=None, tolerance=None): +def get_field_tolerance(diff_field, field_tolerances): + diff_field_str = diff_field[0] + for s in diff_field[1:]: + # loop until number in field + if not isinstance(s, str): + break + diff_field_str += '.'+s + if diff_field_str in field_tolerances: + return field_tolerances[diff_field_str] + + +def compare_logs(log1, log2, ignore_fields=None, ignore_msgs=None, tolerance=None, field_tolerances=None): if ignore_fields is None: ignore_fields = [] if ignore_msgs is None: ignore_msgs = [] + if field_tolerances is None: + field_tolerances = {} + default_tolerance = EPSILON if tolerance is None else tolerance log1, log2 = (list(filter(lambda m: m.which() not in ignore_msgs, log)) for log in (log1, log2)) @@ -72,7 +86,6 @@ def compare_logs(log1, log2, ignore_fields=None, ignore_msgs=None, tolerance=Non msg1_dict = msg1.to_dict(verbose=True) msg2_dict = msg2.to_dict(verbose=True) - tolerance = EPSILON if tolerance is None else tolerance dd = dictdiffer.diff(msg1_dict, msg2_dict, ignore=ignore_fields) # Dictdiffer only supports relative tolerance, we also want to check for absolute @@ -80,10 +93,13 @@ def compare_logs(log1, log2, ignore_fields=None, ignore_msgs=None, tolerance=Non def outside_tolerance(diff): try: if diff[0] == "change": + field_tolerance = default_tolerance + if (tol := get_field_tolerance(diff[1], field_tolerances)) is not None: + field_tolerance = tol a, b = diff[2] finite = math.isfinite(a) and math.isfinite(b) if finite and isinstance(a, numbers.Number) and isinstance(b, numbers.Number): - return abs(a - b) > max(tolerance, tolerance * max(abs(a), abs(b))) + return abs(a - b) > max(field_tolerance, field_tolerance * max(abs(a), abs(b))) except TypeError: pass return True diff --git a/selfdrive/test/process_replay/process_replay.py b/selfdrive/test/process_replay/process_replay.py index bea7dc46ee..0c642cde17 100755 --- a/selfdrive/test/process_replay/process_replay.py +++ b/selfdrive/test/process_replay/process_replay.py @@ -28,7 +28,7 @@ TIMEOUT = 15 PROC_REPLAY_DIR = os.path.dirname(os.path.abspath(__file__)) FAKEDATA = os.path.join(PROC_REPLAY_DIR, "fakedata/") -ProcessConfig = namedtuple('ProcessConfig', ['proc_name', 'pub_sub', 'ignore', 'init_callback', 'should_recv_callback', 'tolerance', 'fake_pubsubmaster', 'submaster_config', 'environ', 'subtest_name'], defaults=({}, {}, "")) +ProcessConfig = namedtuple('ProcessConfig', ['proc_name', 'pub_sub', 'ignore', 'init_callback', 'should_recv_callback', 'tolerance', 'fake_pubsubmaster', 'submaster_config', 'environ', 'subtest_name', "field_tolerances"], defaults=({}, {}, "", {})) def wait_for_event(evt): diff --git a/selfdrive/test/process_replay/test_processes.py b/selfdrive/test/process_replay/test_processes.py index 91cc40f5ce..d8cd1fd57a 100755 --- a/selfdrive/test/process_replay/test_processes.py +++ b/selfdrive/test/process_replay/test_processes.py @@ -100,7 +100,7 @@ def test_process(cfg, lr, ref_log_path, new_log_path, ignore_fields=None, ignore return f"Route did not enable at all or for long enough: {new_log_path}", log_msgs try: - return compare_logs(ref_log_msgs, log_msgs, ignore_fields + cfg.ignore, ignore_msgs, cfg.tolerance), log_msgs + return compare_logs(ref_log_msgs, log_msgs, ignore_fields + cfg.ignore, ignore_msgs, cfg.tolerance, cfg.field_tolerances), log_msgs except Exception as e: return str(e), log_msgs From f0b5ff5c1addff7932fe86a2874a23d87b5eb5f3 Mon Sep 17 00:00:00 2001 From: Gijs Koning Date: Tue, 12 Jul 2022 14:03:35 +0200 Subject: [PATCH 085/112] Replay: Fix --upload-only (#25127) Add checking for list back --- selfdrive/test/process_replay/test_processes.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/selfdrive/test/process_replay/test_processes.py b/selfdrive/test/process_replay/test_processes.py index d8cd1fd57a..77d73a4ff4 100755 --- a/selfdrive/test/process_replay/test_processes.py +++ b/selfdrive/test/process_replay/test_processes.py @@ -217,7 +217,8 @@ if __name__ == "__main__": results: Any = defaultdict(dict) p2 = pool.map(run_test_process, pool_args) for (segment, proc, subtest_name, result) in tqdm(p2, desc="Running Tests", total=len(pool_args)): - results[segment][proc + subtest_name] = result + if isinstance(result, list): + results[segment][proc + subtest_name] = result diff1, diff2, failed = format_diff(results, ref_commit) if not upload: From 205f6f7414f502248082949addac25a215c73d59 Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Tue, 12 Jul 2022 16:09:21 +0200 Subject: [PATCH 086/112] casync: manifest compare script (#25129) * casync compare script * typo * cleanup output --- .../tici/tests/compare_casync_manifest.py | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100755 system/hardware/tici/tests/compare_casync_manifest.py diff --git a/system/hardware/tici/tests/compare_casync_manifest.py b/system/hardware/tici/tests/compare_casync_manifest.py new file mode 100755 index 0000000000..5e5fa24556 --- /dev/null +++ b/system/hardware/tici/tests/compare_casync_manifest.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python3 +import argparse +import collections +import multiprocessing +import os +from typing import Dict, List + +import requests +from tqdm import tqdm + +import system.hardware.tici.casync as casync + + +def get_chunk_download_size(chunk): + sha = chunk.sha.hex() + path = os.path.join(remote_url, sha[:4], sha + ".cacnk") + if os.path.isfile(path): + return os.path.getsize(path) + else: + r = requests.head(path) + r.raise_for_status() + return int(r.headers['content-length']) + + +if __name__ == "__main__": + + parser = argparse.ArgumentParser(description='Compute overlap between two casync manifests') + parser.add_argument('frm') + parser.add_argument('to') + args = parser.parse_args() + + frm = casync.parse_caibx(args.frm) + to = casync.parse_caibx(args.to) + remote_url = args.to.replace('.caibx', '') + + most_common = collections.Counter(t.sha for t in to).most_common(1)[0][0] + + frm_dict = casync.build_chunk_dict(frm) + + # Get content-length for each chunk + with multiprocessing.Pool() as pool: + szs = list(tqdm(pool.imap(get_chunk_download_size, to), total=len(to))) + chunk_sizes = {t.sha: sz for (t, sz) in zip(to, szs)} + + sources: Dict[str, List[int]] = { + 'seed': [], + 'remote_uncompressed': [], + 'remote_compressed': [], + } + + for chunk in to: + # Assume most common chunk is the zero chunk + if chunk.sha == most_common: + continue + + if chunk.sha in frm_dict: + sources['seed'].append(chunk.length) + else: + sources['remote_uncompressed'].append(chunk.length) + sources['remote_compressed'].append(chunk_sizes[chunk.sha]) + + print() + print("Update statistics (excluding zeros)") + print() + print("Download only with no seed:") + print(f" Remote (uncompressed)\t\t{sum(sources['seed'] + sources['remote_uncompressed']) / 1000 / 1000:.2f} MB\tn = {len(to)}") + print(f" Remote (compressed download)\t{sum(chunk_sizes.values()) / 1000 / 1000:.2f} MB\tn = {len(to)}") + print() + print("Upgrade with seed partition:") + print(f" Seed (uncompressed)\t\t{sum(sources['seed']) / 1000 / 1000:.2f} MB\t\t\t\tn = {len(sources['seed'])}") + sz, n = sum(sources['remote_uncompressed']), len(sources['remote_uncompressed']) + print(f" Remote (uncompressed)\t\t{sz / 1000 / 1000:.2f} MB\t(avg {sz / 1000 / 1000 / n:4f} MB)\tn = {n}") + sz, n = sum(sources['remote_compressed']), len(sources['remote_compressed']) + print(f" Remote (compressed download)\t{sz / 1000 / 1000:.2f} MB\t(avg {sz / 1000 / 1000 / n:4f} MB)\tn = {n}") From 105afee4a21ad008fa741f19c5a62a6d52fdd773 Mon Sep 17 00:00:00 2001 From: Gijs Koning Date: Tue, 12 Jul 2022 18:11:47 +0200 Subject: [PATCH 087/112] Laikad: set cache dir to comma_download_cache (#25131) * Cache downloads for process replay * set cache dir permanent * Create constant --- selfdrive/locationd/laikad.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/selfdrive/locationd/laikad.py b/selfdrive/locationd/laikad.py index 0954cb4c9f..4868e8ae52 100755 --- a/selfdrive/locationd/laikad.py +++ b/selfdrive/locationd/laikad.py @@ -27,6 +27,7 @@ from system.swaglog import cloudlog MAX_TIME_GAP = 10 EPHEMERIS_CACHE = 'LaikadEphemeris' +DOWNLOADS_CACHE_FOLDER = "/tmp/comma_download_cache" CACHE_VERSION = 0.1 POS_FIX_RESIDUAL_THRESHOLD = 100.0 @@ -42,7 +43,7 @@ class Laikad: valid_ephem_types: Valid ephemeris types to be used by AstroDog save_ephemeris: If true saves and loads nav and orbit ephemeris to cache. """ - self.astro_dog = AstroDog(valid_const=valid_const, auto_update=auto_update, valid_ephem_types=valid_ephem_types, clear_old_ephemeris=True) + self.astro_dog = AstroDog(valid_const=valid_const, auto_update=auto_update, valid_ephem_types=valid_ephem_types, clear_old_ephemeris=True, cache_dir=DOWNLOADS_CACHE_FOLDER) self.gnss_kf = GNSSKalman(GENERATED_DIR, cython=True) self.auto_fetch_orbits = auto_fetch_orbits @@ -183,7 +184,7 @@ class Laikad: def fetch_orbits(self, t: GPSTime, block): # Download new orbits if 1 hour of orbits data left if t + SECS_IN_HR not in self.astro_dog.orbit_fetched_times and (self.last_fetch_orbits_t is None or abs(t - self.last_fetch_orbits_t) > SECS_IN_MIN): - astro_dog_vars = self.astro_dog.valid_const, self.astro_dog.auto_update, self.astro_dog.valid_ephem_types + astro_dog_vars = self.astro_dog.valid_const, self.astro_dog.auto_update, self.astro_dog.valid_ephem_types, self.astro_dog.cache_dir ret = None if block: # Used for testing purposes @@ -203,8 +204,8 @@ class Laikad: self.cache_ephemeris(t=t) -def get_orbit_data(t: GPSTime, valid_const, auto_update, valid_ephem_types): - astro_dog = AstroDog(valid_const=valid_const, auto_update=auto_update, valid_ephem_types=valid_ephem_types) +def get_orbit_data(t: GPSTime, valid_const, auto_update, valid_ephem_types, cache_dir): + astro_dog = AstroDog(valid_const=valid_const, auto_update=auto_update, valid_ephem_types=valid_ephem_types, cache_dir=cache_dir) cloudlog.info(f"Start to download/parse orbits for time {t.as_datetime()}") start_time = time.monotonic() try: @@ -301,6 +302,7 @@ def main(sm=None, pm=None): replay = "REPLAY" in os.environ use_internet = "LAIKAD_NO_INTERNET" not in os.environ laikad = Laikad(save_ephemeris=not replay, auto_fetch_orbits=use_internet) + while True: sm.update() From 780c60324bf19762e9b72da38be0a9f09d624efd Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 12 Jul 2022 11:12:35 -0700 Subject: [PATCH 088/112] process replay: fix string failures after #25127 --- selfdrive/test/process_replay/test_processes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/test/process_replay/test_processes.py b/selfdrive/test/process_replay/test_processes.py index 77d73a4ff4..4ebb0701dd 100755 --- a/selfdrive/test/process_replay/test_processes.py +++ b/selfdrive/test/process_replay/test_processes.py @@ -217,7 +217,7 @@ if __name__ == "__main__": results: Any = defaultdict(dict) p2 = pool.map(run_test_process, pool_args) for (segment, proc, subtest_name, result) in tqdm(p2, desc="Running Tests", total=len(pool_args)): - if isinstance(result, list): + if not args.upload_only: results[segment][proc + subtest_name] = result diff1, diff2, failed = format_diff(results, ref_commit) From 1f17f812cfa74c1db2ceba05dae4946b5e472e2a Mon Sep 17 00:00:00 2001 From: Erich Moraga <33645296+ErichMoraga@users.noreply.github.com> Date: Tue, 12 Jul 2022 15:45:43 -0500 Subject: [PATCH 089/112] Add missing RAV4H_TSS2_2022 engine f/w (#25111) `@Rocks#8913` 2021 RAV4 Hybrid (Italy) DongleID/route 081a1d5f242294c0|2022-07-10--17-39-33 Continental camera p/n 8646C-0R090... https://discord.com/channels/469524606043160576/524327905937850394/995781101903679558 --- selfdrive/car/toyota/values.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py index 2a03999342..723fa85820 100644 --- a/selfdrive/car/toyota/values.py +++ b/selfdrive/car/toyota/values.py @@ -1381,11 +1381,12 @@ FW_VERSIONS = { b'8965B42172\x00\x00\x00\x00\x00\x00', ], (Ecu.engine, 0x700, None): [ - b'\x01896634A62000\x00\x00\x00\x00', - b'\x01896634A08000\x00\x00\x00\x00', - b'\x01896634A61000\x00\x00\x00\x00', b'\x01896634A02001\x00\x00\x00\x00', b'\x01896634A03000\x00\x00\x00\x00', + b'\x01896634A08000\x00\x00\x00\x00', + b'\x01896634A61000\x00\x00\x00\x00', + b'\x01896634A62000\x00\x00\x00\x00', + b'\x01896634A63000\x00\x00\x00\x00', ], (Ecu.fwdRadar, 0x750, 0xf): [ b'\x018821F0R01100\x00\x00\x00\x00', From ecac734160f719f59364a637b7cd781460456845 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 12 Jul 2022 13:51:25 -0700 Subject: [PATCH 090/112] update compatibility docs with VIN data (#25134) * start with genesis * chrysler * honda * toyota * subaru --- docs/CARS.md | 46 ++++++++++++++++---------------- selfdrive/car/chrysler/values.py | 4 +-- selfdrive/car/honda/values.py | 20 +++++++------- selfdrive/car/hyundai/values.py | 6 ++--- selfdrive/car/subaru/values.py | 6 ++--- selfdrive/car/toyota/values.py | 10 +++---- 6 files changed, 46 insertions(+), 46 deletions(-) diff --git a/docs/CARS.md b/docs/CARS.md index 5e185ed278..c3efe87515 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -49,12 +49,12 @@ How We Rate The Cars |Kia|Niro Electric 2021|All|||||| |Kia|Niro Electric 2022|All|||||| |Kia|Telluride 2020|SCC + LKAS|||||| -|Lexus|ES 2019-21|All|||||| +|Lexus|ES 2019-22|All|||||| |Lexus|ES Hybrid 2019-22|All|||||| -|Lexus|NX 2020|All|||||| -|Lexus|NX Hybrid 2020|All|||||| +|Lexus|NX 2020-21|All|||||| +|Lexus|NX Hybrid 2020-21|All|||||| |Lexus|RX 2020-22|All|||||| -|Lexus|UX Hybrid 2019-21|All|||||| +|Lexus|UX Hybrid 2019-22|All|||||| |Toyota|Avalon 2022|All|||||| |Toyota|Avalon Hybrid 2022|All|||||| |Toyota|Camry 2021-22|All||[4](#footnotes)|||| @@ -80,8 +80,8 @@ How We Rate The Cars |Audi|RS3 2018|ACC + Lane Assist|||||| |Audi|S3 2015-17|ACC + Lane Assist|||||| |Chevrolet|Volt 2017-18[1](#footnotes)|Adaptive Cruise|||||| -|Genesis|G70 2018|All|||||| -|Genesis|G80 2018|All|||||| +|Genesis|G70 2018-19|All|||||| +|Genesis|G80 2017-19|All|||||| |Hyundai|Elantra 2021-22|SCC + LKAS|||||| |Hyundai|Elantra Hybrid 2021-22|SCC + LKAS|||||| |Hyundai|Ioniq Electric 2020|SCC + LKAS|||||| @@ -117,10 +117,10 @@ How We Rate The Cars |Nissan|X-Trail 2017|ProPILOT|||||| |SEAT|Ateca 2018|Driver Assistance|||||| |SEAT|Leon 2014-20|Driver Assistance|||||| -|Subaru|Ascent 2019-20|All|||||| +|Subaru|Ascent 2019-21|All|||||| |Subaru|Crosstrek 2020-21|EyeSight|||||| -|Subaru|Forester 2019-21|All|||||| -|Subaru|Impreza 2020-21|EyeSight|||||| +|Subaru|Forester 2019-22|All|||||| +|Subaru|Impreza 2020-22|EyeSight|||||| |Subaru|XV 2020-21|EyeSight|||||| |Toyota|Alphard 2019-20|All|||||| |Toyota|Alphard Hybrid 2021|All|||||| @@ -151,7 +151,7 @@ How We Rate The Cars |---|---|---|:---:|:---:|:---:|:---:|:---:| |Acura|ILX 2016-19|AcuraWatch Plus|||||| |Acura|RDX 2016-18|AcuraWatch Plus|||||| -|Acura|RDX 2019-21|All|||||| +|Acura|RDX 2019-22|All|||||| |Audi|Q2 2018|ACC + Lane Assist|||||| |Audi|Q3 2020-21|ACC + Lane Assist|||||| |Cadillac|Escalade ESV 2016[1](#footnotes)|ACC + LKAS|||||| @@ -159,27 +159,27 @@ How We Rate The Cars |Chrysler|Pacifica 2019-20|Adaptive Cruise|||||| |Chrysler|Pacifica Hybrid 2017-18|Adaptive Cruise|||||| |Chrysler|Pacifica Hybrid 2019-22|Adaptive Cruise|||||| -|Genesis|G90 2018|All|||||| +|Genesis|G90 2017-18|All|||||| |GMC|Acadia 2018[1](#footnotes)|Adaptive Cruise|||||| -|Honda|Accord 2018-21|All|||||| -|Honda|Accord Hybrid 2018-21|All|||||| +|Honda|Accord 2016-22|All|||||| +|Honda|Accord Hybrid 2018-22|All|||||| |Honda|Civic 2016-18|Honda Sensing|||||| -|Honda|Civic 2019-20|All|||[2](#footnotes)||| +|Honda|Civic 2019-21|All|||[2](#footnotes)||| |Honda|Civic 2022|All|||||| |Honda|Civic Hatchback 2017-21|Honda Sensing|||||| |Honda|Civic Hatchback 2022|All|||||| |Honda|CR-V 2015-16|Touring|||||| -|Honda|CR-V 2017-21|Honda Sensing|||||| +|Honda|CR-V 2017-22|Honda Sensing|||||| |Honda|CR-V Hybrid 2017-19|Honda Sensing|||||| |Honda|e 2020|All|||||| -|Honda|Fit 2018-19|Honda Sensing|||||| +|Honda|Fit 2018-20|Honda Sensing|||||| |Honda|Freed 2020|Honda Sensing|||||| -|Honda|HR-V 2019-20|Honda Sensing|||||| -|Honda|Insight 2019-21|All|||||| +|Honda|HR-V 2019-22|Honda Sensing|||||| +|Honda|Insight 2019-22|All|||||| |Honda|Inspire 2018|All|||||| -|Honda|Odyssey 2018-20|Honda Sensing|||||| +|Honda|Odyssey 2018-22|Honda Sensing|||||| |Honda|Passport 2019-21|All|||||| -|Honda|Pilot 2016-21|Honda Sensing|||||| +|Honda|Pilot 2016-22|Honda Sensing|||||| |Honda|Ridgeline 2017-22|Honda Sensing|||||| |Hyundai|Elantra 2017-19|SCC + LKAS|||||| |Hyundai|Genesis 2015-16|SCC + LKAS|||||| @@ -190,16 +190,16 @@ How We Rate The Cars |Hyundai|Tucson 2021|SCC + LKAS|||||| |Hyundai|Veloster 2019-20|SCC + LKAS|||||| |Jeep|Grand Cherokee 2016-18|Adaptive Cruise|||||| -|Jeep|Grand Cherokee 2019-20|Adaptive Cruise|||||| +|Jeep|Grand Cherokee 2019-21|Adaptive Cruise|||||| |Kia|Niro Plug-in Hybrid 2019|SCC + LKAS|||||| |Kia|Optima 2017|SCC + LKAS|||||| |Lexus|IS 2017-19|All|||||| -|Lexus|RC 2020|All|||||| +|Lexus|RC 2017-2020|All|||||| |Lexus|RX 2016-18|All|[3](#footnotes)||||| |Lexus|RX Hybrid 2016-19|All|[3](#footnotes)||||| |Mazda|CX-5 2022|All|||||| |Mazda|CX-9 2021|All|||||| -|Ram|1500 2019-21|Adaptive Cruise|||||| +|Ram|1500 2019-22|Adaptive Cruise|||||| |Subaru|Crosstrek 2018-19|EyeSight|||||| |Subaru|Impreza 2017-19|EyeSight|||||| |Subaru|XV 2018-19|EyeSight|||||| diff --git a/selfdrive/car/chrysler/values.py b/selfdrive/car/chrysler/values.py index 69dade4b64..80baba9bd6 100644 --- a/selfdrive/car/chrysler/values.py +++ b/selfdrive/car/chrysler/values.py @@ -53,8 +53,8 @@ CAR_INFO: Dict[str, Optional[Union[ChryslerCarInfo, List[ChryslerCarInfo]]]] = { CAR.PACIFICA_2018: ChryslerCarInfo("Chrysler Pacifica 2017-18"), CAR.PACIFICA_2020: ChryslerCarInfo("Chrysler Pacifica 2019-20"), CAR.JEEP_CHEROKEE: ChryslerCarInfo("Jeep Grand Cherokee 2016-18", video_link="https://www.youtube.com/watch?v=eLR9o2JkuRk"), - CAR.JEEP_CHEROKEE_2019: ChryslerCarInfo("Jeep Grand Cherokee 2019-20", video_link="https://www.youtube.com/watch?v=jBe4lWnRSu4"), - CAR.RAM_1500: ChryslerCarInfo("Ram 1500 2019-21"), + CAR.JEEP_CHEROKEE_2019: ChryslerCarInfo("Jeep Grand Cherokee 2019-21", video_link="https://www.youtube.com/watch?v=jBe4lWnRSu4"), + CAR.RAM_1500: ChryslerCarInfo("Ram 1500 2019-22"), } # Unique CAN messages: diff --git a/selfdrive/car/honda/values.py b/selfdrive/car/honda/values.py index c6e20f2d83..bfa42bd509 100644 --- a/selfdrive/car/honda/values.py +++ b/selfdrive/car/honda/values.py @@ -109,13 +109,13 @@ class HondaCarInfo(CarInfo): CAR_INFO: Dict[str, Optional[Union[HondaCarInfo, List[HondaCarInfo]]]] = { CAR.ACCORD: [ - HondaCarInfo("Honda Accord 2018-21", "All", video_link="https://www.youtube.com/watch?v=mrUwlj3Mi58", min_steer_speed=3. * CV.MPH_TO_MS, harness=Harness.bosch_a), + HondaCarInfo("Honda Accord 2016-22", "All", video_link="https://www.youtube.com/watch?v=mrUwlj3Mi58", min_steer_speed=3. * CV.MPH_TO_MS, harness=Harness.bosch_a), HondaCarInfo("Honda Inspire 2018", "All", min_steer_speed=3. * CV.MPH_TO_MS, harness=Harness.bosch_a), ], - CAR.ACCORDH: HondaCarInfo("Honda Accord Hybrid 2018-21", "All", min_steer_speed=3. * CV.MPH_TO_MS, harness=Harness.bosch_a), + CAR.ACCORDH: HondaCarInfo("Honda Accord Hybrid 2018-22", "All", min_steer_speed=3. * CV.MPH_TO_MS, harness=Harness.bosch_a), CAR.CIVIC: HondaCarInfo("Honda Civic 2016-18", harness=Harness.nidec), CAR.CIVIC_BOSCH: [ - HondaCarInfo("Honda Civic 2019-20", "All", video_link="https://www.youtube.com/watch?v=4Iz1Mz5LGF8", footnotes=[Footnote.CIVIC_DIESEL], min_steer_speed=2. * CV.MPH_TO_MS, harness=Harness.bosch_a), + HondaCarInfo("Honda Civic 2019-21", "All", video_link="https://www.youtube.com/watch?v=4Iz1Mz5LGF8", footnotes=[Footnote.CIVIC_DIESEL], min_steer_speed=2. * CV.MPH_TO_MS, harness=Harness.bosch_a), HondaCarInfo("Honda Civic Hatchback 2017-21", harness=Harness.bosch_a), ], CAR.CIVIC_BOSCH_DIESEL: None, # same platform @@ -125,20 +125,20 @@ CAR_INFO: Dict[str, Optional[Union[HondaCarInfo, List[HondaCarInfo]]]] = { ], CAR.ACURA_ILX: HondaCarInfo("Acura ILX 2016-19", "AcuraWatch Plus", min_steer_speed=25. * CV.MPH_TO_MS, harness=Harness.nidec), CAR.CRV: HondaCarInfo("Honda CR-V 2015-16", "Touring", harness=Harness.nidec), - CAR.CRV_5G: HondaCarInfo("Honda CR-V 2017-21", harness=Harness.bosch_a), + CAR.CRV_5G: HondaCarInfo("Honda CR-V 2017-22", harness=Harness.bosch_a), CAR.CRV_EU: None, # HondaCarInfo("Honda CR-V EU", "Touring"), # Euro version of CRV Touring CAR.CRV_HYBRID: HondaCarInfo("Honda CR-V Hybrid 2017-19", harness=Harness.bosch_a), - CAR.FIT: HondaCarInfo("Honda Fit 2018-19", harness=Harness.nidec), + CAR.FIT: HondaCarInfo("Honda Fit 2018-20", harness=Harness.nidec), CAR.FREED: HondaCarInfo("Honda Freed 2020", harness=Harness.nidec), - CAR.HRV: HondaCarInfo("Honda HR-V 2019-20", harness=Harness.nidec), - CAR.ODYSSEY: HondaCarInfo("Honda Odyssey 2018-20", min_steer_speed=0., harness=Harness.nidec), + CAR.HRV: HondaCarInfo("Honda HR-V 2019-22", harness=Harness.nidec), + CAR.ODYSSEY: HondaCarInfo("Honda Odyssey 2018-22", min_steer_speed=0., harness=Harness.nidec), CAR.ODYSSEY_CHN: None, # Chinese version of Odyssey CAR.ACURA_RDX: HondaCarInfo("Acura RDX 2016-18", "AcuraWatch Plus", harness=Harness.nidec), - CAR.ACURA_RDX_3G: HondaCarInfo("Acura RDX 2019-21", "All", min_steer_speed=3. * CV.MPH_TO_MS, harness=Harness.bosch_a), - CAR.PILOT: HondaCarInfo("Honda Pilot 2016-21", harness=Harness.nidec), + CAR.ACURA_RDX_3G: HondaCarInfo("Acura RDX 2019-22", "All", min_steer_speed=3. * CV.MPH_TO_MS, harness=Harness.bosch_a), + CAR.PILOT: HondaCarInfo("Honda Pilot 2016-22", harness=Harness.nidec), CAR.PASSPORT: HondaCarInfo("Honda Passport 2019-21", "All", harness=Harness.nidec), CAR.RIDGELINE: HondaCarInfo("Honda Ridgeline 2017-22", harness=Harness.nidec), - CAR.INSIGHT: HondaCarInfo("Honda Insight 2019-21", "All", min_steer_speed=3. * CV.MPH_TO_MS, harness=Harness.bosch_a), + CAR.INSIGHT: HondaCarInfo("Honda Insight 2019-22", "All", min_steer_speed=3. * CV.MPH_TO_MS, harness=Harness.bosch_a), CAR.HONDA_E: HondaCarInfo("Honda e 2020", "All", min_steer_speed=3. * CV.MPH_TO_MS, harness=Harness.bosch_a), } diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index 2e6a2017ea..6e184ce9ef 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -156,10 +156,10 @@ CAR_INFO: Dict[str, Optional[Union[HyundaiCarInfo, List[HyundaiCarInfo]]]] = { CAR.KIA_EV6: HyundaiCarInfo("Kia EV6 2022", "All", harness=Harness.hyundai_p), # Genesis - CAR.GENESIS_G70: HyundaiCarInfo("Genesis G70 2018", "All", harness=Harness.hyundai_f), + CAR.GENESIS_G70: HyundaiCarInfo("Genesis G70 2018-19", "All", harness=Harness.hyundai_f), CAR.GENESIS_G70_2020: HyundaiCarInfo("Genesis G70 2020", "All", harness=Harness.hyundai_f), - CAR.GENESIS_G80: HyundaiCarInfo("Genesis G80 2018", "All", harness=Harness.hyundai_h), - CAR.GENESIS_G90: HyundaiCarInfo("Genesis G90 2018", "All", harness=Harness.hyundai_c), + CAR.GENESIS_G80: HyundaiCarInfo("Genesis G80 2017-19", "All", harness=Harness.hyundai_h), + CAR.GENESIS_G90: HyundaiCarInfo("Genesis G90 2017-18", "All", harness=Harness.hyundai_c), } class Buttons: diff --git a/selfdrive/car/subaru/values.py b/selfdrive/car/subaru/values.py index ea923b1b50..8fac934285 100644 --- a/selfdrive/car/subaru/values.py +++ b/selfdrive/car/subaru/values.py @@ -41,18 +41,18 @@ class SubaruCarInfo(CarInfo): CAR_INFO: Dict[str, Union[SubaruCarInfo, List[SubaruCarInfo]]] = { - CAR.ASCENT: SubaruCarInfo("Subaru Ascent 2019-20", "All"), + CAR.ASCENT: SubaruCarInfo("Subaru Ascent 2019-21", "All"), CAR.IMPREZA: [ SubaruCarInfo("Subaru Impreza 2017-19"), SubaruCarInfo("Subaru Crosstrek 2018-19", video_link="https://youtu.be/Agww7oE1k-s?t=26"), SubaruCarInfo("Subaru XV 2018-19", video_link="https://youtu.be/Agww7oE1k-s?t=26"), ], CAR.IMPREZA_2020: [ - SubaruCarInfo("Subaru Impreza 2020-21"), + SubaruCarInfo("Subaru Impreza 2020-22"), SubaruCarInfo("Subaru Crosstrek 2020-21"), SubaruCarInfo("Subaru XV 2020-21"), ], - CAR.FORESTER: SubaruCarInfo("Subaru Forester 2019-21", "All"), + CAR.FORESTER: SubaruCarInfo("Subaru Forester 2019-22", "All"), CAR.FORESTER_PREGLOBAL: SubaruCarInfo("Subaru Forester 2017-18"), CAR.LEGACY_PREGLOBAL: SubaruCarInfo("Subaru Legacy 2015-18"), CAR.OUTBACK_PREGLOBAL: SubaruCarInfo("Subaru Outback 2015-17"), diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py index 723fa85820..f47ab87040 100644 --- a/selfdrive/car/toyota/values.py +++ b/selfdrive/car/toyota/values.py @@ -124,7 +124,7 @@ CAR_INFO: Dict[str, Union[ToyotaCarInfo, List[ToyotaCarInfo]]] = { ], CAR.COROLLAH_TSS2: [ ToyotaCarInfo("Toyota Corolla Hybrid 2020-22"), - ToyotaCarInfo("Lexus UX Hybrid 2019-21"), + ToyotaCarInfo("Lexus UX Hybrid 2019-22"), ], CAR.HIGHLANDER: ToyotaCarInfo("Toyota Highlander 2017-19", video_link="https://www.youtube.com/watch?v=0wS0wXSLzoo", footnotes=[Footnote.DSU]), CAR.HIGHLANDER_TSS2: ToyotaCarInfo("Toyota Highlander 2020-22"), @@ -151,14 +151,14 @@ CAR_INFO: Dict[str, Union[ToyotaCarInfo, List[ToyotaCarInfo]]] = { # Lexus CAR.LEXUS_CTH: ToyotaCarInfo("Lexus CT Hybrid 2017-18", "LSS", footnotes=[Footnote.DSU]), CAR.LEXUS_ESH: ToyotaCarInfo("Lexus ES Hybrid 2017-18", "LSS", footnotes=[Footnote.DSU]), - CAR.LEXUS_ES_TSS2: ToyotaCarInfo("Lexus ES 2019-21"), + CAR.LEXUS_ES_TSS2: ToyotaCarInfo("Lexus ES 2019-22"), CAR.LEXUS_ESH_TSS2: ToyotaCarInfo("Lexus ES Hybrid 2019-22", video_link="https://youtu.be/BZ29osRVJeg?t=12"), CAR.LEXUS_IS: ToyotaCarInfo("Lexus IS 2017-19"), CAR.LEXUS_NX: ToyotaCarInfo("Lexus NX 2018-19", footnotes=[Footnote.DSU]), CAR.LEXUS_NXH: ToyotaCarInfo("Lexus NX Hybrid 2018-19", footnotes=[Footnote.DSU]), - CAR.LEXUS_NX_TSS2: ToyotaCarInfo("Lexus NX 2020"), - CAR.LEXUS_NXH_TSS2: ToyotaCarInfo("Lexus NX Hybrid 2020"), - CAR.LEXUS_RC: ToyotaCarInfo("Lexus RC 2020"), + CAR.LEXUS_NX_TSS2: ToyotaCarInfo("Lexus NX 2020-21"), + CAR.LEXUS_NXH_TSS2: ToyotaCarInfo("Lexus NX Hybrid 2020-21"), + CAR.LEXUS_RC: ToyotaCarInfo("Lexus RC 2017-2020"), CAR.LEXUS_RX: ToyotaCarInfo("Lexus RX 2016-18", footnotes=[Footnote.DSU]), CAR.LEXUS_RXH: ToyotaCarInfo("Lexus RX Hybrid 2016-19", footnotes=[Footnote.DSU]), CAR.LEXUS_RX_TSS2: ToyotaCarInfo("Lexus RX 2020-22"), From ea449f1fe0bbff0eff5b12d64f0b5e75b7983998 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Tue, 12 Jul 2022 14:08:17 -0700 Subject: [PATCH 091/112] Use upstream wait-on-check-action action (#25126) Use upstream lewagon action --- .github/workflows/prebuilt.yaml | 2 +- .github/workflows/release.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/prebuilt.yaml b/.github/workflows/prebuilt.yaml index 7acc8a2254..99d9694f24 100644 --- a/.github/workflows/prebuilt.yaml +++ b/.github/workflows/prebuilt.yaml @@ -25,7 +25,7 @@ jobs: IMAGE_NAME: openpilot-prebuilt steps: - name: Wait for green check mark - uses: commaai/wait-on-check-action@f16fc3bb6cd4886520b4e9328db1d42104d5cadc + uses: lewagon/wait-on-check-action@e2558238c09778af25867eb5de5a3ce4bbae3dcd with: ref: master wait-interval: 30 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index fb5a37eeef..8df89dcc38 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -12,7 +12,7 @@ jobs: if: github.repository == 'commaai/openpilot' steps: - name: Wait for green check mark - uses: commaai/wait-on-check-action@f16fc3bb6cd4886520b4e9328db1d42104d5cadc + uses: lewagon/wait-on-check-action@e2558238c09778af25867eb5de5a3ce4bbae3dcd with: ref: master wait-interval: 30 From b632d56244c5fd6821477a642d6f151ea4b13b20 Mon Sep 17 00:00:00 2001 From: ZwX1616 Date: Tue, 12 Jul 2022 16:39:13 -0700 Subject: [PATCH 092/112] UI: change wording for dcam preview description (#25142) --- selfdrive/ui/qt/offroad/settings.cc | 2 +- selfdrive/ui/translations/main_ja.ts | 4 ++-- selfdrive/ui/translations/main_ko.qm | Bin 20040 -> 19981 bytes selfdrive/ui/translations/main_ko.ts | 4 ++-- selfdrive/ui/translations/main_zh-CHS.qm | Bin 18508 -> 18469 bytes selfdrive/ui/translations/main_zh-CHS.ts | 4 ++-- selfdrive/ui/translations/main_zh-CHT.qm | Bin 18568 -> 18509 bytes selfdrive/ui/translations/main_zh-CHT.ts | 6 +++--- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index d5b8d4bbd1..9aeb966ccf 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -102,7 +102,7 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) { // offroad-only buttons auto dcamBtn = new ButtonControl(tr("Driver Camera"), tr("PREVIEW"), - tr("Preview the driver facing camera to help optimize device mounting position for best driver monitoring experience. (vehicle must be off)")); + tr("Preview the driver facing camera to ensure that driver monitoring has good visibility. (vehicle must be off)")); connect(dcamBtn, &ButtonControl::clicked, [=]() { emit showDriverView(); }); addItem(dcamBtn); diff --git a/selfdrive/ui/translations/main_ja.ts b/selfdrive/ui/translations/main_ja.ts index 5c0f54a314..f3b8733128 100644 --- a/selfdrive/ui/translations/main_ja.ts +++ b/selfdrive/ui/translations/main_ja.ts @@ -134,8 +134,8 @@ - Preview the driver facing camera to help optimize device mounting position for best driver monitoring experience. (vehicle must be off) - ドライバーカメラのプレビューにより、デバイスの取り付け位置を最適化し、最高のドライバーモニタリング体験を提供します。(車両の電源を切る必要があります) + Preview the driver facing camera to ensure that driver monitoring has good visibility. (vehicle must be off) + ドライバー向けカメラをプレビューする、ドライバーモニタリングの視認性を確保します。(車両の電源を切る必要があります) diff --git a/selfdrive/ui/translations/main_ko.qm b/selfdrive/ui/translations/main_ko.qm index c5c66d1e73491c2ff09d91b6fdd5200002b2a6da..40b0bb65a38d65ee901ac7a85257e88868b4513c 100644 GIT binary patch delta 1903 zcmX9;Yfx2H7+v?=bMEupb1%xnv5>m`N23+hBMX66Gk z3REhz6o^d786aOtzL1B83 z7}gP&0zTV_{I|2PWxJT56j%%-hyzN)w4{`mcz^qb;mDd1`3bBpIE`T7QFmrF$=$mg~vO&eh5!!L78*TA!^bT;N{|&LK<{_){5O-h8BF+`-f7nVpYQ*N(Yk&kr zJS0;W<(_!v*Iv$Ni)U`#p^!uM;??QRw4YTnO(5ZMsgk8MpZsa1I3<_@*`@i5DafQ~ z$zl4APU(|!f@;ZAg_QHeQKmTJKivPdwEDGGj9(+Y8KtlX;-u1TEX0)WM)kfM10viQ zA1hUb)=)_ARH^C%IzkSYYTjE%CMu+T?S15Dnsj0?h|Sv|o%BCP0rXPuB^DICUFu)k zNud+nIBTEuXpjYtgHG^IqjPd}%3V7dd`UOuW&#<^)y-~f0j53BWoXFz$Thm^hmV24 zak@vzJtef*Q~H1qQWYxbYlpAp%?9=Ra{HOMKz}!NH>sPb|K}DN(caPjJNY^=qSFu; z(#n_Ph#^VKLTwif*|-0t}eJv?V*kH_9K#E8GXv}Jh1x9xpw}8$D>mE(1$ipLak)DlzWk!t$UVXC_DA_eI(?d+nk;&@ZTh6?gi zZ8{t-u~X-iza{yUY&P9^)kQX7*6e?qt2T4su~W>YF(+K!2n>xgFTBb=5B}bqe_kX> zbIfasJV}nl-1a+JAN`cM<2jPy{f_K;jM>7^$^MO;A5|%bOc8_PRRkCM~3^1KrNdGhjkEMMx9w?BG`2kep?KVex&5b#&hFs zW#gyp-_QYN$MqSMJx}?nhKZv8R$3lV?h$3m*%?35zbCAQKlt()lB}LH*|9PGR_|XQ z0}}-6oNGKUs>Pb@qJNDxYp!D;f`T{_~&j z{9m2@f7hRVh_i~*uYh>1WEv2%~R&*08W0Nkh}Y*$*w{O+dc-;TOjNo z1XK!y=6EKpfYA9j;zsN;4^VTD54}v6}kL z71PY&q-_%mma!po)`%t2MZok2@r|%r>U3Rv!|Nz%Gx0I=zY;gTzJc+L;+yei-hs{H zjt@yhsvE=L*f9)QHHP!w65UZXY-B*S=zgD$kXMQ|?{1|M*Tt_}Z&RO*V$*0CFK@kg zC75@@Cspk0C!z3vigzm7+2}1}nEpT<870Bz61D2!JUXjZYkm|>1wYUx-Or$cc5SBT z0x&O5yF^9Zr#5Pj4L=1!OSO&B2V8)`M>~?+L#yTMLLwKph>aHXX_3vGAdmIg8WQ&P*IR#jLWytatJfX`g0|~FIl(&q zKKe6vL;0R#(3$>32fbzpb?bRmA`B_NxJr03mEo0~K{9PJE3cDrAsub&TeLWjxqGoRT4@vX56ael-O)sI>4bYMQ2=nLm=@A<2&p8 zsG!N%@*`U`E#KJoA{7g`Ap2b+fjC)q1$+1*;)eWe@ zl}gMjlk@knU~r{e`jVGer~J{#A9;d*%bwl5Ys!am`w=QPxQ5R?ZQZfw zFGH!j(9_$R4y9G-aq@p{SAjRKwf0)1cde_yTg#jMue_dRO%u4bz3Ggn%`=E-D2TWg zajyO9&wJ{9rs}sXbXeEftn2rb&Yzg;EK^okSCuPeG4b? - Preview the driver facing camera to help optimize device mounting position for best driver monitoring experience. (vehicle must be off) - 운전자 카메라를 미리 보면서 최적의 운전자 모니터링 경험을 위해 장치의 장착 위치를 최적화할수 있습니다. (차량연결은 해제되어있어야 합니다) + Preview the driver facing camera to ensure that driver monitoring has good visibility. (vehicle must be off) + 운전자 모니터링이 좋은 가시성을 갖도록 운전자를 향한 카메라를 미리 봅니다. (차량연결은 해제되어있어야 합니다) diff --git a/selfdrive/ui/translations/main_zh-CHS.qm b/selfdrive/ui/translations/main_zh-CHS.qm index 45fae52b4286bb3e57938bf6c7c4ad53d3bd3ba1..2c7963cf17a496e356fb5b0372b565ac82514661 100644 GIT binary patch delta 1858 zcmX9;c~n$o9KAF1-Yjos-a{S41!UL+6j=%v1Q9VYutb!QLNf^(#t;$)lw8Qv6e+{N zB*hgF%gl4ousB+pNTOkJva&doq6lb2+bI&ku7~;O&ij_%cfWh@@B6AmRb8SgaV>lb zP!9kT0s)PUxPZ8tm_yu6ECU42%LYIU0w#V*3-2adpVN7n%}{jv0X6XzdbWtu1VzlAje+;5J+q03i+C=+TO&jbEZXc!UC zi=0Bo_B_rPt44+epb*~6RipNMQ|lj9lXuY1kWs3HMt{IZquTQw$EOXbt|kgBoUFR8 zt_0kys_w@(17rSDOSX%EUxnJIqn-P%t79YwiS1M`apH}GFRJ%lV;0;p)u-PivBx6S zpT*K^WvTkx1lAoVs@s}Uo&W-Ot8W~12F509gg_U-5}oy9Y>C6; zg0=VKzbj=T|$hyUYlXSfc4^z5y-M@FKh^AiGAKnSL-qX+a zZ{W*Or;pQ+s8Xg+@98JOB>h`?dpK{?A2`N3BUb4@?(pJwfI(+o#^lU0cva}xB0h#$ zf7-bI4Z}0@Cf%m=0fwYalq~9~A!P|A9`9;MYm6o#7gL1Z9!{LWz`rULcPjioAe9Z$NT1VE`I$-{-y>CAe};y%Nc)>xtf0%3!u zdC|P%^m0?uF4ik_&oHf=Px|6w)9(9=S)j&LyOZrRuE5lEkfH=nFn!fZ4E)~I+DL-J z4zsq}n|QNz z|N8wX@9T`B?LP7cRXk|&X!-0vwA=NRd^L)1w2MX2|IU|B*Qi)#v12E9D32lK0cP06x#gixxvO3C#tv^hh0FFlKrJybq_4W6w{|v98R{vOBVK>{&Kz#`0XNEjv5Sns3jwr`j{^ Mj)Id#P8X*B4>phSf&c&j delta 1954 zcmX9;4Nz3)6+Qd*z5RK+`yS{@tWjAPP!PnWK@>$nXdt2m5kw|v%m6RzCbA$dAWd{* z#3+#>4jPr9!3Z&_wV6Sqi7{#vu^2&R#e*;unC(?}`hMrUQ}xCe8t(W)SnaM;k#W z_ZuDp0XqTX1mdT}c;Y{ZX8~I+V7&;090n#|0|I{sOyRyIfvJ4p#=w2R^VNW>14!S> zLNkFy*~B-2tQaQwjkpR33M6jkdMB{@01K1>Yo8K-1$@KbckK8%*#9lWE$;#I9zxvH z2k2yo?Xe764zcSqVk^WeA`m%g>wNW04pV>jRha{F^RgYjtC%Zs;==m z*W*KV-8mu?`*k;jgTRC|-M#0kfoI1FvikxMeqIRczspN=*zR1c;<`x!wQ*4Df+hKisBS>4Sao|I z;J7QkQ9wF|DshYWUm)(HxM#sB+A($nRp$uW&y1iWL~LpqB&&Ji2Yp4v4dP#~>;jzU z#AC0uP*1n`xs`LV^@?Br*h8B-#IJv%)%}4F#M_C-Xg|Ls$5HUP|B-Cl)&R4*r4%KM zw3kVFFLNMqDB((kB;hQJ-Mx+)yYF?{?|@q;Ke` z`%+IY358@xKWyp*LNAYCVvzKBhykSF_c=incGNiSA3C!MT z$k$Q#Fwt;u@F_59nc-CQUO$)eqqvnenO(_O@A(L1jg5y-apJdqxYCT z?GNF5w%KS~Ne8VmhcuaZR2G@%KlHm9aKyZHVIM~jWzOA1>5{IP^OsZV$tmWdj${&= zVy*)nhWE|adNSy!1Loeq5?)J(<@u4**`XpAUF~AWX>!dyUOB-9#JTMBfV}OF%J&X= z=TnY2?54cu)ImDcE;rp+%25r<`~6*qL}sn>IX43(QErzf@^<-3 zZVyTzq3iP9LLa3Iv*?a*pwyL?kh2#^D9Dm}vj!M7)w1F?FNKixmNnmrBwl0LSYc=U z6HCW^j%Z4r_Om1qEn5AP+W29zYMnN>ie`CaO-_H>Y-SZ6b| zhO%I~ZTf_Nl1RKQeuzY$J#9O}s|`-O-*%#s5AjvDcISumLbk0vnK&iJb}4~gkPB_s z@_0P$Z!2RyZsq!*GHweM80}D;gDJoagEH$@6wUWQSy)R2N9QYRlAouUqm-KWc-SML z?7NdhZ!A*&(!x43l9Vrhp(n=oDBVd{Y4+SXs_6mmNn?j|X9m-<2< z6UMx&dfok;omZ{Dv6&uNrS8?dBsN(+Q~Ez3;e^_IcRxEBP;aIFjqgqmFn`q1*~V&< zZgImIb!>8Zct%~VUi0PGY`swP?MokK^lv(`aa6w=~!SLKm&lR+lvoiu wto8UjC0@rXC1s8RZLQByROYGB%DBVp@s*Sf@6pzkYGoeHTc{l^2sl6U|7&9g_5c6? diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts index 04bd2415f0..d9377054a5 100644 --- a/selfdrive/ui/translations/main_zh-CHS.ts +++ b/selfdrive/ui/translations/main_zh-CHS.ts @@ -134,8 +134,8 @@ - Preview the driver facing camera to help optimize device mounting position for best driver monitoring experience. (vehicle must be off) - 打开并预览驾驶员摄像头,用于调整安装角度以获得最优驾驶员监控体验。仅熄火时可用。 + Preview the driver facing camera to ensure that driver monitoring has good visibility. (vehicle must be off) + 打开并预览驾驶员摄像头,以确保驾驶员监控具有良好视野。仅熄火时可用。 diff --git a/selfdrive/ui/translations/main_zh-CHT.qm b/selfdrive/ui/translations/main_zh-CHT.qm index 130bcfc92670cff84c6c6fcf359be599e4941e3e..0d448f2080322661cb712bd3c06b4049fabbf935 100644 GIT binary patch delta 1928 zcmX9;3s93+8a+w=KhHmZP=oDKfd~N+1cJo}2!c?s;I4q6wMF}&U`Ry}2%v+STA!3^ zrT73vtqQd-*BP|fwZ(NSVxbMTQ*7;I=_-n-W0$SnSzKN0o=!58Imx}>{l0V0cfPy5 zLE+w|*fq&z1(ajJ)cb(S4uqSDHN@$}eZ*`);J$GL5Tk(z2XPLugP6~lm%JDh1gM$A zCk@c}6IT%9h}($gc|Hq}E&;)@KxjYLdx0s8TjVp!9}FC~5J=k$*n)w~?JRr__+u^$ zDS(_9CLw{GV!-zc;ufxF0wqV7i1C$=iSGkW?oXWE@N=LmAHuc+z}z7SO*a9B455pa z!v`R^Kjq<22$uyQ;26X=Ex@!~h$oH%h9yvU{6yRUjb$m5$ z@(MPxFtFr!E1*lj(v01V8^#OouLF|Ou>5a5+&_v{g_PE}9BamS-WY}>y?sD(7}}jL zvTZ=u1WFrFf}uC7xL>K57&i?rSbY^w9AvF5)0+W5k5X^H2!s_VLxu){m;z{~qN)PyRDNRG{+OyS~6v&!~i`Cjj$!mH$1F0b5l;^+~+h z1yxlJ6VDt~eI%24#12(^2hC$?c~SOw(Y(%!f$c&|>jO6Kq;T|RA#qsv`0^egXn}Bg zWh?buCj3QWUyO%@uWos`{(F=@nnIwo#`(@wML_r7I%R;#xm(?TR(L_EfPpR^}YI#QMD?qI=tm z0hhcO_{fV%`^A=sRyNZ7vDor99buRzwr<@*B|a5TUb;qoUKhU@vvPRr#S4?arK8$J z&j1Mp{UF}h)Wb$U@5Lm8_;8E_qux;~C+E>wU21tGiV6m+6Yiu_!CUJ2?VUh;iaK9G z-K`DkV-Fs4e^C7}>xzp`aBG65QmQHUG;MyH*zsu1$9VS-QiOc@Cz}K=i~MD!zQjT*6)7I)`k@6n?65A zLT-J_)x~U4jsB3EtyVqKpOCljreve~vo?{#8{W8He8RO_fBRJ@1v+g|bZp>mi6Qv> zMOyHbA^oR1z6Bn`@&M>e1raL=)T8BgpL@#{1f#t|6MYlXSv8K zX>vQ)L-tCMiEHVIPANT=4Ndq_%ACC%i0hXYr10ADuS-kzFrOjUr|5R+YY#E%Mak1mg2FpSb(@u=t}#aY|3D&%#<(#OeX7oQB9{A; z4;s(Z5aU9PT|w{Bs%gfq6k_O?#@+-rULS7kU&z`w9%4N8f3q1RABtKa?pcR z>e49BzQ&gEn6)IJnLsWhftSGTb9 z#ir(>QcCuV>94E*N69vr25ukX46HF-OaC)4=Y|8AH{n#g=B&mjHD77=-kyR`A75pYG99nZWYapjOr^c>(qwM+hb$c87Y|8A5 z&xMt5UcGWfO72Kim`zEq(q#OWH2%TI8dFqSSyfSFaTdSgv=ml2s*5TttIA3p&aw(e fsohfiN~OhKR#s@Kc2qhF93>9t+EaBtzs>qT^2rE( delta 2026 zcmX|B3sjV48h+-V|DVf0|I80^v10?s1I0^;v8|aMEKJ0_gd`?rCv4qiaY@13X6{;NBVBMG4!b+&%z0+M?|a|x`JVTA z-}cR#jaxLEM|xfcgnnRb6rjx|+K45@JmOAbB_ML&G8T}=1LNw5Q;Gj1X7LQ;2Qg$3 zpnCv#tp)S}#CM4C#IwZHfVl!tz5qh=fl(cRw*-vlxw+o4{K13X<-jv#K+H=(+D2ad z3-IgT@S!CM>3h~xz6tjUgE{`s|JWS05|vjS8cf$ppcEGk`D`gXq@f`{HeT%uT{ltJO z%o9H6x()NP-{8elv7o*VFqU9p>NZ{&f*1bqDv7VfqBCvW??PTq2;)CMX+Pu5cD!@p z5|C&|gPSiOGZig9ELmVZdMk>!|Dnb|J`x^;WoVw*8%C|a)l8~lJ!85wnXO}hum_r5 zSGXQ;&|I1)GI5FKs&D`Zh|=77stkD2UyyUp0TFwI@ZRgdggruv>?W~Y!i!#faZH)8 zr^CqedBU+xBo-?PpQTm-YN_x|Ci4c0LRVYXuYl+mgzo)*Oz6>y(Zd1XIog2lS@eK2 z+K|cwzHC5Sl*z zSKDdZH^q;a*HO=%;&Fv_G5=Zo@@6O3d&DpA{=hDR3cjS9b|-}j-qg)% zI0;O7O_!yi?qL^o2l@tp-~e57bd871UAl+1E3}$HA2NoLMU2)T9I=isT&6$bx5!@fhz z<5Ok$q&JlRXBqWoPLseyV`!~`ts)we9(ZyYaKJc!b`MJsV_dL~(k1DQSuaxRQ5s`T zYci+DBV!flFzhpSbf(i$Ym8mq95d1hIcXe6mTrWcbGe-__Lj@H< z(;LOUjQ_>d`aMfDdaUXE94h8FT=6|k0#P3+p5O*O6!{?Y_t+s~+>Q68?x^Y;Fm8k6uVJwHE6H@BM>Zzi1h;feQF2mXN-gRO*sta(5&z-ej4*i3B+)AW35-oqM<2{oMmXrUYCq|yJTuQtQ3||nS8vemKsc%$$li1&r{-XNd z9N^d~QlIT%!U?geE4P;lC99jSuBQix$~_{9V-f~`2}ugp7Xcd<1xF# znwMYXaywnQ)`I+1PPa4PWnGeAXw7!4a{o7)CtOZ9zXpb D32iIQ diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts index 806dd54ad3..efd893ec4c 100644 --- a/selfdrive/ui/translations/main_zh-CHT.ts +++ b/selfdrive/ui/translations/main_zh-CHT.ts @@ -125,7 +125,7 @@ Driver Camera - 駕駛監控 + 駕駛員攝像頭 @@ -134,8 +134,8 @@ - Preview the driver facing camera to help optimize device mounting position for best driver monitoring experience. (vehicle must be off) - 預覽駕駛監控鏡頭畫面,方便調整設備安裝的位置,以提供更準確的駕駛監控。(車子必須保持在熄火的狀態) + Preview the driver facing camera to ensure that driver monitoring has good visibility. (vehicle must be off) + 預覽駕駛員監控鏡頭畫面,以確保其具有良好視野。僅在熄火時可用。 From ee6dc0311818fd97cb78c58fb9a47267385312a0 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 12 Jul 2022 17:25:54 -0700 Subject: [PATCH 093/112] fix accord years --- docs/CARS.md | 2 +- selfdrive/car/honda/values.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/CARS.md b/docs/CARS.md index c3efe87515..ec7da7a845 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -161,7 +161,7 @@ How We Rate The Cars |Chrysler|Pacifica Hybrid 2019-22|Adaptive Cruise|||||| |Genesis|G90 2017-18|All|||||| |GMC|Acadia 2018[1](#footnotes)|Adaptive Cruise|||||| -|Honda|Accord 2016-22|All|||||| +|Honda|Accord 2018-22|All|||||| |Honda|Accord Hybrid 2018-22|All|||||| |Honda|Civic 2016-18|Honda Sensing|||||| |Honda|Civic 2019-21|All|||[2](#footnotes)||| diff --git a/selfdrive/car/honda/values.py b/selfdrive/car/honda/values.py index bfa42bd509..b8417ee19b 100644 --- a/selfdrive/car/honda/values.py +++ b/selfdrive/car/honda/values.py @@ -109,7 +109,7 @@ class HondaCarInfo(CarInfo): CAR_INFO: Dict[str, Optional[Union[HondaCarInfo, List[HondaCarInfo]]]] = { CAR.ACCORD: [ - HondaCarInfo("Honda Accord 2016-22", "All", video_link="https://www.youtube.com/watch?v=mrUwlj3Mi58", min_steer_speed=3. * CV.MPH_TO_MS, harness=Harness.bosch_a), + HondaCarInfo("Honda Accord 2018-22", "All", video_link="https://www.youtube.com/watch?v=mrUwlj3Mi58", min_steer_speed=3. * CV.MPH_TO_MS, harness=Harness.bosch_a), HondaCarInfo("Honda Inspire 2018", "All", min_steer_speed=3. * CV.MPH_TO_MS, harness=Harness.bosch_a), ], CAR.ACCORDH: HondaCarInfo("Honda Accord Hybrid 2018-22", "All", min_steer_speed=3. * CV.MPH_TO_MS, harness=Harness.bosch_a), From 00bb07f6248010afb197854257c2958433159990 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Tue, 12 Jul 2022 17:45:00 -0700 Subject: [PATCH 094/112] fw_versions.py: fix debug scanning (#25144) * Fix scanning all requests * fix replace --- selfdrive/car/fw_versions.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/selfdrive/car/fw_versions.py b/selfdrive/car/fw_versions.py index c4b158aebb..a8f5357f0e 100755 --- a/selfdrive/car/fw_versions.py +++ b/selfdrive/car/fw_versions.py @@ -394,7 +394,7 @@ def get_fw_versions_ordered(logcan, sendcan, ecu_rx_addrs, timeout=0.1, debug=Fa brand_matches = get_brand_ecu_matches(ecu_rx_addrs) for brand in sorted(brand_matches, key=lambda b: len(brand_matches[b]), reverse=True): - car_fw = get_fw_versions(logcan, sendcan, brand=brand, timeout=timeout, debug=debug, progress=progress) + car_fw = get_fw_versions(logcan, sendcan, query_brand=brand, timeout=timeout, debug=debug, progress=progress) all_car_fw.extend(car_fw) matches = match_fw_to_car_exact(build_fw_dict(car_fw)) if len(matches) == 1: @@ -403,10 +403,10 @@ def get_fw_versions_ordered(logcan, sendcan, ecu_rx_addrs, timeout=0.1, debug=Fa return all_car_fw -def get_fw_versions(logcan, sendcan, brand=None, extra=None, timeout=0.1, debug=False, progress=False): +def get_fw_versions(logcan, sendcan, query_brand=None, extra=None, timeout=0.1, debug=False, progress=False): versions = get_interface_attr('FW_VERSIONS', ignore_none=True) - if brand is not None: - versions = {brand: versions[brand]} + if query_brand is not None: + versions = {query_brand: versions[query_brand]} if extra is not None: versions.update(extra) @@ -434,7 +434,7 @@ def get_fw_versions(logcan, sendcan, brand=None, extra=None, timeout=0.1, debug= addrs.insert(0, parallel_addrs) fw_versions = {} - requests = [r for r in REQUESTS if brand is None or r.brand == brand] + requests = [r for r in REQUESTS if query_brand is None or r.brand == query_brand] for addr in tqdm(addrs, disable=not progress): for addr_chunk in chunks(addr): for r in requests: @@ -503,7 +503,7 @@ if __name__ == "__main__": print() t = time.time() - fw_vers = get_fw_versions(logcan, sendcan, brand=args.brand, extra=extra, debug=args.debug, progress=True) + fw_vers = get_fw_versions(logcan, sendcan, query_brand=args.brand, extra=extra, debug=args.debug, progress=True) _, candidates = match_fw_to_car(fw_vers) print() From 44c6ca7eb4c9ea83aca18d4f648764cabdad8861 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 12 Jul 2022 18:23:48 -0700 Subject: [PATCH 095/112] EV6: reject fake cruise engagements (#25143) * EV6: reject fake cruise engagements * bump panda * raise to 8 * update refs * bump panda Co-authored-by: Comma Device --- opendbc | 2 +- panda | 2 +- selfdrive/car/hyundai/carcontroller.py | 4 ++-- selfdrive/car/hyundai/carstate.py | 11 ++++++++--- selfdrive/car/hyundai/hda2can.py | 8 +++----- selfdrive/car/hyundai/interface.py | 5 ++--- selfdrive/car/hyundai/values.py | 2 +- selfdrive/test/process_replay/ref_commit | 2 +- 8 files changed, 19 insertions(+), 17 deletions(-) diff --git a/opendbc b/opendbc index 81148db67f..3fb3f5e821 160000 --- a/opendbc +++ b/opendbc @@ -1 +1 @@ -Subproject commit 81148db67fd00d4e2a107b5b8269c532436edf2b +Subproject commit 3fb3f5e82129ad76232bcdca10632ed0566b20f8 diff --git a/panda b/panda index baecd2ecc6..2abeab913f 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit baecd2ecc6a2a608e1305601f6f697feca69fe88 +Subproject commit 2abeab913f6432e4327b07e247b8a46994ac77a1 diff --git a/selfdrive/car/hyundai/carcontroller.py b/selfdrive/car/hyundai/carcontroller.py index a878ad3274..d0d9c40839 100644 --- a/selfdrive/car/hyundai/carcontroller.py +++ b/selfdrive/car/hyundai/carcontroller.py @@ -82,12 +82,12 @@ class CarController: if (self.frame - self.last_button_frame) * DT_CTRL > 0.25: if CC.cruiseControl.cancel: for _ in range(20): - can_sends.append(hda2can.create_buttons(self.packer, CS.buttons_counter+1, True, False)) + can_sends.append(hda2can.create_buttons(self.packer, CS.buttons_counter+1, Buttons.CANCEL)) self.last_button_frame = self.frame # cruise standstill resume elif CC.cruiseControl.resume: - can_sends.append(hda2can.create_buttons(self.packer, CS.buttons_counter+1, False, True)) + can_sends.append(hda2can.create_buttons(self.packer, CS.buttons_counter+1, Buttons.RES_ACCEL)) self.last_button_frame = self.frame else: diff --git a/selfdrive/car/hyundai/carstate.py b/selfdrive/car/hyundai/carstate.py index a10cdadbca..8afd851f00 100644 --- a/selfdrive/car/hyundai/carstate.py +++ b/selfdrive/car/hyundai/carstate.py @@ -8,7 +8,7 @@ from opendbc.can.can_define import CANDefine from selfdrive.car.hyundai.values import DBC, FEATURES, HDA2_CAR, EV_CAR, HYBRID_CAR, Buttons, CarControllerParams from selfdrive.car.interfaces import CarStateBase -PREV_BUTTON_SAMPLES = 4 +PREV_BUTTON_SAMPLES = 8 class CarState(CarStateBase): @@ -171,7 +171,10 @@ class CarState(CarStateBase): speed_factor = CV.MPH_TO_MS if cp.vl["CLUSTER_INFO"]["DISTANCE_UNIT"] == 1 else CV.KPH_TO_MS ret.cruiseState.speed = cp.vl["CRUISE_INFO"]["SET_SPEED"] * speed_factor - self.buttons_counter = cp.vl["CRUISE_BUTTONS"]["_COUNTER"] + self.cruise_buttons.extend(cp.vl_all["CRUISE_BUTTONS"]["CRUISE_BUTTONS"]) + self.main_buttons.extend(cp.vl_all["CRUISE_BUTTONS"]["ADAPTIVE_CRUISE_MAIN_BTN"]) + self.buttons_counter = cp.vl["CRUISE_BUTTONS"]["COUNTER"] + self.cam_0x2a4 = copy.copy(cp_cam.vl["CAM_0x2a4"]) return ret @@ -362,7 +365,9 @@ class CarState(CarStateBase): ("CRUISE_ACTIVE", "SCC1"), ("SET_SPEED", "CRUISE_INFO"), ("CRUISE_STANDSTILL", "CRUISE_INFO"), - ("_COUNTER", "CRUISE_BUTTONS"), + ("COUNTER", "CRUISE_BUTTONS"), + ("CRUISE_BUTTONS", "CRUISE_BUTTONS"), + ("ADAPTIVE_CRUISE_MAIN_BTN", "CRUISE_BUTTONS"), ("DISTANCE_UNIT", "CLUSTER_INFO"), diff --git a/selfdrive/car/hyundai/hda2can.py b/selfdrive/car/hyundai/hda2can.py index 437f5cf538..9a9e477cf5 100644 --- a/selfdrive/car/hyundai/hda2can.py +++ b/selfdrive/car/hyundai/hda2can.py @@ -18,11 +18,9 @@ def create_cam_0x2a4(packer, frame, camera_values): }) return packer.make_can_msg("CAM_0x2a4", 4, camera_values, frame % 255) -def create_buttons(packer, cnt, cancel, resume): +def create_buttons(packer, cnt, btn): values = { - "_COUNTER": cnt % 0xf, "SET_ME_1": 1, - "DISTANCE_BTN": 1 if resume else 0, - "PAUSE_RESUME_BTN": 1 if cancel else 0, + "CRUISE_BUTTONS": btn, } - return packer.make_can_msg("CRUISE_BUTTONS", 5, values) + return packer.make_can_msg("CRUISE_BUTTONS", 5, values, cnt % 0xf) diff --git a/selfdrive/car/hyundai/interface.py b/selfdrive/car/hyundai/interface.py index 069b0e74e5..a32ee2c0ab 100644 --- a/selfdrive/car/hyundai/interface.py +++ b/selfdrive/car/hyundai/interface.py @@ -2,7 +2,7 @@ from cereal import car from panda import Panda from common.conversions import Conversions as CV -from selfdrive.car.hyundai.values import CAR, DBC, HDA2_CAR, EV_CAR, HYBRID_CAR, LEGACY_SAFETY_MODE_CAR, Buttons, CarControllerParams +from selfdrive.car.hyundai.values import CAR, DBC, EV_CAR, HYBRID_CAR, LEGACY_SAFETY_MODE_CAR, Buttons, CarControllerParams from selfdrive.car.hyundai.radar_interface import RADAR_START_ADDR from selfdrive.car import STD_CARGO_KG, create_button_enable_events, create_button_event, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config from selfdrive.car.interfaces import CarInterfaceBase @@ -321,8 +321,7 @@ class CarInterface(CarInterfaceBase): # To avoid re-engaging when openpilot cancels, check user engagement intention via buttons # Main button also can trigger an engagement on these cars allow_enable = any(btn in ENABLE_BUTTONS for btn in self.CS.cruise_buttons) or any(self.CS.main_buttons) - allow_enable = allow_enable or self.CP.carFingerprint in HDA2_CAR - events = self.create_common_events(ret, pcm_enable=self.CS.CP.pcmCruise, allow_enable=allow_enable or True) + events = self.create_common_events(ret, pcm_enable=self.CS.CP.pcmCruise, allow_enable=allow_enable) if self.CS.brake_error: events.add(EventName.brakeUnavailable) diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index 6e184ce9ef..ffa29c60d4 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -167,7 +167,7 @@ class Buttons: RES_ACCEL = 1 SET_DECEL = 2 GAP_DIST = 3 - CANCEL = 4 + CANCEL = 4 # on newer models, this is a pause/resume button FINGERPRINTS = { CAR.ELANTRA: [{ diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index b165b163ba..e77a38de5f 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -11e721366f1c177a84e6cb8b48171113ac3b54f9 \ No newline at end of file +5efbbdf69e16db3d989bfaf62d10e958e80b9ca2 \ No newline at end of file From aadaaabd54988a286704ef2bea0bacf4bd62fa8b Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Tue, 12 Jul 2022 18:58:46 -0700 Subject: [PATCH 096/112] compatibility docs: print diff from PR (#24941) * print docs diff * revert car changes * cause a diff * temp so it works * text diff * tier inline is a bit too much * comments * fix * use paths * fix * temp * temp * diff * fix * remove something * more text diff * Delete comment if outdated * Smaller diff * remove * no diff * Don't try to run on fork PRs * cause some errors * Fix * Fix * Doesn't support env in job if, only step if * in case file was moved, don't throw error * See if this does what I think it does * See if this does what I think it does * should work * change something * revert * uncomment * no comment * this shouldn't fail * rename to base * Remove true * Remove other true --- .github/workflows/selfdrive_tests.yaml | 71 +++++++++++++++++++- selfdrive/debug/dump_car_info.py | 18 ++++++ selfdrive/debug/print_docs_diff.py | 90 ++++++++++++++++++++++++++ 3 files changed, 176 insertions(+), 3 deletions(-) create mode 100755 selfdrive/debug/dump_car_info.py create mode 100755 selfdrive/debug/print_docs_diff.py diff --git a/.github/workflows/selfdrive_tests.yaml b/.github/workflows/selfdrive_tests.yaml index 99a21b58f3..298ea5fb49 100644 --- a/.github/workflows/selfdrive_tests.yaml +++ b/.github/workflows/selfdrive_tests.yaml @@ -10,6 +10,7 @@ env: CL_BASE_IMAGE: openpilot-base-cl DOCKER_REGISTRY: ghcr.io/commaai AZURE_TOKEN: ${{ secrets.AZURE_COMMADATACI_OPENPILOTCI_TOKEN }} + HAS_AZURE_TOKEN: $AZURE_TOKEN != '' DOCKER_LOGIN: docker login ghcr.io -u adeebshihadeh -p ${{ secrets.CONTAINER_TOKEN }} BUILD: | @@ -17,12 +18,12 @@ env: docker pull $DOCKER_REGISTRY/$BASE_IMAGE:latest || true docker build --cache-from $DOCKER_REGISTRY/$BASE_IMAGE:latest -t $DOCKER_REGISTRY/$BASE_IMAGE:latest -t $BASE_IMAGE:latest -f Dockerfile.openpilot_base . - RUN: docker run --shm-size 1G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v /tmp/scons_cache:/tmp/scons_cache -v /tmp/comma_download_cache:/tmp/comma_download_cache $BASE_IMAGE /bin/sh -c + RUN: docker run --shm-size 1G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v /tmp/scons_cache:/tmp/scons_cache -v /tmp/comma_download_cache:/tmp/comma_download_cache -v /tmp/openpilot_cache:/tmp/openpilot_cache $BASE_IMAGE /bin/sh -c BUILD_CL: | docker pull $DOCKER_REGISTRY/$CL_BASE_IMAGE:latest || true docker build --cache-from $DOCKER_REGISTRY/$CL_BASE_IMAGE:latest -t $DOCKER_REGISTRY/$CL_BASE_IMAGE:latest -t $CL_BASE_IMAGE:latest -f Dockerfile.openpilot_base_cl . - RUN_CL: docker run --shm-size 1G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v /tmp/scons_cache:/tmp/scons_cache -v /tmp/comma_download_cache:/tmp/comma_download_cache $CL_BASE_IMAGE /bin/sh -c + RUN_CL: docker run --shm-size 1G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v /tmp/scons_cache:/tmp/scons_cache -v /tmp/comma_download_cache:/tmp/comma_download_cache -v /tmp/openpilot_cache:/tmp/openpilot_cache $CL_BASE_IMAGE /bin/sh -c UNIT_TEST: coverage run --append -m unittest discover @@ -365,7 +366,7 @@ jobs: name: process_replay_diff.txt path: selfdrive/test/process_replay/diff.txt - name: Upload reference logs - if: ${{ failure() && github.event_name == 'pull_request' && github.repository == 'commaai/openpilot' && env.AZURE_TOKEN != '' }} + if: ${{ failure() && github.event_name == 'pull_request' && github.repository == 'commaai/openpilot' && env.HAS_AZURE_TOKEN }} run: | ${{ env.RUN }} "scons -j$(nproc) && \ CI=1 AZURE_TOKEN='$AZURE_TOKEN' python selfdrive/test/process_replay/test_processes.py -j$(nproc) --upload-only" @@ -510,3 +511,67 @@ jobs: run: | $DOCKER_LOGIN docker push $DOCKER_REGISTRY/openpilot-docs:latest + + car_docs_diff: + name: comment on PR with car docs diff + runs-on: ubuntu-20.04 + timeout-minutes: 50 + if: github.event_name == 'pull_request' + steps: + - uses: actions/checkout@v3 + with: + submodules: true + ref: ${{ github.event.pull_request.base.ref }} + - name: Cache scons + id: scons-cache + # TODO: Change the version to the released version when https://github.com/actions/cache/pull/489 (or 571) is merged. + uses: actions/cache@03e00da99d75a2204924908e1cca7902cafce66b + env: + CACHE_SKIP_SAVE: true + with: + path: /tmp/scons_cache + key: scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}- + restore-keys: | + scons-${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}- + scons- + - name: Build Docker image + run: eval "$BUILD" + - name: Get base car info + run: | + ${{ env.RUN }} "scons -j$(nproc) && python selfdrive/debug/dump_car_info.py --path /tmp/openpilot_cache/base_car_info" + sudo chown -R $USER:$USER ${{ github.workspace }} + - uses: actions/checkout@v3 + with: + submodules: true + - name: Save car docs diff + id: save_diff + run: | + ${{ env.RUN }} "scons -j$(nproc)" + output=$(${{ env.RUN }} "python selfdrive/debug/print_docs_diff.py --path /tmp/openpilot_cache/base_car_info") + output="${output//$'\n'/'%0A'}" + echo "::set-output name=diff::$output" + - name: Find comment + if: env.HAS_AZURE_TOKEN + uses: peter-evans/find-comment@v1 + id: fc + with: + issue-number: ${{ github.event.pull_request.number }} + body-includes: This PR makes changes to + - name: Update comment + if: steps.save_diff.outputs.diff != '' && env.HAS_AZURE_TOKEN + uses: peter-evans/create-or-update-comment@v1 + with: + comment-id: ${{ steps.fc.outputs.comment-id }} + issue-number: ${{ github.event.pull_request.number }} + body: "${{ steps.save_diff.outputs.diff }}" + edit-mode: replace + - name: Delete comment + if: steps.fc.outputs.comment-id != '' && steps.save_diff.outputs.diff == '' && env.HAS_AZURE_TOKEN + uses: actions/github-script@v6 + with: + script: | + github.rest.issues.deleteComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: ${{ steps.fc.outputs.comment-id }} + }) diff --git a/selfdrive/debug/dump_car_info.py b/selfdrive/debug/dump_car_info.py new file mode 100755 index 0000000000..c9a21c2848 --- /dev/null +++ b/selfdrive/debug/dump_car_info.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +import argparse +import pickle + +from selfdrive.car.docs import get_all_car_info + + +def dump_car_info(path): + with open(path, 'wb') as f: + pickle.dump(get_all_car_info(), f) + print(f'Dumping car info to {path}') + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("--path", required=True) + args = parser.parse_args() + dump_car_info(args.path) diff --git a/selfdrive/debug/print_docs_diff.py b/selfdrive/debug/print_docs_diff.py new file mode 100755 index 0000000000..5cf3867b2d --- /dev/null +++ b/selfdrive/debug/print_docs_diff.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 +import argparse +import pickle + +from selfdrive.car.docs import get_all_car_info +from selfdrive.car.docs_definitions import Column + +STAR_ICON = '' +COLUMNS = "|" + "|".join([column.value for column in Column]) + "|" +COLUMN_HEADER = "|---|---|---|:---:|:---:|:---:|:---:|:---:|" +ARROW_SYMBOL = "➡️" + + +def load_base_car_info(path): + with open(path, "rb") as f: + return pickle.load(f) + + +def get_star_diff(base_car, new_car): + return [column for column, value in base_car.row.items() if value != new_car.row[column]] + + +def format_row(builder): + return "|" + "|".join(builder) + "|" + + +def print_car_info_diff(path): + base_car_info = {f"{i.make} {i.model}": i for i in load_base_car_info(path)} + new_car_info = {f"{i.make} {i.model}": i for i in get_all_car_info()} + + tier_changes = [] + star_changes = [] + removals = [] + additions = [] + + # Changes (tier + stars) + for base_car_model, base_car in base_car_info.items(): + if base_car_model not in new_car_info: + continue + + new_car = new_car_info[base_car_model] + + # Tier changes + if base_car.tier != new_car.tier: + tier_changes.append(f"- Tier for {base_car.make} {base_car.model} changed! ({base_car.tier.name.title()} {ARROW_SYMBOL} {new_car.tier.name.title()})") + + # Star changes + diff = get_star_diff(base_car, new_car) + if not len(diff): + continue + + row_builder = [] + for column in list(Column): + if column not in diff: + row_builder.append(new_car.get_column(column, STAR_ICON, "{}")) + else: + row_builder.append(base_car.get_column(column, STAR_ICON, "{}") + ARROW_SYMBOL + new_car.get_column(column, STAR_ICON, "{}")) + + star_changes.append(format_row(row_builder)) + + # Removals + for model in set(base_car_info) - set(new_car_info): + car_info = base_car_info[model] + removals.append(format_row([car_info.get_column(column, STAR_ICON, "{}") for column in Column])) + + # Additions + for model in set(new_car_info) - set(base_car_info): + car_info = new_car_info[model] + additions.append(format_row([car_info.get_column(column, STAR_ICON, "{}") for column in Column])) + + # Print diff + if len(star_changes) or len(tier_changes) or len(removals) or len(additions): + markdown_builder = ["### ⚠️ This PR makes changes to [CARS.md](../blob/master/docs/CARS.md) ⚠️"] + + for title, category in (("## 🏅 Tier Changes", tier_changes), ("## 🔀 Star Changes", star_changes), ("## ❌ Removed", removals), ("## ➕ Added", additions)): + if len(category): + markdown_builder.append(title) + if "Tier" not in title: + markdown_builder.append(COLUMNS) + markdown_builder.append(COLUMN_HEADER) + markdown_builder.extend(category) + + print("\n".join(markdown_builder)) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("--path", required=True) + args = parser.parse_args() + print_car_info_diff(args.path) From 01de46ad82358efa12797a50f501d902ca711547 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Tue, 12 Jul 2022 19:25:03 -0700 Subject: [PATCH 097/112] Corolla Cross: Update minimum enable speed (#25132) * Update min steer speed for intl. Corolla Cross 27 km/h, thanks to Ale Sato * update docs --- docs/CARS.md | 6 +++--- selfdrive/car/toyota/values.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/CARS.md b/docs/CARS.md index ec7da7a845..e24672e9bc 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -35,7 +35,7 @@ How We Rate The Cars **All supported cars can move between the tiers as support changes.** -# Gold - 31 cars +# Gold - 30 cars |Make|Model|Supported Package|openpilot ACC|Stop and Go|Steer to 0|Steering Torque|Actively Maintained| |---|---|---|:---:|:---:|:---:|:---:|:---:| @@ -60,7 +60,6 @@ How We Rate The Cars |Toyota|Camry 2021-22|All||[4](#footnotes)|||| |Toyota|Camry Hybrid 2021-22|All|||||| |Toyota|Corolla 2020-22|All|||||| -|Toyota|Corolla Cross 2020-21 (Non-US only)|All|||||| |Toyota|Corolla Hatchback 2019-22|All|||||| |Toyota|Corolla Hybrid 2020-22|All|||||| |Toyota|Highlander 2020-22|All|||||| @@ -71,7 +70,7 @@ How We Rate The Cars |Toyota|RAV4 2019-21|All|||||| |Toyota|RAV4 Hybrid 2019-21|All|||||| -# Silver - 69 cars +# Silver - 70 cars |Make|Model|Supported Package|openpilot ACC|Stop and Go|Steer to 0|Steering Torque|Actively Maintained| |---|---|---|:---:|:---:|:---:|:---:|:---:| @@ -126,6 +125,7 @@ How We Rate The Cars |Toyota|Alphard Hybrid 2021|All|||||| |Toyota|Camry 2018-20|All||[4](#footnotes)|||| |Toyota|Camry Hybrid 2018-20|All||[4](#footnotes)|||| +|Toyota|Corolla Cross 2020-21 (Non-US only)|All|||||| |Toyota|Highlander 2017-19|All|[3](#footnotes)||||| |Toyota|Highlander Hybrid 2017-19|All|[3](#footnotes)||||| |Toyota|Prius 2016-20|TSS-P|[3](#footnotes)||||| diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py index f47ab87040..f40a58b5a7 100644 --- a/selfdrive/car/toyota/values.py +++ b/selfdrive/car/toyota/values.py @@ -119,7 +119,7 @@ CAR_INFO: Dict[str, Union[ToyotaCarInfo, List[ToyotaCarInfo]]] = { CAR.COROLLA: ToyotaCarInfo("Toyota Corolla 2017-19", footnotes=[Footnote.DSU]), CAR.COROLLA_TSS2: [ ToyotaCarInfo("Toyota Corolla 2020-22", video_link="https://www.youtube.com/watch?v=_66pXk0CBYA"), - ToyotaCarInfo("Toyota Corolla Cross 2020-21 (Non-US only)"), + ToyotaCarInfo("Toyota Corolla Cross 2020-21 (Non-US only)", min_enable_speed=7.5), ToyotaCarInfo("Toyota Corolla Hatchback 2019-22", video_link="https://www.youtube.com/watch?v=_66pXk0CBYA"), ], CAR.COROLLAH_TSS2: [ From 906a8a912cbd39863f43582677f2435f11ecb904 Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Wed, 13 Jul 2022 04:28:48 +0200 Subject: [PATCH 098/112] casync: only when run from updater (#25130) * casync: only when run from updater * also here --- system/hardware/tici/agnos.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/system/hardware/tici/agnos.py b/system/hardware/tici/agnos.py index 750aa630ae..ca2498a00c 100755 --- a/system/hardware/tici/agnos.py +++ b/system/hardware/tici/agnos.py @@ -222,7 +222,7 @@ def extract_casync_image(target_slot_number: int, partition: dict, cloudlog): raise Exception(f"Raw hash mismatch '{partition['hash_raw'].lower()}'") -def flash_partition(target_slot_number: int, partition: dict, cloudlog): +def flash_partition(target_slot_number: int, partition: dict, cloudlog, standalone=False): cloudlog.info(f"Downloading and writing {partition['name']}") if verify_partition(target_slot_number, partition): @@ -236,7 +236,7 @@ def flash_partition(target_slot_number: int, partition: dict, cloudlog): path = get_partition_path(target_slot_number, partition) - if 'casync_caibx' in partition: + if ('casync_caibx' in partition) and not standalone: extract_casync_image(target_slot_number, partition, cloudlog) else: extract_compressed_image(target_slot_number, partition, cloudlog) @@ -263,7 +263,7 @@ def swap(manifest_path: str, target_slot_number: int, cloudlog) -> None: cloudlog.error(f"Swap failed {out}") -def flash_agnos_update(manifest_path: str, target_slot_number: int, cloudlog) -> None: +def flash_agnos_update(manifest_path: str, target_slot_number: int, cloudlog, standalone=False) -> None: update = json.load(open(manifest_path)) cloudlog.info(f"Target slot {target_slot_number}") @@ -276,7 +276,7 @@ def flash_agnos_update(manifest_path: str, target_slot_number: int, cloudlog) -> for retries in range(10): try: - flash_partition(target_slot_number, partition, cloudlog) + flash_partition(target_slot_number, partition, cloudlog, standalone) success = True break @@ -320,9 +320,9 @@ if __name__ == "__main__": elif args.swap: while not verify_agnos_update(args.manifest, target_slot_number): logging.error("Verification failed. Flashing AGNOS") - flash_agnos_update(args.manifest, target_slot_number, logging) + flash_agnos_update(args.manifest, target_slot_number, logging, standalone=True) logging.warning(f"Verification succeeded. Swapping to slot {target_slot_number}") swap(args.manifest, target_slot_number, logging) else: - flash_agnos_update(args.manifest, target_slot_number, logging) + flash_agnos_update(args.manifest, target_slot_number, logging, standalone=True) From 0eab1ed817ece20b25de7438d32238c482613df3 Mon Sep 17 00:00:00 2001 From: Jafar Al-Gharaibeh Date: Tue, 12 Jul 2022 20:38:18 -0600 Subject: [PATCH 099/112] Mazda: CX-5 22 FW FP (#24778) Mazda CX-5 2022 FW FP dongle-id: 661621a8442f0688 Signed-off-by: Jafar Al-Gharaibeh --- selfdrive/car/mazda/values.py | 1 + 1 file changed, 1 insertion(+) diff --git a/selfdrive/car/mazda/values.py b/selfdrive/car/mazda/values.py index 09b9b7732b..12e9eafc4f 100644 --- a/selfdrive/car/mazda/values.py +++ b/selfdrive/car/mazda/values.py @@ -65,6 +65,7 @@ FW_VERSIONS = { ], (Ecu.engine, 0x7e0, None): [ b'PX2G-188K2-H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', + b'PX2H-188K2-H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'SH54-188K2-D\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], (Ecu.fwdRadar, 0x764, None): [ From 3b4e939b9f88b70727e687613a912aef36178755 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Tue, 12 Jul 2022 19:58:39 -0700 Subject: [PATCH 100/112] UI: translations cleanup (#25120) * Make this one translation * Remote html from translations * getBrand as argument * some stuff * Forget Wi-Fi network * Update translations * Remove obsolete * compilation fixes * remove * Fix missing translation --- selfdrive/ui/qt/offroad/networking.cc | 8 +-- selfdrive/ui/qt/offroad/settings.cc | 2 +- selfdrive/ui/qt/widgets/input.cc | 2 +- selfdrive/ui/qt/widgets/prime.cc | 13 ++-- selfdrive/ui/translations/main_ko.qm | Bin 19981 -> 19439 bytes selfdrive/ui/translations/main_ko.ts | 79 +++++++++++------------ selfdrive/ui/translations/main_zh-CHS.qm | Bin 18469 -> 17931 bytes selfdrive/ui/translations/main_zh-CHS.ts | 79 +++++++++++------------ selfdrive/ui/translations/main_zh-CHT.qm | Bin 18509 -> 17969 bytes selfdrive/ui/translations/main_zh-CHT.ts | 79 +++++++++++------------ selfdrive/ui/update_translations.py | 10 ++- 11 files changed, 129 insertions(+), 143 deletions(-) diff --git a/selfdrive/ui/qt/offroad/networking.cc b/selfdrive/ui/qt/offroad/networking.cc index 536ca495ca..c7341d1987 100644 --- a/selfdrive/ui/qt/offroad/networking.cc +++ b/selfdrive/ui/qt/offroad/networking.cc @@ -84,7 +84,7 @@ void Networking::connectToNetwork(const Network &n) { } else if (n.security_type == SecurityType::OPEN) { wifi->connect(n); } else if (n.security_type == SecurityType::WPA) { - QString pass = InputDialog::getText(tr("Enter password"), this, tr("for \"") + n.ssid + "\"", true, 8); + QString pass = InputDialog::getText(tr("Enter password"), this, tr("for \"%1\"").arg(QString::fromUtf8(n.ssid)), true, 8); if (!pass.isEmpty()) { wifi->connect(n, pass); } @@ -94,7 +94,7 @@ void Networking::connectToNetwork(const Network &n) { void Networking::wrongPassword(const QString &ssid) { if (wifi->seenNetworks.contains(ssid)) { const Network &n = wifi->seenNetworks.value(ssid); - QString pass = InputDialog::getText(tr("Wrong password"), this, tr("for \"") + n.ssid +"\"", true, 8); + QString pass = InputDialog::getText(tr("Wrong password"), this, tr("for \"%1\"").arg(QString::fromUtf8(n.ssid)), true, 8); if (!pass.isEmpty()) { wifi->connect(n, pass); } @@ -174,7 +174,7 @@ AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWid list->addItem(editApnButton); // Set initial config - wifi->updateGsmSettings(roamingEnabled, QString::fromStdString(params.get("GsmApn"))); + wifi->updateGsmSettings(roamingEnabled, QString::fromStdString(params.get("GsmApn"))); main_layout->addWidget(new ScrollView(list, this)); main_layout->addStretch(1); @@ -296,7 +296,7 @@ void WifiUI::refresh() { QPushButton *forgetBtn = new QPushButton(tr("FORGET")); forgetBtn->setObjectName("forgetBtn"); QObject::connect(forgetBtn, &QPushButton::clicked, [=]() { - if (ConfirmationDialog::confirm(tr("Forget Wi-Fi Network \"") + QString::fromUtf8(network.ssid) + "\"?", this)) { + if (ConfirmationDialog::confirm(tr("Forget Wi-Fi Network \"%1\"?").arg(QString::fromUtf8(network.ssid)), this)) { wifi->forgetConnection(network.ssid); } }); diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index 9aeb966ccf..9a6e203966 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -249,7 +249,7 @@ SoftwarePanel::SoftwarePanel(QWidget* parent) : ListWidget(parent) { }); - auto uninstallBtn = new ButtonControl(tr("Uninstall ") + getBrand(), tr("UNINSTALL")); + auto uninstallBtn = new ButtonControl(tr("Uninstall %1").arg(getBrand()), tr("UNINSTALL")); connect(uninstallBtn, &ButtonControl::clicked, [&]() { if (ConfirmationDialog::confirm(tr("Are you sure you want to uninstall?"), this)) { params.putBool("DoUninstall", true); diff --git a/selfdrive/ui/qt/widgets/input.cc b/selfdrive/ui/qt/widgets/input.cc index b0facfce83..dc54a3621c 100644 --- a/selfdrive/ui/qt/widgets/input.cc +++ b/selfdrive/ui/qt/widgets/input.cc @@ -165,7 +165,7 @@ void InputDialog::handleEnter() { done(QDialog::Accepted); emitText(line->text()); } else { - setMessage(tr("Need at least ") + QString::number(minLength) + tr(" characters!"), false); + setMessage(tr("Need at least %1 characters!").arg(minLength), false); } } diff --git a/selfdrive/ui/qt/widgets/prime.cc b/selfdrive/ui/qt/widgets/prime.cc index d2529821f4..5419475262 100644 --- a/selfdrive/ui/qt/widgets/prime.cc +++ b/selfdrive/ui/qt/widgets/prime.cc @@ -88,13 +88,16 @@ PairingPopup::PairingPopup(QWidget *parent) : QDialogBase(parent) { title->setWordWrap(true); vlayout->addWidget(title); - QLabel *instructions = new QLabel(tr(R"( + QLabel *instructions = new QLabel(QString(R"(
    -
  1. Go to https://connect.comma.ai on your phone
  2. -
  3. Click "add new device" and scan the QR code on the right
  4. -
  5. Bookmark connect.comma.ai to your home screen to use it like an app
  6. +
  7. %1
  8. +
  9. %2
  10. +
  11. %3
- )"), this); + )").arg(tr("Go to https://connect.comma.ai on your phone")) + .arg(tr("Click \"add new device\" and scan the QR code on the right")) + .arg(tr("Bookmark connect.comma.ai to your home screen to use it like an app")), this); + instructions->setStyleSheet("font-size: 47px; font-weight: bold; color: black;"); instructions->setWordWrap(true); vlayout->addWidget(instructions); diff --git a/selfdrive/ui/translations/main_ko.qm b/selfdrive/ui/translations/main_ko.qm index 40b0bb65a38d65ee901ac7a85257e88868b4513c..d59698e07432f37ed105ada86a1c83bc815e0e0f 100644 GIT binary patch delta 2085 zcmYLJ3s98T89lrE|NHp&1qcfgS@r=c1%WkcK?M{P0~C=K4Mjyk2tp9$p~gJAlTkwq zYBdWLX;|7-Q0vsO$ zsjsu}HQ;BzV4uIE&S_uS7$S8GDtRSrT2dnz$;ODP=3(QME zmi(_=FF{uRtE^_ms*??X6oBlMTAph{&Z(CHXW}`mz1YJ8=kdY>0}b2o&ZR3r(kV1o z<#I}a=$Mj0+PN5gV=MQ2WTw~%Af!zea5RKM?v%~l&*{yMk!5y<0il~^Z}oG1fkSpB zO8`u_WH;rU#I!52dr$8o;X1ig^a&7_BM%)Nh7+?N$&;ljsu&?(<7GR2j|31?|PqbSYe z1QuIFeN8zq|GJoD2qp0cV)lAYC`Kt3NgvTVLt;tD2~HqiENMK+5hoG9V|EM&B2u{r&21hG{@#O0UZOj^!O4-$7u~<6H+0cr!)v>##BQ;Df{M!< z#eqQ*u&)zu@1$iyy*-%tia0(&LQ&mHxiyQO#V8G9kyI>Lx$s^x6)RIFE+3}ntjcB0 zZNS0~ll=Wtddf(Q!xbLU_?P~1wL)n7Crn=UfWp;`P*5#u^FE7L|uv|Y2xxsy^Y$=9r2LuseiYYIAf+h)2o z`$2D^MbkI1oLji@Qq&@fe!k9;iaqMths<}fC2d7K5 zlN{;vFsc6hae6dEa^GCZ(bP#tdpTlZuGIK?EtM;moF7JuyuK!>y@-M07O6ur^D((D zb(j|Nwq;3oH&juwZmq2KSA1-4Y3&z2p%<=dlW*+-ri5$P4)Zy%*J{f@6DX;d_SJ2^ zR8X(&{E8!*aa-G+PUTD`I^PQ<5P4W%bzJE;VK?XO*i< zOQaHUa^0#rCJZ*|HZ6ZltXFqv{8=U_)-@mGEi>D7J;$h=BVPCE05R%K-9RS^3ZLth zCqh{8h(0Rl1{=xH$4-#wQ*rvnIo!97>CbH^F4(W{u)RyuItTR~iTs$+s=u_5UeJ2! z`?7f*{kjZ(@15W%HX8z~seo^+!S*nTO6@bm4DmgRzF|n)O9_2nG?XVUW!!zko+B%$ zK%?RJ4JAOZ zfcP85G*V;Be3jPA^{zD4<@WbpYVKWgaW5v&yM+EVOlSLlLfeyY z^>dpmEVfXG&1EtBwwyF)%jC#$jahS~Cr6T8ZhMj|H^d}c$+2U#BNlM+yvf{GJs=U%t5_bJN#=oU$ewUAIrfXZe Y#mB=C2~SQ3x{jrr1aeGpwWdG&KXjTDOaK4? delta 2644 zcmcIk2~bq`9sYLry=6zG(a>Wyk%k_Jfz*{i zM9jOR=-<7EHcHV|An8nG55pE_LUcsc+ z*MacGm~`_4AjXEt`gzQC6&YhUq3_99l1!4WBg^h0Nj`Y#DzkYPVd_us)4m+j)Sq&F z0jAAc&MY~|*;@}tgOQtFL%U;m`Im37%3GLyvK4TK-AD0!KW@ZgX)gnq7GvibGMRcA z4URd$=&5KLl*O_)qi5YB?zgI}v7^c8x2nP01AtM#RYh-L_o5c4vYSVd*uAQEJGh?s zs_NV{0kA$$T~f0X!?mhgkt=~=ZEC6TGaz`QIE$lW-P_0#3WcI{ zGVGo$R9;I0{EiE6%wtJ9gRolo28i1))TSS$0$&?IOX>hx{RYr>Q>d$d$kN<}UETAE znZo`rHc^2p;qXuDfi#ow8=1{9-51V&*~#^M;q2|Za169++cc_Yf!1^{lnl<$CfrIRgC*KY z4ab0_2iln`k{`5OyZhl|z<-SPQI@lVG8?M%8%3&u)w(@HR`6uKx_=isPYhK7Y&F1zL5`JTG3b$e?O=hXK_x1aB09M2B7 z4|@FhZPDwDuTaMRdjC4k`SW-56Tar38!c+R36{IX}jeh1VQatj!ett6t z?YVaS22fsT)VFs|p`5DqSKLc^^Y}{>f_Xb>H%jx*xACO1wDuM+7n=_;k^W<(svBm0 zuaasWv$Z4hq}rpqDbqr!?$UI&s7>15##Rf_lJmft8dA1f`Z!$V1W%Su71B{GlbR%7 z-Xj;JCTju*ZM}5!RR<}9LG|G>+FK0%Cq83ADnr`u*8+o5470ECMhN`eP<~M$lame0 z7kiRHqoMgLw&uB^hSM*SG3(D{&l4;l{DN$2;QGi~ryP=4Ns(-m(^A;uJHbpL;(pOlUyyejh2G}V#yu(3LX3DKQ$XsNZ{COua;*8wc%mRhW zM(v&eCTui@`TULt$uh?FvQVEz#sg8@4+t`Tw1k-GJYj6|`vui|#n_Zg9Cg=tCV^To zSd8tt980f1n7rQK!xQW^4OvYFJhM%H4^zn0aZ^keucAn^DRVs;^xSAFPfn%Z9n;$P zIO)MXrfoOIQyZnGU)3{F%r~ZE52y*>YSX##=PB}2X171_j-26^VfLKBxsJVVwto2- z7^^lO;+4 zX$SeOFQSkxHYV!~79Wq6>is0CV`6hnM^VG+hHluXKMIGh?E1C0&Glf!k6Z=b?!&ch zvrevu^24raN`C%)CC{PQ^Ya!ul*Xgp`?SO4j@*OcEkegEDDeBiR4gd1Q2bmLU(d!J zzPT!=dNCv#{Oy;3QrP+JKqbnMk3<9^g0F&w{cH9oYsJVz1qxAw5`@qr9|hcxqg@1| z>A4i~^h)}N=zVz-XkGLqUSwszYhRMT4>*ryIQT2&dSB3Jgg*`H%Ce20!zf|>asE?= z{~-aATt}4ga}oM~PLgL+Ttk#N=f6qRcgntgJafvYtyDQArTBXAwT%u- z2(uUcOQ(P0qqfET*FJNU6zj8j62eOD136tg6>DRst=u|PdwSUZvS-vTO)n`bS?I{K i+ZETzvEGd - Need at least - 최소 - - - - characters! - 자가 필요합니다! + Need at least %1 characters! + 최소 %1 자가 필요합니다!
@@ -481,8 +476,8 @@ location set - for " - 하기위한 " + for "%1" + 하기위한 "%1" @@ -547,52 +542,50 @@ location set 장치를 콤마 계정과 페어링합니다 - - - <ol type='1' style='margin-left: 15px;'> - <li style='margin-bottom: 50px;'>Go to https://connect.comma.ai on your phone</li> - <li style='margin-bottom: 50px;'>Click "add new device" and scan the QR code on the right</li> - <li style='margin-bottom: 50px;'>Bookmark connect.comma.ai to your home screen to use it like an app</li> - </ol> - - - <ol type='1' style='margin-left: 15px;'> - <li style='margin-bottom: 50px;'>https://connect.comma.ai에 접속하세요</li> - <li style='margin-bottom: 50px;'>"새 장치 추가"를 클릭하고 오른쪽 QR 코드를 검색합니다.</li> - <li style='margin-bottom: 50px;'>connect.comma.ai을 앱처럼 사용하려면 홈 화면에 바로가기를 만드십시오.</li> - </ol> - + + Go to https://connect.comma.ai on your phone + https://connect.comma.ai에 접속하세요 + + + + Click "add new device" and scan the QR code on the right + "새 장치 추가"를 클릭하고 오른쪽 QR 코드를 검색합니다 + + + + Bookmark connect.comma.ai to your home screen to use it like an app + connect.comma.ai을 앱처럼 사용하려면 홈 화면에 바로가기를 만드십시오 PrimeAdWidget - + Upgrade Now 지금 업그레이드 - + Become a comma prime member at connect.comma.ai connect.comma.ai에서 comma prime에 가입합니다 - + PRIME FEATURES: PRIME 기능: - + Remote access 원격 접속 - + 1 year of storage 1년간 저장 - + Developer perks 개발자 혜택 @@ -600,22 +593,22 @@ location set PrimeUserWidget - + ✓ SUBSCRIBED ✓ 구독함 - + comma prime comma prime - + CONNECT.COMMA.AI CONNECT.COMMA.AI - + COMMA POINTS COMMA POINTS @@ -857,17 +850,17 @@ location set SetupWidget - + Finish Setup 설정 완료 - + Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer. 장치를 (connect.comma.ai)에서 페어링하고 comma prime 오퍼를 청구합니다. - + Pair device 장치 페어링 @@ -1023,13 +1016,13 @@ location set - Uninstall - 제거 + UNINSTALL + 제거 - UNINSTALL - 제거 + Uninstall %1 + 제거 %1 @@ -1274,8 +1267,8 @@ location set - Forget Wi-Fi Network " - wifi 네트워크 저장안함 " + Forget Wi-Fi Network "%1"? + wifi 네트워크 저장안함 "%1"? diff --git a/selfdrive/ui/translations/main_zh-CHS.qm b/selfdrive/ui/translations/main_zh-CHS.qm index 2c7963cf17a496e356fb5b0372b565ac82514661..eed52b27788c46e02689a14fb9f11e17c776755a 100644 GIT binary patch delta 2088 zcmYLJ4OCQR8h+-^z4LQt<_;(zBIwKjA%Y-?3OT?L6a5v5t5eF!7x6L%^C2JkbL@>&65@Jm@YFdC+|kFy|E@Y!#6D zDlh&Vc#6q_{ei3qCK)EK06ae)D^25;|zy3gyak-FvU!iE0Nr_76?f~ z^6jHQWDw@+my&A@Qm6A_{H2yBFzee$JFo!ojzmVWi;umA%xk>W^AP5}{4d6pBU|`@ zB8DM*X*F-NAg84X&}U*{%1&|?@a%z?0H^&wSbV072RczP#6XiB`_EqlV!uGEgOv!9 z(J?xMw5xDqa~bz*RbDZnfGtGjy*B^|XjDzx%IbyPR%LYtbG=)&=VPux4yad~sNv@W&pOe%y4SvDgg6 zO%vL;*nlaD@P5ixz?>*t&f*2*E(uqBVvF2J9M8@lBcr(GxtcQ z+BFokTuM{|$$L;*xP%3Y(n*E#`*cpf^n5@w5bh;Cf4GGet|a~h=q5^)%PaW)G-+*= z!Zz3?)&8DD^o=9v`_%}JH;-WKJgFh1i3Ra^OKR9gYZ&6Bri~k@#AnjkAqp;RllrcZ zfaM42>-BVuZPf_cPf3GABox}C5v49 zq{&lJZ(EC|@%}@e8`KPDd`w4tsY`qF8oRQ(lq4h`v`JS!xeFI41ZfA0qT?#ML*958+oF_!VO<=R`cuwRk9^C3&> zUoG!`uaU$q%MHB?SeklyZ#PS<9+D5gx|7NslutOPNbKHp`D`HrB~k8>$8(mPkvqKX zY_?4EfSQP^-2LIFN=!H{;q%UhYB?b(O`#BA)7Q>p$A|(wqRKMuK_y>m0 zZ&;#$2ZoQHrg9!%8a+;vKuC+x+RAnRR^#N@N_wN)=uArd2k_)^V`}tbV8%sbS^|}b zUSZ6sV?w`3J^_&RAAIsitT{8OUP{PqZ%9?~ZG_R!8)MrwGM&-{< zydZKwIr$?!;ZtSSeb0HQ?KFGLV*5@#ZuYwQkkjQwvv*E5r$c(XdG2*43XeBuIOuZS zI&(?k4NBy0-rl=`9#~=iLqQ3p8aAI={a-4z#QfncD+!!6U%9=P-SL|FYSLRk%!MKv zsjKZtZI|NuWZc-kuD-X(eHUt~VL>1wU`d~pm%H|fVHGV( zPx0@YUQn>ilJBq-7vz^ZEP)X&Z!c?Gz1I{?z$j-{)fd^O%I}ALVEZ}T_Bc$peARC( zw!nzCo4zlo1Z29bmQ4BaZldd~HPN-s=B2W^_D`_=vJvgdvqnGKaETM*e_0NF%^Lb> zwJpLXd0OT97294OA^bR_aY0E@NvR{hxR?~%vS!S43-W!gxArf{MG=xv^oS}${!bI} Vj{|*Nr<1+JzzAEs>yzY+{{iv64I%&l delta 2662 zcmcIk3sjTm8Ge)ee=a}CAJ7n5x%~t%Ah%G#aS4cU#EKmkMPQ<}Fe1hVf)ER-mXuj* zDb~vg4pymJfnvw3J79J5Xs0bw(P8VU-RKybQY~W3Y;|X)BDe>zJ#;(U&UVg{!+FT} zy_e^E-sk)3c8FSci*{=q0+G0c$n6Q>IMKXtB1thY6Icl>2Q~ofi5Tqj3L-XwDCB)$ zJW(hQ%twrA8g+=5-XU^DO_?`vComRx6nKV6g*YX0{a+xOdxdC~D}wb1bn^uw(Crzb z#n?0)AWC})ja-SISONSIQC1|1JOHjIa=!)KhV?^4me8BxUq@IxXS_O%=KjQBj} z-%iZ-eME^DiD|q}B;ttaib7U2F}=S6Rul69L*(-nu`ff4&^Mh4A`eFr$wENRb+pI&4o81t(G0>Jv8;c?+W9`7aR7xhv+1&k+SRi34v8l7k}q#HpMO%=U;^ zyW+%#bK=*oVD#P=@rfNE_E@6$ouwG9dX4y_EEM)(#REOCL3o4s>OprR&pZhe?m?sp zm3V)_BJYeuSGN!f>Lr`9Q1=J(CG9+jhYU$Nj>Br|%aW5F$TQ?iy7bk~Yhq7FJM&aq zCm5V&%u6A#tBSD?CK3r}nJtB2B(*c!nY%;_4l<2PPr-mu)5woaqo#2heeW|(Eu&!O z!5q3?1k7cA@xfjq-9F~n(=CuRiTSk>vr!#qE`HXJ^>3JqxBh||xb-lD3y;BY4whR0 z%@Z!Ls=AHPu#HXO12IGcoA(rEvLJ>n=H7u>2H6b(tGnnPuQlA7R*3%o^9F%SGXjyEiZ0^61Ui+?_VW~ z7-iobhvwp4?0bHf;i_|N{{RU2>)B7Y_P_+K)0lXhy*Cbm5u8-)mkoCvmh!j5p`cl6 z98QITe~>QeI879{N}4Z%_5lOZ=FtfvKZEpM#>Wo0OeNC=L#m)4S?ipwI9Z$QXz8bD zoFluv{1Buw$-ce?MIWAQ^oUZ2ZTg1c}Hj?2>|AgZpHn?}Y!Fh~B%rdP3FEI-hW zIUZhBTR;AX`G)Xpsm!Q&+5xuOqyaZ-V+9md<@8xKstHF%b* z8&c!<0j_=mqYXU4HJ)k)p%JdBZzV=_ncLrsQA@_TBaWBqAz43n(!hdQHTP~Y5?O}p z;(YLooaMT-Mi6?7yZK`q8cn!}j#nc-)5ZVHIe6l>OX{C$iDpS$)(ql7@XvAC_z?r* zg)TMEXpleV()|TSqmOhs|3fII8C7b|fI!%Q(ys&Sfj5e!e8RjW}+Yb!?owC0h z1eu*GX=?x;0Do14_wPX@RuwxAqMi+^BT?A*8&RF81ja6RsJe7-z`ZL}UCBT_r@CN- z7dWHpN*=DIW-agjW-Hb&^K-UCfmz@1y3rIU^=CfjDqf<99)8&lC^$Qc-zjm`#=QW!7%t!I@fFcoL!!eIs>$B{#?!7)ou+` zTSLNk5q!GIR3sGG1dFMl!X`Kct$Sy!)*$s#I7= zdB-b9R57(?dAL?W1yoMOWTsLILxzdgVLuLW zkra*0DvC!|;y+ZM>|{i=`C+~J_Nmm#Cf_eu2pTqgtyrHd8cl|8i#jWPlb%GCh^adN zsl)%!fD)Y(KDz&Ri!`51$G<$q=yi2 zQczxOE)BDo*4g5O$mp`Fczxo-a6vFy%-@f54J)+TY}S%EA=)q%>OAWk8expEnEy@E zKjqBxjrp&0T6|KpGy51Ltd{AXog==U?w-;WRlA;>;c{+eskyYmR$#FR&aa|8I+LQ~ wUFXkQ+gJBX%7vLy$vo-y89vvhTFZ+~HX+v>mTDH#O}0vF`O`4|sl^$82ZSevfB*mh diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts index d9377054a5..0870ff7028 100644 --- a/selfdrive/ui/translations/main_zh-CHS.ts +++ b/selfdrive/ui/translations/main_zh-CHS.ts @@ -308,13 +308,8 @@ - Need at least - 至少需要 - - - - characters! - 个字符! + Need at least %1 characters! + 至少需要 %1 个字符! @@ -479,8 +474,8 @@ location set - for " - 网络名称:" + for "%1" + 网络名称:"%1" @@ -545,52 +540,50 @@ location set 将您的设备与comma账号配对 - - - <ol type='1' style='margin-left: 15px;'> - <li style='margin-bottom: 50px;'>Go to https://connect.comma.ai on your phone</li> - <li style='margin-bottom: 50px;'>Click "add new device" and scan the QR code on the right</li> - <li style='margin-bottom: 50px;'>Bookmark connect.comma.ai to your home screen to use it like an app</li> - </ol> - - - <ol type='1' style='margin-left: 15px;'> - <li style='margin-bottom: 50px;'>在手机上访问 https://connect.comma.ai</li> - <li style='margin-bottom: 50px;'>点击“添加新设备”,扫描右侧二维码</li> - <li style='margin-bottom: 50px;'>将 connect.comma.ai 收藏到您的主屏幕,以便像应用程序一样使用它</li> - </ol> - + + Go to https://connect.comma.ai on your phone + 在手机上访问 https://connect.comma.ai + + + + Click "add new device" and scan the QR code on the right + 点击“添加新设备”,扫描右侧二维码 + + + + Bookmark connect.comma.ai to your home screen to use it like an app + 将 connect.comma.ai 收藏到您的主屏幕,以便像应用程序一样使用它 PrimeAdWidget - + Upgrade Now 现在升级 - + Become a comma prime member at connect.comma.ai 打开connect.comma.ai以注册comma prime会员 - + PRIME FEATURES: comma prime特权: - + Remote access 远程访问 - + 1 year of storage 1年数据存储 - + Developer perks 开发者福利 @@ -598,22 +591,22 @@ location set PrimeUserWidget - + ✓ SUBSCRIBED ✓ 已订阅 - + comma prime comma prime - + CONNECT.COMMA.AI CONNECT.COMMA.AI - + COMMA POINTS COMMA POINTS点数 @@ -855,17 +848,17 @@ location set SetupWidget - + Finish Setup 完成设置 - + Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer. 将您的设备与comma connect (connect.comma.ai)配对并领取您的comma prime优惠。 - + Pair device 配对设备 @@ -1021,13 +1014,13 @@ location set - Uninstall - 卸载 + UNINSTALL + 卸载 - UNINSTALL - 卸载 + Uninstall %1 + 卸载 %1 @@ -1272,8 +1265,8 @@ location set - Forget Wi-Fi Network " - 忘记WiFi网络" + Forget Wi-Fi Network "%1"? + 忘记WiFi网络 "%1"? diff --git a/selfdrive/ui/translations/main_zh-CHT.qm b/selfdrive/ui/translations/main_zh-CHT.qm index 0d448f2080322661cb712bd3c06b4049fabbf935..029332de238d74b5cf8c40073a31d27ea6f0bf4f 100644 GIT binary patch delta 2149 zcmZ`(eNa^Q6}@lwz1@9p-|hol5Y`3u0}RLlqJ#o2GC+iYDK3={Ctxe;x}tn2ELE#< zON}LnQFNsmgG3_)O=1%vV&X@l2Bl(=IGWTBLuw5wX0#gZBoxK;;Lg~;%FNDT-tXSu zJ@?%6yM2w!ku6N4&K*u9D<|?5fMY~2oFtMvf!_jG1D^nQ5rylCSe$F_6LB#_5i@`@ zfxib9A?7z;47p3Bcu3?ENu&${z5+}HqK5J`^5+tXJw(Q*L{qL3z3THZii`&i0uksN zM>P9&qNqni*>9jQey_{}UL?wm#U&t+yNt;12yhb!=!nYpBcCU##-%=6iCj4Me_{K* zV7DoZ*t)lgY)6URJw(K4iS0&(@OEPRJ_SA?wx1<3loPkvNHjHwxWny4>H<=9K?3y# zQX1!@+88M#L08>M(yrszp1!RM6f^#M@|o)=tEIL$4lO zPn7IO3(j0X!7^GihCEF;?eD#W?<3UV`ZcudrS6H))(}rOH`n02n(2GIwUY4#I6R!FdiBTV-K4 zZxF>ymt_bp=$a!d_Cd$dfwH|_C}BG%HtjY>OFjdt{$yVFr>#b|p6-1txoB zgBReC$UCy@`}~LkwQ@Fk64AsFdC*-B=XSZdAqAbiDX+;zfw&%d^O;5zx-9=di%ud6 z??8UkN1i@eh`X9y*xre#-?61xP+RI}*WQ>#6g-<CWSzN=PK!o4sMZ@vK7wK z?ckcX!5L~R*ZRjzP@{6N|n&7Ok zE@hj3BRcw7`BBApC~Q~$^gR@icPSswybWj6snR35@x~HV+4AccQGv>F?=h@yQ@vTU z2j{-3cRoP=#6;E6n-&=38(yiw8kyYBTbfmPQ*ZI1&;vJGmcYXcH&YRlO&$1dStv#&uZ1^G ziSCT_%S1_s#O#CxM89Yi=cGZ21iM(!gbNMBVtLLuF{ij|v=A3aV#jv8F#{uB*azjJ z{viH!0B8*t2hM{ayF;UB3q`?unwX%!fk?6@aSTKQ=V=bd;XK5tIkp-Y|D&ec{2oj@ z+pXzN!#|-rG`+Sa?8B*=tMl<3brD*>Lv84&NUN`d0uzpD%_HepbBnbJ*R3c#SvzM7 zB%Cm!U6nQ)d5^U9Z{u-KS*(4(6$Pg6)t>qhp3vJR)dQ?UWtXH&#q*s}Df!=eN;FN7 z0t)hoCgs#iFAw3O=pJdV3ochxNfpkUaO-8M@!BSMV43umqXJU>Abqj&36#o_dTyIQ zAX^$7Zh`b^()El#6D4+*!btZ!laz15=%C}0=W*VaBN z_9Y{QQ7jql>Y~Ej^q(166rRG*kmGPHF_yTDWsZ_+moY5XGva6JT<0IB2oYafiZt`H zMDz0m)zZo;qd6?r?1?q#I{$9SU=);BtR$o7ez3_i)fgi@4^8*HZ%Ut}L>19qQd(77 z;j~w-tXcVtS(2wbBtZclG)VP4oAL1|hFlNu`Oug0H2BkcY)@M{!IUO!zVQExGsWHdlT3uPS N;#p@Yp3%&C{{>l+97q5F delta 2681 zcmcIl3s98T89lrE|GVtJyZ?$V+ZJ{Cc_{dR1p@|QL4|^XElTj!phgJ`Zd@M18emX2 zj8S9oy&B&d6>4l^oq)kKiPkF7V1h9dlGveGix1SA+GwX*t+od+iD{?pv@?a-IqbdP zLS2DjQ9W;atqKD0z)mt3gQUjCgLPO;J)c5AliXpE@C3F ziI~fnXL>Ot1kkcZpEN)>kXS$*MO;oi#{7wZ@e~jm3k+@pp6+uR2=5NOLu8J-tI5y} zBV9usqRm8U9>%p)1CfCkcl9kGR)g{SJhHDw=E#lc{>iLJffqx!V4~Z{bDzSb-;qGT zHaxZHPfW_)x!NfD9Wd{0rOG$ zfcd5f>^^-47!!d8&n(UjXzoXCZEjqCc>(v!Rn}3%y+Bxi>iavxDE2m0+-eRqdXFmm zB%{L)tG0f|_4roRnaKhRJ5=Y?dw~JBRM(z(5eRHoONH+P5qauCmpg%&JaxL{p%Txi zXY}ETqchYy+VsG{5$eM$Ni62H`e?>#z?`K1G@Eq?wx~N=(&&t+AoYb;1AzWN)Cf`E z11x=iEc9=(7e;YJo|5b9qJ(ODq;4% zMz*gNTp3i?d`+n8Oa_!{VPPKWXqO7hh1;x>FKo_ukA95mMY+8fEem@ws6p6Xcb9`Z zDD1hEPwW!j_;@1_GC?>rua0`o5Po6gTueKK53jUyeZTPG^*;b!|J_38=tJ~hwJ43G z;7Om0rrP<`uR=_f2a)zUar$fyB<{LcC>^C!PK(cl)l;W4;&a`O(mRRtxL=@HRZz)e z4-ugXiP8{+mgbcA8JShs8`m3Uh`cfP$-Q#S_7w&{6ebdj|=Hd?8+3(!xRiq!&jU#Cs1&FlxP49Xy%NYSzj(qo`o0 z)^RPJ3SQBUYd8WVq-b+h)IDsScJJMX-0#%hoA?=>6w#^+8A7STZ|Ld+mvG{C-NE9E zY&=PK^Qk?Qu10s~Iu+40>Fy_X(Md=AQinA2t`+-bYDm;v>gW9OJ_$PfRxQ}d{c(P~ zUT2+tIeu?l4&`^FUT5MnViWbD+x>tiTJ&RY6*7LVe#!*zB}yNypSpySjrmBQJA)Dr zI;qb;nLD7UuuOaPkI6Gx((G|3TTdMan^ z__Z-JekL%g%{U>2N+i5soVt+(gKWm4tZrh3#!dI8u|S%!VIA+7?MY+Ht5nY3VEm|^ z7&Xh-ev$-*^(Jk77%#uhWFPnii6oguJs{EkD@+GsxgWg4bhv^zYOvST9P(4TH_g9m7hkcOJtrt?}_QssdC^&G`IIdC}@==+HrayOMq`Q-QueB12V@`ROCuwP$! zeo7kiZp$mS@sdYuk#}^Bp*KYNXLW28+bSRVGd(e2nS5r$qKJ>y?MVhy?TaODq_D$2`$Pm;05OiwiGPDxG=lxux{NT=N!ZF%|pD{L9k6QnAJ6 zj;lL)D=N(w(ti#lUUUIt`!%NM_R9ehlu3r%Y1yfNQ_*)c3_nKScx$lFBmKZ9Sp7q# zO;}M=b9;tAly4&BET=PHnd4F1&N<~CWxX|^(PfR*251)*KtaeiabiJ9nbP>~fLxVV zoe%bU?AL)3xcS|KDwM*BB!nY|9|h$-YwkyDMVNy!6vBmKL^8vP0`4a;E(USTtVANS zlK-K4cP9sAB`#9_+?%tlhWX0O}`=EMDe{D|X8vSD~m!=fEipxE7+-{}u&Dbk_ z5(A4x{=ZT%jkbzJdbhb2HLSYHm2WL?O)n`cbb6F&uE=zklI8SNl$6a=LVV}ba{dnW C?SW|k diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts index efd893ec4c..0620382a63 100644 --- a/selfdrive/ui/translations/main_zh-CHT.ts +++ b/selfdrive/ui/translations/main_zh-CHT.ts @@ -308,13 +308,8 @@ - Need at least - 需要至少 - - - - characters! - 個字元! + Need at least %1 characters! + 需要至少 %1 個字元! @@ -481,8 +476,8 @@ location set - for " - 給 " + for "%1" + 給 "%1" @@ -547,52 +542,50 @@ location set 將設備與您的 comma 帳號配對 - - - <ol type='1' style='margin-left: 15px;'> - <li style='margin-bottom: 50px;'>Go to https://connect.comma.ai on your phone</li> - <li style='margin-bottom: 50px;'>Click "add new device" and scan the QR code on the right</li> - <li style='margin-bottom: 50px;'>Bookmark connect.comma.ai to your home screen to use it like an app</li> - </ol> - - - <ol type='1' style='margin-left: 15px;'> - <li style='margin-bottom: 50px;'>用手機連至 https://connect.comma.ai</li> - <li style='margin-bottom: 50px;'>點選 "add new device" 後掃描右邊的二維碼</li> - <li style='margin-bottom: 50px;'>將 connect.comma.ai 加入您的主屏幕,以便像手機 App 一樣使用它</li> - </ol> - + + Go to https://connect.comma.ai on your phone + 用手機連至 https://connect.comma.ai + + + + Click "add new device" and scan the QR code on the right + 點選 "add new device" 後掃描右邊的二維碼 + + + + Bookmark connect.comma.ai to your home screen to use it like an app + 將 connect.comma.ai 加入您的主屏幕,以便像手機 App 一樣使用它 PrimeAdWidget - + Upgrade Now 馬上升級 - + Become a comma prime member at connect.comma.ai 成為 connect.comma.ai 的高級會員 - + PRIME FEATURES: 高級會員特點: - + Remote access 遠程訪問 - + 1 year of storage 一年的雲端行車記錄 - + Developer perks 開發者福利 @@ -600,22 +593,22 @@ location set PrimeUserWidget - + ✓ SUBSCRIBED ✓ 已訂閱 - + comma prime comma 高級會員 - + CONNECT.COMMA.AI CONNECT.COMMA.AI - + COMMA POINTS COMMA 積分 @@ -860,17 +853,17 @@ location set SetupWidget - + Finish Setup 完成設置 - + Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer. 將您的設備與 comma connect (connect.comma.ai) 配對並領取您的 comma 高級會員優惠。 - + Pair device 配對設備 @@ -1026,13 +1019,13 @@ location set - Uninstall - 卸載 + UNINSTALL + 卸載 - UNINSTALL - 卸載 + Uninstall %1 + 卸載 %1 @@ -1277,8 +1270,8 @@ location set - Forget Wi-Fi Network " - 清除 Wi-Fi 網路 " + Forget Wi-Fi Network "%1"? + 清除 Wi-Fi 網路 "%1"? diff --git a/selfdrive/ui/update_translations.py b/selfdrive/ui/update_translations.py index d872be0d86..f06d54b2d5 100755 --- a/selfdrive/ui/update_translations.py +++ b/selfdrive/ui/update_translations.py @@ -10,7 +10,7 @@ TRANSLATIONS_DIR = os.path.join(UI_DIR, "translations") LANGUAGES_FILE = os.path.join(TRANSLATIONS_DIR, "languages.json") -def update_translations(release=False, translations_dir=TRANSLATIONS_DIR): +def update_translations(release=False, vanish=False, translations_dir=TRANSLATIONS_DIR): with open(LANGUAGES_FILE, "r") as f: translation_files = json.load(f) @@ -20,7 +20,10 @@ def update_translations(release=False, translations_dir=TRANSLATIONS_DIR): continue tr_file = os.path.join(translations_dir, f"{file}.ts") - ret = os.system(f"lupdate -recursive {UI_DIR} -ts {tr_file}") + args = f"lupdate -recursive {UI_DIR} -ts {tr_file}" + if vanish: + args += " -no-obsolete" + ret = os.system(args) assert ret == 0 if release: @@ -32,6 +35,7 @@ if __name__ == "__main__": parser = argparse.ArgumentParser(description="Update translation files for UI", formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument("--release", action="store_true", help="Create compiled QM translation files used by UI") + parser.add_argument("--vanish", action="store_true", help="Remove translations with source text no longer found") args = parser.parse_args() - update_translations(args.release) + update_translations(args.release, args.vanish) From 97d7ee369b9b8193fe1580fbaa00e65a26235432 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 12 Jul 2022 23:11:55 -0700 Subject: [PATCH 101/112] Chrysler: send LKAS control bit while above minSteerSpeed (#25150) * Chrysler: send LKAS control bit while above minSteerSpeed * update refs * rework that a bit * little more * update refs --- selfdrive/car/chrysler/carcontroller.py | 11 ++++++----- selfdrive/car/chrysler/chryslercan.py | 4 ++-- selfdrive/test/process_replay/ref_commit | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/selfdrive/car/chrysler/carcontroller.py b/selfdrive/car/chrysler/carcontroller.py index 8156e7841e..00893b6bc4 100644 --- a/selfdrive/car/chrysler/carcontroller.py +++ b/selfdrive/car/chrysler/carcontroller.py @@ -14,7 +14,7 @@ class CarController: self.hud_count = 0 self.last_lkas_falling_edge = 0 - self.lkas_active_prev = False + self.lkas_control_bit_prev = False self.last_button_frame = 0 self.packer = CANPacker(dbc_name) @@ -24,7 +24,8 @@ class CarController: can_sends = [] # EPS faults if LKAS re-enables too quickly - lkas_active = CC.latActive and not low_speed_alert and (self.frame - self.last_lkas_falling_edge > 200) + lkas_control_bit = not low_speed_alert and (self.frame - self.last_lkas_falling_edge > 200) + lkas_active = CC.latActive and self.lkas_control_bit_prev # *** control msgs *** @@ -59,12 +60,12 @@ class CarController: self.apply_steer_last = apply_steer idx = self.frame // 2 - can_sends.append(create_lkas_command(self.packer, self.CP, int(apply_steer), lkas_active, idx)) + can_sends.append(create_lkas_command(self.packer, self.CP, int(apply_steer), lkas_control_bit, idx)) self.frame += 1 - if not lkas_active and self.lkas_active_prev: + if not lkas_control_bit and self.lkas_control_bit_prev: self.last_lkas_falling_edge = self.frame - self.lkas_active_prev = lkas_active + self.lkas_control_bit_prev = lkas_control_bit new_actuators = CC.actuators.copy() new_actuators.steer = self.apply_steer_last / self.params.STEER_MAX diff --git a/selfdrive/car/chrysler/chryslercan.py b/selfdrive/car/chrysler/chryslercan.py index 632c0d2bcf..1e26a6d275 100644 --- a/selfdrive/car/chrysler/chryslercan.py +++ b/selfdrive/car/chrysler/chryslercan.py @@ -52,12 +52,12 @@ def create_lkas_hud(packer, CP, lkas_active, hud_alert, hud_count, car_model, au return packer.make_can_msg("DAS_6", 0, values) -def create_lkas_command(packer, CP, apply_steer, lat_active, frame): +def create_lkas_command(packer, CP, apply_steer, lkas_control_bit, frame): # LKAS_COMMAND Lane-keeping signal to turn the wheel enabled_val = 2 if CP.carFingerprint in RAM_CARS else 1 values = { "STEERING_TORQUE": apply_steer, - "LKAS_CONTROL_BIT": enabled_val if lat_active else 0, + "LKAS_CONTROL_BIT": enabled_val if lkas_control_bit else 0, } return packer.make_can_msg("LKAS_COMMAND", 0, values, frame % 0x10) diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index e77a38de5f..c99a1653f4 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -5efbbdf69e16db3d989bfaf62d10e958e80b9ca2 \ No newline at end of file +7fbe776f271ed2d45abe989736133a5cfa0ec826 \ No newline at end of file From e710ba549a3e0b1aba50ba8d4ed47e695a02c538 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Wed, 13 Jul 2022 00:20:35 -0700 Subject: [PATCH 102/112] Car docs diff bot: skip PRs from forks (#25151) * check permissions explicitly * fix syntax * Fix * Diff * fix * revert --- .github/workflows/selfdrive_tests.yaml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/selfdrive_tests.yaml b/.github/workflows/selfdrive_tests.yaml index 298ea5fb49..fc151cc2e2 100644 --- a/.github/workflows/selfdrive_tests.yaml +++ b/.github/workflows/selfdrive_tests.yaml @@ -10,7 +10,6 @@ env: CL_BASE_IMAGE: openpilot-base-cl DOCKER_REGISTRY: ghcr.io/commaai AZURE_TOKEN: ${{ secrets.AZURE_COMMADATACI_OPENPILOTCI_TOKEN }} - HAS_AZURE_TOKEN: $AZURE_TOKEN != '' DOCKER_LOGIN: docker login ghcr.io -u adeebshihadeh -p ${{ secrets.CONTAINER_TOKEN }} BUILD: | @@ -366,7 +365,7 @@ jobs: name: process_replay_diff.txt path: selfdrive/test/process_replay/diff.txt - name: Upload reference logs - if: ${{ failure() && github.event_name == 'pull_request' && github.repository == 'commaai/openpilot' && env.HAS_AZURE_TOKEN }} + if: ${{ failure() && github.event_name == 'pull_request' && github.repository == 'commaai/openpilot' && env.AZURE_TOKEN != '' }} run: | ${{ env.RUN }} "scons -j$(nproc) && \ CI=1 AZURE_TOKEN='$AZURE_TOKEN' python selfdrive/test/process_replay/test_processes.py -j$(nproc) --upload-only" @@ -551,22 +550,22 @@ jobs: output="${output//$'\n'/'%0A'}" echo "::set-output name=diff::$output" - name: Find comment - if: env.HAS_AZURE_TOKEN - uses: peter-evans/find-comment@v1 + if: ${{ env.AZURE_TOKEN != '' }} + uses: peter-evans/find-comment@1769778a0c5bd330272d749d12c036d65e70d39d id: fc with: issue-number: ${{ github.event.pull_request.number }} body-includes: This PR makes changes to - name: Update comment - if: steps.save_diff.outputs.diff != '' && env.HAS_AZURE_TOKEN - uses: peter-evans/create-or-update-comment@v1 + if: ${{ steps.save_diff.outputs.diff != '' && env.AZURE_TOKEN != '' }} + uses: peter-evans/create-or-update-comment@b95e16d2859ad843a14218d1028da5b2c4cbc4b4 with: comment-id: ${{ steps.fc.outputs.comment-id }} issue-number: ${{ github.event.pull_request.number }} body: "${{ steps.save_diff.outputs.diff }}" edit-mode: replace - name: Delete comment - if: steps.fc.outputs.comment-id != '' && steps.save_diff.outputs.diff == '' && env.HAS_AZURE_TOKEN + if: ${{ steps.fc.outputs.comment-id != '' && steps.save_diff.outputs.diff == '' && env.AZURE_TOKEN != '' }} uses: actions/github-script@v6 with: script: | From a7b778c324bf4eaba7f5db32ec60f88212e2c6fe Mon Sep 17 00:00:00 2001 From: Jafar Al-Gharaibeh Date: Wed, 13 Jul 2022 01:31:52 -0600 Subject: [PATCH 103/112] Mazda: Support CX-9 2022 (#25147) * Mazda: Support CX-9 2022 dongle-id: 8c6e0e30decb68f7 Signed-off-by: Jafar Al-Gharaibeh * update years Co-authored-by: Shane Smiskol --- docs/CARS.md | 2 +- selfdrive/car/mazda/values.py | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/CARS.md b/docs/CARS.md index e24672e9bc..754052085d 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -198,7 +198,7 @@ How We Rate The Cars |Lexus|RX 2016-18|All|[3](#footnotes)||||| |Lexus|RX Hybrid 2016-19|All|[3](#footnotes)||||| |Mazda|CX-5 2022|All|||||| -|Mazda|CX-9 2021|All|||||| +|Mazda|CX-9 2021-22|All|||||| |Ram|1500 2019-22|Adaptive Cruise|||||| |Subaru|Crosstrek 2018-19|EyeSight|||||| |Subaru|Impreza 2017-19|EyeSight|||||| diff --git a/selfdrive/car/mazda/values.py b/selfdrive/car/mazda/values.py index 12e9eafc4f..e1d6907991 100644 --- a/selfdrive/car/mazda/values.py +++ b/selfdrive/car/mazda/values.py @@ -40,7 +40,7 @@ CAR_INFO: Dict[str, Union[MazdaCarInfo, List[MazdaCarInfo]]] = { CAR.CX9: MazdaCarInfo("Mazda CX-9 2016-17"), CAR.MAZDA3: MazdaCarInfo("Mazda 3 2017"), CAR.MAZDA6: MazdaCarInfo("Mazda 6 2017"), - CAR.CX9_2021: MazdaCarInfo("Mazda CX-9 2021"), + CAR.CX9_2021: MazdaCarInfo("Mazda CX-9 2021-22"), CAR.CX5_2022: MazdaCarInfo("Mazda CX-5 2022"), } @@ -267,6 +267,7 @@ FW_VERSIONS = { (Ecu.engine, 0x7e0, None): [ b'PXM4-188K2-C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'PXM4-188K2-D\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', + b'PXM6-188K2-E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], (Ecu.fwdRadar, 0x764, None): [ b'K131-67XK2-E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', @@ -279,9 +280,11 @@ FW_VERSIONS = { b'GSH7-67XK2-M\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'GSH7-67XK2-N\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'GSH7-67XK2-P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', + b'GSH7-67XK2-S\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], (Ecu.transmission, 0x7e1, None): [ b'PXM4-21PS1-B\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', + b'PXM6-21PS1-B\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], } } From 3a8f17111c3439cb22eb627aec805898d9d9a41a Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Wed, 13 Jul 2022 01:10:56 -0700 Subject: [PATCH 104/112] Log VIN response address (#25148) * log vin rx addr * clean up --- selfdrive/car/car_helpers.py | 8 ++++---- selfdrive/car/fw_versions.py | 6 +++--- selfdrive/car/isotp_parallel_query.py | 2 +- selfdrive/car/vin.py | 10 +++++----- selfdrive/debug/disable_ecu.py | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/selfdrive/car/car_helpers.py b/selfdrive/car/car_helpers.py index b6bdece676..1a9a5f50f3 100644 --- a/selfdrive/car/car_helpers.py +++ b/selfdrive/car/car_helpers.py @@ -93,17 +93,17 @@ def fingerprint(logcan, sendcan): if cached_params is not None and len(cached_params.carFw) > 0 and cached_params.carVin is not VIN_UNKNOWN: cloudlog.warning("Using cached CarParams") - vin = cached_params.carVin + vin, vin_rx_addr = cached_params.carVin, 0 car_fw = list(cached_params.carFw) else: cloudlog.warning("Getting VIN & FW versions") - _, vin = get_vin(logcan, sendcan, bus) + _, vin_rx_addr, vin = get_vin(logcan, sendcan, bus) ecu_rx_addrs = get_present_ecus(logcan, sendcan) car_fw = get_fw_versions_ordered(logcan, sendcan, ecu_rx_addrs) exact_fw_match, fw_candidates = match_fw_to_car(car_fw) else: - vin = VIN_UNKNOWN + vin, vin_rx_addr = VIN_UNKNOWN, 0 exact_fw_match, fw_candidates, car_fw = True, set(), [] if len(vin) != 17: @@ -166,7 +166,7 @@ def fingerprint(logcan, sendcan): source = car.CarParams.FingerprintSource.fixed cloudlog.event("fingerprinted", car_fingerprint=car_fingerprint, source=source, fuzzy=not exact_match, - fw_count=len(car_fw), ecu_responses=list(ecu_rx_addrs), error=True) + fw_count=len(car_fw), ecu_responses=list(ecu_rx_addrs), vin_rx_addr=vin_rx_addr, error=True) return car_fingerprint, finger, vin, car_fw, source, exact_match diff --git a/selfdrive/car/fw_versions.py b/selfdrive/car/fw_versions.py index a8f5357f0e..5a33cdf6b7 100755 --- a/selfdrive/car/fw_versions.py +++ b/selfdrive/car/fw_versions.py @@ -444,7 +444,7 @@ def get_fw_versions(logcan, sendcan, query_brand=None, extra=None, timeout=0.1, if addrs: query = IsoTpParallelQuery(sendcan, logcan, r.bus, addrs, r.request, r.response, r.rx_offset, debug=debug) - fw_versions.update({(r.brand, addr): (version, r) for addr, version in query.get_data(timeout).items()}) + fw_versions.update({(r.brand, addr): (version, r) for (addr, _), version in query.get_data(timeout).items()}) except Exception: cloudlog.warning(f"FW query exception: {traceback.format_exc()}") @@ -497,8 +497,8 @@ if __name__ == "__main__": t = time.time() print("Getting vin...") - addr, vin = get_vin(logcan, sendcan, 1, retry=10, debug=args.debug) - print(f"VIN: {vin}") + addr, vin_rx_addr, vin = get_vin(logcan, sendcan, 1, retry=10, debug=args.debug) + print(f'TX: {hex(addr)}, RX: {hex(vin_rx_addr)}, VIN: {vin}') print(f"Getting VIN took {time.time() - t:.3f} s") print() diff --git a/selfdrive/car/isotp_parallel_query.py b/selfdrive/car/isotp_parallel_query.py index 0e807512cf..bb96572c33 100644 --- a/selfdrive/car/isotp_parallel_query.py +++ b/selfdrive/car/isotp_parallel_query.py @@ -126,7 +126,7 @@ class IsoTpParallelQuery: msg.send(self.request[counter + 1]) request_counter[tx_addr] += 1 else: - results[tx_addr] = dat[len(expected_response):] + results[(tx_addr, msg._can_client.rx_addr)] = dat[len(expected_response):] request_done[tx_addr] = True else: error_code = dat[2] if len(dat) > 2 else -1 diff --git a/selfdrive/car/vin.py b/selfdrive/car/vin.py index fd1ca61e66..007c10e772 100755 --- a/selfdrive/car/vin.py +++ b/selfdrive/car/vin.py @@ -22,18 +22,18 @@ def get_vin(logcan, sendcan, bus, timeout=0.1, retry=5, debug=False): for request, response in ((UDS_VIN_REQUEST, UDS_VIN_RESPONSE), (OBD_VIN_REQUEST, OBD_VIN_RESPONSE)): try: query = IsoTpParallelQuery(sendcan, logcan, bus, FUNCTIONAL_ADDRS, [request, ], [response, ], functional_addr=True, debug=debug) - for addr, vin in query.get_data(timeout).items(): + for (addr, rx_addr), vin in query.get_data(timeout).items(): # Honda Bosch response starts with a length, trim to correct length if vin.startswith(b'\x11'): vin = vin[1:18] - return addr[0], vin.decode() + return addr[0], rx_addr, vin.decode() print(f"vin query retry ({i+1}) ...") except Exception: cloudlog.warning(f"VIN query exception: {traceback.format_exc()}") - return 0, VIN_UNKNOWN + return 0, 0, VIN_UNKNOWN if __name__ == "__main__": @@ -41,5 +41,5 @@ if __name__ == "__main__": sendcan = messaging.pub_sock('sendcan') logcan = messaging.sub_sock('can') time.sleep(1) - addr, vin = get_vin(logcan, sendcan, 1, debug=False) - print(hex(addr), vin) + addr, vin_rx_addr, vin = get_vin(logcan, sendcan, 1, debug=False) + print(f'TX: {hex(addr)}, RX: {hex(vin_rx_addr)}, VIN: {vin}') diff --git a/selfdrive/debug/disable_ecu.py b/selfdrive/debug/disable_ecu.py index af007207eb..c01c22fdd0 100644 --- a/selfdrive/debug/disable_ecu.py +++ b/selfdrive/debug/disable_ecu.py @@ -16,7 +16,7 @@ def disable_ecu(ecu_addr, logcan, sendcan, bus, timeout=0.5, retry=5, debug=Fals try: # enter extended diagnostic session query = IsoTpParallelQuery(sendcan, logcan, bus, [ecu_addr], [EXT_DIAG_REQUEST], [EXT_DIAG_RESPONSE], debug=debug) - for addr, dat in query.get_data(timeout).items(): # pylint: disable=unused-variable + for _, _ in query.get_data(timeout).items(): # pylint: disable=unused-variable print("ecu communication control disable tx/rx ...") # communication control disable tx and rx query = IsoTpParallelQuery(sendcan, logcan, bus, [ecu_addr], [COM_CONT_REQUEST], [COM_CONT_RESPONSE], debug=debug) From 0edd8201cb8d8f21f361d0be581b02bc43c1b80e Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Wed, 13 Jul 2022 15:12:49 +0200 Subject: [PATCH 105/112] README.md: update directory structure --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 34b17625f9..3dce9d4475 100755 --- a/README.md +++ b/README.md @@ -105,23 +105,25 @@ Directory Structure ├── third_party # External libraries ├── pyextra # Extra python packages └── system # Generic services + ├── camerad # Driver to capture images from the camera sensors + ├── clocksd # Broadcasts current time + ├── hardware # Hardware abstraction classes ├── logcatd # systemd journal as a service └── proclogd # Logs information from /proc └── selfdrive # Code needed to drive the car ├── assets # Fonts, images, and sounds for UI ├── athena # Allows communication with the app ├── boardd # Daemon to talk to the board - ├── camerad # Driver to capture images from the camera sensors ├── car # Car specific code to read states and control actuators - ├── common # Shared C/C++ code for the daemons ├── controls # Planning and controls ├── debug # Tools to help you debug and do car ports ├── locationd # Precise localization and vehicle parameter estimation ├── loggerd # Logger and uploader of car data + ├── manager # Deamon that starts/stops all other daemons as needed ├── modeld # Driving and monitoring model runners - ├── proclogd # Logs information from proc - ├── sensord # IMU interface code + ├── monitoring # Daemon to determine driver attention ├── navd # Turn-by-turn navigation + ├── sensord # IMU interface code ├── test # Unit tests, system tests, and a car simulator └── ui # The UI From a006cd168ea5a2fec2f03b29460a3a685538b9cf Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Wed, 13 Jul 2022 17:55:05 +0200 Subject: [PATCH 106/112] run pre-commit in release CI (#25158) * run pre-commit in release * add pylintrc and init files * build first * add mypy ini * limit amount of debug scripts shipped in release * add python version? * add more missing __init__.py * excluded rednose for cppcheck * remove files before dirty check --- .github/workflows/selfdrive_tests.yaml | 7 +++++++ .pre-commit-config.yaml | 2 +- release/files_common | 16 +++++++++++++++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/.github/workflows/selfdrive_tests.yaml b/.github/workflows/selfdrive_tests.yaml index fc151cc2e2..fbc0d94194 100644 --- a/.github/workflows/selfdrive_tests.yaml +++ b/.github/workflows/selfdrive_tests.yaml @@ -58,6 +58,9 @@ jobs: run: | TARGET_DIR=$STRIPPED_DIR release/build_devel.sh cp Dockerfile.openpilot_base $STRIPPED_DIR + cp .pre-commit-config.yaml $STRIPPED_DIR + cp .pylintrc $STRIPPED_DIR + cp mypy.ini $STRIPPED_DIR - name: Build Docker image run: | eval "$BUILD" @@ -66,6 +69,10 @@ jobs: run: | cd $STRIPPED_DIR ${{ env.RUN }} "CI=1 python selfdrive/manager/build.py && \ + pre-commit run --all && \ + rm .pre-commit-config.yaml && \ + rm .pylintrc && \ + rm mypy.ini && \ release/check-dirty.sh && \ python -m unittest discover selfdrive/car" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b901e07721..8b8bc1f1b9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -54,7 +54,7 @@ repos: entry: cppcheck language: system types: [c++] - exclude: '^(third_party/)|(pyextra/)|(cereal/)|(opendbc/)|(panda/)|(tools/)|(selfdrive/modeld/thneed/debug/)|(selfdrive/modeld/test/)|(selfdrive/camerad/test/)/|(installer/)' + exclude: '^(third_party/)|(pyextra/)|(cereal/)|(rednose/)|(rednose_repo/)|(opendbc/)|(panda/)|(tools/)|(selfdrive/modeld/thneed/debug/)|(selfdrive/modeld/test/)|(selfdrive/camerad/test/)/|(installer/)' args: - --error-exitcode=1 - --language=c++ diff --git a/release/files_common b/release/files_common index fb91170561..954726d967 100644 --- a/release/files_common +++ b/release/files_common @@ -57,6 +57,7 @@ common/api/__init__.py release/* +tools/__init__.py tools/lib/* tools/joystick/* tools/replay/*.cc @@ -128,7 +129,15 @@ system/clocksd/.gitignore system/clocksd/SConscript system/clocksd/clocksd.cc -selfdrive/debug/*.py +selfdrive/debug/can_printer.py +selfdrive/debug/check_freq.py +selfdrive/debug/dump.py +selfdrive/debug/filter_log_message.py +selfdrive/debug/get_fingerprint.py +selfdrive/debug/uiview.py + +selfdrive/debug/hyundai_enable_radar_points.py +selfdrive/debug/vw_mqb_config.py common/SConscript common/version.h @@ -187,6 +196,9 @@ selfdrive/controls/lib/lateral_mpc_lib/* selfdrive/controls/lib/longitudinal_mpc_lib/* selfdrive/hardware + +system/__init__.py + system/hardware/__init__.py system/hardware/base.h system/hardware/base.py @@ -220,6 +232,7 @@ selfdrive/locationd/laikad_helpers.py selfdrive/locationd/locationd.h selfdrive/locationd/locationd.cc selfdrive/locationd/paramsd.py +selfdrive/locationd/models/__init__.py selfdrive/locationd/models/.gitignore selfdrive/locationd/models/car_kf.py selfdrive/locationd/models/gnss_kf.py @@ -330,6 +343,7 @@ selfdrive/manager/process.py selfdrive/manager/test/__init__.py selfdrive/manager/test/test_manager.py +selfdrive/modeld/__init__.py selfdrive/modeld/SConscript selfdrive/modeld/modeld.cc selfdrive/modeld/dmonitoringmodeld.cc From 49dd56fc241d5ea3e0ab37e10175ad545ef4d528 Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Wed, 13 Jul 2022 17:58:45 +0200 Subject: [PATCH 107/112] nav: draw inactive lanes with 50% opacity (#25157) * nav: draw inactive lanes with 50% opacity * update ts --- .../navigation/direction_turn_left_inactive.png | Bin 0 -> 7221 bytes .../navigation/direction_turn_right_inactive.png | Bin 0 -> 7239 bytes .../direction_turn_straight_inactive.png | Bin 0 -> 5452 bytes selfdrive/ui/qt/maps/map.cc | 4 ++++ selfdrive/ui/translations/main_ko.ts | 10 +++++----- selfdrive/ui/translations/main_zh-CHS.ts | 10 +++++----- selfdrive/ui/translations/main_zh-CHT.ts | 10 +++++----- 7 files changed, 19 insertions(+), 15 deletions(-) create mode 100644 selfdrive/assets/navigation/direction_turn_left_inactive.png create mode 100644 selfdrive/assets/navigation/direction_turn_right_inactive.png create mode 100644 selfdrive/assets/navigation/direction_turn_straight_inactive.png diff --git a/selfdrive/assets/navigation/direction_turn_left_inactive.png b/selfdrive/assets/navigation/direction_turn_left_inactive.png new file mode 100644 index 0000000000000000000000000000000000000000..2946984acd3252f257898cec9f6cda866811adc3 GIT binary patch literal 7221 zcmZu#2Q*yYw?;&XUZVFtIuVS{5R5)V7(~?QC3*>>MHzjR=w%SmMXw2h=)H^H%jhHO z^Lu6e|LeVX&pqd^`>kE>{qEjppK~L%HI)gT(L6&#LnBaCQG`5R`~K-TSdU}5K}9wi z8qqsnJp*@$nHQ7G2WM+r2P-Cb9~UboD{otCG&Jw|wlB7cw339O4`<|Vm`+T6>n<^A zw1X$xPYT~IU7k^BMd|;3O&%SFDNI(o@Nk24eOOIqS58&3w=ML3+q6j`Y5Fa&b^Z=t zW_jc$U0|lO_w49GVMA{%jp1SPo^BZ^;4JH%_1<3!xpxLG8;R`P??xpb3}1e1GiBRe zU-$1DiJTAc2bAyK6vl2Vo&k^fH~*$CGa%a!mXEq{*}-a!I#I60@waznanIRqqD$QL zWI*OR{?_ekcCnyVP!}r`BLi}C=k5mWBhKl77z%h@xh(Tk_Hz60IUr?|nzh~Ehq{=@VD)Q-iZt22pb>kNdiyrFX5j;;)`#-cN+aAYv2DU z_GijV_LKkLU2G&ZG$Qwdai3WjgXSzsyvs5Yc=VOdB2#F|?WL`QYZ10)Ygc4C6k38Y z4O=Me-o0v0aX~H|-C2KK^m!WI^TTqr^C7F@X6%=#Pm5bo7}wP`4bSv*zDmPz=Jz=; zjChyq#@__T12?!GfvK_xZk&Dsw@vgG#yCKDXu~3ya=Tl6^@=NR#a)_{NpaE0KwX7t zMNNeid`wdiE=R|M=AqA^8~X$^SjCuEcnc18r?Ic~JEJA=a)2A;XN6~=DM0e-xp6#x z^v4_Iaqs{q*;OeLSh%NDliospD}ez}*hVwQ5I0n>&TitZ?$B$y5~#gnUBfIX9ap)C zV_n^}pL-Uq$JQPUnMv)6NcapBcAp%3m4g@=)V2O1vG4G`vT;0^L*KA@&#n}?BC1|} zmSR$W)Vy%?*;sOSgSD7W`l5EiRL3v>dgz8y8&7L;O{u?Um&Y#CklqHfp{{Hr0D!(h^;l@%2Jh`u>KD{-QX=!+-Dcprwr2S0P-f z@QA%4S%j25z&vfEoBD12jGz~x@gEBt$@VzvL_73DojBR?5A*C;z>-kt`p&|qni;cx z@4bTuYuKxqbya~KyUce$GE1tMb3>yqFOV;aYRpfkO9$)iWg>jiX5$k*rKO*f9vv_k z%`DZ{a&72*(*gI#GJbw(l-{j;y=&-2CGmunP~G5_u`maW`gc#l{ya@_p{;&EHR$VN zwG&eGQz1hd*Kd}GF1Zyj{X)`w1S5QYV23Y{8w2_kie~@#Op`Y(?Gq zU8?kAVSv2^z1c*)k&Q4Dz5&ax`jGUi$)=LqWX0{o7azv=d?WG9|A2yCcHx!|{^ z($ok~=!0pG{P8RF)ZCpa25gcM9tp5rh>_Lp*#9Q?WA}c2n>HHsIk1y74MRL4B=gHD z`rw!n2VB02e%(Hg%lY zb~urOi8nI-Iv|HO)T4iPtm^zuZ#>41mZ0*@bkSp$W(M|KYPEapVf!o1=gf!q^_!r- z>B~2}^Y|O!^XHCG=d-XQ$S9leu^9DmSJ(RDs@g;Q8wnBnCU{5%EJ`wn4ZZ zdpqjb5`BGe<*(t16J(G*?mI$}{wCFh<8823cgxF{65!bdF2s|KC_#z9t?Ma&U z0@ZMvM|m^wdxW_;e*|V;LFhPPjnTZG?fgI@NgLz`*VJ6Um5#anfDM9CDKarpQBcTj zY{UcKmcl-C!<9U3kO&?ZI{$S}!c1J;i?FN$rR`CaW|ZSsVx0#Can+SvwrUbZnU9}o z%QQYY?B*?cdB?t6# zyyYQlQ6=stRah*`vBVb+AJ`IjS8Px8T=376x8w-R%4imq?^{H>ikkPQ6<4&g!1W1j zWa$ODx7_RyBJbT_nU;qL!(j0?ChdrV@Q+ngT}u7@hblg?h6rUFs_#=f;woq1JX0nx zA3qSGsyr-MRbW7|;ECS%PMU#Jo6+~7?WqY;MA$P>_G9+j@v#KbmXVsZpMLyK-DeZ0 zV+&q!#Pbu}p{mnI>(tOUnX^Hv=weWn>J)sfHu^2-(>DaR20a$}8^-zJFrvEPzvyUm zVw#j4bIikvPw2nDK9}Gdp-M>Dm=qxYsY?JSNkDPX84WOnTcq{CK%TES=9n8|u}3y2 zqYF#FO*_!9WUX-xE@;HyudW}6qSIB2YUw~SKc|#kFRt}a#0>X;mEB2#*V);2PIA;%V@B+xP3?U+^YX&r zj?;BY5p8rO0O4G2PZb7wbnunW1a1)QpJLC{lOeZGxyhcs+0Ly03RXwIh@q4x;iK8y%c2?@Dd z`cB(#)Oc#_4q16sGQXd&)#gxT61~&aL4b4~V2}jQIs#N^uk*5cv)IeuNmsdeK<&@Kw3^ zMH&!BG6rorzhfT*vfF%~rJiIzPH(MvXVvA~4g#vF5mk7ZfosvC;jFsnc`M;)!rW|( zn6n5l_2n=H7!fV{jK5r^=PALPE1x5oo%_yM;-LehXa}0TckZsXU$j$qSUfCAF&x24 z(dHe#KClN^9omOGx|N)S*6LjqIP&A178W0B<+8lXpzX0AH5*)XiP2lDYF0j1U^vkR z%#pDh#DhUIQ9x~HDyC^`naH2b8B$U-MHuNu=cjEApyqImll1LSB&WTkqpV}n4Si17 z((lVJo+%T+L_w_IFw*B^ij2wg?{JP90#_DlE*8tb(L z*AHwPq27yf9>D;q9`kLou_x}hN$f>gqA#q2r|-C}^D;mu$E9%By|QQK3w50#OWUBc zAoa9A8x}WK#I=s3ma_rqJ|fxq@!Wt{38OiQ$|*n$l9sB$Y%Kg-F)iEkxpHbD+)it` z2g&nyaR%ke=k)_bWbr@j{E|h+{WsE&FYmPEIOFEcX zmn^Y>4ndQH>U_On%|#a7^F>7N^2=TQqI?Fa5TYns1^KAA867q-*MoY{+77a)gO)v> z04v{|X}ZprnpREUNcGja>IqjWepwJft_L&PWe(}Lt%R&>Z%2^N+`$iR^}?3kX)-q$ z$vwIs38}Qfpa|oqX*60%6`GZ?P&!@ZBg{eelrlLcsk3hJFMgaadDjO|)1r&2+p|AR zME01g0|i%JtgQ|i$LMGF0KYo32iiD(lcIPXU}(5lOlB#wFL_1Yx$gJ^9~opIQrI2w zbcsjowUx(I>p+u2uPmK?*7`Sr#d3oj`YsbcLtMrX^yQ}n8`$uXD$k&|MMgBE&EIgn zL42BSY4?Ag+A;}dB?Y_8m=A^zcd1^@_6Vm6K`Mbixi*#@Hdl(V9jgxQyBaIf)rM(u zNlnAQyzb^P(@WHtBkhrbqFAVvN4bb$tn4yF76O(MA>Nhao?D<;~;4i z>qi|jcO%%Z7p+sDP$z>sk*bW+dJ?du;=zdBF_&ojrHyZ^{*T{$JvK?_r}6aMEFS?W z{#{2Sw4T3WCVQnb)4N}j-(9|(sEsK_)~pe5Dun_0>h1sfj9NqxyzBhpAcLYET1)L^ z)Iw~nDc2Ng2dq}ijCRa!+ss;Mcpf_gR!A2F}|Ft~;Hg^O|kGAwC zF6TX19CRq$oA0$_UPyioRF8SH5m;V)S6pzze0u-n61ji>=}zfh=kjP||6Zv3&SyzB z_K2ujS$U-2l`*yDP%;mBne#E>PeLpem=Vu8W`ry5V`9wq%hFie5MDeP0$|#0%|ePq z(RhoQfx^lqV?Hs@q1;c({zLn?i_bYNvvn>PSF}Q|Fe-z|UHE!GU>Zr1weY77Q>JZ6 z&;m5}pqXwxCn_21G^_tZ@FsMqD9_6C%V*I^Gxhr(&w8&wThm()meQE5d!nNUt_aOr z)D0RMdWbCuq^$}9{m)+eafhAxF+p0TOOEcBscs<)AE76)YoB%&Z$y-Y-Sa4I=E-N} z5^2WQPc>)~$tjh8)~&4cnos@wW%vgBjXd!!nydQT#cv#F~&EMj~!c<%{ zv`!N}!8(~Na&-B_8C#QBMw&wwm+mgVrd+|p(BaD8%zHfe^^58VnR4VWb8H^^L2%J4 zDOEb%mszJ_Wxd?ne8bSf9w=%<0Dt=;*{WiKPJuMqAQ+S6nH^UF2CXa91Hy~2m0ewD zbiX5QBL9&5v#&acTcodo@s=pS%lPaDDoV<*5hGtP{u7Efe9_Uz+<_z)S>6~6JV zV_+Tnpnu|9XZvc_TxZ(GMko7z2A8HM_)^q0fEGx6kv10^^8L96F!zCC$K=e{{&4*q zy-)j13GK=XF%F8+bnN*J;w!5l^680800lp;XBJ;&BG_+^Es*3V@-t&h`$T;KI^t~r; zBTa7a-}h>M@uU<@KF)P8D=$jK`o(0IuL_EX*G92lFFy2e$`mLDld3aSW0BH=ekkTe z;mOgi8?-8U(hHTpc{8ZAJ{IWDTN1-`%&ttonYEw-7)0vEDX=#U;aI)bL zhWVclZwr3m^mXHO9Y?@V;qVW>pJm63rf~WcN1=hH;J-^Inkx^l21w!|`>2}>-?jiK z*aztpFihoEqF;JpBaZ=r{w6)525jC7`DTjQ{&TNG{!tfjF)J=>4{M^q{3%>+!@O~n|u^)^RG0`a~#a-y{ zU#Zr}%CQYk7VQ3@RXPQM?vu46AJ|G=wDlE;))1DsC>Z=Sn>UciiXF2XXe+Q9i=&)c zLyEBm=Za#`2WR!Id;M}9?0=5#3OaT8mIUc9@VS-g2QP{w6ml3D8F^i|2fhOP2v#nu z8sbVv@PNKqWN%BSPjOH2`4aVm>0SyAv_6t(0WO*F31^l6N2V=NKs2l07Z;_^#ly@r z{jBS_3Vz!A^qgj)t27#(OiXOFO}nfEzRT@H<<$;BM?bj#=Po2E zKh;H9V>lTy;^s3JLJnN!^2hZGm29j{3n9;++1Icw543X?4~3t;qY77UY^5^a+|%dm zp6{dj?gaZQ&0~nkR>?edLQfZLYo#4ZY_AZ(w3)q(!_300$Q3$EtbiX%oYUj#{~~rh zTWIT5<;;z{lao`Q)!VfocZsZbo}QOFfK6AKifWAONa8hFS31)PsA;Kw>5Of1B4&3F z`ywf(wF!3eg9yzNX!oZeghwlyCw+<< zbiW~(sS#{%KowsbNBQIGEJZx_p}n^D{Jyg@n1hL8b^y1!&#C=UJ%fjb2dTbim-Za} z_l`F@f)Y;aO4o68bFYMvSnwDGu7FJ;eh_DHOc-99Rj|^ijlaq*tHd9e89^Uz2trkomXU_x6gsp;QA6@KsE zzaOcE@+lD|GWTm|B31bt77i&*=$(Kk$wtqpadFX`Vk`kyk@<`&Z3B1~LQ(l%_4V~w z$zXPsi;y!ZKw+70w%Df6A9{s|=4~Gh=5AQbz-CXH8n`4CN97X4&*`}wEtOO?WmnSm znP{24uyx_A)yK$*n?HMEXCvvk58W~uFQ!bx00Dd8>uLC;vw z09@F0EI$-ZU%$2(gjP^4K6oyUocp!`eB*D!ji(RWKbu{Z;hFN<)j{n70`8d$CnGcc z61|ckmBjIxv-LMlu%)!E*DU-Qj;CA9pl zbHl>>GhV7>NOtYVudmY?Hr%{8cs!R)s9*X2aS?A-26%ACeGa9y;O8zJ9t+v%L*4xn z#2=xta3WufrbD7`JZ9zvaDq$k0v>jyd@UYBC?hV4%StYh$j3*JD)VKJG2ry$m9iI5p6FZXQJMg$97vRyY_NqHs8u;VWAsnqc++?RbnTM-PTRT^`} zfGo!E$8bdjBuULlA)hs4Q;CM&nC_dVPQ|p>jHoSt6U&nHNDcQeV?OtH9*Jfa8JD8cXL!{sj&H- zTn(|rNWutWg~6dAg2yUWJH73O6QR4w+3=Gq3$5(EQW-S z*`_QeDw>Yj-I)iPZb4S0o2xqaQrwm3OCnW&~QL0wC0Sxb&L z^`QNM`)~;*49{^;%kH>&i`7;36l1MVPyyia*8U@Zxug|!zm|->I9+?zPr?26d^{@L zzN0Png%)IqI#_yyXUOuOFs|XUmU3D7L5J?DQgd_fPD2^;SPK8K`J(5RHRSDv6UN#~ zni1dvLeqkT^pBsjl$Mq<7E2qVq~aL5SD9zbslrE&tR6p>kF#OFR^spL4oJY902%S; zr}8cyl`Y72q%0)mGGg5uu*p3AlLZCCQF&JHwcN|s5)WbcUU+F!na_1CemGM$v+qS3 zPpS>R14QLh_E3N3B!YYXnVg)on?EB4Y|>*Q*tnCyeuGP>ad-|6vpyuCO@Jhxl=?lY z&2p1-X57De1CtK}!m)nP?w5_aNK~JcEyVsAd+-6ZB%mtiL`r;MPzP=MgGA-b{XDwi z#N5D}!d3arKGICzbW>3m@Et#}bXww2x6~g)7znC(^Bv~tQ$8fwL+B*&o*X%RuNAN(T5V`4%>N5{dDlS9M6ASMn9 zLc_#-g#Hik-!lJ__&25hQu#OFzpVrTA#9$#@KBnNbu zR?h6pJ}$`UU(o$$sc33yVn&y@b#!nL`M8`zqM+w_#kx9_A@;E3ASz}n{r{~R(Q>sP Zo~{oAPRia=wfrNXs-&q{q3|yFKLGp@*MI;3 literal 0 HcmV?d00001 diff --git a/selfdrive/assets/navigation/direction_turn_right_inactive.png b/selfdrive/assets/navigation/direction_turn_right_inactive.png new file mode 100644 index 0000000000000000000000000000000000000000..7d327766af13be26a23159e354cce5df6453f920 GIT binary patch literal 7239 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

52)T=qZliR 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 literal 0 HcmV?d00001 diff --git a/selfdrive/ui/qt/maps/map.cc b/selfdrive/ui/qt/maps/map.cc index a486110a73..3967416f73 100644 --- a/selfdrive/ui/qt/maps/map.cc +++ b/selfdrive/ui/qt/maps/map.cc @@ -526,6 +526,10 @@ void MapInstructions::updateInstructions(cereal::NavInstruction::Reader instruct fn += "turn_straight"; } + if (!active) { + fn += "_inactive"; + } + auto icon = new QLabel; int wh = active ? 125 : 75; icon->setPixmap(loadPixmap(fn + ICON_SUFFIX, {wh, wh}, Qt::IgnoreAspectRatio)); diff --git a/selfdrive/ui/translations/main_ko.ts b/selfdrive/ui/translations/main_ko.ts index 2fefa69a80..07d6877463 100644 --- a/selfdrive/ui/translations/main_ko.ts +++ b/selfdrive/ui/translations/main_ko.ts @@ -338,27 +338,27 @@ MapETA - + eta 도착 - + min - + hr 시간 - + km km - + mi mi diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts index 0870ff7028..424488fc56 100644 --- a/selfdrive/ui/translations/main_zh-CHS.ts +++ b/selfdrive/ui/translations/main_zh-CHS.ts @@ -338,27 +338,27 @@ MapETA - + eta 埃塔 - + min 分钟 - + hr 小时 - + km km - + mi mi diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts index 0620382a63..1eab75a6b4 100644 --- a/selfdrive/ui/translations/main_zh-CHT.ts +++ b/selfdrive/ui/translations/main_zh-CHT.ts @@ -338,27 +338,27 @@ MapETA - + eta 埃塔 - + min 分鐘 - + hr 小時 - + km km - + mi mi From 18f2a50501d67345e2fa2e44b6046d412c3452de Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Wed, 13 Jul 2022 12:43:36 -0700 Subject: [PATCH 108/112] disable_ecu.py: remove duplicate file (#25154) * remove duplicate function * make executable --- selfdrive/car/disable_ecu.py | 14 ++++++++++++ selfdrive/debug/disable_ecu.py | 40 ---------------------------------- 2 files changed, 14 insertions(+), 40 deletions(-) mode change 100644 => 100755 selfdrive/car/disable_ecu.py delete mode 100644 selfdrive/debug/disable_ecu.py diff --git a/selfdrive/car/disable_ecu.py b/selfdrive/car/disable_ecu.py old mode 100644 new mode 100755 index ac5c6c9f8f..cd3e93fa80 --- a/selfdrive/car/disable_ecu.py +++ b/selfdrive/car/disable_ecu.py @@ -6,6 +6,7 @@ EXT_DIAG_RESPONSE = b'\x50\x03' COM_CONT_RESPONSE = b'' + def disable_ecu(logcan, sendcan, bus=0, addr=0x7d0, com_cont_req=b'\x28\x83\x01', timeout=0.1, retry=10, debug=False): """Silence an ECU by disabling sending and receiving messages using UDS 0x28. The ECU will stay silent as long as openpilot keeps sending Tester Present. @@ -26,9 +27,22 @@ def disable_ecu(logcan, sendcan, bus=0, addr=0x7d0, com_cont_req=b'\x28\x83\x01' cloudlog.warning("ecu disabled") return True + except Exception: cloudlog.exception("ecu disable exception") print(f"ecu disable retry ({i+1}) ...") cloudlog.warning("ecu disable failed") return False + + +if __name__ == "__main__": + import time + import cereal.messaging as messaging + sendcan = messaging.pub_sock('sendcan') + logcan = messaging.sub_sock('can') + time.sleep(1) + + # honda bosch radar disable + disabled = disable_ecu(logcan, sendcan, bus=1, addr=0x18DAB0F1, com_cont_req=b'\x28\x83\x03', timeout=0.5, debug=False) + print(f"disabled: {disabled}") diff --git a/selfdrive/debug/disable_ecu.py b/selfdrive/debug/disable_ecu.py deleted file mode 100644 index c01c22fdd0..0000000000 --- a/selfdrive/debug/disable_ecu.py +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env python3 -import traceback - -import cereal.messaging as messaging -from selfdrive.car.isotp_parallel_query import IsoTpParallelQuery -from system.swaglog import cloudlog - -EXT_DIAG_REQUEST = b'\x10\x03' -EXT_DIAG_RESPONSE = b'\x50\x03' -COM_CONT_REQUEST = b'\x28\x83\x03' -COM_CONT_RESPONSE = b'' - -def disable_ecu(ecu_addr, logcan, sendcan, bus, timeout=0.5, retry=5, debug=False): - print(f"ecu disable {hex(ecu_addr)} ...") - for i in range(retry): - try: - # enter extended diagnostic session - query = IsoTpParallelQuery(sendcan, logcan, bus, [ecu_addr], [EXT_DIAG_REQUEST], [EXT_DIAG_RESPONSE], debug=debug) - for _, _ in query.get_data(timeout).items(): # pylint: disable=unused-variable - print("ecu communication control disable tx/rx ...") - # communication control disable tx and rx - query = IsoTpParallelQuery(sendcan, logcan, bus, [ecu_addr], [COM_CONT_REQUEST], [COM_CONT_RESPONSE], debug=debug) - query.get_data(0) - return True - print(f"ecu disable retry ({i+1}) ...") - except Exception: - cloudlog.warning(f"ecu disable exception: {traceback.format_exc()}") - - return False - - -if __name__ == "__main__": - import time - sendcan = messaging.pub_sock('sendcan') - logcan = messaging.sub_sock('can') - time.sleep(1) - - # honda bosch radar disable - disabled = disable_ecu(0x18DAB0F1, logcan, sendcan, 1, debug=False) - print(f"disabled: {disabled}") From d5719913a97f7cf3c3fc171d0aa562c7d9cafb15 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 13 Jul 2022 13:22:30 -0700 Subject: [PATCH 109/112] Chrysler: never drop control bit on older models (#25159) * Chrysler: never drop control bit on older models * update refs --- selfdrive/car/chrysler/carcontroller.py | 17 ++++++++++++++--- selfdrive/car/chrysler/interface.py | 2 +- selfdrive/test/process_replay/ref_commit | 2 +- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/selfdrive/car/chrysler/carcontroller.py b/selfdrive/car/chrysler/carcontroller.py index 00893b6bc4..6d158e7cd0 100644 --- a/selfdrive/car/chrysler/carcontroller.py +++ b/selfdrive/car/chrysler/carcontroller.py @@ -2,7 +2,7 @@ from opendbc.can.packer import CANPacker from common.realtime import DT_CTRL from selfdrive.car import apply_toyota_steer_torque_limits from selfdrive.car.chrysler.chryslercan import create_lkas_hud, create_lkas_command, create_cruise_buttons -from selfdrive.car.chrysler.values import RAM_CARS, CarControllerParams +from selfdrive.car.chrysler.values import CAR, RAM_CARS, CarControllerParams class CarController: @@ -20,11 +20,22 @@ class CarController: self.packer = CANPacker(dbc_name) self.params = CarControllerParams(CP) - def update(self, CC, CS, low_speed_alert): + def update(self, CC, CS): can_sends = [] + # TODO: can we make this more sane? why is it different for all the cars? + lkas_control_bit = self.lkas_control_bit_prev + if CS.out.vEgo > self.CP.minSteerSpeed: + lkas_control_bit = True + elif self.CP.carFingerprint in (CAR.PACIFICA_2019_HYBRID, CAR.PACIFICA_2020, CAR.JEEP_CHEROKEE_2019): + if CS.out.vEgo < (self.CP.minSteerSpeed - 3.0): + lkas_control_bit = False + elif self.CP.carFingerprint in RAM_CARS: + if CS.out.vEgo < (self.CP.minSteerSpeed - 0.5): + lkas_control_bit = False + # EPS faults if LKAS re-enables too quickly - lkas_control_bit = not low_speed_alert and (self.frame - self.last_lkas_falling_edge > 200) + lkas_control_bit = lkas_control_bit and (self.frame - self.last_lkas_falling_edge > 200) lkas_active = CC.latActive and self.lkas_control_bit_prev # *** control msgs *** diff --git a/selfdrive/car/chrysler/interface.py b/selfdrive/car/chrysler/interface.py index 8826a92523..acc08954a8 100755 --- a/selfdrive/car/chrysler/interface.py +++ b/selfdrive/car/chrysler/interface.py @@ -93,4 +93,4 @@ class CarInterface(CarInterfaceBase): return ret def apply(self, c): - return self.CC.update(c, self.CS, self.low_speed_alert) + return self.CC.update(c, self.CS) diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index c99a1653f4..dff232911e 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -7fbe776f271ed2d45abe989736133a5cfa0ec826 \ No newline at end of file +fa52fa6c6703269e23610b1c6aba8a56b911fbbb \ No newline at end of file From 18c1700f72e9c03750365a302dcb15b5e3d46366 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Wed, 13 Jul 2022 14:28:55 -0700 Subject: [PATCH 110/112] RAV4 2022: Add missing engine fw (#25136) Add engine fw from 909a5635aa370818 --- selfdrive/car/toyota/values.py | 1 + 1 file changed, 1 insertion(+) diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py index f40a58b5a7..63b7240e2f 100644 --- a/selfdrive/car/toyota/values.py +++ b/selfdrive/car/toyota/values.py @@ -1302,6 +1302,7 @@ FW_VERSIONS = { b'\x01896634AA0000\x00\x00\x00\x00', b'\x01896634AA1000\x00\x00\x00\x00', b'\x01896634A88000\x00\x00\x00\x00', + b'\x01896634A89000\x00\x00\x00\x00', ], (Ecu.fwdRadar, 0x750, 0xf): [ b'\x018821F0R01100\x00\x00\x00\x00', From 5a7c2f90361e72e9c35e88abd2e11acdc4aba354 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 13 Jul 2022 14:44:34 -0700 Subject: [PATCH 111/112] bump panda --- panda | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda b/panda index 2abeab913f..e51aa5ebce 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 2abeab913f6432e4327b07e247b8a46994ac77a1 +Subproject commit e51aa5ebce031c96e802b07d13120a039fa7b82f From c8051154d2a03f94d54f085d491469800c4e915a Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Wed, 13 Jul 2022 20:03:55 -0700 Subject: [PATCH 112/112] Civic 2022: Add missing fw versions (#25164) Add fingerprints from a918d2895b3210a1 --- selfdrive/car/honda/values.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/selfdrive/car/honda/values.py b/selfdrive/car/honda/values.py index b8417ee19b..c665b1cd03 100644 --- a/selfdrive/car/honda/values.py +++ b/selfdrive/car/honda/values.py @@ -1406,6 +1406,7 @@ FW_VERSIONS = { b'38897-T20-A020\x00\x00', b'38897-T20-A510\x00\x00', b'38897-T21-A010\x00\x00', + b'38897-T20-A210\x00\x00', ], (Ecu.srs, 0x18DA53F1, None): [ b'77959-T20-A970\x00\x00', @@ -1415,6 +1416,7 @@ FW_VERSIONS = { b'78108-T21-A220\x00\x00', b'78108-T21-A620\x00\x00', b'78108-T23-A110\x00\x00', + b'78108-T21-A230\x00\x00', ], (Ecu.vsa, 0x18DA28F1, None): [ b'57114-T20-AB40\x00\x00', @@ -1429,6 +1431,7 @@ FW_VERSIONS = { b'37805-64L-A540\x00\x00', b'37805-64S-A540\x00\x00', b'37805-64S-A720\x00\x00', + b'37805-64A-A540\x00\x00', ], }, }