新增 `DistractionDetectionLevel` 参数以控制驾驶员分心检测的灵敏度等级,并在 `dmonitoringd.py` 和 `helpers.py` 中实现不同等级对应的时间阈值配置。同时更新了相关逻辑以支持动态调整该参数。 fix(toyota): 支持 Toyota Wildlander PHEV 车型接入与控制 增加对 Toyota Wildlander PHEV 的指纹识别、车辆规格定义及接口适配,确保其在 TSS2 平台下的正常运行,并修正部分雷达ACC判断条件。 feat(ui): 优化 Dragonpilot 设置界面选项显示语言一致性 将 Dragonpilot 设置页面中的多个下拉选项文本进行国际化处理,统一使用翻译函数包裹,提升多语言兼容性。 chore(config): 更新 launch 脚本 API 地址并切换 shell 解释器 修改 `launch_openpilot.sh` 使用 `/usr/bin/bash` 作为解释器,并设置自定义 API 与 Athena 服务地址。 refactor(key): 实现 ECU 秘钥提取脚本并写入参数存储 创建 `key.py` 脚本用于通过 UDS 协议从 ECU 提取 SecOC 密钥,并将其保存至系统参数中供后续使用。 docs(vscode): 移除不再使用的终端配置项 清理 `.vscode/settings.json` 文件中过时的 terminal 配置内容。 feat(fonts): 新增中文字体资源文件 添加 `china.ttf` 字体文件以增强 UI 在中文环境下的渲染效果。 build(payload): 添加二进制负载文件 引入新的二进制 payload 文件用于辅助密钥提取流程。
185 lines
7.3 KiB
Python
185 lines
7.3 KiB
Python
from openpilot.common.params import Params
|
|
from openpilot.selfdrive.ui.widgets.ssh_key import ssh_key_item
|
|
from openpilot.selfdrive.ui.ui_state import ui_state
|
|
from openpilot.system.ui.widgets import Widget
|
|
from openpilot.system.ui.widgets.list_view import toggle_item, button_item
|
|
from openpilot.system.ui.widgets.scroller import Scroller
|
|
from openpilot.system.ui.widgets.confirm_dialog import ConfirmDialog
|
|
from openpilot.system.ui.lib.application import gui_app
|
|
from openpilot.system.ui.lib.multilang import tr, tr_noop
|
|
from openpilot.system.ui.widgets import DialogResult
|
|
|
|
# rick - for show error logs
|
|
from openpilot.system.ui.widgets.html_render import HtmlModal
|
|
import os
|
|
from openpilot.common.basedir import BASEDIR
|
|
|
|
# Description constants
|
|
DESCRIPTIONS = {
|
|
'enable_adb': tr_noop(
|
|
"ADB (Android Debug Bridge) allows connecting to your device over USB or over the network. " +
|
|
"See https://docs.comma.ai/how-to/connect-to-comma for more info."
|
|
),
|
|
'ssh_key': tr_noop(
|
|
"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."
|
|
),
|
|
'alpha_longitudinal': tr_noop(
|
|
"<b>WARNING: openpilot longitudinal control is in alpha for this car and will disable Automatic Emergency Braking (AEB).</b><br><br>" +
|
|
"On this car, openpilot defaults to the car's built-in ACC instead of openpilot's longitudinal control. " +
|
|
"Enable this to switch to openpilot longitudinal control. Enabling Experimental mode is recommended when enabling openpilot longitudinal control alpha. " +
|
|
"Changing this setting will restart openpilot if the car is powered on."
|
|
),
|
|
}
|
|
|
|
|
|
class DeveloperLayout(Widget):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._params = Params()
|
|
self._is_release = self._params.get_bool("IsReleaseBranch")
|
|
self._last_error_log_dialog: HtmlModal | None = None
|
|
|
|
# Build items and keep references for callbacks/state updates
|
|
self._adb_toggle = toggle_item(
|
|
lambda: tr("Enable ADB"),
|
|
description=lambda: tr(DESCRIPTIONS["enable_adb"]),
|
|
initial_state=self._params.get_bool("AdbEnabled"),
|
|
callback=self._on_enable_adb,
|
|
enabled=ui_state.is_offroad,
|
|
)
|
|
|
|
# SSH enable toggle + SSH key management
|
|
self._ssh_toggle = toggle_item(
|
|
lambda: tr("Enable SSH"),
|
|
description="",
|
|
initial_state=self._params.get_bool("SshEnabled"),
|
|
callback=self._on_enable_ssh,
|
|
)
|
|
self._ssh_keys = ssh_key_item(lambda: tr("SSH Keys"), description=lambda: tr(DESCRIPTIONS["ssh_key"]))
|
|
|
|
self._joystick_toggle = toggle_item(
|
|
lambda: tr("Joystick Debug Mode"),
|
|
description="",
|
|
initial_state=self._params.get_bool("JoystickDebugMode"),
|
|
callback=self._on_joystick_debug_mode,
|
|
enabled=ui_state.is_offroad,
|
|
)
|
|
|
|
self._long_maneuver_toggle = toggle_item(
|
|
lambda: tr("Longitudinal Maneuver Mode"),
|
|
description="",
|
|
initial_state=self._params.get_bool("LongitudinalManeuverMode"),
|
|
callback=self._on_long_maneuver_mode,
|
|
)
|
|
|
|
self._alpha_long_toggle = toggle_item(
|
|
lambda: tr("openpilot Longitudinal Control (Alpha)"),
|
|
description=lambda: tr(DESCRIPTIONS["alpha_longitudinal"]),
|
|
initial_state=self._params.get_bool("AlphaLongitudinalEnabled"),
|
|
callback=self._on_alpha_long_enabled,
|
|
enabled=lambda: not ui_state.engaged,
|
|
)
|
|
|
|
items = [
|
|
self._adb_toggle,
|
|
self._ssh_toggle,
|
|
self._ssh_keys,
|
|
self._joystick_toggle,
|
|
self._long_maneuver_toggle,
|
|
self._alpha_long_toggle,
|
|
button_item(lambda: tr("Show Last Errors"), lambda: tr("Show"), callback=self._on_show_last_errors),
|
|
]
|
|
|
|
self._scroller = Scroller(items, line_separator=True, spacing=0)
|
|
|
|
# Toggles should be not available to change in onroad state
|
|
ui_state.add_offroad_transition_callback(self._update_toggles)
|
|
|
|
def _render(self, rect):
|
|
self._scroller.render(rect)
|
|
|
|
def show_event(self):
|
|
self._scroller.show_event()
|
|
self._update_toggles()
|
|
|
|
def _update_toggles(self):
|
|
ui_state.update_params()
|
|
|
|
# Hide non-release toggles on release builds
|
|
# TODO: we can do an onroad cycle, but alpha long toggle requires a deinit function to re-enable radar and not fault
|
|
for item in (self._adb_toggle, self._joystick_toggle, self._long_maneuver_toggle, self._alpha_long_toggle):
|
|
item.set_visible(not self._is_release)
|
|
|
|
# CP gating
|
|
if ui_state.CP is not None:
|
|
alpha_avail = ui_state.CP.alphaLongitudinalAvailable
|
|
if not alpha_avail or self._is_release:
|
|
self._alpha_long_toggle.set_visible(False)
|
|
self._params.remove("AlphaLongitudinalEnabled")
|
|
else:
|
|
self._alpha_long_toggle.set_visible(True)
|
|
|
|
long_man_enabled = ui_state.has_longitudinal_control and ui_state.is_offroad()
|
|
self._long_maneuver_toggle.action_item.set_enabled(long_man_enabled)
|
|
if not long_man_enabled:
|
|
self._long_maneuver_toggle.action_item.set_state(False)
|
|
self._params.put_bool("LongitudinalManeuverMode", False)
|
|
else:
|
|
self._long_maneuver_toggle.action_item.set_enabled(False)
|
|
self._alpha_long_toggle.set_visible(False)
|
|
|
|
# TODO: make a param control list item so we don't need to manage internal state as much here
|
|
# refresh toggles from params to mirror external changes
|
|
for key, item in (
|
|
("AdbEnabled", self._adb_toggle),
|
|
("SshEnabled", self._ssh_toggle),
|
|
("JoystickDebugMode", self._joystick_toggle),
|
|
("LongitudinalManeuverMode", self._long_maneuver_toggle),
|
|
("AlphaLongitudinalEnabled", self._alpha_long_toggle),
|
|
):
|
|
item.action_item.set_state(self._params.get_bool(key))
|
|
|
|
def _on_enable_adb(self, state: bool):
|
|
self._params.put_bool("AdbEnabled", state)
|
|
|
|
def _on_enable_ssh(self, state: bool):
|
|
self._params.put_bool("SshEnabled", state)
|
|
|
|
def _on_joystick_debug_mode(self, state: bool):
|
|
self._params.put_bool("JoystickDebugMode", state)
|
|
self._params.put_bool("LongitudinalManeuverMode", False)
|
|
self._long_maneuver_toggle.action_item.set_state(False)
|
|
|
|
def _on_long_maneuver_mode(self, state: bool):
|
|
self._params.put_bool("LongitudinalManeuverMode", state)
|
|
self._params.put_bool("JoystickDebugMode", False)
|
|
self._joystick_toggle.action_item.set_state(False)
|
|
|
|
def _on_alpha_long_enabled(self, state: bool):
|
|
if state:
|
|
def confirm_callback(result: int):
|
|
if result == DialogResult.CONFIRM:
|
|
self._params.put_bool("AlphaLongitudinalEnabled", True)
|
|
self._params.put_bool("OnroadCycleRequested", True)
|
|
self._update_toggles()
|
|
else:
|
|
self._alpha_long_toggle.action_item.set_state(False)
|
|
|
|
# show confirmation dialog
|
|
content = (f"<h1>{self._alpha_long_toggle.title}</h1><br>" +
|
|
f"<p>{self._alpha_long_toggle.description}</p>")
|
|
|
|
dlg = ConfirmDialog(content, tr("Enable"), rich=True)
|
|
gui_app.set_modal_overlay(dlg, callback=confirm_callback)
|
|
|
|
else:
|
|
self._params.put_bool("AlphaLongitudinalEnabled", False)
|
|
self._params.put_bool("OnroadCycleRequested", True)
|
|
self._update_toggles()
|
|
|
|
def _on_show_last_errors(self):
|
|
if not self._last_error_log_dialog:
|
|
self._last_error_log_dialog = HtmlModal(text=(self._params.get("dp_dev_last_log") or ""))
|
|
gui_app.set_modal_overlay(self._last_error_log_dialog)
|