Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 38fe76e2df | |||
| c430381736 | |||
| 24ce7c586b | |||
| 6332384304 | |||
| c6416a899b | |||
| e578a8ef87 | |||
| 30239bfbd2 | |||
| 0cc5666b64 | |||
| 59d951ea32 | |||
| 10bf80af09 | |||
| 1bff880a88 | |||
| 74f0ba7b7a | |||
| cdf424d261 | |||
| 92ebfb42ca | |||
| 6fe513fd66 | |||
| 237816d8f9 | |||
| c75bf1ad61 | |||
| 7dc8596bbd | |||
| 5eca39c629 | |||
| 2997cb455b | |||
| a0844b6aa3 | |||
| e53e809fce | |||
| e810b1c1e7 | |||
| 9967a69abe | |||
| 858a9d6fb9 | |||
| 026d0a5e48 | |||
| b2f5adc98f | |||
| cae81899fb | |||
| 4015dbd04c | |||
| 3c388b5648 | |||
| 7c44d10fed |
@@ -0,0 +1,11 @@
|
||||
* @sunnypilot/dev-internal
|
||||
/.github/ @devtekve @sunnyhaibin
|
||||
/release/ci/ @devtekve @sunnyhaibin
|
||||
/tinygrad_repo @devtekve @Discountchubbs
|
||||
/tinygrad/ @devtekve @Discountchubbs
|
||||
/selfdrive/controls/lib/longitudinal_planner.py @devtekve @Discountchubbs
|
||||
/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py @devtekve @Discountchubbs
|
||||
/selfdrive/modeld/ @devtekve @Discountchubbs
|
||||
/sunnypilot/model* @devtekve @Discountchubbs
|
||||
/sunnypilot/sunnylink/ @devtekve
|
||||
/system/athena/ @devtekve
|
||||
@@ -0,0 +1,47 @@
|
||||
name: Bug report
|
||||
description: For issues with running openpilot on your comma device
|
||||
labels: ["bug"]
|
||||
body:
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: >
|
||||
Before creating a **bug report**, please check the following:
|
||||
* If the issue likely only affects your car model or make, go back and open a **car bug report** instead.
|
||||
* If the issue is related to the driving or driver monitoring models, you should open a [discussion](https://github.com/commaai/openpilot/discussions/categories/model-feedback) instead.
|
||||
* Ensure you're running the latest openpilot release.
|
||||
* Ensure you're using officially supported hardware. Issues running on PCs have a different issue template.
|
||||
* Ensure there isn't an existing issue for your bug. If there is, leave a comment on the existing issue.
|
||||
* Ensure you're running stock openpilot. We cannot look into bug reports from forks.
|
||||
|
||||
If you're unsure whether you've hit a bug, check out the #installation-help channel in the [community Discord server](https://discord.comma.ai).
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the bug
|
||||
description: Also include a description of how to reproduce the bug
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: route
|
||||
attributes:
|
||||
label: Provide a route where the issue occurs
|
||||
description: Ensure the route is fully uploaded at https://useradmin.comma.ai. We cannot look into issues without routes, or at least a Dongle ID.
|
||||
placeholder: 77611a1fac303767|2020-05-11--16-37-07
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: openpilot version
|
||||
description: If you're not on release, provide the commit hash
|
||||
placeholder: 0.8.10
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional info
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Car bug report
|
||||
url: https://github.com/commaai/opendbc/issues/new
|
||||
about: For issues with a particular car make or model
|
||||
- name: Join the Discord
|
||||
url: https://discord.comma.ai
|
||||
about: The community Discord is for both openpilot development and experience discussion
|
||||
- name: Report driving behavior feedback
|
||||
url: https://discord.com/channels/469524606043160576/1254834193066623017
|
||||
about: Feedback for the driving and driver monitoring models goes in the #driving-feedback in Discord
|
||||
- name: Community Wiki
|
||||
url: https://github.com/commaai/openpilot/wiki
|
||||
about: Check out our community wiki
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
name: Enhancement
|
||||
about: For openpilot enhancement suggestions
|
||||
title: ''
|
||||
labels: 'enhancement'
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
name: PC bug report
|
||||
description: For issues with running openpilot on PC
|
||||
labels: ["PC"]
|
||||
body:
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: >
|
||||
Before creating a **bug report**, please check the following:
|
||||
* Ensure you're running the latest openpilot release.
|
||||
* Ensure there isn't an existing issue for your bug. If there is, leave a comment on the existing issue.
|
||||
* Ensure you're running stock openpilot. We cannot look into bug reports from forks.
|
||||
|
||||
If you're unsure whether you've hit a bug, check out the #installation-help channel in the [community Discord server](https://discord.comma.ai).
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the bug
|
||||
description: Also include a description of how to reproduce the bug
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: os-version
|
||||
attributes:
|
||||
label: OS Version
|
||||
placeholder: Ubuntu 24.04
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: openpilot version or commit
|
||||
placeholder: bd36f2ec8d3559909678eff2690c10a520938367
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional info
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
ci:
|
||||
- changed-files:
|
||||
- any-glob-to-all-files: "{.github/**,**/test_*,**/test/**,Jenkinsfile}"
|
||||
|
||||
chore:
|
||||
- changed-files:
|
||||
- any-glob-to-all-files: "{.github/**}"
|
||||
|
||||
car:
|
||||
- changed-files:
|
||||
- any-glob-to-all-files: '{selfdrive/car/**,opendbc_repo}'
|
||||
|
||||
simulation:
|
||||
- changed-files:
|
||||
- any-glob-to-all-files: 'tools/sim/**'
|
||||
|
||||
ui:
|
||||
- changed-files:
|
||||
- any-glob-to-all-files: '{selfdrive/assets/**,selfdrive/ui/**,system/ui/**}'
|
||||
|
||||
tools:
|
||||
- changed-files:
|
||||
- any-glob-to-all-files: 'tools/**'
|
||||
|
||||
multilanguage:
|
||||
- changed-files:
|
||||
- any-glob-to-all-files: 'selfdrive/ui/translations/**'
|
||||
|
||||
autonomy:
|
||||
- changed-files:
|
||||
- any-glob-to-all-files: "{selfdrive/modeld/models/**,selfdrive/test/process_replay/model_replay_ref_commit,sunnypilot/modeld*/models/**}"
|
||||
@@ -0,0 +1,68 @@
|
||||
<!-- Please copy and paste the relevant template -->
|
||||
|
||||
<!--- ***** Template: Fingerprint *****
|
||||
|
||||
**Car**
|
||||
Which car (make, model, year) this fingerprint is for
|
||||
|
||||
**Route**
|
||||
A route with the fingerprint
|
||||
|
||||
-->
|
||||
|
||||
<!--- ***** Template: Car Bugfix *****
|
||||
|
||||
**Description**
|
||||
|
||||
A description of the bug and the fix. Also link the issue if it exists.
|
||||
|
||||
**Verification**
|
||||
|
||||
Explain how you tested this bug fix.
|
||||
|
||||
**Route**
|
||||
|
||||
Route: [a route with the bug fix]
|
||||
|
||||
|
||||
-->
|
||||
|
||||
<!--- ***** Template: Bugfix *****
|
||||
|
||||
**Description**
|
||||
|
||||
A description of the bug and the fix. Also link the issue if it exists.
|
||||
|
||||
**Verification**
|
||||
|
||||
Explain how you tested this bug fix.
|
||||
|
||||
|
||||
-->
|
||||
|
||||
<!--- ***** Template: Car Port *****
|
||||
|
||||
**Checklist**
|
||||
|
||||
- [ ] added entry to CAR in selfdrive/car/*/values.py and ran `selfdrive/car/docs.py` to generate new docs
|
||||
- [ ] test route added to [routes.py](https://github.com/commaai/openpilot/blob/master/selfdrive/car/tests/routes.py)
|
||||
- [ ] route with openpilot:
|
||||
- [ ] route with stock system:
|
||||
- [ ] car harness used (if comma doesn't sell it, put N/A):
|
||||
|
||||
|
||||
-->
|
||||
|
||||
<!--- ***** Template: Refactor *****
|
||||
|
||||
**Description**
|
||||
|
||||
A description of the refactor, including the goals it accomplishes.
|
||||
|
||||
**Verification**
|
||||
|
||||
Explain how you tested the refactor for regressions.
|
||||
|
||||
|
||||
-->
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
exclude-labels:
|
||||
- 'no-changelog'
|
||||
categories:
|
||||
- title: '🚀 Features'
|
||||
labels:
|
||||
- 'feature'
|
||||
- 'enhancement'
|
||||
- title: '🐛 Bug Fixes'
|
||||
collapse-after: 5
|
||||
labels:
|
||||
- 'fix'
|
||||
- 'bugfix'
|
||||
- 'bug'
|
||||
- title: '🧰 Maintenance'
|
||||
collapse-after: 5
|
||||
label: 'chore'
|
||||
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
|
||||
change-title-escapes: '\<*_&'
|
||||
replacers:
|
||||
- search: '/[Ss][Uu][Nn][Nn][Yy][Pp][Ii][Ll][Oo][Tt]/g'
|
||||
replace: 'sunnypilot'
|
||||
- search: '/\b[Ss][Pp]\b/g'
|
||||
replace: 'SP'
|
||||
version-resolver:
|
||||
major:
|
||||
labels:
|
||||
- 'major'
|
||||
minor:
|
||||
labels:
|
||||
- 'minor'
|
||||
patch:
|
||||
labels:
|
||||
- 'patch'
|
||||
default: patch
|
||||
name-template: 'v$RESOLVED_VERSION 🚀'
|
||||
tag-template: 'v$RESOLVED_VERSION'
|
||||
version-template: "0.$MAJOR.$MINOR.$PATCH" # The day OP becomes v1, we need to bump this
|
||||
tag-prefix: "v0." # The day OP becomes v1, we need to bump this
|
||||
prerelease-identifier: "staging"
|
||||
template: |
|
||||
## Changes
|
||||
|
||||
$CHANGES
|
||||
@@ -1,83 +0,0 @@
|
||||
#!/bin/env sh
|
||||
|
||||
persist_dir=/persist
|
||||
target_dir=${persist_dir}/comma
|
||||
# Change target dir from sunnylink to comma to make this no longer a test
|
||||
|
||||
|
||||
# Function to remount /persist as read-only
|
||||
cleanup() {
|
||||
echo "Remounting ${persist_dir} as read-only..."
|
||||
sudo mount -o remount,ro ${persist_dir}
|
||||
}
|
||||
|
||||
# Function to check and backup existing keys
|
||||
backup_keys() {
|
||||
if [ -f "id_rsa" ] || [ -f "id_rsa.pub" ]; then
|
||||
timestamp=$(date +%s)
|
||||
backup_base="id_rsa_backup_$timestamp"
|
||||
backup_private="$backup_base"
|
||||
backup_public="${backup_base}.pub"
|
||||
|
||||
# Ensure we're not overwriting an existing backup
|
||||
counter=0
|
||||
while [ -f "$backup_private" ] || [ -f "$backup_public" ]; do
|
||||
counter=$((counter + 1))
|
||||
backup_private="${backup_base}_$counter"
|
||||
backup_public="${backup_base}_$counter.pub"
|
||||
done
|
||||
|
||||
# Backup the keys
|
||||
cp id_rsa "$backup_private"
|
||||
cp id_rsa.pub "$backup_public"
|
||||
|
||||
# Verify the backup
|
||||
original_private_hash=$(sha256sum id_rsa | cut -d ' ' -f 1)
|
||||
backup_private_hash=$(sha256sum "$backup_private" | cut -d ' ' -f 1)
|
||||
original_public_hash=$(sha256sum id_rsa.pub | cut -d ' ' -f 1)
|
||||
backup_public_hash=$(sha256sum "$backup_public" | cut -d ' ' -f 1)
|
||||
|
||||
if [ "$original_private_hash" = "$backup_private_hash" ] && [ "$original_public_hash" = "$backup_public_hash" ]; then
|
||||
echo "Backup verified successfully."
|
||||
# Safe to delete original keys after successful backup verification
|
||||
else
|
||||
echo "Backup verification failed. Aborting operation."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Existing keys backed up as $backup_private and $backup_public"
|
||||
fi
|
||||
}
|
||||
|
||||
# Trap any signal that exits the script to run cleanup function
|
||||
trap cleanup EXIT
|
||||
|
||||
# Remount /persist as read-write
|
||||
sudo mount -o remount,rw ${persist_dir}
|
||||
|
||||
# Ensure the directory exists
|
||||
mkdir -p ${target_dir}
|
||||
cd ${target_dir}
|
||||
|
||||
# Check for and backup existing keys
|
||||
#backup_keys
|
||||
|
||||
# Generate new keys
|
||||
if ! ssh-keygen -t rsa -b 4096 -m PEM -f id_rsa -N ''; then
|
||||
echo "Failed to generate new RSA keys. Exiting..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Convert the generated SSH public key to PEM format and store it temporarily
|
||||
if ! openssl rsa -pubout -in id_rsa -out id_rsa.pub -outform PEM; then
|
||||
echo "Failed to convert the public key to PEM format. Exiting..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Display the public key
|
||||
echo "Displaying the public key:"
|
||||
cat id_rsa.pub
|
||||
|
||||
# Cleanup will be called automatically due to trap on EXIT
|
||||
#echo "Operation completed successfully. System will reboot now."
|
||||
#sudo reboot
|
||||
+269
@@ -0,0 +1,269 @@
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import sysconfig
|
||||
import platform
|
||||
import shlex
|
||||
import importlib
|
||||
import numpy as np
|
||||
|
||||
import SCons.Errors
|
||||
from SCons.Defaults import _stripixes
|
||||
|
||||
SCons.Warnings.warningAsException(True)
|
||||
|
||||
Decider('MD5-timestamp')
|
||||
|
||||
SetOption('num_jobs', max(1, int(os.cpu_count()/2)))
|
||||
|
||||
AddOption('--ccflags', action='store', type='string', default='', help='pass arbitrary flags over the command line')
|
||||
AddOption('--verbose', action='store_true', default=False, help='show full build commands')
|
||||
AddOption('--minimal',
|
||||
action='store_false',
|
||||
dest='extras',
|
||||
default=os.path.exists(File('#.gitattributes').abspath), # minimal by default on release branch (where there's no LFS)
|
||||
help='the minimum build to run openpilot. no tests, tools, etc.')
|
||||
|
||||
# Detect platform
|
||||
arch = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip()
|
||||
if platform.system() == "Darwin":
|
||||
arch = "Darwin"
|
||||
elif arch == "aarch64" and os.path.isfile('/TICI'):
|
||||
arch = "larch64"
|
||||
assert arch in [
|
||||
"larch64", # linux tici arm64
|
||||
"aarch64", # linux pc arm64
|
||||
"x86_64", # linux pc x64
|
||||
"Darwin", # macOS arm64 (x86 not supported)
|
||||
]
|
||||
|
||||
pkg_names = ['bzip2', 'capnproto', 'eigen', 'ffmpeg', 'libjpeg', 'libyuv', 'ncurses', 'zeromq', 'zstd']
|
||||
pkgs = [importlib.import_module(name) for name in pkg_names]
|
||||
|
||||
|
||||
# ***** enforce a whitelist of system libraries *****
|
||||
# this prevents silently relying on a 3rd party package,
|
||||
# e.g. apt-installed libusb. all libraries should either
|
||||
# be distributed with all Linux distros and macOS, or
|
||||
# vendored in commaai/dependencies.
|
||||
allowed_system_libs = {
|
||||
"EGL", "GLESv2", "GL",
|
||||
"Qt5Charts", "Qt5Core", "Qt5Gui", "Qt5Widgets",
|
||||
"dl", "drm", "gbm", "m", "pthread",
|
||||
}
|
||||
|
||||
def _resolve_lib(env, name):
|
||||
for d in env.Flatten(env.get('LIBPATH', [])):
|
||||
p = Dir(str(d)).abspath
|
||||
for ext in ('.a', '.so', '.dylib'):
|
||||
f = File(os.path.join(p, f'lib{name}{ext}'))
|
||||
if f.exists() or f.has_builder():
|
||||
return name
|
||||
if name in allowed_system_libs:
|
||||
return name
|
||||
raise SCons.Errors.UserError(f"Unexpected non-vendored library '{name}'")
|
||||
|
||||
def _libflags(target, source, env, for_signature):
|
||||
libs = []
|
||||
lp = env.subst('$LIBLITERALPREFIX')
|
||||
for lib in env.Flatten(env.get('LIBS', [])):
|
||||
if isinstance(lib, str):
|
||||
if os.sep in lib or lib.startswith('#'):
|
||||
libs.append(File(lib))
|
||||
elif lib.startswith('-') or (lp and lib.startswith(lp)):
|
||||
libs.append(lib)
|
||||
else:
|
||||
libs.append(_resolve_lib(env, lib))
|
||||
else:
|
||||
libs.append(lib)
|
||||
return _stripixes(env['LIBLINKPREFIX'], libs, env['LIBLINKSUFFIX'],
|
||||
env['LIBPREFIXES'], env['LIBSUFFIXES'], env, env['LIBLITERALPREFIX'])
|
||||
|
||||
env = Environment(
|
||||
ENV={
|
||||
"PATH": os.environ['PATH'],
|
||||
"PYTHONPATH": Dir("#").abspath + ':' + Dir(f"#third_party/acados").abspath,
|
||||
"ACADOS_SOURCE_DIR": Dir("#third_party/acados").abspath,
|
||||
"ACADOS_PYTHON_INTERFACE_PATH": Dir("#third_party/acados/acados_template").abspath,
|
||||
"TERA_PATH": Dir("#").abspath + f"/third_party/acados/{arch}/t_renderer"
|
||||
},
|
||||
CCFLAGS=[
|
||||
"-g",
|
||||
"-fPIC",
|
||||
"-O2",
|
||||
"-Wunused",
|
||||
"-Werror",
|
||||
"-Wshadow" if arch in ("Darwin", "larch64") else "-Wshadow=local",
|
||||
"-Wno-unknown-warning-option",
|
||||
"-Wno-inconsistent-missing-override",
|
||||
"-Wno-c99-designator",
|
||||
"-Wno-reorder-init-list",
|
||||
"-Wno-vla-cxx-extension",
|
||||
],
|
||||
CFLAGS=["-std=gnu11"],
|
||||
CXXFLAGS=["-std=c++1z"],
|
||||
CPPPATH=[
|
||||
"#",
|
||||
"#msgq",
|
||||
"#third_party",
|
||||
"#third_party/json11",
|
||||
"#third_party/linux/include",
|
||||
"#third_party/acados/include",
|
||||
"#third_party/acados/include/blasfeo/include",
|
||||
"#third_party/acados/include/hpipm/include",
|
||||
"#third_party/catch2/include",
|
||||
[x.INCLUDE_DIR for x in pkgs],
|
||||
],
|
||||
LIBPATH=[
|
||||
"#common",
|
||||
"#msgq_repo",
|
||||
"#third_party",
|
||||
"#selfdrive/pandad",
|
||||
"#rednose/helpers",
|
||||
f"#third_party/acados/{arch}/lib",
|
||||
[x.LIB_DIR for x in pkgs],
|
||||
],
|
||||
RPATH=[],
|
||||
CYTHONCFILESUFFIX=".cpp",
|
||||
COMPILATIONDB_USE_ABSPATH=True,
|
||||
REDNOSE_ROOT="#",
|
||||
tools=["default", "cython", "compilation_db", "rednose_filter"],
|
||||
toolpath=["#site_scons/site_tools", "#rednose_repo/site_scons/site_tools"],
|
||||
)
|
||||
if arch != "larch64":
|
||||
env['_LIBFLAGS'] = _libflags
|
||||
|
||||
# Arch-specific flags and paths
|
||||
if arch == "larch64":
|
||||
env["CC"] = "clang"
|
||||
env["CXX"] = "clang++"
|
||||
env.Append(LIBPATH=[
|
||||
"/usr/lib/aarch64-linux-gnu",
|
||||
])
|
||||
arch_flags = ["-D__TICI__", "-mcpu=cortex-a57", "-DQCOM2"]
|
||||
env.Append(CCFLAGS=arch_flags)
|
||||
env.Append(CXXFLAGS=arch_flags)
|
||||
elif arch == "Darwin":
|
||||
env.Append(LIBPATH=[
|
||||
"/System/Library/Frameworks/OpenGL.framework/Libraries",
|
||||
])
|
||||
env.Append(CCFLAGS=["-DGL_SILENCE_DEPRECATION"])
|
||||
env.Append(CXXFLAGS=["-DGL_SILENCE_DEPRECATION"])
|
||||
|
||||
_extra_cc = shlex.split(GetOption('ccflags') or '')
|
||||
if _extra_cc:
|
||||
env.Append(CCFLAGS=_extra_cc)
|
||||
|
||||
# no --as-needed on mac linker
|
||||
if arch != "Darwin":
|
||||
env.Append(LINKFLAGS=["-Wl,--as-needed", "-Wl,--no-undefined"])
|
||||
|
||||
# Shorter build output: show brief descriptions instead of full commands.
|
||||
# Full command lines are still printed on failure by scons.
|
||||
if not GetOption('verbose'):
|
||||
for action, short in (
|
||||
("CC", "CC"),
|
||||
("CXX", "CXX"),
|
||||
("LINK", "LINK"),
|
||||
("SHCC", "CC"),
|
||||
("SHCXX", "CXX"),
|
||||
("SHLINK", "LINK"),
|
||||
("AR", "AR"),
|
||||
("RANLIB", "RANLIB"),
|
||||
("AS", "AS"),
|
||||
):
|
||||
env[f"{action}COMSTR"] = f" [{short}] $TARGET"
|
||||
|
||||
# progress output
|
||||
node_interval = 5
|
||||
node_count = 0
|
||||
def progress_function(node):
|
||||
global node_count
|
||||
node_count += node_interval
|
||||
sys.stderr.write("progress: %d\n" % node_count)
|
||||
if os.environ.get('SCONS_PROGRESS'):
|
||||
Progress(progress_function, interval=node_interval)
|
||||
|
||||
# ********** Cython build environment **********
|
||||
envCython = env.Clone()
|
||||
envCython["CPPPATH"] += [sysconfig.get_paths()['include'], np.get_include()]
|
||||
envCython["CCFLAGS"] += ["-Wno-#warnings", "-Wno-cpp", "-Wno-shadow", "-Wno-deprecated-declarations"]
|
||||
envCython["CCFLAGS"].remove("-Werror")
|
||||
|
||||
envCython["LIBS"] = []
|
||||
if arch == "Darwin":
|
||||
envCython["LINKFLAGS"] = env["LINKFLAGS"] + ["-bundle", "-undefined", "dynamic_lookup"]
|
||||
else:
|
||||
envCython["LINKFLAGS"] = ["-pthread", "-shared"]
|
||||
|
||||
np_version = SCons.Script.Value(np.__version__)
|
||||
Export('envCython', 'np_version')
|
||||
|
||||
Export('env', 'arch')
|
||||
|
||||
# Setup cache dir
|
||||
default_cache_dir = '/data/scons_cache' if arch == "larch64" else '/tmp/scons_cache'
|
||||
cache_dir = ARGUMENTS.get('cache_dir', default_cache_dir)
|
||||
CacheDir(cache_dir)
|
||||
Clean(["."], cache_dir)
|
||||
|
||||
# ********** start building stuff **********
|
||||
|
||||
# Build common module
|
||||
SConscript(['common/SConscript'])
|
||||
Import('_common')
|
||||
common = [_common, 'json11', 'zmq']
|
||||
Export('common')
|
||||
|
||||
# Build messaging (cereal + msgq + socketmaster + their dependencies)
|
||||
# Enable swaglog include in submodules
|
||||
env_swaglog = env.Clone()
|
||||
env_swaglog['CXXFLAGS'].append('-DSWAGLOG="\\"common/swaglog.h\\""')
|
||||
SConscript(['msgq_repo/SConscript'], exports={'env': env_swaglog})
|
||||
|
||||
SConscript(['cereal/SConscript'])
|
||||
|
||||
Import('socketmaster', 'msgq')
|
||||
messaging = [socketmaster, msgq, 'capnp', 'kj',]
|
||||
Export('messaging')
|
||||
|
||||
|
||||
# Build other submodules
|
||||
SConscript(['panda/SConscript'])
|
||||
|
||||
# Build rednose library
|
||||
SConscript(['rednose/SConscript'])
|
||||
|
||||
# Build system services
|
||||
SConscript([
|
||||
'system/loggerd/SConscript',
|
||||
])
|
||||
|
||||
if arch == "larch64":
|
||||
SConscript(['system/camerad/SConscript'])
|
||||
|
||||
# Build openpilot
|
||||
SConscript(['third_party/SConscript'])
|
||||
|
||||
# Build selfdrive
|
||||
SConscript([
|
||||
'selfdrive/pandad/SConscript',
|
||||
'selfdrive/controls/lib/lateral_mpc_lib/SConscript',
|
||||
'selfdrive/controls/lib/longitudinal_mpc_lib/SConscript',
|
||||
'selfdrive/locationd/SConscript',
|
||||
'selfdrive/modeld/SConscript',
|
||||
'selfdrive/ui/SConscript',
|
||||
])
|
||||
|
||||
SConscript(['sunnypilot/SConscript'])
|
||||
|
||||
# Build tools
|
||||
if arch != "larch64":
|
||||
SConscript([
|
||||
'tools/replay/SConscript',
|
||||
'tools/cabana/SConscript',
|
||||
'tools/jotpluggler/SConscript',
|
||||
])
|
||||
|
||||
|
||||
env.CompilationDatabase('compile_commands.json')
|
||||
@@ -0,0 +1,20 @@
|
||||
Import('env', 'common', 'msgq')
|
||||
|
||||
cereal_dir = Dir('.')
|
||||
gen_dir = Dir('gen')
|
||||
|
||||
# Build cereal
|
||||
schema_files = ['log.capnp', 'car.capnp', 'deprecated.capnp', 'custom.capnp']
|
||||
env.Command([f'gen/cpp/{s}.c++' for s in schema_files] + [f'gen/cpp/{s}.h' for s in schema_files],
|
||||
schema_files,
|
||||
f"capnpc --src-prefix={cereal_dir.path} $SOURCES -o c++:{gen_dir.path}/cpp/")
|
||||
|
||||
cereal = env.Library('cereal', [f'gen/cpp/{s}.c++' for s in schema_files])
|
||||
|
||||
# Build messaging
|
||||
services_h = env.Command(['services.h'], ['services.py'], 'python3 ' + cereal_dir.path + '/services.py > $TARGET')
|
||||
env.Program('messaging/bridge', ['messaging/bridge.cc', 'messaging/msgq_to_zmq.cc', 'messaging/bridge_zmq.cc'], LIBS=[msgq, common, 'pthread'])
|
||||
|
||||
socketmaster = env.Library('socketmaster', ['messaging/socketmaster.cc'])
|
||||
|
||||
Export('cereal', 'socketmaster')
|
||||
@@ -0,0 +1,23 @@
|
||||
Import('env', 'envCython')
|
||||
|
||||
common_libs = [
|
||||
'params.cc',
|
||||
'swaglog.cc',
|
||||
'util.cc',
|
||||
'ratekeeper.cc',
|
||||
]
|
||||
|
||||
_common = env.Library('common', common_libs, LIBS="json11")
|
||||
Export('_common')
|
||||
|
||||
if GetOption('extras'):
|
||||
env.Program('tests/test_common',
|
||||
['tests/test_runner.cc', 'tests/test_params.cc', 'tests/test_util.cc', 'tests/test_swaglog.cc'],
|
||||
LIBS=[_common, 'json11', 'zmq', 'pthread'])
|
||||
|
||||
# Cython bindings
|
||||
params_python = envCython.Program('params_pyx.so', 'params_pyx.pyx', LIBS=envCython['LIBS'] + [_common, 'zmq', 'json11'])
|
||||
|
||||
common_python = [params_python]
|
||||
|
||||
Export('common_python')
|
||||
@@ -0,0 +1 @@
|
||||
dfc3c98b226da57a653daf57131a8a3d66166fcb
|
||||
@@ -0,0 +1 @@
|
||||
1779852714 2026-05-26 23:31:54 -0400
|
||||
+2
-1
@@ -5,7 +5,8 @@ export API_HOST='http://res.mr-one.cn'
|
||||
echo -n "2" > /data/params/d/HasAcceptedTerms
|
||||
echo -n "1.0" > /data/params/d/HasAcceptedTermsSP
|
||||
echo -n "0.2.0" > /data/params/d/CompletedTrainingVersion
|
||||
echo -n "1.0" > /data/params/d/CompletedSunnylinkConsentVersion # Sunnylink 同意
|
||||
echo -n "1" > /data/params/d/IsMetric
|
||||
|
||||
|
||||
|
||||
exec ./launch_chffrplus.sh
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
Import('env', 'envCython', 'arch', 'common')
|
||||
|
||||
|
||||
visionipc_dir = Dir('msgq/visionipc')
|
||||
|
||||
# Build msgq
|
||||
msgq_objects = env.SharedObject([
|
||||
'msgq/ipc.cc',
|
||||
'msgq/event.cc',
|
||||
'msgq/impl_msgq.cc',
|
||||
'msgq/impl_fake.cc',
|
||||
'msgq/msgq.cc',
|
||||
])
|
||||
msgq = env.Library('msgq', msgq_objects)
|
||||
msgq_python = envCython.Program('msgq/ipc_pyx.so', 'msgq/ipc_pyx.pyx', LIBS=envCython["LIBS"]+[msgq, common])
|
||||
|
||||
# Build Vision IPC
|
||||
vipc_files = ['visionipc.cc', 'visionipc_server.cc', 'visionipc_client.cc']
|
||||
if arch == "larch64":
|
||||
vipc_files += ['visionbuf_ion.cc']
|
||||
else:
|
||||
vipc_files += ['visionbuf.cc']
|
||||
vipc_sources = [f'{visionipc_dir.abspath}/{f}' for f in vipc_files]
|
||||
|
||||
vipc_objects = env.SharedObject(vipc_sources)
|
||||
visionipc = env.Library('visionipc', vipc_objects)
|
||||
|
||||
|
||||
vipc_libs = envCython["LIBS"] + [visionipc, msgq, common]
|
||||
envCython.Program(f'{visionipc_dir.abspath}/visionipc_pyx.so', f'{visionipc_dir.abspath}/visionipc_pyx.pyx',
|
||||
LIBS=vipc_libs)
|
||||
|
||||
if GetOption('extras'):
|
||||
env.Program('msgq/test_runner', ['msgq/test_runner.cc', 'msgq/msgq_tests.cc'], LIBS=[msgq, common])
|
||||
env.Program(f'{visionipc_dir.abspath}/test_runner',
|
||||
[f'{visionipc_dir.abspath}/test_runner.cc', f'{visionipc_dir.abspath}/visionipc_tests.cc'],
|
||||
LIBS=['pthread'] + vipc_libs)
|
||||
|
||||
Export('visionipc', 'msgq', 'msgq_python')
|
||||
@@ -0,0 +1,83 @@
|
||||
import os
|
||||
import platform
|
||||
import subprocess
|
||||
import sysconfig
|
||||
import numpy as np
|
||||
|
||||
arch = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip()
|
||||
if platform.system() == "Darwin":
|
||||
arch = "Darwin"
|
||||
|
||||
common = ''
|
||||
|
||||
cpppath = [
|
||||
f"#/",
|
||||
'#msgq/',
|
||||
'/usr/lib/include',
|
||||
sysconfig.get_paths()['include'],
|
||||
]
|
||||
|
||||
AddOption('--minimal',
|
||||
action='store_false',
|
||||
dest='extras',
|
||||
default=True,
|
||||
help='the minimum build. no tests, tools, etc.')
|
||||
|
||||
AddOption('--asan',
|
||||
action='store_true',
|
||||
help='turn on ASAN')
|
||||
|
||||
AddOption('--ubsan',
|
||||
action='store_true',
|
||||
help='turn on UBSan')
|
||||
|
||||
ccflags = []
|
||||
ldflags = []
|
||||
if GetOption('ubsan'):
|
||||
flags = [
|
||||
"-fsanitize=undefined",
|
||||
"-fno-sanitize-recover=undefined",
|
||||
]
|
||||
ccflags += flags
|
||||
ldflags += flags
|
||||
elif GetOption('asan'):
|
||||
ccflags += ["-fsanitize=address", "-fno-omit-frame-pointer"]
|
||||
ldflags += ["-fsanitize=address"]
|
||||
|
||||
env = Environment(
|
||||
ENV=os.environ,
|
||||
CCFLAGS=[
|
||||
"-g",
|
||||
"-fPIC",
|
||||
"-O2",
|
||||
"-Wunused",
|
||||
"-Werror",
|
||||
"-Wshadow" if arch == "Darwin" else "-Wshadow=local",
|
||||
"-Wno-vla-cxx-extension",
|
||||
"-Wno-unknown-warning-option",
|
||||
] + ccflags,
|
||||
LDFLAGS=ldflags,
|
||||
LINKFLAGS=ldflags,
|
||||
|
||||
CFLAGS="-std=gnu11",
|
||||
CXXFLAGS="-std=c++1z",
|
||||
CPPPATH=cpppath,
|
||||
CYTHONCFILESUFFIX=".cpp",
|
||||
tools=["default", "cython"]
|
||||
)
|
||||
|
||||
Export('env', 'arch', 'common')
|
||||
|
||||
envCython = env.Clone(LIBS=[])
|
||||
envCython["CPPPATH"] += [np.get_include()]
|
||||
envCython["CCFLAGS"] += ["-Wno-#warnings", "-Wno-cpp", "-Wno-shadow", "-Wno-deprecated-declarations"]
|
||||
envCython["CCFLAGS"].remove('-Werror')
|
||||
if arch == "Darwin":
|
||||
envCython["LINKFLAGS"] = ["-bundle", "-undefined", "dynamic_lookup"]
|
||||
else:
|
||||
envCython["LINKFLAGS"] = ["-pthread", "-shared"]
|
||||
|
||||
Export('envCython')
|
||||
|
||||
|
||||
SConscript(['SConscript'])
|
||||
@@ -0,0 +1,49 @@
|
||||
name: Car bug report
|
||||
description: For issues with a particular car make or model
|
||||
labels: ["car", "bug"]
|
||||
body:
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: >
|
||||
Before creating a **car bug report**, please check the following:
|
||||
* If the issue likely isn't specific to your car model or make, go back and open an **openpilot bug report** instead.
|
||||
* If the issue is related to the driving or driver monitoring models, you should open a [discussion](https://github.com/commaai/openpilot/discussions/categories/model-feedback) instead.
|
||||
* If you are fingerprinting your car, refer to the [fingerprinting guide](https://github.com/commaai/openpilot/wiki/Fingerprinting) or visit the [community Discord server](https://discord.comma.ai) to request help.
|
||||
* If you are inquiring about future car support, check the [community Discord server](https://discord.comma.ai) for progress on your vehicle and help contribute. Issues simply requesting support for new vehicles will be closed.
|
||||
* Ensure you're running the latest openpilot release.
|
||||
* Ensure you're using officially supported hardware.
|
||||
* Ensure there isn't an existing issue for your bug. If there is, leave a comment on the existing issue.
|
||||
* Ensure you're running stock openpilot. We cannot look into bug reports from forks.
|
||||
|
||||
If you're unsure whether you've hit a bug, check out the #installation-help channel in the [community Discord server](https://discord.comma.ai).
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the car bug
|
||||
description: Also include a description of how to reproduce the bug
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: route
|
||||
attributes:
|
||||
label: Provide a route where the issue occurs
|
||||
description: Ensure the route is fully uploaded at https://useradmin.comma.ai. We cannot look into issues without routes, or at least a Dongle ID.
|
||||
placeholder: 77611a1fac303767|2020-05-11--16-37-07
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: openpilot version
|
||||
description: If you're not on release, provide the commit hash
|
||||
placeholder: 0.8.10
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional info
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: openpilot bug report
|
||||
url: https://github.com/commaai/openpilot/issues/new
|
||||
about: For issues not limited to a particular car make or model, e.g. driving model performance or issues with your comma device.
|
||||
- name: Join the Discord
|
||||
url: https://discord.comma.ai
|
||||
about: The community Discord is for both car port development and experience discussion
|
||||
- name: Report driving behavior feedback
|
||||
url: https://discord.com/channels/469524606043160576/1254834193066623017
|
||||
about: Feedback for the driving and driver monitoring models goes in the #driving-feedback in Discord
|
||||
- name: Community Wiki
|
||||
url: https://github.com/commaai/openpilot/wiki
|
||||
about: Check out our community wiki
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
name: Miscellaneous
|
||||
description: For tools or test bugs, or enhancements
|
||||
labels: ["bug"]
|
||||
body:
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: >
|
||||
* If the issue likely only affects your car model or make, go back and open a **car bug report** instead.
|
||||
Before creating a **miscellaneous bug report**, please check the following:
|
||||
* Ensure there isn't an existing issue for your bug. If there is, leave a comment on the existing issue.
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the bug or enhancement
|
||||
description: Also include a description of how to reproduce the bug or how the enhancement would work
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: route
|
||||
attributes:
|
||||
label: Provide a route where the issue occurs if applicable
|
||||
description: Ensure the route is fully uploaded at https://useradmin.comma.ai
|
||||
placeholder: 77611a1fac303767|2020-05-11--16-37-07
|
||||
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: openpilot version if applicable
|
||||
description: If you're not on release, provide the commit hash
|
||||
placeholder: 0.8.10
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional info
|
||||
Vendored
+76
@@ -0,0 +1,76 @@
|
||||
CI / testing:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: '.github/**'
|
||||
|
||||
car:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: 'opendbc/car/**'
|
||||
|
||||
car safety:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: 'opendbc/safety/**'
|
||||
|
||||
can:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: 'opendbc/can/**'
|
||||
|
||||
DBC signals:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: 'opendbc/dbc/**'
|
||||
|
||||
|
||||
body:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: 'opendbc/car/body/**'
|
||||
|
||||
chrysler:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: 'opendbc/car/chrysler/**'
|
||||
|
||||
ford:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: 'opendbc/car/ford/**'
|
||||
|
||||
gm:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: 'opendbc/car/gm/**'
|
||||
|
||||
honda:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: 'opendbc/car/honda/**'
|
||||
|
||||
hyundai:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: 'opendbc/car/hyundai/**'
|
||||
|
||||
mazda:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: 'opendbc/car/mazda/**'
|
||||
|
||||
nissan:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: 'opendbc/car/nissan/**'
|
||||
|
||||
rivian:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: 'opendbc/car/rivian/**'
|
||||
|
||||
subaru:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: 'opendbc/car/subaru/**'
|
||||
|
||||
tesla:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: 'opendbc/car/tesla/**'
|
||||
|
||||
toyota:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: 'opendbc/car/toyota/**'
|
||||
|
||||
volkswagen:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: 'opendbc/car/volkswagen/**'
|
||||
|
||||
fingerprint:
|
||||
- changed-files:
|
||||
- any-glob-to-all-files: 'opendbc/car/*/fingerprints.py'
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<!--
|
||||
We need these details to verify your pull request.
|
||||
|
||||
Find your device's dongle ID and a route at https://connect.comma.ai.
|
||||
Ideally, the route is recorded with the exact branch of your pull request.
|
||||
|
||||
If you are porting a car with a new harness variant, please add it to https://github.com/commaai/opendbc/blob/master/opendbc/car/docs_definitions.py. Let us know and we can add it to the shop at the time of merge.
|
||||
-->
|
||||
Validation
|
||||
* Dongle ID:
|
||||
* Route:
|
||||
@@ -101,7 +101,7 @@ class CarState(CarStateBase):
|
||||
# Check if LKAS is disabled due to lack of driver torque when all other states indicate
|
||||
# it should be enabled (steer lockout). Don't warn until we actually get lkas active
|
||||
# and lose it again, i.e, after initial lkas activation
|
||||
ret.steerFaultTemporary = self.lkas_allowed_speed and lkas_blocked
|
||||
ret.steerFaultTemporary = False
|
||||
|
||||
self.acc_active_last = ret.cruiseState.enabled
|
||||
|
||||
|
||||
Vendored
+139
@@ -0,0 +1,139 @@
|
||||
def docker_run(String step_label, int timeout_mins, String cmd) {
|
||||
timeout(time: timeout_mins, unit: 'MINUTES') {
|
||||
sh script: "docker run --rm --privileged \
|
||||
--env PYTHONWARNINGS=error \
|
||||
--volume /dev/bus/usb:/dev/bus/usb \
|
||||
--volume /var/run/dbus:/var/run/dbus \
|
||||
--net host \
|
||||
${env.DOCKER_IMAGE_TAG} \
|
||||
bash -c 'scons && ${cmd}'", \
|
||||
label: step_label
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def phone(String ip, String step_label, String cmd) {
|
||||
withCredentials([file(credentialsId: 'id_rsa', variable: 'key_file')]) {
|
||||
def ssh_cmd = """
|
||||
ssh -tt -o StrictHostKeyChecking=no -o ConnectTimeout=30 -o ConnectionAttempts=3 -o ServerAliveInterval=10 -o ServerAliveCountMax=3 -i ${key_file} 'comma@${ip}' /usr/bin/bash <<'END'
|
||||
|
||||
set -e
|
||||
|
||||
|
||||
source ~/.bash_profile
|
||||
if [ -f /etc/profile ]; then
|
||||
source /etc/profile
|
||||
fi
|
||||
|
||||
export CI=1
|
||||
export TEST_DIR=${env.TEST_DIR}
|
||||
export SOURCE_DIR=${env.SOURCE_DIR}
|
||||
export GIT_BRANCH=${env.GIT_BRANCH}
|
||||
export GIT_COMMIT=${env.GIT_COMMIT}
|
||||
export PYTHONPATH=${env.TEST_DIR}/../
|
||||
export PYTHONWARNINGS=error
|
||||
export LOGLEVEL=debug
|
||||
ln -sf /data/openpilot/opendbc_repo/opendbc /data/opendbc
|
||||
|
||||
# TODO: this is an agnos issue
|
||||
export PYTEST_ADDOPTS="-p no:asyncio"
|
||||
|
||||
cd ${env.TEST_DIR} || true
|
||||
${cmd}
|
||||
exit 0
|
||||
|
||||
END"""
|
||||
|
||||
sh script: ssh_cmd, label: step_label
|
||||
}
|
||||
}
|
||||
|
||||
def phone_steps(String device_type, steps) {
|
||||
lock(resource: "", label: device_type, inversePrecedence: true, variable: 'device_ip', quantity: 1) {
|
||||
timeout(time: 20, unit: 'MINUTES') {
|
||||
retry (3) {
|
||||
def date = sh(script: 'date', returnStdout: true).trim()
|
||||
phone(device_ip, "set time", "date -s '${date}'")
|
||||
phone(device_ip, "git checkout", readFile("tests/setup_device_ci.sh"))
|
||||
}
|
||||
steps.each { item ->
|
||||
phone(device_ip, item[0], item[1])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
pipeline {
|
||||
agent any
|
||||
environment {
|
||||
CI = "1"
|
||||
PYTHONWARNINGS= "error"
|
||||
DOCKER_IMAGE_TAG = "panda:build-${env.GIT_COMMIT}"
|
||||
|
||||
TEST_DIR = "/data/panda"
|
||||
SOURCE_DIR = "/data/panda_source/"
|
||||
}
|
||||
options {
|
||||
timeout(time: 3, unit: 'HOURS')
|
||||
disableConcurrentBuilds(abortPrevious: env.BRANCH_NAME != 'master')
|
||||
}
|
||||
|
||||
stages {
|
||||
stage ('Acquire resource locks') {
|
||||
options {
|
||||
lock(resource: "pandas")
|
||||
}
|
||||
stages {
|
||||
stage('Build Docker Image') {
|
||||
steps {
|
||||
timeout(time: 20, unit: 'MINUTES') {
|
||||
script {
|
||||
dockerImage = docker.build("${env.DOCKER_IMAGE_TAG}", "--build-arg CACHEBUST=${env.GIT_COMMIT} .")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('jungle tests') {
|
||||
steps {
|
||||
script {
|
||||
retry (3) {
|
||||
docker_run("reset hardware", 3, "python3 ./tests/hitl/reset_jungles.py")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('parallel tests') {
|
||||
parallel {
|
||||
stage('test cuatro') {
|
||||
agent { docker { image 'ghcr.io/commaai/alpine-ssh'; args '--user=root' } }
|
||||
steps {
|
||||
phone_steps("panda-cuatro", [
|
||||
["build", "scons"],
|
||||
["flash", "cd scripts/ && ./reflash_internal_panda.py"],
|
||||
["flash jungle", "cd board/jungle && ./flash.py --all"],
|
||||
["test", "cd tests/hitl && pytest -o 'addopts=' --durations=0 2*.py [5-9]*.py"],
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
stage('test tres') {
|
||||
agent { docker { image 'ghcr.io/commaai/alpine-ssh'; args '--user=root' } }
|
||||
steps {
|
||||
phone_steps("panda-tres", [
|
||||
["build", "scons"],
|
||||
["flash", "cd scripts/ && ./reflash_internal_panda.py"],
|
||||
["flash jungle", "cd board/jungle && ./flash.py --all"],
|
||||
["test", "cd tests/hitl && pytest -o 'addopts=' --durations=0 2*.py [5-9]*.py"],
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
import os
|
||||
import hashlib
|
||||
import opendbc
|
||||
import subprocess
|
||||
|
||||
PREFIX = "arm-none-eabi-"
|
||||
BUILDER = "DEV"
|
||||
|
||||
common_flags = []
|
||||
|
||||
if os.getenv("RELEASE"):
|
||||
BUILD_TYPE = "RELEASE"
|
||||
cert_fn = os.getenv("CERT")
|
||||
assert cert_fn is not None, 'No certificate file specified. Please set CERT env variable'
|
||||
assert os.path.exists(cert_fn), 'Certificate file not found. Please specify absolute path'
|
||||
else:
|
||||
BUILD_TYPE = "DEBUG"
|
||||
cert_fn = File("./board/certs/debug").srcnode().relpath
|
||||
common_flags += ["-DALLOW_DEBUG"]
|
||||
|
||||
if os.getenv("DEBUG"):
|
||||
common_flags += ["-DDEBUG"]
|
||||
|
||||
def objcopy(source, target, env, for_signature):
|
||||
return '$OBJCOPY -O binary %s %s' % (source[0], target[0])
|
||||
|
||||
def get_version(builder, build_type):
|
||||
try:
|
||||
git = subprocess.check_output(["git", "rev-parse", "--short=8", "HEAD"], encoding='utf8').strip()
|
||||
except subprocess.CalledProcessError:
|
||||
git = "unknown"
|
||||
return f"{builder}-{git}-{build_type}"
|
||||
|
||||
def get_key_header(name):
|
||||
from Crypto.PublicKey import RSA
|
||||
|
||||
public_fn = File(f'./board/certs/{name}.pub').srcnode().get_path()
|
||||
with open(public_fn) as f:
|
||||
rsa = RSA.importKey(f.read())
|
||||
assert(rsa.size_in_bits() == 1024)
|
||||
|
||||
rr = pow(2**1024, 2, rsa.n)
|
||||
n0inv = 2**32 - pow(rsa.n, -1, 2**32)
|
||||
|
||||
r = [
|
||||
f"RSAPublicKey {name}_rsa_key = {{",
|
||||
f" .len = 0x20,",
|
||||
f" .n0inv = {n0inv}U,",
|
||||
f" .n = {to_c_uint32(rsa.n)},",
|
||||
f" .rr = {to_c_uint32(rr)},",
|
||||
f" .exponent = {rsa.e},",
|
||||
f"}};",
|
||||
]
|
||||
return r
|
||||
|
||||
def to_c_uint32(x):
|
||||
nums = []
|
||||
for _ in range(0x20):
|
||||
nums.append(x % (2**32))
|
||||
x //= (2**32)
|
||||
return "{" + 'U,'.join(map(str, nums)) + "U}"
|
||||
|
||||
|
||||
def build_project(project_name, project, main, extra_flags):
|
||||
project_dir = Dir(f'./board/obj/{project_name}/')
|
||||
|
||||
flags = project["FLAGS"] + extra_flags + common_flags + [
|
||||
"-Wall",
|
||||
"-Wextra",
|
||||
"-Wstrict-prototypes",
|
||||
"-Werror",
|
||||
"-mlittle-endian",
|
||||
"-mthumb",
|
||||
"-nostdlib",
|
||||
"-fno-builtin",
|
||||
"-std=gnu11",
|
||||
"-fmax-errors=1",
|
||||
f"-T{File(project['LINKER_SCRIPT']).srcnode().relpath}",
|
||||
"-fsingle-precision-constant",
|
||||
"-Os",
|
||||
"-g",
|
||||
]
|
||||
|
||||
env = Environment(
|
||||
ENV=os.environ,
|
||||
CC=PREFIX + 'gcc',
|
||||
AS=PREFIX + 'gcc',
|
||||
OBJCOPY=PREFIX + 'objcopy',
|
||||
OBJDUMP=PREFIX + 'objdump',
|
||||
OBJPREFIX=project_dir,
|
||||
CFLAGS=flags,
|
||||
ASFLAGS=flags,
|
||||
LINKFLAGS=flags,
|
||||
CPPPATH=[Dir("./"), "./board/stm32h7/inc", opendbc.INCLUDE_PATH],
|
||||
ASCOM="$AS $ASFLAGS -o $TARGET -c $SOURCES",
|
||||
BUILDERS={
|
||||
'Objcopy': Builder(generator=objcopy, suffix='.bin', src_suffix='.elf')
|
||||
},
|
||||
tools=["default", "compilation_db"],
|
||||
)
|
||||
|
||||
startup = env.Object(project["STARTUP_FILE"])
|
||||
|
||||
# Build bootstub
|
||||
bs_env = env.Clone()
|
||||
bs_env.Append(CFLAGS="-DBOOTSTUB", ASFLAGS="-DBOOTSTUB", LINKFLAGS="-DBOOTSTUB")
|
||||
bs_elf = bs_env.Program(f"{project_dir}/bootstub.elf", [
|
||||
startup,
|
||||
"./board/crypto/rsa.c",
|
||||
"./board/crypto/sha.c",
|
||||
"./board/bootstub.c",
|
||||
])
|
||||
bs_env.Objcopy(f"./board/obj/bootstub.{project_name}.bin", bs_elf)
|
||||
|
||||
# Build + sign main (aka app)
|
||||
main_elf = env.Program(f"{project_dir}/main.elf", [
|
||||
startup,
|
||||
main
|
||||
], LINKFLAGS=[f"-Wl,--section-start,.isr_vector={project['APP_START_ADDRESS']}"] + flags)
|
||||
main_bin = env.Objcopy(f"{project_dir}/main.bin", main_elf)
|
||||
sign_py = File(f"./board/crypto/sign.py").srcnode().relpath
|
||||
env.Command(f"./board/obj/{project_name}.bin.signed", main_bin, f"SETLEN=1 {sign_py} $SOURCE $TARGET {cert_fn}")
|
||||
|
||||
|
||||
|
||||
base_project_h7 = {
|
||||
"STARTUP_FILE": "./board/stm32h7/startup_stm32h7x5xx.s",
|
||||
"LINKER_SCRIPT": "./board/stm32h7/stm32h7x5_flash.ld",
|
||||
"APP_START_ADDRESS": "0x8020000",
|
||||
"FLAGS": [
|
||||
"-mcpu=cortex-m7",
|
||||
"-mhard-float",
|
||||
"-DSTM32H7",
|
||||
"-DSTM32H725xx",
|
||||
"-Iboard/stm32h7/inc",
|
||||
"-mfpu=fpv5-d16",
|
||||
],
|
||||
}
|
||||
|
||||
# Common autogenerated includes
|
||||
with open("board/obj/gitversion.h", "w") as f:
|
||||
version = get_version(BUILDER, BUILD_TYPE)
|
||||
f.write(f'extern const uint8_t gitversion[{len(version)+1}];\n')
|
||||
f.write(f'const uint8_t gitversion[{len(version)+1}] = "{version}";\n')
|
||||
|
||||
with open("board/obj/version", "w") as f:
|
||||
f.write(f'{get_version(BUILDER, BUILD_TYPE)}')
|
||||
|
||||
certs = [get_key_header(n) for n in ["debug", "release"]]
|
||||
with open("board/obj/cert.h", "w") as f:
|
||||
for cert in certs:
|
||||
f.write("\n".join(cert) + "\n")
|
||||
|
||||
# Packet version defines: SHA hash of the struct header files
|
||||
def version_hash(path):
|
||||
with open(path, "rb") as f:
|
||||
# Normalize line endings on Windows
|
||||
return int.from_bytes(hashlib.sha256(f.read().replace(b'\r', b'')).digest()[:4], 'little')
|
||||
hh, ch, jh = version_hash("board/health.h"), version_hash(os.path.join(opendbc.INCLUDE_PATH, "opendbc/safety/can.h")), version_hash("board/jungle/jungle_health.h")
|
||||
common_flags += [f"-DHEALTH_PACKET_VERSION=0x{hh:08X}U", f"-DCAN_PACKET_VERSION_HASH=0x{ch:08X}U",
|
||||
f"-DJUNGLE_HEALTH_PACKET_VERSION=0x{jh:08X}U"]
|
||||
|
||||
# panda fw
|
||||
build_project("panda_h7", base_project_h7, "./board/main.c", [])
|
||||
|
||||
# panda jungle fw
|
||||
flags = [
|
||||
"-DPANDA_JUNGLE",
|
||||
]
|
||||
build_project("panda_jungle_h7", base_project_h7, "./board/jungle/main.c", flags)
|
||||
|
||||
# body fw
|
||||
build_project("body_h7", base_project_h7, "./board/body/main.c", ["-DPANDA_BODY"])
|
||||
|
||||
# test files
|
||||
SConscript('tests/libpanda/SConscript')
|
||||
@@ -0,0 +1,13 @@
|
||||
import os
|
||||
|
||||
env = Environment(
|
||||
COMPILATIONDB_USE_ABSPATH=True,
|
||||
tools=["default", "compilation_db"],
|
||||
)
|
||||
|
||||
SetOption('num_jobs', max(1, int((os.cpu_count() or 1)-1)))
|
||||
|
||||
env.CompilationDatabase("compile_commands.json")
|
||||
|
||||
# panda fw & test files
|
||||
SConscript('SConscript')
|
||||
+1
-1
@@ -7,7 +7,7 @@ from .python import (Panda, PandaDFU, # noqa: F401
|
||||
DLC_TO_LEN, LEN_TO_DLC, CANPACKET_HEAD_SIZE)
|
||||
|
||||
# panda jungle
|
||||
#from .board.jungle import PandaJungle, PandaJungleDFU # noqa: F401
|
||||
from .board.jungle import PandaJungle, PandaJungleDFU # noqa: F401
|
||||
|
||||
# panda body
|
||||
from .board.body import PandaBody # noqa: F401
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,2 +1,2 @@
|
||||
extern const uint8_t gitversion[18];
|
||||
const uint8_t gitversion[18] = "DEV-unknown-DEBUG";
|
||||
extern const uint8_t gitversion[19];
|
||||
const uint8_t gitversion[19] = "DEV-24ce7c58-DEBUG";
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
DEV-unknown-DEBUG
|
||||
DEV-24ce7c58-DEBUG
|
||||
@@ -0,0 +1,15 @@
|
||||
import opendbc
|
||||
|
||||
env = Environment(
|
||||
CFLAGS=[
|
||||
'-nostdlib',
|
||||
'-fno-builtin',
|
||||
'-std=gnu11',
|
||||
'-Wfatal-errors',
|
||||
'-Wno-pointer-to-int-cast',
|
||||
],
|
||||
CPPPATH=[".", "../../", "../../board/", opendbc.INCLUDE_PATH],
|
||||
)
|
||||
|
||||
panda = env.SharedObject("panda.os", "panda.c")
|
||||
libpanda = env.SharedLibrary("libpanda.so", [panda])
|
||||
@@ -0,0 +1,57 @@
|
||||
import os
|
||||
import subprocess
|
||||
import sysconfig
|
||||
import numpy as np
|
||||
|
||||
arch = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip()
|
||||
|
||||
common = ''
|
||||
|
||||
python_path = sysconfig.get_paths()['include']
|
||||
cpppath = [
|
||||
'#',
|
||||
'#rednose',
|
||||
'#rednose/examples/generated',
|
||||
'/usr/lib/include',
|
||||
python_path,
|
||||
np.get_include(),
|
||||
]
|
||||
|
||||
env = Environment(
|
||||
ENV=os.environ,
|
||||
CCFLAGS=[
|
||||
"-g",
|
||||
"-fPIC",
|
||||
"-O2",
|
||||
"-Werror=implicit-function-declaration",
|
||||
"-Werror=incompatible-pointer-types",
|
||||
"-Werror=int-conversion",
|
||||
"-Werror=return-type",
|
||||
"-Werror=format-extra-args",
|
||||
"-Wshadow",
|
||||
],
|
||||
LIBPATH=["#rednose/examples/generated"],
|
||||
CFLAGS="-std=gnu11",
|
||||
CXXFLAGS="-std=c++1z",
|
||||
CPPPATH=cpppath,
|
||||
REDNOSE_ROOT=Dir("#").abspath,
|
||||
tools=["default", "cython", "rednose_filter"],
|
||||
)
|
||||
|
||||
# Cython build enviroment
|
||||
envCython = env.Clone()
|
||||
envCython["CCFLAGS"] += ["-Wno-#warnings", "-Wno-cpp", "-Wno-shadow", "-Wno-deprecated-declarations"]
|
||||
|
||||
envCython["LIBS"] = []
|
||||
if arch == "Darwin":
|
||||
envCython["LINKFLAGS"] = ["-bundle", "-undefined", "dynamic_lookup"]
|
||||
elif arch == "aarch64":
|
||||
envCython["LINKFLAGS"] = ["-shared"]
|
||||
envCython["LIBS"] = [os.path.basename(python_path)]
|
||||
else:
|
||||
envCython["LINKFLAGS"] = ["-pthread", "-shared"]
|
||||
|
||||
Export('env', 'envCython', 'common')
|
||||
|
||||
SConscript(['#rednose/SConscript'])
|
||||
SConscript(['#examples/SConscript'])
|
||||
@@ -0,0 +1,19 @@
|
||||
Import('env')
|
||||
|
||||
gen_dir = Dir('generated/').abspath
|
||||
|
||||
env.RednoseCompileFilter(
|
||||
target="live",
|
||||
filter_gen_script="live_kf.py",
|
||||
output_dir=gen_dir,
|
||||
)
|
||||
env.RednoseCompileFilter(
|
||||
target="kinematic",
|
||||
filter_gen_script="kinematic_kf.py",
|
||||
output_dir=gen_dir,
|
||||
)
|
||||
env.RednoseCompileFilter(
|
||||
target="compare",
|
||||
filter_gen_script="test_compare.py",
|
||||
output_dir=gen_dir,
|
||||
)
|
||||
@@ -0,0 +1,17 @@
|
||||
Import('env', 'envCython', 'common')
|
||||
|
||||
cc_sources = [
|
||||
"helpers/ekf_load.cc",
|
||||
"helpers/ekf_sym.cc",
|
||||
]
|
||||
libs = ["dl"]
|
||||
if common != "":
|
||||
# for SWAGLOG support
|
||||
libs += [common, 'zmq']
|
||||
|
||||
ekf_objects = env.SharedObject(cc_sources)
|
||||
rednose = env.Library("helpers/ekf_sym", ekf_objects, LIBS=libs)
|
||||
rednose_python = envCython.Program("helpers/ekf_sym_pyx.so", ["helpers/ekf_sym_pyx.pyx", ekf_objects],
|
||||
LIBS=libs + envCython["LIBS"])
|
||||
|
||||
Export('rednose', 'rednose_python')
|
||||
@@ -26351,7 +26351,7 @@ __Pyx_RefNannySetupContext("PyInit_ekf_sym_pyx", 0);
|
||||
(void)__Pyx_modinit_variable_import_code(__pyx_mstate);
|
||||
(void)__Pyx_modinit_function_import_code(__pyx_mstate);
|
||||
/*--- Execution code ---*/
|
||||
__Pyx_TraceStartFunc("PyInit_ekf_sym_pyx", __pyx_f[0], 1, 0, 0, 0, __PYX_ERR(0, 1, __pyx_L1_error));
|
||||
__Pyx_TraceStartFunc("PyInit_ekf_sym_pyx", __pyx_f[0], 1, 1, 0, 0, __PYX_ERR(0, 1, __pyx_L1_error));
|
||||
|
||||
/* "View.MemoryView":100
|
||||
*
|
||||
@@ -27145,7 +27145,7 @@ __Pyx_RefNannySetupContext("PyInit_ekf_sym_pyx", 0);
|
||||
__Pyx_GOTREF(__pyx_t_5);
|
||||
if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_test, __pyx_t_5) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
|
||||
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
|
||||
__Pyx_TraceReturnValue(Py_None, 0, 0, __PYX_ERR(0, 1, __pyx_L1_error));
|
||||
__Pyx_TraceReturnValue(Py_None, 1, 0, __PYX_ERR(0, 1, __pyx_L1_error));
|
||||
__Pyx_PyMonitoring_ExitScope(0);
|
||||
|
||||
/*--- Wrapped vars code ---*/
|
||||
@@ -27156,7 +27156,7 @@ __Pyx_RefNannySetupContext("PyInit_ekf_sym_pyx", 0);
|
||||
__Pyx_XDECREF(__pyx_t_5);
|
||||
__Pyx_XDECREF(__pyx_t_6);
|
||||
__Pyx_TraceException(__pyx_lineno, 0, 0);
|
||||
__Pyx_TraceExceptionUnwind(0, 0);
|
||||
__Pyx_TraceExceptionUnwind(1, 0);
|
||||
if (__pyx_m) {
|
||||
if (__pyx_mstate->__pyx_d && stringtab_initialized) {
|
||||
__Pyx_AddTraceback("init rednose.helpers.ekf_sym_pyx", __pyx_clineno, __pyx_lineno, __pyx_filename);
|
||||
|
||||
@@ -90,7 +90,7 @@ def _process_font(font_path: Path, codepoints: tuple[int, ...]):
|
||||
print(f"Processing {font_path.name}...")
|
||||
|
||||
font_size = {
|
||||
"unifont.otf": 16, # unifont is only 16x8 or 16x16 pixels per glyph
|
||||
"unifont.otf": 64, # unifont is only 16x8 or 16x16 pixels per glyph
|
||||
}.get(font_path.name, 200)
|
||||
|
||||
data = font_path.read_bytes()
|
||||
|
||||
+1286
-1077
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 3.3 MiB |
Binary file not shown.
@@ -0,0 +1,97 @@
|
||||
Import('env', 'envCython', 'arch', 'msgq_python', 'common_python', 'np_version')
|
||||
|
||||
gen = "c_generated_code"
|
||||
|
||||
casadi_model = [
|
||||
f'{gen}/lat_model/lat_expl_ode_fun.c',
|
||||
f'{gen}/lat_model/lat_expl_vde_forw.c',
|
||||
]
|
||||
|
||||
casadi_cost_y = [
|
||||
f'{gen}/lat_cost/lat_cost_y_fun.c',
|
||||
f'{gen}/lat_cost/lat_cost_y_fun_jac_ut_xt.c',
|
||||
f'{gen}/lat_cost/lat_cost_y_hess.c',
|
||||
]
|
||||
|
||||
casadi_cost_e = [
|
||||
f'{gen}/lat_cost/lat_cost_y_e_fun.c',
|
||||
f'{gen}/lat_cost/lat_cost_y_e_fun_jac_ut_xt.c',
|
||||
f'{gen}/lat_cost/lat_cost_y_e_hess.c',
|
||||
]
|
||||
|
||||
casadi_cost_0 = [
|
||||
f'{gen}/lat_cost/lat_cost_y_0_fun.c',
|
||||
f'{gen}/lat_cost/lat_cost_y_0_fun_jac_ut_xt.c',
|
||||
f'{gen}/lat_cost/lat_cost_y_0_hess.c',
|
||||
]
|
||||
|
||||
build_files = [f'{gen}/acados_solver_lat.c'] + casadi_model + casadi_cost_y + casadi_cost_e + casadi_cost_0
|
||||
|
||||
# extra generated files used to trigger a rebuild
|
||||
generated_files = [
|
||||
f'{gen}/Makefile',
|
||||
|
||||
f'{gen}/main_lat.c',
|
||||
f'{gen}/main_sim_lat.c',
|
||||
f'{gen}/acados_solver_lat.h',
|
||||
f'{gen}/acados_sim_solver_lat.h',
|
||||
f'{gen}/acados_sim_solver_lat.c',
|
||||
f'{gen}/acados_solver.pxd',
|
||||
|
||||
f'{gen}/lat_model/lat_expl_vde_adj.c',
|
||||
|
||||
f'{gen}/lat_model/lat_model.h',
|
||||
f'{gen}/lat_constraints/lat_constraints.h',
|
||||
f'{gen}/lat_cost/lat_cost.h',
|
||||
] + build_files
|
||||
|
||||
acados_dir = '#third_party/acados'
|
||||
acados_templates_dir = '#third_party/acados/acados_template/c_templates_tera'
|
||||
|
||||
source_list = ['lat_mpc.py',
|
||||
'#selfdrive/modeld/constants.py',
|
||||
f'{acados_dir}/include/acados_c/ocp_nlp_interface.h',
|
||||
f'{acados_templates_dir}/acados_solver.in.c',
|
||||
]
|
||||
|
||||
lenv = env.Clone()
|
||||
acados_rel_path = Dir(gen).rel_path(Dir(f"#third_party/acados/{arch}/lib"))
|
||||
lenv["RPATH"] += [lenv.Literal(f'\\$$ORIGIN/{acados_rel_path}')]
|
||||
lenv.Clean(generated_files, Dir(gen))
|
||||
|
||||
generated_lat = lenv.Command(generated_files,
|
||||
source_list,
|
||||
f"cd {Dir('.').abspath} && python3 lat_mpc.py")
|
||||
lenv.Depends(generated_lat, [msgq_python, common_python])
|
||||
|
||||
lenv["CFLAGS"].append("-DACADOS_WITH_QPOASES")
|
||||
lenv["CXXFLAGS"].append("-DACADOS_WITH_QPOASES")
|
||||
lenv["CCFLAGS"].append("-Wno-unused")
|
||||
if arch != "Darwin":
|
||||
lenv["LINKFLAGS"].append("-Wl,--disable-new-dtags")
|
||||
else:
|
||||
lenv["LINKFLAGS"].append("-Wl,-install_name,@loader_path/libacados_ocp_solver_lat.dylib")
|
||||
lenv["LINKFLAGS"].append(f"-Wl,-rpath,@loader_path/{acados_rel_path}")
|
||||
lib_solver = lenv.SharedLibrary(f"{gen}/acados_ocp_solver_lat",
|
||||
build_files,
|
||||
LIBS=['m', 'acados', 'hpipm', 'blasfeo', 'qpOASES_e'])
|
||||
|
||||
# generate cython stuff
|
||||
acados_ocp_solver_pyx = File("#third_party/acados/acados_template/acados_ocp_solver_pyx.pyx")
|
||||
acados_ocp_solver_common = File("#third_party/acados/acados_template/acados_solver_common.pxd")
|
||||
libacados_ocp_solver_pxd = File(f'{gen}/acados_solver.pxd')
|
||||
libacados_ocp_solver_c = File(f'{gen}/acados_ocp_solver_pyx.c')
|
||||
|
||||
lenv2 = envCython.Clone()
|
||||
lenv2["LIBPATH"] += [lib_solver[0].dir.abspath]
|
||||
lenv2["RPATH"] += [lenv2.Literal('\\$$ORIGIN')]
|
||||
lenv2.Command(libacados_ocp_solver_c,
|
||||
[acados_ocp_solver_pyx, acados_ocp_solver_common, libacados_ocp_solver_pxd],
|
||||
f'cython' + \
|
||||
f' -o {libacados_ocp_solver_c.get_labspath()}' + \
|
||||
f' -I {libacados_ocp_solver_pxd.get_dir().get_labspath()}' + \
|
||||
f' -I {acados_ocp_solver_common.get_dir().get_labspath()}' + \
|
||||
f' {acados_ocp_solver_pyx.get_labspath()}')
|
||||
lib_cython = lenv2.Program(f'{gen}/acados_ocp_solver_pyx.so', [libacados_ocp_solver_c], LIBS=['acados_ocp_solver_lat'])
|
||||
lenv2.Depends(lib_cython, lib_solver)
|
||||
lenv2.Depends(libacados_ocp_solver_c, np_version)
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,102 @@
|
||||
Import('env', 'envCython', 'arch', 'msgq_python', 'common_python', 'np_version')
|
||||
|
||||
gen = "c_generated_code"
|
||||
|
||||
casadi_model = [
|
||||
f'{gen}/long_model/long_expl_ode_fun.c',
|
||||
f'{gen}/long_model/long_expl_vde_forw.c',
|
||||
]
|
||||
|
||||
casadi_cost_y = [
|
||||
f'{gen}/long_cost/long_cost_y_fun.c',
|
||||
f'{gen}/long_cost/long_cost_y_fun_jac_ut_xt.c',
|
||||
f'{gen}/long_cost/long_cost_y_hess.c',
|
||||
]
|
||||
|
||||
casadi_cost_e = [
|
||||
f'{gen}/long_cost/long_cost_y_e_fun.c',
|
||||
f'{gen}/long_cost/long_cost_y_e_fun_jac_ut_xt.c',
|
||||
f'{gen}/long_cost/long_cost_y_e_hess.c',
|
||||
]
|
||||
|
||||
casadi_cost_0 = [
|
||||
f'{gen}/long_cost/long_cost_y_0_fun.c',
|
||||
f'{gen}/long_cost/long_cost_y_0_fun_jac_ut_xt.c',
|
||||
f'{gen}/long_cost/long_cost_y_0_hess.c',
|
||||
]
|
||||
|
||||
casadi_constraints = [
|
||||
f'{gen}/long_constraints/long_constr_h_fun.c',
|
||||
f'{gen}/long_constraints/long_constr_h_fun_jac_uxt_zt.c',
|
||||
]
|
||||
|
||||
build_files = [f'{gen}/acados_solver_long.c'] + casadi_model + casadi_cost_y + casadi_cost_e + \
|
||||
casadi_cost_0 + casadi_constraints
|
||||
|
||||
# extra generated files used to trigger a rebuild
|
||||
generated_files = [
|
||||
f'{gen}/Makefile',
|
||||
|
||||
f'{gen}/main_long.c',
|
||||
f'{gen}/main_sim_long.c',
|
||||
f'{gen}/acados_solver_long.h',
|
||||
f'{gen}/acados_sim_solver_long.h',
|
||||
f'{gen}/acados_sim_solver_long.c',
|
||||
f'{gen}/acados_solver.pxd',
|
||||
|
||||
f'{gen}/long_model/long_expl_vde_adj.c',
|
||||
|
||||
f'{gen}/long_model/long_model.h',
|
||||
f'{gen}/long_constraints/long_constraints.h',
|
||||
f'{gen}/long_cost/long_cost.h',
|
||||
] + build_files
|
||||
|
||||
acados_dir = '#third_party/acados'
|
||||
acados_templates_dir = '#third_party/acados/acados_template/c_templates_tera'
|
||||
|
||||
source_list = ['long_mpc.py',
|
||||
'#selfdrive/modeld/constants.py',
|
||||
f'{acados_dir}/include/acados_c/ocp_nlp_interface.h',
|
||||
f'{acados_templates_dir}/acados_solver.in.c',
|
||||
]
|
||||
|
||||
lenv = env.Clone()
|
||||
acados_rel_path = Dir(gen).rel_path(Dir(f"#third_party/acados/{arch}/lib"))
|
||||
lenv["RPATH"] += [lenv.Literal(f'\\$$ORIGIN/{acados_rel_path}')]
|
||||
lenv.Clean(generated_files, Dir(gen))
|
||||
generated_long = lenv.Command(generated_files,
|
||||
source_list,
|
||||
f"cd {Dir('.').abspath} && python3 long_mpc.py")
|
||||
lenv.Depends(generated_long, [msgq_python, common_python])
|
||||
|
||||
lenv["CFLAGS"].append("-DACADOS_WITH_QPOASES")
|
||||
lenv["CXXFLAGS"].append("-DACADOS_WITH_QPOASES")
|
||||
lenv["CCFLAGS"].append("-Wno-unused")
|
||||
if arch != "Darwin":
|
||||
lenv["LINKFLAGS"].append("-Wl,--disable-new-dtags")
|
||||
else:
|
||||
lenv["LINKFLAGS"].append("-Wl,-install_name,@loader_path/libacados_ocp_solver_long.dylib")
|
||||
lenv["LINKFLAGS"].append(f"-Wl,-rpath,@loader_path/{acados_rel_path}")
|
||||
lib_solver = lenv.SharedLibrary(f"{gen}/acados_ocp_solver_long",
|
||||
build_files,
|
||||
LIBS=['m', 'acados', 'hpipm', 'blasfeo', 'qpOASES_e'])
|
||||
|
||||
# generate cython stuff
|
||||
acados_ocp_solver_pyx = File("#third_party/acados/acados_template/acados_ocp_solver_pyx.pyx")
|
||||
acados_ocp_solver_common = File("#third_party/acados/acados_template/acados_solver_common.pxd")
|
||||
libacados_ocp_solver_pxd = File(f'{gen}/acados_solver.pxd')
|
||||
libacados_ocp_solver_c = File(f'{gen}/acados_ocp_solver_pyx.c')
|
||||
|
||||
lenv2 = envCython.Clone()
|
||||
lenv2["LIBPATH"] += [lib_solver[0].dir.abspath]
|
||||
lenv2["RPATH"] += [lenv2.Literal('\\$$ORIGIN')]
|
||||
lenv2.Command(libacados_ocp_solver_c,
|
||||
[acados_ocp_solver_pyx, acados_ocp_solver_common, libacados_ocp_solver_pxd],
|
||||
f'cython' + \
|
||||
f' -o {libacados_ocp_solver_c.get_labspath()}' + \
|
||||
f' -I {libacados_ocp_solver_pxd.get_dir().get_labspath()}' + \
|
||||
f' -I {acados_ocp_solver_common.get_dir().get_labspath()}' + \
|
||||
f' {acados_ocp_solver_pyx.get_labspath()}')
|
||||
lib_cython = lenv2.Program(f'{gen}/acados_ocp_solver_pyx.so', [libacados_ocp_solver_c], LIBS=['acados_ocp_solver_long'])
|
||||
lenv2.Depends(lib_cython, lib_solver)
|
||||
lenv2.Depends(libacados_ocp_solver_c, np_version)
|
||||
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,21 @@
|
||||
Import('env', 'rednose')
|
||||
|
||||
# build ekf models
|
||||
rednose_gen_dir = 'models/generated'
|
||||
rednose_gen_deps = [
|
||||
"models/constants.py",
|
||||
]
|
||||
pose_ekf = env.RednoseCompileFilter(
|
||||
target='pose',
|
||||
filter_gen_script='models/pose_kf.py',
|
||||
output_dir=rednose_gen_dir,
|
||||
extra_gen_artifacts=[],
|
||||
gen_script_deps=rednose_gen_deps,
|
||||
)
|
||||
car_ekf = env.RednoseCompileFilter(
|
||||
target='car',
|
||||
filter_gen_script='models/car_kf.py',
|
||||
output_dir=rednose_gen_dir,
|
||||
extra_gen_artifacts=[],
|
||||
gen_script_deps=rednose_gen_deps,
|
||||
)
|
||||
@@ -45,326 +45,326 @@ const static double MAHA_THRESH_31 = 3.8414588206941227;
|
||||
* *
|
||||
* This file is part of 'ekf' *
|
||||
******************************************************************************/
|
||||
void err_fun(double *nom_x, double *delta_x, double *out_2367152293466283987) {
|
||||
out_2367152293466283987[0] = delta_x[0] + nom_x[0];
|
||||
out_2367152293466283987[1] = delta_x[1] + nom_x[1];
|
||||
out_2367152293466283987[2] = delta_x[2] + nom_x[2];
|
||||
out_2367152293466283987[3] = delta_x[3] + nom_x[3];
|
||||
out_2367152293466283987[4] = delta_x[4] + nom_x[4];
|
||||
out_2367152293466283987[5] = delta_x[5] + nom_x[5];
|
||||
out_2367152293466283987[6] = delta_x[6] + nom_x[6];
|
||||
out_2367152293466283987[7] = delta_x[7] + nom_x[7];
|
||||
out_2367152293466283987[8] = delta_x[8] + nom_x[8];
|
||||
void err_fun(double *nom_x, double *delta_x, double *out_5479217515808027394) {
|
||||
out_5479217515808027394[0] = delta_x[0] + nom_x[0];
|
||||
out_5479217515808027394[1] = delta_x[1] + nom_x[1];
|
||||
out_5479217515808027394[2] = delta_x[2] + nom_x[2];
|
||||
out_5479217515808027394[3] = delta_x[3] + nom_x[3];
|
||||
out_5479217515808027394[4] = delta_x[4] + nom_x[4];
|
||||
out_5479217515808027394[5] = delta_x[5] + nom_x[5];
|
||||
out_5479217515808027394[6] = delta_x[6] + nom_x[6];
|
||||
out_5479217515808027394[7] = delta_x[7] + nom_x[7];
|
||||
out_5479217515808027394[8] = delta_x[8] + nom_x[8];
|
||||
}
|
||||
void inv_err_fun(double *nom_x, double *true_x, double *out_5829526074669369656) {
|
||||
out_5829526074669369656[0] = -nom_x[0] + true_x[0];
|
||||
out_5829526074669369656[1] = -nom_x[1] + true_x[1];
|
||||
out_5829526074669369656[2] = -nom_x[2] + true_x[2];
|
||||
out_5829526074669369656[3] = -nom_x[3] + true_x[3];
|
||||
out_5829526074669369656[4] = -nom_x[4] + true_x[4];
|
||||
out_5829526074669369656[5] = -nom_x[5] + true_x[5];
|
||||
out_5829526074669369656[6] = -nom_x[6] + true_x[6];
|
||||
out_5829526074669369656[7] = -nom_x[7] + true_x[7];
|
||||
out_5829526074669369656[8] = -nom_x[8] + true_x[8];
|
||||
void inv_err_fun(double *nom_x, double *true_x, double *out_8100295571519039240) {
|
||||
out_8100295571519039240[0] = -nom_x[0] + true_x[0];
|
||||
out_8100295571519039240[1] = -nom_x[1] + true_x[1];
|
||||
out_8100295571519039240[2] = -nom_x[2] + true_x[2];
|
||||
out_8100295571519039240[3] = -nom_x[3] + true_x[3];
|
||||
out_8100295571519039240[4] = -nom_x[4] + true_x[4];
|
||||
out_8100295571519039240[5] = -nom_x[5] + true_x[5];
|
||||
out_8100295571519039240[6] = -nom_x[6] + true_x[6];
|
||||
out_8100295571519039240[7] = -nom_x[7] + true_x[7];
|
||||
out_8100295571519039240[8] = -nom_x[8] + true_x[8];
|
||||
}
|
||||
void H_mod_fun(double *state, double *out_1755007343641557895) {
|
||||
out_1755007343641557895[0] = 1.0;
|
||||
out_1755007343641557895[1] = 0.0;
|
||||
out_1755007343641557895[2] = 0.0;
|
||||
out_1755007343641557895[3] = 0.0;
|
||||
out_1755007343641557895[4] = 0.0;
|
||||
out_1755007343641557895[5] = 0.0;
|
||||
out_1755007343641557895[6] = 0.0;
|
||||
out_1755007343641557895[7] = 0.0;
|
||||
out_1755007343641557895[8] = 0.0;
|
||||
out_1755007343641557895[9] = 0.0;
|
||||
out_1755007343641557895[10] = 1.0;
|
||||
out_1755007343641557895[11] = 0.0;
|
||||
out_1755007343641557895[12] = 0.0;
|
||||
out_1755007343641557895[13] = 0.0;
|
||||
out_1755007343641557895[14] = 0.0;
|
||||
out_1755007343641557895[15] = 0.0;
|
||||
out_1755007343641557895[16] = 0.0;
|
||||
out_1755007343641557895[17] = 0.0;
|
||||
out_1755007343641557895[18] = 0.0;
|
||||
out_1755007343641557895[19] = 0.0;
|
||||
out_1755007343641557895[20] = 1.0;
|
||||
out_1755007343641557895[21] = 0.0;
|
||||
out_1755007343641557895[22] = 0.0;
|
||||
out_1755007343641557895[23] = 0.0;
|
||||
out_1755007343641557895[24] = 0.0;
|
||||
out_1755007343641557895[25] = 0.0;
|
||||
out_1755007343641557895[26] = 0.0;
|
||||
out_1755007343641557895[27] = 0.0;
|
||||
out_1755007343641557895[28] = 0.0;
|
||||
out_1755007343641557895[29] = 0.0;
|
||||
out_1755007343641557895[30] = 1.0;
|
||||
out_1755007343641557895[31] = 0.0;
|
||||
out_1755007343641557895[32] = 0.0;
|
||||
out_1755007343641557895[33] = 0.0;
|
||||
out_1755007343641557895[34] = 0.0;
|
||||
out_1755007343641557895[35] = 0.0;
|
||||
out_1755007343641557895[36] = 0.0;
|
||||
out_1755007343641557895[37] = 0.0;
|
||||
out_1755007343641557895[38] = 0.0;
|
||||
out_1755007343641557895[39] = 0.0;
|
||||
out_1755007343641557895[40] = 1.0;
|
||||
out_1755007343641557895[41] = 0.0;
|
||||
out_1755007343641557895[42] = 0.0;
|
||||
out_1755007343641557895[43] = 0.0;
|
||||
out_1755007343641557895[44] = 0.0;
|
||||
out_1755007343641557895[45] = 0.0;
|
||||
out_1755007343641557895[46] = 0.0;
|
||||
out_1755007343641557895[47] = 0.0;
|
||||
out_1755007343641557895[48] = 0.0;
|
||||
out_1755007343641557895[49] = 0.0;
|
||||
out_1755007343641557895[50] = 1.0;
|
||||
out_1755007343641557895[51] = 0.0;
|
||||
out_1755007343641557895[52] = 0.0;
|
||||
out_1755007343641557895[53] = 0.0;
|
||||
out_1755007343641557895[54] = 0.0;
|
||||
out_1755007343641557895[55] = 0.0;
|
||||
out_1755007343641557895[56] = 0.0;
|
||||
out_1755007343641557895[57] = 0.0;
|
||||
out_1755007343641557895[58] = 0.0;
|
||||
out_1755007343641557895[59] = 0.0;
|
||||
out_1755007343641557895[60] = 1.0;
|
||||
out_1755007343641557895[61] = 0.0;
|
||||
out_1755007343641557895[62] = 0.0;
|
||||
out_1755007343641557895[63] = 0.0;
|
||||
out_1755007343641557895[64] = 0.0;
|
||||
out_1755007343641557895[65] = 0.0;
|
||||
out_1755007343641557895[66] = 0.0;
|
||||
out_1755007343641557895[67] = 0.0;
|
||||
out_1755007343641557895[68] = 0.0;
|
||||
out_1755007343641557895[69] = 0.0;
|
||||
out_1755007343641557895[70] = 1.0;
|
||||
out_1755007343641557895[71] = 0.0;
|
||||
out_1755007343641557895[72] = 0.0;
|
||||
out_1755007343641557895[73] = 0.0;
|
||||
out_1755007343641557895[74] = 0.0;
|
||||
out_1755007343641557895[75] = 0.0;
|
||||
out_1755007343641557895[76] = 0.0;
|
||||
out_1755007343641557895[77] = 0.0;
|
||||
out_1755007343641557895[78] = 0.0;
|
||||
out_1755007343641557895[79] = 0.0;
|
||||
out_1755007343641557895[80] = 1.0;
|
||||
void H_mod_fun(double *state, double *out_7285069632640746526) {
|
||||
out_7285069632640746526[0] = 1.0;
|
||||
out_7285069632640746526[1] = 0.0;
|
||||
out_7285069632640746526[2] = 0.0;
|
||||
out_7285069632640746526[3] = 0.0;
|
||||
out_7285069632640746526[4] = 0.0;
|
||||
out_7285069632640746526[5] = 0.0;
|
||||
out_7285069632640746526[6] = 0.0;
|
||||
out_7285069632640746526[7] = 0.0;
|
||||
out_7285069632640746526[8] = 0.0;
|
||||
out_7285069632640746526[9] = 0.0;
|
||||
out_7285069632640746526[10] = 1.0;
|
||||
out_7285069632640746526[11] = 0.0;
|
||||
out_7285069632640746526[12] = 0.0;
|
||||
out_7285069632640746526[13] = 0.0;
|
||||
out_7285069632640746526[14] = 0.0;
|
||||
out_7285069632640746526[15] = 0.0;
|
||||
out_7285069632640746526[16] = 0.0;
|
||||
out_7285069632640746526[17] = 0.0;
|
||||
out_7285069632640746526[18] = 0.0;
|
||||
out_7285069632640746526[19] = 0.0;
|
||||
out_7285069632640746526[20] = 1.0;
|
||||
out_7285069632640746526[21] = 0.0;
|
||||
out_7285069632640746526[22] = 0.0;
|
||||
out_7285069632640746526[23] = 0.0;
|
||||
out_7285069632640746526[24] = 0.0;
|
||||
out_7285069632640746526[25] = 0.0;
|
||||
out_7285069632640746526[26] = 0.0;
|
||||
out_7285069632640746526[27] = 0.0;
|
||||
out_7285069632640746526[28] = 0.0;
|
||||
out_7285069632640746526[29] = 0.0;
|
||||
out_7285069632640746526[30] = 1.0;
|
||||
out_7285069632640746526[31] = 0.0;
|
||||
out_7285069632640746526[32] = 0.0;
|
||||
out_7285069632640746526[33] = 0.0;
|
||||
out_7285069632640746526[34] = 0.0;
|
||||
out_7285069632640746526[35] = 0.0;
|
||||
out_7285069632640746526[36] = 0.0;
|
||||
out_7285069632640746526[37] = 0.0;
|
||||
out_7285069632640746526[38] = 0.0;
|
||||
out_7285069632640746526[39] = 0.0;
|
||||
out_7285069632640746526[40] = 1.0;
|
||||
out_7285069632640746526[41] = 0.0;
|
||||
out_7285069632640746526[42] = 0.0;
|
||||
out_7285069632640746526[43] = 0.0;
|
||||
out_7285069632640746526[44] = 0.0;
|
||||
out_7285069632640746526[45] = 0.0;
|
||||
out_7285069632640746526[46] = 0.0;
|
||||
out_7285069632640746526[47] = 0.0;
|
||||
out_7285069632640746526[48] = 0.0;
|
||||
out_7285069632640746526[49] = 0.0;
|
||||
out_7285069632640746526[50] = 1.0;
|
||||
out_7285069632640746526[51] = 0.0;
|
||||
out_7285069632640746526[52] = 0.0;
|
||||
out_7285069632640746526[53] = 0.0;
|
||||
out_7285069632640746526[54] = 0.0;
|
||||
out_7285069632640746526[55] = 0.0;
|
||||
out_7285069632640746526[56] = 0.0;
|
||||
out_7285069632640746526[57] = 0.0;
|
||||
out_7285069632640746526[58] = 0.0;
|
||||
out_7285069632640746526[59] = 0.0;
|
||||
out_7285069632640746526[60] = 1.0;
|
||||
out_7285069632640746526[61] = 0.0;
|
||||
out_7285069632640746526[62] = 0.0;
|
||||
out_7285069632640746526[63] = 0.0;
|
||||
out_7285069632640746526[64] = 0.0;
|
||||
out_7285069632640746526[65] = 0.0;
|
||||
out_7285069632640746526[66] = 0.0;
|
||||
out_7285069632640746526[67] = 0.0;
|
||||
out_7285069632640746526[68] = 0.0;
|
||||
out_7285069632640746526[69] = 0.0;
|
||||
out_7285069632640746526[70] = 1.0;
|
||||
out_7285069632640746526[71] = 0.0;
|
||||
out_7285069632640746526[72] = 0.0;
|
||||
out_7285069632640746526[73] = 0.0;
|
||||
out_7285069632640746526[74] = 0.0;
|
||||
out_7285069632640746526[75] = 0.0;
|
||||
out_7285069632640746526[76] = 0.0;
|
||||
out_7285069632640746526[77] = 0.0;
|
||||
out_7285069632640746526[78] = 0.0;
|
||||
out_7285069632640746526[79] = 0.0;
|
||||
out_7285069632640746526[80] = 1.0;
|
||||
}
|
||||
void f_fun(double *state, double dt, double *out_8527162516255122736) {
|
||||
out_8527162516255122736[0] = state[0];
|
||||
out_8527162516255122736[1] = state[1];
|
||||
out_8527162516255122736[2] = state[2];
|
||||
out_8527162516255122736[3] = state[3];
|
||||
out_8527162516255122736[4] = state[4];
|
||||
out_8527162516255122736[5] = dt*((-state[4] + (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(mass*state[4]))*state[6] - 9.8100000000000005*state[8] + stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(mass*state[1]) + (-stiffness_front*state[0] - stiffness_rear*state[0])*state[5]/(mass*state[4])) + state[5];
|
||||
out_8527162516255122736[6] = dt*(center_to_front*stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(rotational_inertia*state[1]) + (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])*state[5]/(rotational_inertia*state[4]) + (-pow(center_to_front, 2)*stiffness_front*state[0] - pow(center_to_rear, 2)*stiffness_rear*state[0])*state[6]/(rotational_inertia*state[4])) + state[6];
|
||||
out_8527162516255122736[7] = state[7];
|
||||
out_8527162516255122736[8] = state[8];
|
||||
void f_fun(double *state, double dt, double *out_9063134164133415607) {
|
||||
out_9063134164133415607[0] = state[0];
|
||||
out_9063134164133415607[1] = state[1];
|
||||
out_9063134164133415607[2] = state[2];
|
||||
out_9063134164133415607[3] = state[3];
|
||||
out_9063134164133415607[4] = state[4];
|
||||
out_9063134164133415607[5] = dt*((-state[4] + (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(mass*state[4]))*state[6] - 9.8100000000000005*state[8] + stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(mass*state[1]) + (-stiffness_front*state[0] - stiffness_rear*state[0])*state[5]/(mass*state[4])) + state[5];
|
||||
out_9063134164133415607[6] = dt*(center_to_front*stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(rotational_inertia*state[1]) + (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])*state[5]/(rotational_inertia*state[4]) + (-pow(center_to_front, 2)*stiffness_front*state[0] - pow(center_to_rear, 2)*stiffness_rear*state[0])*state[6]/(rotational_inertia*state[4])) + state[6];
|
||||
out_9063134164133415607[7] = state[7];
|
||||
out_9063134164133415607[8] = state[8];
|
||||
}
|
||||
void F_fun(double *state, double dt, double *out_7094558340758265304) {
|
||||
out_7094558340758265304[0] = 1;
|
||||
out_7094558340758265304[1] = 0;
|
||||
out_7094558340758265304[2] = 0;
|
||||
out_7094558340758265304[3] = 0;
|
||||
out_7094558340758265304[4] = 0;
|
||||
out_7094558340758265304[5] = 0;
|
||||
out_7094558340758265304[6] = 0;
|
||||
out_7094558340758265304[7] = 0;
|
||||
out_7094558340758265304[8] = 0;
|
||||
out_7094558340758265304[9] = 0;
|
||||
out_7094558340758265304[10] = 1;
|
||||
out_7094558340758265304[11] = 0;
|
||||
out_7094558340758265304[12] = 0;
|
||||
out_7094558340758265304[13] = 0;
|
||||
out_7094558340758265304[14] = 0;
|
||||
out_7094558340758265304[15] = 0;
|
||||
out_7094558340758265304[16] = 0;
|
||||
out_7094558340758265304[17] = 0;
|
||||
out_7094558340758265304[18] = 0;
|
||||
out_7094558340758265304[19] = 0;
|
||||
out_7094558340758265304[20] = 1;
|
||||
out_7094558340758265304[21] = 0;
|
||||
out_7094558340758265304[22] = 0;
|
||||
out_7094558340758265304[23] = 0;
|
||||
out_7094558340758265304[24] = 0;
|
||||
out_7094558340758265304[25] = 0;
|
||||
out_7094558340758265304[26] = 0;
|
||||
out_7094558340758265304[27] = 0;
|
||||
out_7094558340758265304[28] = 0;
|
||||
out_7094558340758265304[29] = 0;
|
||||
out_7094558340758265304[30] = 1;
|
||||
out_7094558340758265304[31] = 0;
|
||||
out_7094558340758265304[32] = 0;
|
||||
out_7094558340758265304[33] = 0;
|
||||
out_7094558340758265304[34] = 0;
|
||||
out_7094558340758265304[35] = 0;
|
||||
out_7094558340758265304[36] = 0;
|
||||
out_7094558340758265304[37] = 0;
|
||||
out_7094558340758265304[38] = 0;
|
||||
out_7094558340758265304[39] = 0;
|
||||
out_7094558340758265304[40] = 1;
|
||||
out_7094558340758265304[41] = 0;
|
||||
out_7094558340758265304[42] = 0;
|
||||
out_7094558340758265304[43] = 0;
|
||||
out_7094558340758265304[44] = 0;
|
||||
out_7094558340758265304[45] = dt*(stiffness_front*(-state[2] - state[3] + state[7])/(mass*state[1]) + (-stiffness_front - stiffness_rear)*state[5]/(mass*state[4]) + (-center_to_front*stiffness_front + center_to_rear*stiffness_rear)*state[6]/(mass*state[4]));
|
||||
out_7094558340758265304[46] = -dt*stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(mass*pow(state[1], 2));
|
||||
out_7094558340758265304[47] = -dt*stiffness_front*state[0]/(mass*state[1]);
|
||||
out_7094558340758265304[48] = -dt*stiffness_front*state[0]/(mass*state[1]);
|
||||
out_7094558340758265304[49] = dt*((-1 - (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(mass*pow(state[4], 2)))*state[6] - (-stiffness_front*state[0] - stiffness_rear*state[0])*state[5]/(mass*pow(state[4], 2)));
|
||||
out_7094558340758265304[50] = dt*(-stiffness_front*state[0] - stiffness_rear*state[0])/(mass*state[4]) + 1;
|
||||
out_7094558340758265304[51] = dt*(-state[4] + (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(mass*state[4]));
|
||||
out_7094558340758265304[52] = dt*stiffness_front*state[0]/(mass*state[1]);
|
||||
out_7094558340758265304[53] = -9.8100000000000005*dt;
|
||||
out_7094558340758265304[54] = dt*(center_to_front*stiffness_front*(-state[2] - state[3] + state[7])/(rotational_inertia*state[1]) + (-center_to_front*stiffness_front + center_to_rear*stiffness_rear)*state[5]/(rotational_inertia*state[4]) + (-pow(center_to_front, 2)*stiffness_front - pow(center_to_rear, 2)*stiffness_rear)*state[6]/(rotational_inertia*state[4]));
|
||||
out_7094558340758265304[55] = -center_to_front*dt*stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(rotational_inertia*pow(state[1], 2));
|
||||
out_7094558340758265304[56] = -center_to_front*dt*stiffness_front*state[0]/(rotational_inertia*state[1]);
|
||||
out_7094558340758265304[57] = -center_to_front*dt*stiffness_front*state[0]/(rotational_inertia*state[1]);
|
||||
out_7094558340758265304[58] = dt*(-(-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])*state[5]/(rotational_inertia*pow(state[4], 2)) - (-pow(center_to_front, 2)*stiffness_front*state[0] - pow(center_to_rear, 2)*stiffness_rear*state[0])*state[6]/(rotational_inertia*pow(state[4], 2)));
|
||||
out_7094558340758265304[59] = dt*(-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(rotational_inertia*state[4]);
|
||||
out_7094558340758265304[60] = dt*(-pow(center_to_front, 2)*stiffness_front*state[0] - pow(center_to_rear, 2)*stiffness_rear*state[0])/(rotational_inertia*state[4]) + 1;
|
||||
out_7094558340758265304[61] = center_to_front*dt*stiffness_front*state[0]/(rotational_inertia*state[1]);
|
||||
out_7094558340758265304[62] = 0;
|
||||
out_7094558340758265304[63] = 0;
|
||||
out_7094558340758265304[64] = 0;
|
||||
out_7094558340758265304[65] = 0;
|
||||
out_7094558340758265304[66] = 0;
|
||||
out_7094558340758265304[67] = 0;
|
||||
out_7094558340758265304[68] = 0;
|
||||
out_7094558340758265304[69] = 0;
|
||||
out_7094558340758265304[70] = 1;
|
||||
out_7094558340758265304[71] = 0;
|
||||
out_7094558340758265304[72] = 0;
|
||||
out_7094558340758265304[73] = 0;
|
||||
out_7094558340758265304[74] = 0;
|
||||
out_7094558340758265304[75] = 0;
|
||||
out_7094558340758265304[76] = 0;
|
||||
out_7094558340758265304[77] = 0;
|
||||
out_7094558340758265304[78] = 0;
|
||||
out_7094558340758265304[79] = 0;
|
||||
out_7094558340758265304[80] = 1;
|
||||
void F_fun(double *state, double dt, double *out_6894033823067301907) {
|
||||
out_6894033823067301907[0] = 1;
|
||||
out_6894033823067301907[1] = 0;
|
||||
out_6894033823067301907[2] = 0;
|
||||
out_6894033823067301907[3] = 0;
|
||||
out_6894033823067301907[4] = 0;
|
||||
out_6894033823067301907[5] = 0;
|
||||
out_6894033823067301907[6] = 0;
|
||||
out_6894033823067301907[7] = 0;
|
||||
out_6894033823067301907[8] = 0;
|
||||
out_6894033823067301907[9] = 0;
|
||||
out_6894033823067301907[10] = 1;
|
||||
out_6894033823067301907[11] = 0;
|
||||
out_6894033823067301907[12] = 0;
|
||||
out_6894033823067301907[13] = 0;
|
||||
out_6894033823067301907[14] = 0;
|
||||
out_6894033823067301907[15] = 0;
|
||||
out_6894033823067301907[16] = 0;
|
||||
out_6894033823067301907[17] = 0;
|
||||
out_6894033823067301907[18] = 0;
|
||||
out_6894033823067301907[19] = 0;
|
||||
out_6894033823067301907[20] = 1;
|
||||
out_6894033823067301907[21] = 0;
|
||||
out_6894033823067301907[22] = 0;
|
||||
out_6894033823067301907[23] = 0;
|
||||
out_6894033823067301907[24] = 0;
|
||||
out_6894033823067301907[25] = 0;
|
||||
out_6894033823067301907[26] = 0;
|
||||
out_6894033823067301907[27] = 0;
|
||||
out_6894033823067301907[28] = 0;
|
||||
out_6894033823067301907[29] = 0;
|
||||
out_6894033823067301907[30] = 1;
|
||||
out_6894033823067301907[31] = 0;
|
||||
out_6894033823067301907[32] = 0;
|
||||
out_6894033823067301907[33] = 0;
|
||||
out_6894033823067301907[34] = 0;
|
||||
out_6894033823067301907[35] = 0;
|
||||
out_6894033823067301907[36] = 0;
|
||||
out_6894033823067301907[37] = 0;
|
||||
out_6894033823067301907[38] = 0;
|
||||
out_6894033823067301907[39] = 0;
|
||||
out_6894033823067301907[40] = 1;
|
||||
out_6894033823067301907[41] = 0;
|
||||
out_6894033823067301907[42] = 0;
|
||||
out_6894033823067301907[43] = 0;
|
||||
out_6894033823067301907[44] = 0;
|
||||
out_6894033823067301907[45] = dt*(stiffness_front*(-state[2] - state[3] + state[7])/(mass*state[1]) + (-stiffness_front - stiffness_rear)*state[5]/(mass*state[4]) + (-center_to_front*stiffness_front + center_to_rear*stiffness_rear)*state[6]/(mass*state[4]));
|
||||
out_6894033823067301907[46] = -dt*stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(mass*pow(state[1], 2));
|
||||
out_6894033823067301907[47] = -dt*stiffness_front*state[0]/(mass*state[1]);
|
||||
out_6894033823067301907[48] = -dt*stiffness_front*state[0]/(mass*state[1]);
|
||||
out_6894033823067301907[49] = dt*((-1 - (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(mass*pow(state[4], 2)))*state[6] - (-stiffness_front*state[0] - stiffness_rear*state[0])*state[5]/(mass*pow(state[4], 2)));
|
||||
out_6894033823067301907[50] = dt*(-stiffness_front*state[0] - stiffness_rear*state[0])/(mass*state[4]) + 1;
|
||||
out_6894033823067301907[51] = dt*(-state[4] + (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(mass*state[4]));
|
||||
out_6894033823067301907[52] = dt*stiffness_front*state[0]/(mass*state[1]);
|
||||
out_6894033823067301907[53] = -9.8100000000000005*dt;
|
||||
out_6894033823067301907[54] = dt*(center_to_front*stiffness_front*(-state[2] - state[3] + state[7])/(rotational_inertia*state[1]) + (-center_to_front*stiffness_front + center_to_rear*stiffness_rear)*state[5]/(rotational_inertia*state[4]) + (-pow(center_to_front, 2)*stiffness_front - pow(center_to_rear, 2)*stiffness_rear)*state[6]/(rotational_inertia*state[4]));
|
||||
out_6894033823067301907[55] = -center_to_front*dt*stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(rotational_inertia*pow(state[1], 2));
|
||||
out_6894033823067301907[56] = -center_to_front*dt*stiffness_front*state[0]/(rotational_inertia*state[1]);
|
||||
out_6894033823067301907[57] = -center_to_front*dt*stiffness_front*state[0]/(rotational_inertia*state[1]);
|
||||
out_6894033823067301907[58] = dt*(-(-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])*state[5]/(rotational_inertia*pow(state[4], 2)) - (-pow(center_to_front, 2)*stiffness_front*state[0] - pow(center_to_rear, 2)*stiffness_rear*state[0])*state[6]/(rotational_inertia*pow(state[4], 2)));
|
||||
out_6894033823067301907[59] = dt*(-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(rotational_inertia*state[4]);
|
||||
out_6894033823067301907[60] = dt*(-pow(center_to_front, 2)*stiffness_front*state[0] - pow(center_to_rear, 2)*stiffness_rear*state[0])/(rotational_inertia*state[4]) + 1;
|
||||
out_6894033823067301907[61] = center_to_front*dt*stiffness_front*state[0]/(rotational_inertia*state[1]);
|
||||
out_6894033823067301907[62] = 0;
|
||||
out_6894033823067301907[63] = 0;
|
||||
out_6894033823067301907[64] = 0;
|
||||
out_6894033823067301907[65] = 0;
|
||||
out_6894033823067301907[66] = 0;
|
||||
out_6894033823067301907[67] = 0;
|
||||
out_6894033823067301907[68] = 0;
|
||||
out_6894033823067301907[69] = 0;
|
||||
out_6894033823067301907[70] = 1;
|
||||
out_6894033823067301907[71] = 0;
|
||||
out_6894033823067301907[72] = 0;
|
||||
out_6894033823067301907[73] = 0;
|
||||
out_6894033823067301907[74] = 0;
|
||||
out_6894033823067301907[75] = 0;
|
||||
out_6894033823067301907[76] = 0;
|
||||
out_6894033823067301907[77] = 0;
|
||||
out_6894033823067301907[78] = 0;
|
||||
out_6894033823067301907[79] = 0;
|
||||
out_6894033823067301907[80] = 1;
|
||||
}
|
||||
void h_25(double *state, double *unused, double *out_6286236977752489740) {
|
||||
out_6286236977752489740[0] = state[6];
|
||||
void h_25(double *state, double *unused, double *out_5814763937768226620) {
|
||||
out_5814763937768226620[0] = state[6];
|
||||
}
|
||||
void H_25(double *state, double *unused, double *out_4084839440865213267) {
|
||||
out_4084839440865213267[0] = 0;
|
||||
out_4084839440865213267[1] = 0;
|
||||
out_4084839440865213267[2] = 0;
|
||||
out_4084839440865213267[3] = 0;
|
||||
out_4084839440865213267[4] = 0;
|
||||
out_4084839440865213267[5] = 0;
|
||||
out_4084839440865213267[6] = 1;
|
||||
out_4084839440865213267[7] = 0;
|
||||
out_4084839440865213267[8] = 0;
|
||||
void H_25(double *state, double *unused, double *out_6257982615884140250) {
|
||||
out_6257982615884140250[0] = 0;
|
||||
out_6257982615884140250[1] = 0;
|
||||
out_6257982615884140250[2] = 0;
|
||||
out_6257982615884140250[3] = 0;
|
||||
out_6257982615884140250[4] = 0;
|
||||
out_6257982615884140250[5] = 0;
|
||||
out_6257982615884140250[6] = 1;
|
||||
out_6257982615884140250[7] = 0;
|
||||
out_6257982615884140250[8] = 0;
|
||||
}
|
||||
void h_24(double *state, double *unused, double *out_6918439556027581256) {
|
||||
out_6918439556027581256[0] = state[4];
|
||||
out_6918439556027581256[1] = state[5];
|
||||
void h_24(double *state, double *unused, double *out_8584440790186238681) {
|
||||
out_8584440790186238681[0] = state[4];
|
||||
out_8584440790186238681[1] = state[5];
|
||||
}
|
||||
void H_24(double *state, double *unused, double *out_4929836049648908666) {
|
||||
out_4929836049648908666[0] = 0;
|
||||
out_4929836049648908666[1] = 0;
|
||||
out_4929836049648908666[2] = 0;
|
||||
out_4929836049648908666[3] = 0;
|
||||
out_4929836049648908666[4] = 1;
|
||||
out_4929836049648908666[5] = 0;
|
||||
out_4929836049648908666[6] = 0;
|
||||
out_4929836049648908666[7] = 0;
|
||||
out_4929836049648908666[8] = 0;
|
||||
out_4929836049648908666[9] = 0;
|
||||
out_4929836049648908666[10] = 0;
|
||||
out_4929836049648908666[11] = 0;
|
||||
out_4929836049648908666[12] = 0;
|
||||
out_4929836049648908666[13] = 0;
|
||||
out_4929836049648908666[14] = 1;
|
||||
out_4929836049648908666[15] = 0;
|
||||
out_4929836049648908666[16] = 0;
|
||||
out_4929836049648908666[17] = 0;
|
||||
void H_24(double *state, double *unused, double *out_6654627920237999745) {
|
||||
out_6654627920237999745[0] = 0;
|
||||
out_6654627920237999745[1] = 0;
|
||||
out_6654627920237999745[2] = 0;
|
||||
out_6654627920237999745[3] = 0;
|
||||
out_6654627920237999745[4] = 1;
|
||||
out_6654627920237999745[5] = 0;
|
||||
out_6654627920237999745[6] = 0;
|
||||
out_6654627920237999745[7] = 0;
|
||||
out_6654627920237999745[8] = 0;
|
||||
out_6654627920237999745[9] = 0;
|
||||
out_6654627920237999745[10] = 0;
|
||||
out_6654627920237999745[11] = 0;
|
||||
out_6654627920237999745[12] = 0;
|
||||
out_6654627920237999745[13] = 0;
|
||||
out_6654627920237999745[14] = 1;
|
||||
out_6654627920237999745[15] = 0;
|
||||
out_6654627920237999745[16] = 0;
|
||||
out_6654627920237999745[17] = 0;
|
||||
}
|
||||
void h_30(double *state, double *unused, double *out_6443423646103618885) {
|
||||
out_6443423646103618885[0] = state[4];
|
||||
void h_30(double *state, double *unused, double *out_8994530607687302646) {
|
||||
out_8994530607687302646[0] = state[4];
|
||||
}
|
||||
void H_30(double *state, double *unused, double *out_6603172399372461894) {
|
||||
out_6603172399372461894[0] = 0;
|
||||
out_6603172399372461894[1] = 0;
|
||||
out_6603172399372461894[2] = 0;
|
||||
out_6603172399372461894[3] = 0;
|
||||
out_6603172399372461894[4] = 1;
|
||||
out_6603172399372461894[5] = 0;
|
||||
out_6603172399372461894[6] = 0;
|
||||
out_6603172399372461894[7] = 0;
|
||||
out_6603172399372461894[8] = 0;
|
||||
void H_30(double *state, double *unused, double *out_3739649657376891623) {
|
||||
out_3739649657376891623[0] = 0;
|
||||
out_3739649657376891623[1] = 0;
|
||||
out_3739649657376891623[2] = 0;
|
||||
out_3739649657376891623[3] = 0;
|
||||
out_3739649657376891623[4] = 1;
|
||||
out_3739649657376891623[5] = 0;
|
||||
out_3739649657376891623[6] = 0;
|
||||
out_3739649657376891623[7] = 0;
|
||||
out_3739649657376891623[8] = 0;
|
||||
}
|
||||
void h_26(double *state, double *unused, double *out_7270973478954575704) {
|
||||
out_7270973478954575704[0] = state[7];
|
||||
void h_26(double *state, double *unused, double *out_3809483594941292135) {
|
||||
out_3809483594941292135[0] = state[7];
|
||||
}
|
||||
void H_26(double *state, double *unused, double *out_343336121991157043) {
|
||||
out_343336121991157043[0] = 0;
|
||||
out_343336121991157043[1] = 0;
|
||||
out_343336121991157043[2] = 0;
|
||||
out_343336121991157043[3] = 0;
|
||||
out_343336121991157043[4] = 0;
|
||||
out_343336121991157043[5] = 0;
|
||||
out_343336121991157043[6] = 0;
|
||||
out_343336121991157043[7] = 1;
|
||||
out_343336121991157043[8] = 0;
|
||||
void H_26(double *state, double *unused, double *out_2953456646123339649) {
|
||||
out_2953456646123339649[0] = 0;
|
||||
out_2953456646123339649[1] = 0;
|
||||
out_2953456646123339649[2] = 0;
|
||||
out_2953456646123339649[3] = 0;
|
||||
out_2953456646123339649[4] = 0;
|
||||
out_2953456646123339649[5] = 0;
|
||||
out_2953456646123339649[6] = 0;
|
||||
out_2953456646123339649[7] = 1;
|
||||
out_2953456646123339649[8] = 0;
|
||||
}
|
||||
void h_27(double *state, double *unused, double *out_9123721044512729191) {
|
||||
out_9123721044512729191[0] = state[3];
|
||||
void h_27(double *state, double *unused, double *out_2777977886323893935) {
|
||||
out_2777977886323893935[0] = state[3];
|
||||
}
|
||||
void H_27(double *state, double *unused, double *out_8826766470556405111) {
|
||||
out_8826766470556405111[0] = 0;
|
||||
out_8826766470556405111[1] = 0;
|
||||
out_8826766470556405111[2] = 0;
|
||||
out_8826766470556405111[3] = 1;
|
||||
out_8826766470556405111[4] = 0;
|
||||
out_8826766470556405111[5] = 0;
|
||||
out_8826766470556405111[6] = 0;
|
||||
out_8826766470556405111[7] = 0;
|
||||
out_8826766470556405111[8] = 0;
|
||||
void H_27(double *state, double *unused, double *out_1516055586192948406) {
|
||||
out_1516055586192948406[0] = 0;
|
||||
out_1516055586192948406[1] = 0;
|
||||
out_1516055586192948406[2] = 0;
|
||||
out_1516055586192948406[3] = 1;
|
||||
out_1516055586192948406[4] = 0;
|
||||
out_1516055586192948406[5] = 0;
|
||||
out_1516055586192948406[6] = 0;
|
||||
out_1516055586192948406[7] = 0;
|
||||
out_1516055586192948406[8] = 0;
|
||||
}
|
||||
void h_29(double *state, double *unused, double *out_2352885818162378255) {
|
||||
out_2352885818162378255[0] = state[1];
|
||||
void h_29(double *state, double *unused, double *out_3992857340026457001) {
|
||||
out_3992857340026457001[0] = state[1];
|
||||
}
|
||||
void H_29(double *state, double *unused, double *out_7113403743686854078) {
|
||||
out_7113403743686854078[0] = 0;
|
||||
out_7113403743686854078[1] = 1;
|
||||
out_7113403743686854078[2] = 0;
|
||||
out_7113403743686854078[3] = 0;
|
||||
out_7113403743686854078[4] = 0;
|
||||
out_7113403743686854078[5] = 0;
|
||||
out_7113403743686854078[6] = 0;
|
||||
out_7113403743686854078[7] = 0;
|
||||
out_7113403743686854078[8] = 0;
|
||||
void H_29(double *state, double *unused, double *out_3229418313062499439) {
|
||||
out_3229418313062499439[0] = 0;
|
||||
out_3229418313062499439[1] = 1;
|
||||
out_3229418313062499439[2] = 0;
|
||||
out_3229418313062499439[3] = 0;
|
||||
out_3229418313062499439[4] = 0;
|
||||
out_3229418313062499439[5] = 0;
|
||||
out_3229418313062499439[6] = 0;
|
||||
out_3229418313062499439[7] = 0;
|
||||
out_3229418313062499439[8] = 0;
|
||||
}
|
||||
void h_28(double *state, double *unused, double *out_8180211191611066756) {
|
||||
out_8180211191611066756[0] = state[0];
|
||||
void h_28(double *state, double *unused, double *out_1087530051588212975) {
|
||||
out_1087530051588212975[0] = state[0];
|
||||
}
|
||||
void H_28(double *state, double *unused, double *out_2031004726617323504) {
|
||||
out_2031004726617323504[0] = 1;
|
||||
out_2031004726617323504[1] = 0;
|
||||
out_2031004726617323504[2] = 0;
|
||||
out_2031004726617323504[3] = 0;
|
||||
out_2031004726617323504[4] = 0;
|
||||
out_2031004726617323504[5] = 0;
|
||||
out_2031004726617323504[6] = 0;
|
||||
out_2031004726617323504[7] = 0;
|
||||
out_2031004726617323504[8] = 0;
|
||||
void H_28(double *state, double *unused, double *out_8311817330132030013) {
|
||||
out_8311817330132030013[0] = 1;
|
||||
out_8311817330132030013[1] = 0;
|
||||
out_8311817330132030013[2] = 0;
|
||||
out_8311817330132030013[3] = 0;
|
||||
out_8311817330132030013[4] = 0;
|
||||
out_8311817330132030013[5] = 0;
|
||||
out_8311817330132030013[6] = 0;
|
||||
out_8311817330132030013[7] = 0;
|
||||
out_8311817330132030013[8] = 0;
|
||||
}
|
||||
void h_31(double *state, double *unused, double *out_5572679169480766713) {
|
||||
out_5572679169480766713[0] = state[8];
|
||||
void h_31(double *state, double *unused, double *out_5539569875483720731) {
|
||||
out_5539569875483720731[0] = state[8];
|
||||
}
|
||||
void H_31(double *state, double *unused, double *out_282871980242194433) {
|
||||
out_282871980242194433[0] = 0;
|
||||
out_282871980242194433[1] = 0;
|
||||
out_282871980242194433[2] = 0;
|
||||
out_282871980242194433[3] = 0;
|
||||
out_282871980242194433[4] = 0;
|
||||
out_282871980242194433[5] = 0;
|
||||
out_282871980242194433[6] = 0;
|
||||
out_282871980242194433[7] = 0;
|
||||
out_282871980242194433[8] = 1;
|
||||
void H_31(double *state, double *unused, double *out_818692634627677003) {
|
||||
out_818692634627677003[0] = 0;
|
||||
out_818692634627677003[1] = 0;
|
||||
out_818692634627677003[2] = 0;
|
||||
out_818692634627677003[3] = 0;
|
||||
out_818692634627677003[4] = 0;
|
||||
out_818692634627677003[5] = 0;
|
||||
out_818692634627677003[6] = 0;
|
||||
out_818692634627677003[7] = 0;
|
||||
out_818692634627677003[8] = 1;
|
||||
}
|
||||
#include <eigen3/Eigen/Dense>
|
||||
#include <iostream>
|
||||
@@ -518,68 +518,68 @@ void car_update_28(double *in_x, double *in_P, double *in_z, double *in_R, doubl
|
||||
void car_update_31(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea) {
|
||||
update<1, 3, 0>(in_x, in_P, h_31, H_31, NULL, in_z, in_R, in_ea, MAHA_THRESH_31);
|
||||
}
|
||||
void car_err_fun(double *nom_x, double *delta_x, double *out_2367152293466283987) {
|
||||
err_fun(nom_x, delta_x, out_2367152293466283987);
|
||||
void car_err_fun(double *nom_x, double *delta_x, double *out_5479217515808027394) {
|
||||
err_fun(nom_x, delta_x, out_5479217515808027394);
|
||||
}
|
||||
void car_inv_err_fun(double *nom_x, double *true_x, double *out_5829526074669369656) {
|
||||
inv_err_fun(nom_x, true_x, out_5829526074669369656);
|
||||
void car_inv_err_fun(double *nom_x, double *true_x, double *out_8100295571519039240) {
|
||||
inv_err_fun(nom_x, true_x, out_8100295571519039240);
|
||||
}
|
||||
void car_H_mod_fun(double *state, double *out_1755007343641557895) {
|
||||
H_mod_fun(state, out_1755007343641557895);
|
||||
void car_H_mod_fun(double *state, double *out_7285069632640746526) {
|
||||
H_mod_fun(state, out_7285069632640746526);
|
||||
}
|
||||
void car_f_fun(double *state, double dt, double *out_8527162516255122736) {
|
||||
f_fun(state, dt, out_8527162516255122736);
|
||||
void car_f_fun(double *state, double dt, double *out_9063134164133415607) {
|
||||
f_fun(state, dt, out_9063134164133415607);
|
||||
}
|
||||
void car_F_fun(double *state, double dt, double *out_7094558340758265304) {
|
||||
F_fun(state, dt, out_7094558340758265304);
|
||||
void car_F_fun(double *state, double dt, double *out_6894033823067301907) {
|
||||
F_fun(state, dt, out_6894033823067301907);
|
||||
}
|
||||
void car_h_25(double *state, double *unused, double *out_6286236977752489740) {
|
||||
h_25(state, unused, out_6286236977752489740);
|
||||
void car_h_25(double *state, double *unused, double *out_5814763937768226620) {
|
||||
h_25(state, unused, out_5814763937768226620);
|
||||
}
|
||||
void car_H_25(double *state, double *unused, double *out_4084839440865213267) {
|
||||
H_25(state, unused, out_4084839440865213267);
|
||||
void car_H_25(double *state, double *unused, double *out_6257982615884140250) {
|
||||
H_25(state, unused, out_6257982615884140250);
|
||||
}
|
||||
void car_h_24(double *state, double *unused, double *out_6918439556027581256) {
|
||||
h_24(state, unused, out_6918439556027581256);
|
||||
void car_h_24(double *state, double *unused, double *out_8584440790186238681) {
|
||||
h_24(state, unused, out_8584440790186238681);
|
||||
}
|
||||
void car_H_24(double *state, double *unused, double *out_4929836049648908666) {
|
||||
H_24(state, unused, out_4929836049648908666);
|
||||
void car_H_24(double *state, double *unused, double *out_6654627920237999745) {
|
||||
H_24(state, unused, out_6654627920237999745);
|
||||
}
|
||||
void car_h_30(double *state, double *unused, double *out_6443423646103618885) {
|
||||
h_30(state, unused, out_6443423646103618885);
|
||||
void car_h_30(double *state, double *unused, double *out_8994530607687302646) {
|
||||
h_30(state, unused, out_8994530607687302646);
|
||||
}
|
||||
void car_H_30(double *state, double *unused, double *out_6603172399372461894) {
|
||||
H_30(state, unused, out_6603172399372461894);
|
||||
void car_H_30(double *state, double *unused, double *out_3739649657376891623) {
|
||||
H_30(state, unused, out_3739649657376891623);
|
||||
}
|
||||
void car_h_26(double *state, double *unused, double *out_7270973478954575704) {
|
||||
h_26(state, unused, out_7270973478954575704);
|
||||
void car_h_26(double *state, double *unused, double *out_3809483594941292135) {
|
||||
h_26(state, unused, out_3809483594941292135);
|
||||
}
|
||||
void car_H_26(double *state, double *unused, double *out_343336121991157043) {
|
||||
H_26(state, unused, out_343336121991157043);
|
||||
void car_H_26(double *state, double *unused, double *out_2953456646123339649) {
|
||||
H_26(state, unused, out_2953456646123339649);
|
||||
}
|
||||
void car_h_27(double *state, double *unused, double *out_9123721044512729191) {
|
||||
h_27(state, unused, out_9123721044512729191);
|
||||
void car_h_27(double *state, double *unused, double *out_2777977886323893935) {
|
||||
h_27(state, unused, out_2777977886323893935);
|
||||
}
|
||||
void car_H_27(double *state, double *unused, double *out_8826766470556405111) {
|
||||
H_27(state, unused, out_8826766470556405111);
|
||||
void car_H_27(double *state, double *unused, double *out_1516055586192948406) {
|
||||
H_27(state, unused, out_1516055586192948406);
|
||||
}
|
||||
void car_h_29(double *state, double *unused, double *out_2352885818162378255) {
|
||||
h_29(state, unused, out_2352885818162378255);
|
||||
void car_h_29(double *state, double *unused, double *out_3992857340026457001) {
|
||||
h_29(state, unused, out_3992857340026457001);
|
||||
}
|
||||
void car_H_29(double *state, double *unused, double *out_7113403743686854078) {
|
||||
H_29(state, unused, out_7113403743686854078);
|
||||
void car_H_29(double *state, double *unused, double *out_3229418313062499439) {
|
||||
H_29(state, unused, out_3229418313062499439);
|
||||
}
|
||||
void car_h_28(double *state, double *unused, double *out_8180211191611066756) {
|
||||
h_28(state, unused, out_8180211191611066756);
|
||||
void car_h_28(double *state, double *unused, double *out_1087530051588212975) {
|
||||
h_28(state, unused, out_1087530051588212975);
|
||||
}
|
||||
void car_H_28(double *state, double *unused, double *out_2031004726617323504) {
|
||||
H_28(state, unused, out_2031004726617323504);
|
||||
void car_H_28(double *state, double *unused, double *out_8311817330132030013) {
|
||||
H_28(state, unused, out_8311817330132030013);
|
||||
}
|
||||
void car_h_31(double *state, double *unused, double *out_5572679169480766713) {
|
||||
h_31(state, unused, out_5572679169480766713);
|
||||
void car_h_31(double *state, double *unused, double *out_5539569875483720731) {
|
||||
h_31(state, unused, out_5539569875483720731);
|
||||
}
|
||||
void car_H_31(double *state, double *unused, double *out_282871980242194433) {
|
||||
H_31(state, unused, out_282871980242194433);
|
||||
void car_H_31(double *state, double *unused, double *out_818692634627677003) {
|
||||
H_31(state, unused, out_818692634627677003);
|
||||
}
|
||||
void car_predict(double *in_x, double *in_P, double *in_Q, double dt) {
|
||||
predict(in_x, in_P, in_Q, dt);
|
||||
|
||||
@@ -9,27 +9,27 @@ void car_update_27(double *in_x, double *in_P, double *in_z, double *in_R, doubl
|
||||
void car_update_29(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
|
||||
void car_update_28(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
|
||||
void car_update_31(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
|
||||
void car_err_fun(double *nom_x, double *delta_x, double *out_2367152293466283987);
|
||||
void car_inv_err_fun(double *nom_x, double *true_x, double *out_5829526074669369656);
|
||||
void car_H_mod_fun(double *state, double *out_1755007343641557895);
|
||||
void car_f_fun(double *state, double dt, double *out_8527162516255122736);
|
||||
void car_F_fun(double *state, double dt, double *out_7094558340758265304);
|
||||
void car_h_25(double *state, double *unused, double *out_6286236977752489740);
|
||||
void car_H_25(double *state, double *unused, double *out_4084839440865213267);
|
||||
void car_h_24(double *state, double *unused, double *out_6918439556027581256);
|
||||
void car_H_24(double *state, double *unused, double *out_4929836049648908666);
|
||||
void car_h_30(double *state, double *unused, double *out_6443423646103618885);
|
||||
void car_H_30(double *state, double *unused, double *out_6603172399372461894);
|
||||
void car_h_26(double *state, double *unused, double *out_7270973478954575704);
|
||||
void car_H_26(double *state, double *unused, double *out_343336121991157043);
|
||||
void car_h_27(double *state, double *unused, double *out_9123721044512729191);
|
||||
void car_H_27(double *state, double *unused, double *out_8826766470556405111);
|
||||
void car_h_29(double *state, double *unused, double *out_2352885818162378255);
|
||||
void car_H_29(double *state, double *unused, double *out_7113403743686854078);
|
||||
void car_h_28(double *state, double *unused, double *out_8180211191611066756);
|
||||
void car_H_28(double *state, double *unused, double *out_2031004726617323504);
|
||||
void car_h_31(double *state, double *unused, double *out_5572679169480766713);
|
||||
void car_H_31(double *state, double *unused, double *out_282871980242194433);
|
||||
void car_err_fun(double *nom_x, double *delta_x, double *out_5479217515808027394);
|
||||
void car_inv_err_fun(double *nom_x, double *true_x, double *out_8100295571519039240);
|
||||
void car_H_mod_fun(double *state, double *out_7285069632640746526);
|
||||
void car_f_fun(double *state, double dt, double *out_9063134164133415607);
|
||||
void car_F_fun(double *state, double dt, double *out_6894033823067301907);
|
||||
void car_h_25(double *state, double *unused, double *out_5814763937768226620);
|
||||
void car_H_25(double *state, double *unused, double *out_6257982615884140250);
|
||||
void car_h_24(double *state, double *unused, double *out_8584440790186238681);
|
||||
void car_H_24(double *state, double *unused, double *out_6654627920237999745);
|
||||
void car_h_30(double *state, double *unused, double *out_8994530607687302646);
|
||||
void car_H_30(double *state, double *unused, double *out_3739649657376891623);
|
||||
void car_h_26(double *state, double *unused, double *out_3809483594941292135);
|
||||
void car_H_26(double *state, double *unused, double *out_2953456646123339649);
|
||||
void car_h_27(double *state, double *unused, double *out_2777977886323893935);
|
||||
void car_H_27(double *state, double *unused, double *out_1516055586192948406);
|
||||
void car_h_29(double *state, double *unused, double *out_3992857340026457001);
|
||||
void car_H_29(double *state, double *unused, double *out_3229418313062499439);
|
||||
void car_h_28(double *state, double *unused, double *out_1087530051588212975);
|
||||
void car_H_28(double *state, double *unused, double *out_8311817330132030013);
|
||||
void car_h_31(double *state, double *unused, double *out_5539569875483720731);
|
||||
void car_H_31(double *state, double *unused, double *out_818692634627677003);
|
||||
void car_predict(double *in_x, double *in_P, double *in_Q, double dt);
|
||||
void car_set_mass(double x);
|
||||
void car_set_rotational_inertia(double x);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -5,18 +5,18 @@ void pose_update_4(double *in_x, double *in_P, double *in_z, double *in_R, doubl
|
||||
void pose_update_10(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
|
||||
void pose_update_13(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
|
||||
void pose_update_14(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
|
||||
void pose_err_fun(double *nom_x, double *delta_x, double *out_228345055687174559);
|
||||
void pose_inv_err_fun(double *nom_x, double *true_x, double *out_3726714603593551859);
|
||||
void pose_H_mod_fun(double *state, double *out_6712772131857650620);
|
||||
void pose_f_fun(double *state, double dt, double *out_2706993655191654809);
|
||||
void pose_F_fun(double *state, double dt, double *out_372841931129064371);
|
||||
void pose_h_4(double *state, double *unused, double *out_3997723666308670841);
|
||||
void pose_H_4(double *state, double *unused, double *out_4134113474779579353);
|
||||
void pose_h_10(double *state, double *unused, double *out_6627456117207891484);
|
||||
void pose_H_10(double *state, double *unused, double *out_1462818273599549569);
|
||||
void pose_h_13(double *state, double *unused, double *out_2824244578095522440);
|
||||
void pose_H_13(double *state, double *unused, double *out_921839649447246552);
|
||||
void pose_h_14(double *state, double *unused, double *out_696698419016090920);
|
||||
void pose_H_14(double *state, double *unused, double *out_7216901907074951649);
|
||||
void pose_err_fun(double *nom_x, double *delta_x, double *out_2580540694739946519);
|
||||
void pose_inv_err_fun(double *nom_x, double *true_x, double *out_5357096832042119822);
|
||||
void pose_H_mod_fun(double *state, double *out_7228847589067930749);
|
||||
void pose_f_fun(double *state, double dt, double *out_8526672508847459198);
|
||||
void pose_F_fun(double *state, double dt, double *out_4769745432950749149);
|
||||
void pose_h_4(double *state, double *unused, double *out_6566956173213773055);
|
||||
void pose_H_4(double *state, double *unused, double *out_2076329204028850014);
|
||||
void pose_h_10(double *state, double *unused, double *out_6519103870371093687);
|
||||
void pose_H_10(double *state, double *unused, double *out_1454480582190579456);
|
||||
void pose_h_13(double *state, double *unused, double *out_8545332083251637040);
|
||||
void pose_H_13(double *state, double *unused, double *out_1135944621303482787);
|
||||
void pose_h_14(double *state, double *unused, double *out_529654494281334242);
|
||||
void pose_H_14(double *state, double *unused, double *out_2511445730673733613);
|
||||
void pose_predict(double *in_x, double *in_P, double *in_Q, double dt);
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
import glob
|
||||
import json
|
||||
import os
|
||||
from SCons.Script import Value
|
||||
from openpilot.common.file_chunker import chunk_file, get_chunk_paths
|
||||
from tinygrad import Device
|
||||
|
||||
Import('env', 'arch')
|
||||
chunker_file = File("#common/file_chunker.py")
|
||||
lenv = env.Clone()
|
||||
|
||||
tinygrad_root = env.Dir("#").abspath
|
||||
tinygrad_files = ["#"+x for x in glob.glob(env.Dir("#tinygrad_repo").relpath + "/**", recursive=True, root_dir=tinygrad_root)
|
||||
if 'pycache' not in x and os.path.isfile(os.path.join(tinygrad_root, x))]
|
||||
|
||||
def estimate_pickle_max_size(onnx_size):
|
||||
return 1.2 * onnx_size + 10 * 1024 * 1024 # 20% + 10MB is plenty
|
||||
|
||||
# THREADS=0 is need to prevent bug: https://github.com/tinygrad/tinygrad/issues/14689
|
||||
# get fastest TG config
|
||||
available = set(Device.get_available_devices())
|
||||
# FIXME-SP: reset when we bump tg
|
||||
if False: # 'CUDA' in available:
|
||||
tg_backend = 'CUDA'
|
||||
tg_flags = f'DEV={tg_backend}'
|
||||
elif 'QCOM' in available:
|
||||
tg_backend = 'QCOM'
|
||||
tg_flags = f'DEV={tg_backend} FLOAT16=1 NOLOCALS=1 JIT_BATCH_SIZE=0'
|
||||
else:
|
||||
tg_backend = 'CPU' if arch == 'Darwin' else 'CPU CPU_LLVM=1' # FIXME-SP: reset when we bump tg
|
||||
tg_flags = f'DEV={tg_backend} THREADS=0'
|
||||
|
||||
def write_tg_compiled_flags(target, source, env):
|
||||
with open(str(target[0]), "w") as f:
|
||||
json.dump({"DEV": tg_backend}, f)
|
||||
f.write("\n")
|
||||
|
||||
compiled_flags_node = lenv.Command(
|
||||
File("models/tg_compiled_flags.json").abspath,
|
||||
tinygrad_files + [Value(tg_backend)],
|
||||
write_tg_compiled_flags,
|
||||
)
|
||||
|
||||
# tinygrad calls brew which needs a $HOME in the env
|
||||
mac_brew_string = f'HOME={os.path.expanduser("~")}' if arch == 'Darwin' else ''
|
||||
|
||||
# Get model metadata
|
||||
for model_name in ['driving_vision', 'driving_policy', 'dmonitoring_model']:
|
||||
fn = File(f"models/{model_name}").abspath
|
||||
script_files = [File(Dir("#selfdrive/modeld").File("get_model_metadata.py").abspath)]
|
||||
cmd = f'{tg_flags} {mac_brew_string} python3 {Dir("#selfdrive/modeld").abspath}/get_model_metadata.py {fn}.onnx'
|
||||
lenv.Command(fn + "_metadata.pkl", [fn + ".onnx"] + tinygrad_files + script_files + [compiled_flags_node], cmd)
|
||||
|
||||
image_flag = {
|
||||
'larch64': 'IMAGE=2',
|
||||
}.get(arch, 'IMAGE=0')
|
||||
script_files = [File(Dir("#selfdrive/modeld").File("compile_warp.py").abspath)]
|
||||
compile_warp_cmd = f'{tg_flags} {mac_brew_string} python3 {Dir("#selfdrive/modeld").abspath}/compile_warp.py '
|
||||
from openpilot.common.transformations.camera import _ar_ox_fisheye, _os_fisheye
|
||||
warp_targets = []
|
||||
for cam in [_ar_ox_fisheye, _os_fisheye]:
|
||||
w, h = cam.width, cam.height
|
||||
warp_targets += [File(f"models/warp_{w}x{h}_tinygrad.pkl").abspath, File(f"models/dm_warp_{w}x{h}_tinygrad.pkl").abspath]
|
||||
lenv.Command(warp_targets, tinygrad_files + script_files + [compiled_flags_node], compile_warp_cmd)
|
||||
|
||||
def tg_compile(flags, model_name):
|
||||
pythonpath_string = 'PYTHONPATH="${PYTHONPATH}:' + env.Dir("#tinygrad_repo").abspath + '"'
|
||||
fn = File(f"models/{model_name}").abspath
|
||||
pkl = fn + "_tinygrad.pkl"
|
||||
onnx_path = fn + ".onnx"
|
||||
chunk_targets = get_chunk_paths(pkl, estimate_pickle_max_size(os.path.getsize(onnx_path)))
|
||||
compile_node = lenv.Command(
|
||||
pkl,
|
||||
[onnx_path] + tinygrad_files + [chunker_file, compiled_flags_node],
|
||||
f'{pythonpath_string} {flags} {image_flag} python3 {Dir("#tinygrad_repo").abspath}/examples/openpilot/compile3.py {fn}.onnx {pkl}',
|
||||
)
|
||||
def do_chunk(target, source, env):
|
||||
chunk_file(pkl, chunk_targets)
|
||||
return lenv.Command(
|
||||
chunk_targets,
|
||||
compile_node,
|
||||
do_chunk,
|
||||
)
|
||||
|
||||
# Compile small models
|
||||
for model_name in ['driving_vision', 'driving_policy', 'dmonitoring_model']:
|
||||
tg_compile(tg_flags, model_name)
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
driving_policy.onnx
|
||||
@@ -1 +0,0 @@
|
||||
driving_vision.onnx
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,10 @@
|
||||
Import('env', 'arch', 'common', 'messaging')
|
||||
|
||||
if arch != "Darwin":
|
||||
libs = [common, messaging, 'pthread']
|
||||
panda = env.Library('panda', ['panda.cc', 'spi.cc'])
|
||||
|
||||
env.Program('pandad', ['main.cc', 'pandad.cc', 'panda_safety.cc'], LIBS=[panda] + libs)
|
||||
|
||||
if GetOption('extras'):
|
||||
env.Program('tests/test_pandad_canprotocol', ['tests/test_pandad_canprotocol.cc'], LIBS=[panda] + libs)
|
||||
+201
-201
@@ -73,25 +73,25 @@ def startup_master_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubM
|
||||
if "REPLAY" in os.environ:
|
||||
branch = "replay"
|
||||
|
||||
return StartupAlert("WARNING: This branch is not tested", branch, alert_status=AlertStatus.userPrompt)
|
||||
return StartupAlert("警告:此分支未经测试", branch, alert_status=AlertStatus.userPrompt)
|
||||
|
||||
def below_engage_speed_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
return NoEntryAlert(f"Drive above {get_display_speed(CP.minEnableSpeed, metric)} to engage")
|
||||
return NoEntryAlert(f"车速超过 {get_display_speed(CP.minEnableSpeed, metric)} 才可开启")
|
||||
|
||||
|
||||
def below_steer_speed_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
return Alert(
|
||||
f"Steer Assist Unavailable Below {get_display_speed(CP.minSteerSpeed, metric)}",
|
||||
f"转向辅助在 {get_display_speed(CP.minSteerSpeed, metric)} 以下不可用",
|
||||
"",
|
||||
AlertStatus.userPrompt, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.prompt, 0.4)
|
||||
|
||||
|
||||
def calibration_incomplete_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
first_word = 'Recalibrating' if sm['liveCalibration'].calStatus == log.LiveCalibrationData.Status.recalibrating else 'Calibrating'
|
||||
first_word = '重新标定中' if sm['liveCalibration'].calStatus == log.LiveCalibrationData.Status.recalibrating else '标定中'
|
||||
return Alert(
|
||||
f"{first_word}: {sm['liveCalibration'].calPerc:.0f}%",
|
||||
f"Drive Above {get_display_speed(MIN_SPEED_FILTER, metric)}",
|
||||
f"{first_word}:{sm['liveCalibration'].calPerc:.0f}%",
|
||||
f"车速超过 {get_display_speed(MIN_SPEED_FILTER, metric)} 即可",
|
||||
AlertStatus.normal, AlertSize.mid,
|
||||
Priority.LOWEST, VisualAlert.none, AudibleAlert.none, .2)
|
||||
|
||||
@@ -99,8 +99,8 @@ def calibration_incomplete_alert(CP: car.CarParams, CS: car.CarState, sm: messag
|
||||
def audio_feedback_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
duration = FEEDBACK_MAX_DURATION - ((sm['audioFeedback'].blockNum + 1) * SAMPLE_BUFFER / SAMPLE_RATE)
|
||||
return NormalPermanentAlert(
|
||||
"Recording Audio Feedback",
|
||||
f"{round(duration)} second{'s' if round(duration) != 1 else ''} remaining. Press again to save early.",
|
||||
"正在录制语音反馈",
|
||||
f"剩余 {round(duration)} 秒,再次按下可提前保存。",
|
||||
priority=Priority.LOW)
|
||||
|
||||
|
||||
@@ -108,57 +108,57 @@ def audio_feedback_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubM
|
||||
|
||||
def out_of_space_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
full_perc = round(100. - sm['deviceState'].freeSpacePercent)
|
||||
return NormalPermanentAlert("Out of Storage", f"{full_perc}% full")
|
||||
return NormalPermanentAlert("存储空间不足", f"已用 {full_perc}%")
|
||||
|
||||
|
||||
def posenet_invalid_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
mdl = sm['modelV2'].velocity.x[0] if len(sm['modelV2'].velocity.x) else math.nan
|
||||
err = CS.vEgo - mdl
|
||||
msg = f"Speed Error: {err:.1f} m/s"
|
||||
return NoEntryAlert(msg, alert_text_1="Posenet Speed Invalid")
|
||||
msg = f"速度误差:{err:.1f} m/s"
|
||||
return NoEntryAlert(msg, alert_text_1="Posenet 速度无效")
|
||||
|
||||
|
||||
def process_not_running_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
not_running = [p.name for p in sm['managerState'].processes if not p.running and p.shouldBeRunning]
|
||||
msg = ', '.join(not_running)
|
||||
return NoEntryAlert(msg, alert_text_1="Process Not Running")
|
||||
return NoEntryAlert(msg, alert_text_1="进程未运行")
|
||||
|
||||
|
||||
def comm_issue_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
bs = [s for s in sm.data.keys() if not sm.all_checks([s, ])]
|
||||
msg = ', '.join(bs[:4]) # can't fit too many on one line
|
||||
return NoEntryAlert(msg, alert_text_1="Communication Issue Between Processes")
|
||||
return NoEntryAlert(msg, alert_text_1="进程间通信异常")
|
||||
|
||||
|
||||
def camera_malfunction_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
all_cams = ('roadCameraState', 'driverCameraState', 'wideRoadCameraState')
|
||||
bad_cams = [s.replace('State', '') for s in all_cams if s in sm.data.keys() and not sm.all_checks([s, ])]
|
||||
return NormalPermanentAlert("Camera Malfunction", ', '.join(bad_cams))
|
||||
return NormalPermanentAlert("摄像头故障", '、'.join(bad_cams))
|
||||
|
||||
|
||||
def calibration_invalid_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
rpy = sm['liveCalibration'].rpyCalib
|
||||
yaw = math.degrees(rpy[2] if len(rpy) == 3 else math.nan)
|
||||
pitch = math.degrees(rpy[1] if len(rpy) == 3 else math.nan)
|
||||
angles = f"Remount Device (Pitch: {pitch:.1f}°, Yaw: {yaw:.1f}°)"
|
||||
return NormalPermanentAlert("Calibration Invalid", angles)
|
||||
angles = f"重新安装设备(俯仰:{pitch:.1f}°,偏航:{yaw:.1f}°)"
|
||||
return NormalPermanentAlert("标定无效", angles)
|
||||
|
||||
|
||||
def paramsd_invalid_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
if not sm['liveParameters'].angleOffsetValid:
|
||||
angle_offset_deg = sm['liveParameters'].angleOffsetDeg
|
||||
title = "Steering misalignment detected"
|
||||
text = f"Angle offset too high (Offset: {angle_offset_deg:.1f}°)"
|
||||
title = "检测到转向偏移"
|
||||
text = f"角度偏移过大(偏移:{angle_offset_deg:.1f}°)"
|
||||
elif not sm['liveParameters'].steerRatioValid:
|
||||
steer_ratio = sm['liveParameters'].steerRatio
|
||||
title = "Steer ratio mismatch"
|
||||
text = f"Steering rack geometry may be off (Ratio: {steer_ratio:.1f})"
|
||||
title = "转向比不匹配"
|
||||
text = f"转向几何可能存在问题(比例:{steer_ratio:.1f})"
|
||||
elif not sm['liveParameters'].stiffnessFactorValid:
|
||||
stiffness_factor = sm['liveParameters'].stiffnessFactor
|
||||
title = "Abnormal tire stiffness"
|
||||
text = f"Check tires, pressure, or alignment (Factor: {stiffness_factor:.1f})"
|
||||
title = "轮胎刚度异常"
|
||||
text = f"检查轮胎、胎压或定位(系数:{stiffness_factor:.1f})"
|
||||
else:
|
||||
return NoEntryAlert("paramsd Temporary Error")
|
||||
return NoEntryAlert("paramsd 临时错误")
|
||||
|
||||
return NoEntryAlert(alert_text_1=title, alert_text_2=text)
|
||||
|
||||
@@ -166,27 +166,27 @@ def overheat_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster,
|
||||
cpu = max(sm['deviceState'].cpuTempC, default=0.)
|
||||
gpu = max(sm['deviceState'].gpuTempC, default=0.)
|
||||
temp = max((cpu, gpu, sm['deviceState'].memoryTempC))
|
||||
return NormalPermanentAlert("System Overheated", f"{temp:.0f} °C")
|
||||
return NormalPermanentAlert("系统过热", f"{temp:.0f} °C")
|
||||
|
||||
|
||||
def low_memory_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
return NormalPermanentAlert("Low Memory", f"{sm['deviceState'].memoryUsagePercent}% used")
|
||||
return NormalPermanentAlert("内存不足", f"已用 {sm['deviceState'].memoryUsagePercent}%")
|
||||
|
||||
|
||||
def high_cpu_usage_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
x = max(sm['deviceState'].cpuUsagePercent, default=0.)
|
||||
return NormalPermanentAlert("High CPU Usage", f"{x}% used")
|
||||
return NormalPermanentAlert("CPU 负载过高", f"已用 {x}%")
|
||||
|
||||
|
||||
def modeld_lagging_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
return NormalPermanentAlert("Driving Model Lagging", f"{sm['modelV2'].frameDropPerc:.1f}% frames dropped")
|
||||
return NormalPermanentAlert("驾驶模型延迟", f"丢帧 {sm['modelV2'].frameDropPerc:.1f}%")
|
||||
|
||||
|
||||
def joystick_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
gb = sm['carControl'].actuators.accel / 4.
|
||||
steer = sm['carControl'].actuators.torque
|
||||
vals = f"Gas: {round(gb * 100.)}%, Steer: {round(steer * 100.)}%"
|
||||
return NormalPermanentAlert("Joystick Mode", vals)
|
||||
vals = f"油门:{round(gb * 100.)}%,转向:{round(steer * 100.)}%"
|
||||
return NormalPermanentAlert("摇杆模式", vals)
|
||||
|
||||
|
||||
def longitudinal_maneuver_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
@@ -201,18 +201,18 @@ def longitudinal_maneuver_alert(CP: car.CarParams, CS: car.CarState, sm: messagi
|
||||
|
||||
def personality_changed_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
personality = str(personality).title()
|
||||
return NormalPermanentAlert(f"Driving Personality: {personality}", duration=1.5)
|
||||
return NormalPermanentAlert(f"驾驶风格:{personality}", duration=1.5)
|
||||
|
||||
|
||||
def invalid_lkas_setting_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
text = "Toggle stock LKAS on or off to engage"
|
||||
text = "切换原车 LKAS 开关后即可开启"
|
||||
if CP.brand == "tesla":
|
||||
text = "Switch to Traffic-Aware Cruise Control to engage"
|
||||
text = "切换到交通感知巡航控制后即可开启"
|
||||
elif CP.brand == "mazda":
|
||||
text = "Enable your car's LKAS to engage"
|
||||
text = "开启车辆原车 LKAS 后即可开启"
|
||||
elif CP.brand == "nissan":
|
||||
text = "Disable your car's stock LKAS to engage"
|
||||
return NormalPermanentAlert("Invalid LKAS setting", text)
|
||||
text = "关闭原车 LKAS 后即可开启"
|
||||
return NormalPermanentAlert("LKAS 设置无效", text)
|
||||
|
||||
|
||||
|
||||
@@ -226,26 +226,26 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
|
||||
|
||||
EventName.joystickDebug: {
|
||||
ET.WARNING: joystick_alert,
|
||||
ET.PERMANENT: NormalPermanentAlert("Joystick Mode"),
|
||||
ET.PERMANENT: NormalPermanentAlert("摇杆模式"),
|
||||
},
|
||||
|
||||
EventName.longitudinalManeuver: {
|
||||
ET.WARNING: longitudinal_maneuver_alert,
|
||||
ET.PERMANENT: NormalPermanentAlert("Longitudinal Maneuver Mode",
|
||||
"Ensure road ahead is clear"),
|
||||
ET.PERMANENT: NormalPermanentAlert("纵向操纵模式",
|
||||
"确保前方道路空旷"),
|
||||
},
|
||||
|
||||
EventName.lateralManeuver: {
|
||||
ET.WARNING: longitudinal_maneuver_alert,
|
||||
ET.PERMANENT: NormalPermanentAlert("Lateral Maneuver Mode"),
|
||||
ET.PERMANENT: NormalPermanentAlert("横向操纵模式"),
|
||||
},
|
||||
|
||||
EventName.selfdriveInitializing: {
|
||||
ET.NO_ENTRY: NoEntryAlert("System Initializing"),
|
||||
ET.NO_ENTRY: NoEntryAlert("系统初始化中"),
|
||||
},
|
||||
|
||||
EventName.startup: {
|
||||
ET.PERMANENT: StartupAlert("Be ready to take over at any time")
|
||||
ET.PERMANENT: StartupAlert("随时准备接管")
|
||||
},
|
||||
|
||||
EventName.startupMaster: {
|
||||
@@ -253,28 +253,28 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
|
||||
},
|
||||
|
||||
EventName.startupNoControl: {
|
||||
ET.PERMANENT: StartupAlert("Dashcam mode"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Dashcam mode"),
|
||||
ET.PERMANENT: StartupAlert("行车记录仪模式"),
|
||||
ET.NO_ENTRY: NoEntryAlert("行车记录仪模式"),
|
||||
},
|
||||
|
||||
EventName.startupNoCar: {
|
||||
ET.PERMANENT: StartupAlert("Dashcam mode for unsupported car"),
|
||||
ET.PERMANENT: StartupAlert("不支持的车型,进入行车记录仪模式"),
|
||||
},
|
||||
|
||||
EventName.startupNoSecOcKey: {
|
||||
ET.PERMANENT: NormalPermanentAlert("Dashcam Mode",
|
||||
"Security Key Not Available",
|
||||
ET.PERMANENT: NormalPermanentAlert("行车记录仪模式",
|
||||
"安全密钥不可用",
|
||||
priority=Priority.HIGH),
|
||||
},
|
||||
|
||||
EventName.dashcamMode: {
|
||||
ET.PERMANENT: NormalPermanentAlert("Dashcam Mode",
|
||||
ET.PERMANENT: NormalPermanentAlert("行车记录仪模式",
|
||||
priority=Priority.LOWEST),
|
||||
},
|
||||
|
||||
EventName.invalidLkasSetting: {
|
||||
ET.PERMANENT: invalid_lkas_setting_alert,
|
||||
ET.NO_ENTRY: NoEntryAlert("Invalid LKAS setting"),
|
||||
ET.NO_ENTRY: NoEntryAlert("LKAS 设置无效"),
|
||||
},
|
||||
|
||||
EventName.cruiseMismatch: {
|
||||
@@ -285,44 +285,44 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
|
||||
# read-only mode. This can be solved by adding your fingerprint.
|
||||
# See https://github.com/commaai/openpilot/wiki/Fingerprinting for more information
|
||||
EventName.carUnrecognized: {
|
||||
ET.PERMANENT: NormalPermanentAlert("Dashcam Mode",
|
||||
"Car Unrecognized",
|
||||
ET.PERMANENT: NormalPermanentAlert("行车记录仪模式",
|
||||
"车型未识别",
|
||||
priority=Priority.LOWEST),
|
||||
},
|
||||
|
||||
EventName.aeb: {
|
||||
ET.PERMANENT: Alert(
|
||||
"BRAKE!",
|
||||
"Emergency Braking: Risk of Collision",
|
||||
"刹车!",
|
||||
"紧急刹车:碰撞风险",
|
||||
AlertStatus.critical, AlertSize.full,
|
||||
Priority.HIGHEST, VisualAlert.fcw, AudibleAlert.none, 2.),
|
||||
ET.NO_ENTRY: NoEntryAlert("AEB: Risk of Collision"),
|
||||
ET.NO_ENTRY: NoEntryAlert("AEB:碰撞风险"),
|
||||
},
|
||||
|
||||
EventName.stockAeb: {
|
||||
ET.PERMANENT: Alert(
|
||||
"BRAKE!",
|
||||
"Stock AEB: Risk of Collision",
|
||||
"刹车!",
|
||||
"原车 AEB:碰撞风险",
|
||||
AlertStatus.critical, AlertSize.full,
|
||||
Priority.HIGHEST, VisualAlert.fcw, AudibleAlert.none, 2.),
|
||||
ET.NO_ENTRY: NoEntryAlert("Stock AEB: Risk of Collision"),
|
||||
ET.NO_ENTRY: NoEntryAlert("原车 AEB:碰撞风险"),
|
||||
},
|
||||
|
||||
EventName.stockLkas: {
|
||||
ET.NO_ENTRY: NoEntryAlert("Stock LKAS: Lane Departure Detected"),
|
||||
ET.NO_ENTRY: NoEntryAlert("原车 LKAS:检测到车道偏离"),
|
||||
},
|
||||
|
||||
EventName.fcw: {
|
||||
ET.PERMANENT: Alert(
|
||||
"BRAKE!",
|
||||
"Risk of Collision",
|
||||
"刹车!",
|
||||
"碰撞风险",
|
||||
AlertStatus.critical, AlertSize.full,
|
||||
Priority.HIGHEST, VisualAlert.fcw, AudibleAlert.warningSoft, 2.),
|
||||
},
|
||||
|
||||
EventName.ldw: {
|
||||
ET.PERMANENT: Alert(
|
||||
"Lane Departure Detected",
|
||||
"检测到车道偏离",
|
||||
"",
|
||||
AlertStatus.userPrompt, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.ldw, AudibleAlert.prompt, 3.),
|
||||
@@ -332,7 +332,7 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
|
||||
|
||||
EventName.steerTempUnavailableSilent: {
|
||||
ET.WARNING: Alert(
|
||||
"Steering Assist Temporarily Unavailable",
|
||||
"转向辅助暂时不可用",
|
||||
"",
|
||||
AlertStatus.userPrompt, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.prompt, 1.8),
|
||||
@@ -340,7 +340,7 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
|
||||
|
||||
EventName.driverDistracted1: {
|
||||
ET.PERMANENT: Alert(
|
||||
"Pay Attention",
|
||||
"请注意路况",
|
||||
"",
|
||||
AlertStatus.normal, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, .1),
|
||||
@@ -348,23 +348,23 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
|
||||
|
||||
EventName.driverDistracted2: {
|
||||
ET.PERMANENT: Alert(
|
||||
"Pay Attention",
|
||||
"Driver Distracted",
|
||||
"请注意路况",
|
||||
"驾驶分心",
|
||||
AlertStatus.userPrompt, AlertSize.mid,
|
||||
Priority.MID, VisualAlert.steerRequired, AudibleAlert.promptDistracted, .1),
|
||||
},
|
||||
|
||||
EventName.driverDistracted3: {
|
||||
ET.PERMANENT: Alert(
|
||||
"DISENGAGE IMMEDIATELY",
|
||||
"Driver Distracted",
|
||||
"立即退出",
|
||||
"驾驶分心",
|
||||
AlertStatus.critical, AlertSize.full,
|
||||
Priority.HIGH, VisualAlert.steerRequired, AudibleAlert.warningImmediate, .1),
|
||||
},
|
||||
|
||||
EventName.driverUnresponsive1: {
|
||||
ET.PERMANENT: Alert(
|
||||
"Touch Steering Wheel: No Face Detected",
|
||||
"请握住方向盘:未检测到面部",
|
||||
"",
|
||||
AlertStatus.normal, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.none, .1),
|
||||
@@ -372,31 +372,31 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
|
||||
|
||||
EventName.driverUnresponsive2: {
|
||||
ET.PERMANENT: Alert(
|
||||
"Touch Steering Wheel",
|
||||
"Driver Unresponsive",
|
||||
"请握住方向盘",
|
||||
"驾驶员无响应",
|
||||
AlertStatus.userPrompt, AlertSize.mid,
|
||||
Priority.MID, VisualAlert.steerRequired, AudibleAlert.promptDistracted, .1),
|
||||
},
|
||||
|
||||
EventName.driverUnresponsive3: {
|
||||
ET.PERMANENT: Alert(
|
||||
"DISENGAGE IMMEDIATELY",
|
||||
"Driver Unresponsive",
|
||||
"立即退出",
|
||||
"驾驶员无响应",
|
||||
AlertStatus.critical, AlertSize.full,
|
||||
Priority.HIGH, VisualAlert.steerRequired, AudibleAlert.warningImmediate, .1),
|
||||
},
|
||||
|
||||
EventName.manualRestart: {
|
||||
ET.WARNING: Alert(
|
||||
"TAKE CONTROL",
|
||||
"Resume Driving Manually",
|
||||
"请接管",
|
||||
"请手动恢复驾驶",
|
||||
AlertStatus.userPrompt, AlertSize.mid,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, .2),
|
||||
},
|
||||
|
||||
EventName.resumeRequired: {
|
||||
ET.WARNING: Alert(
|
||||
"Press Resume to Exit Standstill",
|
||||
"按 Resume 退出静止状态",
|
||||
"",
|
||||
AlertStatus.userPrompt, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, .2),
|
||||
@@ -408,7 +408,7 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
|
||||
|
||||
EventName.preLaneChangeLeft: {
|
||||
ET.WARNING: Alert(
|
||||
"Steer Left to Start Lane Change Once Safe",
|
||||
"确认安全后左转方向盘开始变道",
|
||||
"",
|
||||
AlertStatus.normal, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, .1),
|
||||
@@ -416,7 +416,7 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
|
||||
|
||||
EventName.preLaneChangeRight: {
|
||||
ET.WARNING: Alert(
|
||||
"Steer Right to Start Lane Change Once Safe",
|
||||
"确认安全后右转方向盘开始变道",
|
||||
"",
|
||||
AlertStatus.normal, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, .1),
|
||||
@@ -424,7 +424,7 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
|
||||
|
||||
EventName.laneChangeBlocked: {
|
||||
ET.WARNING: Alert(
|
||||
"Car Detected in Blindspot",
|
||||
"盲区检测到车辆",
|
||||
"",
|
||||
AlertStatus.userPrompt, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.prompt, .1),
|
||||
@@ -432,7 +432,7 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
|
||||
|
||||
EventName.laneChange: {
|
||||
ET.WARNING: Alert(
|
||||
"Changing Lanes",
|
||||
"正在变道",
|
||||
"",
|
||||
AlertStatus.normal, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, .1),
|
||||
@@ -440,41 +440,41 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
|
||||
|
||||
EventName.steerSaturated: {
|
||||
ET.WARNING: Alert(
|
||||
"Take Control",
|
||||
"Turn Exceeds Steering Limit",
|
||||
"请接管",
|
||||
"转向达到极限",
|
||||
AlertStatus.userPrompt, AlertSize.mid,
|
||||
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.promptRepeat, 2.),
|
||||
},
|
||||
|
||||
# Thrown when the fan is driven at >50% but is not rotating
|
||||
EventName.fanMalfunction: {
|
||||
ET.PERMANENT: NormalPermanentAlert("Fan Malfunction", "Likely Hardware Issue"),
|
||||
ET.PERMANENT: NormalPermanentAlert("风扇故障", "可能为硬件问题"),
|
||||
},
|
||||
|
||||
# Camera is not outputting frames
|
||||
EventName.cameraMalfunction: {
|
||||
ET.PERMANENT: camera_malfunction_alert,
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Camera Malfunction"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Camera Malfunction: Reboot Your Device"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("摄像头故障"),
|
||||
ET.NO_ENTRY: NoEntryAlert("摄像头故障:请重启设备"),
|
||||
},
|
||||
# Camera framerate too low
|
||||
EventName.cameraFrameRate: {
|
||||
ET.PERMANENT: NormalPermanentAlert("Camera Frame Rate Low", "Reboot your Device"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Camera Frame Rate Low"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Camera Frame Rate Low: Reboot Your Device"),
|
||||
ET.PERMANENT: NormalPermanentAlert("摄像头帧率过低", "请重启设备"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("摄像头帧率过低"),
|
||||
ET.NO_ENTRY: NoEntryAlert("摄像头帧率过低:请重启设备"),
|
||||
},
|
||||
|
||||
# Unused
|
||||
|
||||
EventName.locationdTemporaryError: {
|
||||
ET.NO_ENTRY: NoEntryAlert("locationd Temporary Error"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("locationd Temporary Error"),
|
||||
ET.NO_ENTRY: NoEntryAlert("locationd 临时错误"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("locationd 临时错误"),
|
||||
},
|
||||
|
||||
EventName.locationdPermanentError: {
|
||||
ET.NO_ENTRY: NoEntryAlert("locationd Permanent Error"),
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("locationd Permanent Error"),
|
||||
ET.PERMANENT: NormalPermanentAlert("locationd Permanent Error"),
|
||||
ET.NO_ENTRY: NoEntryAlert("locationd 永久错误"),
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("locationd 永久错误"),
|
||||
ET.PERMANENT: NormalPermanentAlert("locationd 永久错误"),
|
||||
},
|
||||
|
||||
# openpilot tries to learn certain parameters about your car by observing
|
||||
@@ -487,13 +487,13 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
|
||||
# bad alignment or bad sensor data. If this happens consistently consider creating an issue on GitHub
|
||||
EventName.paramsdTemporaryError: {
|
||||
ET.NO_ENTRY: paramsd_invalid_alert,
|
||||
ET.SOFT_DISABLE: soft_disable_alert("paramsd Temporary Error"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("paramsd 临时错误"),
|
||||
},
|
||||
|
||||
EventName.paramsdPermanentError: {
|
||||
ET.NO_ENTRY: NoEntryAlert("paramsd Permanent Error"),
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("paramsd Permanent Error"),
|
||||
ET.PERMANENT: NormalPermanentAlert("paramsd Permanent Error"),
|
||||
ET.NO_ENTRY: NoEntryAlert("paramsd 永久错误"),
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("paramsd 永久错误"),
|
||||
ET.PERMANENT: NormalPermanentAlert("paramsd 永久错误"),
|
||||
},
|
||||
|
||||
# ********** events that affect controls state transitions **********
|
||||
@@ -512,12 +512,12 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
|
||||
|
||||
EventName.buttonCancel: {
|
||||
ET.USER_DISABLE: EngagementAlert(AudibleAlert.disengage),
|
||||
ET.NO_ENTRY: NoEntryAlert("Cancel Pressed"),
|
||||
ET.NO_ENTRY: NoEntryAlert("已按下取消"),
|
||||
},
|
||||
|
||||
EventName.brakeHold: {
|
||||
ET.WARNING: Alert(
|
||||
"Press Resume to Exit Brake Hold",
|
||||
"按 Resume 退出刹车保持",
|
||||
"",
|
||||
AlertStatus.userPrompt, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, .2),
|
||||
@@ -525,23 +525,23 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
|
||||
|
||||
EventName.parkBrake: {
|
||||
ET.USER_DISABLE: EngagementAlert(AudibleAlert.disengage),
|
||||
ET.NO_ENTRY: NoEntryAlert("Parking Brake Engaged"),
|
||||
ET.NO_ENTRY: NoEntryAlert("手刹已拉起"),
|
||||
},
|
||||
|
||||
EventName.pedalPressed: {
|
||||
ET.USER_DISABLE: EngagementAlert(AudibleAlert.disengage),
|
||||
ET.NO_ENTRY: NoEntryAlert("Pedal Pressed",
|
||||
ET.NO_ENTRY: NoEntryAlert("已踩下踏板",
|
||||
visual_alert=VisualAlert.brakePressed),
|
||||
},
|
||||
|
||||
EventName.steerDisengage: {
|
||||
ET.USER_DISABLE: EngagementAlert(AudibleAlert.disengage),
|
||||
ET.NO_ENTRY: NoEntryAlert("Steering Pressed"),
|
||||
ET.NO_ENTRY: NoEntryAlert("已转动方向盘"),
|
||||
},
|
||||
|
||||
EventName.preEnableStandstill: {
|
||||
ET.PRE_ENABLE: Alert(
|
||||
"Release Brake to Engage",
|
||||
"松开刹车以开启",
|
||||
"",
|
||||
AlertStatus.normal, AlertSize.small,
|
||||
Priority.LOWEST, VisualAlert.none, AudibleAlert.none, .1, creation_delay=1.),
|
||||
@@ -569,27 +569,27 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
|
||||
},
|
||||
|
||||
EventName.resumeBlocked: {
|
||||
ET.NO_ENTRY: NoEntryAlert("Press Set to Engage"),
|
||||
ET.NO_ENTRY: NoEntryAlert("按 Set 以开启"),
|
||||
},
|
||||
|
||||
EventName.wrongCruiseMode: {
|
||||
ET.USER_DISABLE: EngagementAlert(AudibleAlert.disengage),
|
||||
ET.NO_ENTRY: NoEntryAlert("Adaptive Cruise Disabled"),
|
||||
ET.NO_ENTRY: NoEntryAlert("自适应巡航已禁用"),
|
||||
},
|
||||
|
||||
EventName.steerTempUnavailable: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Steering Assist Temporarily Unavailable"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Steering Temporarily Unavailable"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("转向辅助暂时不可用"),
|
||||
ET.NO_ENTRY: NoEntryAlert("转向暂时不可用"),
|
||||
},
|
||||
|
||||
EventName.steerTimeLimit: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Vehicle Steering Time Limit"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Vehicle Steering Time Limit"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("车辆转向时间限制"),
|
||||
ET.NO_ENTRY: NoEntryAlert("车辆转向时间限制"),
|
||||
},
|
||||
|
||||
EventName.outOfSpace: {
|
||||
ET.PERMANENT: out_of_space_alert,
|
||||
ET.NO_ENTRY: NoEntryAlert("Out of Storage"),
|
||||
ET.NO_ENTRY: NoEntryAlert("存储空间不足"),
|
||||
},
|
||||
|
||||
EventName.belowEngageSpeed: {
|
||||
@@ -598,35 +598,35 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
|
||||
|
||||
EventName.sensorDataInvalid: {
|
||||
ET.PERMANENT: Alert(
|
||||
"Sensor Data Invalid",
|
||||
"Possible Hardware Issue",
|
||||
"传感器数据无效",
|
||||
"可能为硬件问题",
|
||||
AlertStatus.normal, AlertSize.mid,
|
||||
Priority.LOWER, VisualAlert.none, AudibleAlert.none, .2, creation_delay=1.),
|
||||
ET.NO_ENTRY: NoEntryAlert("Sensor Data Invalid"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Sensor Data Invalid"),
|
||||
ET.NO_ENTRY: NoEntryAlert("传感器数据无效"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("传感器数据无效"),
|
||||
},
|
||||
|
||||
EventName.noGps: {
|
||||
},
|
||||
|
||||
EventName.tooDistracted: {
|
||||
ET.NO_ENTRY: NoEntryAlert("Distraction Level Too High"),
|
||||
ET.NO_ENTRY: NoEntryAlert("分心程度过高"),
|
||||
},
|
||||
|
||||
EventName.excessiveActuation: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Excessive Actuation"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Excessive Actuation"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("执行器过度动作"),
|
||||
ET.NO_ENTRY: NoEntryAlert("执行器过度动作"),
|
||||
},
|
||||
|
||||
EventName.overheat: {
|
||||
ET.PERMANENT: overheat_alert,
|
||||
ET.SOFT_DISABLE: soft_disable_alert("System Overheated"),
|
||||
ET.NO_ENTRY: NoEntryAlert("System Overheated"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("系统过热"),
|
||||
ET.NO_ENTRY: NoEntryAlert("系统过热"),
|
||||
},
|
||||
|
||||
EventName.wrongGear: {
|
||||
ET.SOFT_DISABLE: user_soft_disable_alert("Gear not D"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Gear not D"),
|
||||
ET.SOFT_DISABLE: user_soft_disable_alert("不在 D 档"),
|
||||
ET.NO_ENTRY: NoEntryAlert("不在 D 档"),
|
||||
},
|
||||
|
||||
# This alert is thrown when the calibration angles are outside of the acceptable range.
|
||||
@@ -636,40 +636,40 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
|
||||
# See https://comma.ai/setup for more information
|
||||
EventName.calibrationInvalid: {
|
||||
ET.PERMANENT: calibration_invalid_alert,
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Calibration Invalid: Remount Device & Recalibrate"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Calibration Invalid: Remount Device & Recalibrate"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("标定无效:重新安装设备并重新标定"),
|
||||
ET.NO_ENTRY: NoEntryAlert("标定无效:重新安装设备并重新标定"),
|
||||
},
|
||||
|
||||
EventName.calibrationIncomplete: {
|
||||
ET.PERMANENT: calibration_incomplete_alert,
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Calibration Incomplete"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Calibration in Progress"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("标定未完成"),
|
||||
ET.NO_ENTRY: NoEntryAlert("标定进行中"),
|
||||
},
|
||||
|
||||
EventName.calibrationRecalibrating: {
|
||||
ET.PERMANENT: calibration_incomplete_alert,
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Device Remount Detected: Recalibrating"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Remount Detected: Recalibrating"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("检测到设备重装:正在重新标定"),
|
||||
ET.NO_ENTRY: NoEntryAlert("检测到重装:正在重新标定"),
|
||||
},
|
||||
|
||||
EventName.doorOpen: {
|
||||
ET.SOFT_DISABLE: user_soft_disable_alert("Door Open"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Door Open"),
|
||||
ET.SOFT_DISABLE: user_soft_disable_alert("车门打开"),
|
||||
ET.NO_ENTRY: NoEntryAlert("车门打开"),
|
||||
},
|
||||
|
||||
EventName.seatbeltNotLatched: {
|
||||
ET.SOFT_DISABLE: user_soft_disable_alert("Seatbelt Unlatched"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Seatbelt Unlatched"),
|
||||
ET.SOFT_DISABLE: user_soft_disable_alert("安全带未系"),
|
||||
ET.NO_ENTRY: NoEntryAlert("安全带未系"),
|
||||
},
|
||||
|
||||
EventName.espDisabled: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Electronic Stability Control Disabled"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Electronic Stability Control Disabled"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("车身稳定系统已关闭"),
|
||||
ET.NO_ENTRY: NoEntryAlert("车身稳定系统已关闭"),
|
||||
},
|
||||
|
||||
EventName.lowBattery: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Low Battery"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Low Battery"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("电池电量低"),
|
||||
ET.NO_ENTRY: NoEntryAlert("电池电量低"),
|
||||
},
|
||||
|
||||
# Different openpilot services communicate between each other at a certain
|
||||
@@ -677,41 +677,41 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
|
||||
# is thrown. This can mean a service crashed, did not broadcast a message for
|
||||
# ten times the regular interval, or the average interval is more than 10% too high.
|
||||
EventName.commIssue: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Communication Issue Between Processes"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("进程间通信异常"),
|
||||
ET.NO_ENTRY: comm_issue_alert,
|
||||
},
|
||||
EventName.commIssueAvgFreq: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Low Communication Rate Between Processes"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Low Communication Rate Between Processes"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("进程间通信频率过低"),
|
||||
ET.NO_ENTRY: NoEntryAlert("进程间通信频率过低"),
|
||||
},
|
||||
|
||||
EventName.selfdrivedLagging: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("System Lagging"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Selfdrive Process Lagging: Reboot Your Device"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("系统延迟"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Selfdrive 进程延迟:请重启设备"),
|
||||
},
|
||||
|
||||
# Thrown when manager detects a service exited unexpectedly while driving
|
||||
EventName.processNotRunning: {
|
||||
ET.NO_ENTRY: process_not_running_alert,
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Process Not Running"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("进程未运行"),
|
||||
},
|
||||
|
||||
EventName.radarFault: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Radar Error: Restart the Car"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Radar Error: Restart the Car"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("雷达错误:请重启车辆"),
|
||||
ET.NO_ENTRY: NoEntryAlert("雷达错误:请重启车辆"),
|
||||
},
|
||||
|
||||
EventName.radarTempUnavailable: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Radar Temporarily Unavailable"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Radar Temporarily Unavailable"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("雷达暂时不可用"),
|
||||
ET.NO_ENTRY: NoEntryAlert("雷达暂时不可用"),
|
||||
},
|
||||
|
||||
# Every frame from the camera should be processed by the model. If modeld
|
||||
# is not processing frames fast enough they have to be dropped. This alert is
|
||||
# thrown when over 20% of frames are dropped.
|
||||
EventName.modeldLagging: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Driving Model Lagging"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Driving Model Lagging"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("驾驶模型延迟"),
|
||||
ET.NO_ENTRY: NoEntryAlert("驾驶模型延迟"),
|
||||
ET.PERMANENT: modeld_lagging_alert,
|
||||
},
|
||||
|
||||
@@ -721,45 +721,45 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
|
||||
# usually means the model has trouble understanding the scene. This is used
|
||||
# as a heuristic to warn the driver.
|
||||
EventName.posenetInvalid: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Posenet Speed Invalid"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Posenet 速度无效"),
|
||||
ET.NO_ENTRY: posenet_invalid_alert,
|
||||
},
|
||||
|
||||
# When the localizer detects an acceleration of more than 40 m/s^2 (~4G) we
|
||||
# alert the driver the device might have fallen from the windshield.
|
||||
EventName.deviceFalling: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Device Fell Off Mount"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Device Fell Off Mount"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("设备从支架掉落"),
|
||||
ET.NO_ENTRY: NoEntryAlert("设备从支架掉落"),
|
||||
},
|
||||
|
||||
EventName.lowMemory: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Low Memory: Reboot Your Device"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("内存不足:请重启设备"),
|
||||
ET.PERMANENT: low_memory_alert,
|
||||
ET.NO_ENTRY: NoEntryAlert("Low Memory: Reboot Your Device"),
|
||||
ET.NO_ENTRY: NoEntryAlert("内存不足:请重启设备"),
|
||||
},
|
||||
|
||||
EventName.accFaulted: {
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("Cruise Fault: Restart the Car"),
|
||||
ET.PERMANENT: NormalPermanentAlert("Cruise Fault: Restart the car to engage"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Cruise Fault: Restart the Car"),
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("巡航故障:请重启车辆"),
|
||||
ET.PERMANENT: NormalPermanentAlert("巡航故障:重启车辆后可开启"),
|
||||
ET.NO_ENTRY: NoEntryAlert("巡航故障:请重启车辆"),
|
||||
},
|
||||
|
||||
EventName.espActive: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Electronic Stability Control Active"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Electronic Stability Control Active"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("车身稳定系统已激活"),
|
||||
ET.NO_ENTRY: NoEntryAlert("车身稳定系统已激活"),
|
||||
},
|
||||
|
||||
EventName.controlsMismatch: {
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("Controls Mismatch"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Controls Mismatch"),
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("控制不匹配"),
|
||||
ET.NO_ENTRY: NoEntryAlert("控制不匹配"),
|
||||
},
|
||||
|
||||
# Sometimes the USB stack on the device can get into a bad state
|
||||
# causing the connection to the panda to be lost
|
||||
EventName.usbError: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("USB Error: Reboot Your Device"),
|
||||
ET.PERMANENT: NormalPermanentAlert("USB Error: Reboot Your Device"),
|
||||
ET.NO_ENTRY: NoEntryAlert("USB Error: Reboot Your Device"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("USB 错误:请重启设备"),
|
||||
ET.PERMANENT: NormalPermanentAlert("USB 错误:请重启设备"),
|
||||
ET.NO_ENTRY: NoEntryAlert("USB 错误:请重启设备"),
|
||||
},
|
||||
|
||||
# This alert can be thrown for the following reasons:
|
||||
@@ -767,45 +767,45 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
|
||||
# - CAN data is received, but some message are not received at the right frequency
|
||||
# If you're not writing a new car port, this is usually cause by faulty wiring
|
||||
EventName.canError: {
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("Unknown Vehicle Variant"),
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("未知车型变体"),
|
||||
ET.PERMANENT: Alert(
|
||||
"Unknown Vehicle Variant",
|
||||
"未知车型变体",
|
||||
"",
|
||||
AlertStatus.normal, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, 1., creation_delay=1.),
|
||||
ET.NO_ENTRY: NoEntryAlert("Unknown Vehicle Variant"),
|
||||
ET.NO_ENTRY: NoEntryAlert("未知车型变体"),
|
||||
},
|
||||
|
||||
EventName.canBusMissing: {
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("CAN Bus Disconnected"),
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("CAN 总线断开"),
|
||||
ET.PERMANENT: Alert(
|
||||
"CAN Bus Disconnected: Likely Faulty Cable",
|
||||
"CAN 总线断开:可能为线缆故障",
|
||||
"",
|
||||
AlertStatus.normal, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, 1., creation_delay=1.),
|
||||
ET.NO_ENTRY: NoEntryAlert("CAN Bus Disconnected: Check Connections"),
|
||||
ET.NO_ENTRY: NoEntryAlert("CAN 总线断开:请检查连接"),
|
||||
},
|
||||
|
||||
EventName.steerUnavailable: {
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("LKAS Fault: Restart the Car"),
|
||||
ET.PERMANENT: NormalPermanentAlert("LKAS Fault: Restart the car to engage"),
|
||||
ET.NO_ENTRY: NoEntryAlert("LKAS Fault: Restart the Car"),
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("LKAS故障:请重启车辆"),
|
||||
ET.PERMANENT: NormalPermanentAlert("LKAS故障:重启车辆后可开启"),
|
||||
ET.NO_ENTRY: NoEntryAlert("LKAS故障:请重启车辆"),
|
||||
},
|
||||
|
||||
EventName.reverseGear: {
|
||||
ET.PERMANENT: Alert(
|
||||
"Reverse\nGear",
|
||||
"倒车\n档位",
|
||||
"",
|
||||
AlertStatus.normal, AlertSize.full,
|
||||
Priority.LOWEST, VisualAlert.none, AudibleAlert.none, .2, creation_delay=0.5),
|
||||
ET.USER_DISABLE: ImmediateDisableAlert("Reverse Gear"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Reverse Gear"),
|
||||
ET.USER_DISABLE: ImmediateDisableAlert("倒车档位"),
|
||||
ET.NO_ENTRY: NoEntryAlert("倒车档位"),
|
||||
},
|
||||
|
||||
# On cars that use stock ACC the car can decide to cancel ACC for various reasons.
|
||||
# When this happens we can no long control the car so the user needs to be warned immediately.
|
||||
EventName.cruiseDisabled: {
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("Cruise Is Off"),
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("巡航已关闭"),
|
||||
},
|
||||
|
||||
# When the relay in the harness box opens the CAN bus between the LKAS camera
|
||||
@@ -813,15 +813,15 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
|
||||
# are received on the car side this usually means the relay hasn't opened correctly
|
||||
# and this alert is thrown.
|
||||
EventName.relayMalfunction: {
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("Harness Relay Malfunction"),
|
||||
ET.PERMANENT: NormalPermanentAlert("Harness Relay Malfunction", "Check Hardware"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Harness Relay Malfunction"),
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("线束继电器故障"),
|
||||
ET.PERMANENT: NormalPermanentAlert("线束继电器故障", "请检查硬件"),
|
||||
ET.NO_ENTRY: NoEntryAlert("线束继电器故障"),
|
||||
},
|
||||
|
||||
EventName.speedTooLow: {
|
||||
ET.IMMEDIATE_DISABLE: Alert(
|
||||
"openpilot Canceled",
|
||||
"Speed too low",
|
||||
"openpilot 已取消",
|
||||
"速度过低",
|
||||
AlertStatus.normal, AlertSize.mid,
|
||||
Priority.HIGH, VisualAlert.none, AudibleAlert.disengage, 3.),
|
||||
},
|
||||
@@ -829,17 +829,17 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
|
||||
# When the car is driving faster than most cars in the training data, the model outputs can be unpredictable.
|
||||
EventName.speedTooHigh: {
|
||||
ET.WARNING: Alert(
|
||||
"Speed Too High",
|
||||
"Model uncertain at this speed",
|
||||
"速度过高",
|
||||
"模型在此速度下不确定",
|
||||
AlertStatus.userPrompt, AlertSize.mid,
|
||||
Priority.HIGH, VisualAlert.steerRequired, AudibleAlert.promptRepeat, 4.),
|
||||
ET.NO_ENTRY: NoEntryAlert("Slow down to engage"),
|
||||
ET.NO_ENTRY: NoEntryAlert("请减速后开启"),
|
||||
},
|
||||
|
||||
EventName.vehicleSensorsInvalid: {
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("Vehicle Sensors Invalid"),
|
||||
ET.PERMANENT: NormalPermanentAlert("Vehicle Sensors Calibrating", "Drive to Calibrate"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Vehicle Sensors Calibrating"),
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("车辆传感器无效"),
|
||||
ET.PERMANENT: NormalPermanentAlert("车辆传感器校准中", "行驶即可完成标定"),
|
||||
ET.NO_ENTRY: NoEntryAlert("车辆传感器校准中"),
|
||||
},
|
||||
|
||||
EventName.personalityChanged: {
|
||||
@@ -847,7 +847,7 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
|
||||
},
|
||||
|
||||
EventName.userBookmark: {
|
||||
ET.PERMANENT: NormalPermanentAlert("Bookmark Saved", duration=1.5),
|
||||
ET.PERMANENT: NormalPermanentAlert("书签已保存", duration=1.5),
|
||||
},
|
||||
|
||||
EventName.audioFeedback: {
|
||||
@@ -860,66 +860,66 @@ if HARDWARE.get_device_type() == 'mici':
|
||||
EVENTS.update({
|
||||
EventName.driverDistracted1: {
|
||||
ET.PERMANENT: Alert(
|
||||
"Pay Attention",
|
||||
"请注意路况",
|
||||
"",
|
||||
AlertStatus.normal, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, 2),
|
||||
},
|
||||
EventName.driverDistracted2: {
|
||||
ET.PERMANENT: Alert(
|
||||
"Pay Attention",
|
||||
"Driver Distracted",
|
||||
"请注意路况",
|
||||
"驾驶分心",
|
||||
AlertStatus.userPrompt, AlertSize.mid,
|
||||
Priority.MID, VisualAlert.steerRequired, AudibleAlert.promptDistracted, 1),
|
||||
},
|
||||
EventName.resumeRequired: {
|
||||
ET.WARNING: Alert(
|
||||
"Press Resume",
|
||||
"按 Resume",
|
||||
"",
|
||||
AlertStatus.userPrompt, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, .2),
|
||||
},
|
||||
EventName.preLaneChangeLeft: {
|
||||
ET.WARNING: Alert(
|
||||
"Steer Left",
|
||||
"Confirm Lane Change",
|
||||
"向左转向",
|
||||
"确认变道",
|
||||
AlertStatus.normal, AlertSize.mid,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, .1),
|
||||
},
|
||||
EventName.preLaneChangeRight: {
|
||||
ET.WARNING: Alert(
|
||||
"Steer Right",
|
||||
"Confirm Lane Change",
|
||||
"向右转向",
|
||||
"确认变道",
|
||||
AlertStatus.normal, AlertSize.mid,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, .1),
|
||||
},
|
||||
EventName.laneChangeBlocked: {
|
||||
ET.WARNING: Alert(
|
||||
"Car in Blindspot",
|
||||
"盲区有车辆",
|
||||
"",
|
||||
AlertStatus.userPrompt, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.prompt, .1),
|
||||
},
|
||||
EventName.steerSaturated: {
|
||||
ET.WARNING: Alert(
|
||||
"take control",
|
||||
"turn exceeds limit",
|
||||
"请接管",
|
||||
"转向超过限制",
|
||||
AlertStatus.userPrompt, AlertSize.mid,
|
||||
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.promptRepeat, 2.),
|
||||
},
|
||||
EventName.calibrationIncomplete: {
|
||||
ET.PERMANENT: calibration_incomplete_alert,
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Calibration Incomplete"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Calibrating"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("标定未完成"),
|
||||
ET.NO_ENTRY: NoEntryAlert("标定中"),
|
||||
},
|
||||
EventName.reverseGear: {
|
||||
ET.PERMANENT: Alert(
|
||||
"Reverse",
|
||||
"倒车",
|
||||
"",
|
||||
AlertStatus.normal, AlertSize.full,
|
||||
Priority.LOWEST, VisualAlert.none, AudibleAlert.none, .2, creation_delay=0.5),
|
||||
ET.USER_DISABLE: ImmediateDisableAlert("Reverse"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Reverse"),
|
||||
ET.USER_DISABLE: ImmediateDisableAlert("倒车"),
|
||||
ET.NO_ENTRY: NoEntryAlert("倒车"),
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
Executable
+953
@@ -0,0 +1,953 @@
|
||||
#!/usr/bin/env python3
|
||||
import math
|
||||
import os
|
||||
|
||||
from cereal import log, car
|
||||
import cereal.messaging as messaging
|
||||
from openpilot.common.constants import CV
|
||||
from openpilot.common.git import get_short_branch
|
||||
from openpilot.common.realtime import DT_CTRL
|
||||
from openpilot.selfdrive.locationd.calibrationd import MIN_SPEED_FILTER
|
||||
from openpilot.system.micd import SAMPLE_RATE, SAMPLE_BUFFER
|
||||
from openpilot.selfdrive.ui.feedback.feedbackd import FEEDBACK_MAX_DURATION
|
||||
from openpilot.system.hardware import HARDWARE
|
||||
|
||||
from openpilot.sunnypilot.selfdrive.selfdrived.events_base import EventsBase, Priority, ET, Alert, \
|
||||
NoEntryAlert, SoftDisableAlert, UserSoftDisableAlert, ImmediateDisableAlert, EngagementAlert, NormalPermanentAlert, \
|
||||
StartupAlert, AlertCallbackType, wrong_car_mode_alert
|
||||
|
||||
|
||||
AlertSize = log.SelfdriveState.AlertSize
|
||||
AlertStatus = log.SelfdriveState.AlertStatus
|
||||
VisualAlert = car.CarControl.HUDControl.VisualAlert
|
||||
AudibleAlert = car.CarControl.HUDControl.AudibleAlert
|
||||
EventName = log.OnroadEvent.EventName
|
||||
|
||||
|
||||
# get event name from enum
|
||||
EVENT_NAME = {v: k for k, v in EventName.schema.enumerants.items()}
|
||||
|
||||
|
||||
class Events(EventsBase):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.event_counters = dict.fromkeys(EVENTS.keys(), 0)
|
||||
|
||||
def get_events_mapping(self) -> dict[int, dict[str, Alert | AlertCallbackType]]:
|
||||
return EVENTS
|
||||
|
||||
def get_event_name(self, event: int):
|
||||
return EVENT_NAME[event]
|
||||
|
||||
def get_event_msg_type(self):
|
||||
return log.OnroadEvent
|
||||
|
||||
|
||||
|
||||
# ********** helper functions **********
|
||||
def get_display_speed(speed_ms: float, metric: bool) -> str:
|
||||
speed = int(round(speed_ms * (CV.MS_TO_KPH if metric else CV.MS_TO_MPH)))
|
||||
unit = 'km/h' if metric else 'mph'
|
||||
return f"{speed} {unit}"
|
||||
|
||||
|
||||
# ********** alert callback functions **********
|
||||
|
||||
|
||||
def soft_disable_alert(alert_text_2: str) -> AlertCallbackType:
|
||||
def func(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
if soft_disable_time < int(0.5 / DT_CTRL):
|
||||
return ImmediateDisableAlert(alert_text_2)
|
||||
return SoftDisableAlert(alert_text_2)
|
||||
return func
|
||||
|
||||
def user_soft_disable_alert(alert_text_2: str) -> AlertCallbackType:
|
||||
def func(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
if soft_disable_time < int(0.5 / DT_CTRL):
|
||||
return ImmediateDisableAlert(alert_text_2)
|
||||
return UserSoftDisableAlert(alert_text_2)
|
||||
return func
|
||||
|
||||
def startup_master_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
branch = get_short_branch() # Ensure get_short_branch is cached to avoid lags on startup
|
||||
if "REPLAY" in os.environ:
|
||||
branch = "replay"
|
||||
|
||||
return StartupAlert("WARNING: This branch is not tested", branch, alert_status=AlertStatus.userPrompt)
|
||||
|
||||
def below_engage_speed_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
return NoEntryAlert(f"Drive above {get_display_speed(CP.minEnableSpeed, metric)} to engage")
|
||||
|
||||
|
||||
def below_steer_speed_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
return Alert(
|
||||
f"Steer Assist Unavailable Below {get_display_speed(CP.minSteerSpeed, metric)}",
|
||||
"",
|
||||
AlertStatus.userPrompt, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.prompt, 0.4)
|
||||
|
||||
|
||||
def calibration_incomplete_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
first_word = 'Recalibrating' if sm['liveCalibration'].calStatus == log.LiveCalibrationData.Status.recalibrating else 'Calibrating'
|
||||
return Alert(
|
||||
f"{first_word}: {sm['liveCalibration'].calPerc:.0f}%",
|
||||
f"Drive Above {get_display_speed(MIN_SPEED_FILTER, metric)}",
|
||||
AlertStatus.normal, AlertSize.mid,
|
||||
Priority.LOWEST, VisualAlert.none, AudibleAlert.none, .2)
|
||||
|
||||
|
||||
def audio_feedback_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
duration = FEEDBACK_MAX_DURATION - ((sm['audioFeedback'].blockNum + 1) * SAMPLE_BUFFER / SAMPLE_RATE)
|
||||
return NormalPermanentAlert(
|
||||
"Recording Audio Feedback",
|
||||
f"{round(duration)} second{'s' if round(duration) != 1 else ''} remaining. Press again to save early.",
|
||||
priority=Priority.LOW)
|
||||
|
||||
|
||||
# *** debug alerts ***
|
||||
|
||||
def out_of_space_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
full_perc = round(100. - sm['deviceState'].freeSpacePercent)
|
||||
return NormalPermanentAlert("Out of Storage", f"{full_perc}% full")
|
||||
|
||||
|
||||
def posenet_invalid_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
mdl = sm['modelV2'].velocity.x[0] if len(sm['modelV2'].velocity.x) else math.nan
|
||||
err = CS.vEgo - mdl
|
||||
msg = f"Speed Error: {err:.1f} m/s"
|
||||
return NoEntryAlert(msg, alert_text_1="Posenet Speed Invalid")
|
||||
|
||||
|
||||
def process_not_running_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
not_running = [p.name for p in sm['managerState'].processes if not p.running and p.shouldBeRunning]
|
||||
msg = ', '.join(not_running)
|
||||
return NoEntryAlert(msg, alert_text_1="Process Not Running")
|
||||
|
||||
|
||||
def comm_issue_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
bs = [s for s in sm.data.keys() if not sm.all_checks([s, ])]
|
||||
msg = ', '.join(bs[:4]) # can't fit too many on one line
|
||||
return NoEntryAlert(msg, alert_text_1="Communication Issue Between Processes")
|
||||
|
||||
|
||||
def camera_malfunction_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
all_cams = ('roadCameraState', 'driverCameraState', 'wideRoadCameraState')
|
||||
bad_cams = [s.replace('State', '') for s in all_cams if s in sm.data.keys() and not sm.all_checks([s, ])]
|
||||
return NormalPermanentAlert("Camera Malfunction", ', '.join(bad_cams))
|
||||
|
||||
|
||||
def calibration_invalid_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
rpy = sm['liveCalibration'].rpyCalib
|
||||
yaw = math.degrees(rpy[2] if len(rpy) == 3 else math.nan)
|
||||
pitch = math.degrees(rpy[1] if len(rpy) == 3 else math.nan)
|
||||
angles = f"Remount Device (Pitch: {pitch:.1f}°, Yaw: {yaw:.1f}°)"
|
||||
return NormalPermanentAlert("Calibration Invalid", angles)
|
||||
|
||||
|
||||
def paramsd_invalid_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
if not sm['liveParameters'].angleOffsetValid:
|
||||
angle_offset_deg = sm['liveParameters'].angleOffsetDeg
|
||||
title = "Steering misalignment detected"
|
||||
text = f"Angle offset too high (Offset: {angle_offset_deg:.1f}°)"
|
||||
elif not sm['liveParameters'].steerRatioValid:
|
||||
steer_ratio = sm['liveParameters'].steerRatio
|
||||
title = "Steer ratio mismatch"
|
||||
text = f"Steering rack geometry may be off (Ratio: {steer_ratio:.1f})"
|
||||
elif not sm['liveParameters'].stiffnessFactorValid:
|
||||
stiffness_factor = sm['liveParameters'].stiffnessFactor
|
||||
title = "Abnormal tire stiffness"
|
||||
text = f"Check tires, pressure, or alignment (Factor: {stiffness_factor:.1f})"
|
||||
else:
|
||||
return NoEntryAlert("paramsd Temporary Error")
|
||||
|
||||
return NoEntryAlert(alert_text_1=title, alert_text_2=text)
|
||||
|
||||
def overheat_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
cpu = max(sm['deviceState'].cpuTempC, default=0.)
|
||||
gpu = max(sm['deviceState'].gpuTempC, default=0.)
|
||||
temp = max((cpu, gpu, sm['deviceState'].memoryTempC))
|
||||
return NormalPermanentAlert("System Overheated", f"{temp:.0f} °C")
|
||||
|
||||
|
||||
def low_memory_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
return NormalPermanentAlert("Low Memory", f"{sm['deviceState'].memoryUsagePercent}% used")
|
||||
|
||||
|
||||
def high_cpu_usage_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
x = max(sm['deviceState'].cpuUsagePercent, default=0.)
|
||||
return NormalPermanentAlert("High CPU Usage", f"{x}% used")
|
||||
|
||||
|
||||
def modeld_lagging_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
return NormalPermanentAlert("Driving Model Lagging", f"{sm['modelV2'].frameDropPerc:.1f}% frames dropped")
|
||||
|
||||
|
||||
def joystick_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
gb = sm['carControl'].actuators.accel / 4.
|
||||
steer = sm['carControl'].actuators.torque
|
||||
vals = f"Gas: {round(gb * 100.)}%, Steer: {round(steer * 100.)}%"
|
||||
return NormalPermanentAlert("Joystick Mode", vals)
|
||||
|
||||
|
||||
def longitudinal_maneuver_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
ad = sm['alertDebug']
|
||||
audible_alert = AudibleAlert.prompt if 'Active' in ad.alertText1 else AudibleAlert.none
|
||||
alert_status = AlertStatus.userPrompt if 'Active' in ad.alertText1 else AlertStatus.normal
|
||||
alert_size = AlertSize.mid if ad.alertText2 else AlertSize.small
|
||||
return Alert(ad.alertText1, ad.alertText2,
|
||||
alert_status, alert_size,
|
||||
Priority.LOW, VisualAlert.none, audible_alert, 0.2)
|
||||
|
||||
|
||||
def personality_changed_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
personality = str(personality).title()
|
||||
return NormalPermanentAlert(f"Driving Personality: {personality}", duration=1.5)
|
||||
|
||||
|
||||
def invalid_lkas_setting_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert:
|
||||
text = "Toggle stock LKAS on or off to engage"
|
||||
if CP.brand == "tesla":
|
||||
text = "Switch to Traffic-Aware Cruise Control to engage"
|
||||
elif CP.brand == "mazda":
|
||||
text = "Enable your car's LKAS to engage"
|
||||
elif CP.brand == "nissan":
|
||||
text = "Disable your car's stock LKAS to engage"
|
||||
return NormalPermanentAlert("Invalid LKAS setting", text)
|
||||
|
||||
|
||||
|
||||
EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
|
||||
# ********** events with no alerts **********
|
||||
|
||||
EventName.stockFcw: {},
|
||||
EventName.actuatorsApiUnavailable: {},
|
||||
|
||||
# ********** events only containing alerts displayed in all states **********
|
||||
|
||||
EventName.joystickDebug: {
|
||||
ET.WARNING: joystick_alert,
|
||||
ET.PERMANENT: NormalPermanentAlert("Joystick Mode"),
|
||||
},
|
||||
|
||||
EventName.longitudinalManeuver: {
|
||||
ET.WARNING: longitudinal_maneuver_alert,
|
||||
ET.PERMANENT: NormalPermanentAlert("Longitudinal Maneuver Mode",
|
||||
"Ensure road ahead is clear"),
|
||||
},
|
||||
|
||||
EventName.lateralManeuver: {
|
||||
ET.WARNING: longitudinal_maneuver_alert,
|
||||
ET.PERMANENT: NormalPermanentAlert("Lateral Maneuver Mode"),
|
||||
},
|
||||
|
||||
EventName.selfdriveInitializing: {
|
||||
ET.NO_ENTRY: NoEntryAlert("System Initializing"),
|
||||
},
|
||||
|
||||
EventName.startup: {
|
||||
ET.PERMANENT: StartupAlert("Be ready to take over at any time")
|
||||
},
|
||||
|
||||
EventName.startupMaster: {
|
||||
ET.PERMANENT: startup_master_alert,
|
||||
},
|
||||
|
||||
EventName.startupNoControl: {
|
||||
ET.PERMANENT: StartupAlert("Dashcam mode"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Dashcam mode"),
|
||||
},
|
||||
|
||||
EventName.startupNoCar: {
|
||||
ET.PERMANENT: StartupAlert("Dashcam mode for unsupported car"),
|
||||
},
|
||||
|
||||
EventName.startupNoSecOcKey: {
|
||||
ET.PERMANENT: NormalPermanentAlert("Dashcam Mode",
|
||||
"Security Key Not Available",
|
||||
priority=Priority.HIGH),
|
||||
},
|
||||
|
||||
EventName.dashcamMode: {
|
||||
ET.PERMANENT: NormalPermanentAlert("Dashcam Mode",
|
||||
priority=Priority.LOWEST),
|
||||
},
|
||||
|
||||
EventName.invalidLkasSetting: {
|
||||
ET.PERMANENT: invalid_lkas_setting_alert,
|
||||
ET.NO_ENTRY: NoEntryAlert("Invalid LKAS setting"),
|
||||
},
|
||||
|
||||
EventName.cruiseMismatch: {
|
||||
#ET.PERMANENT: ImmediateDisableAlert("openpilot failed to cancel cruise"),
|
||||
},
|
||||
|
||||
# openpilot doesn't recognize the car. This switches openpilot into a
|
||||
# read-only mode. This can be solved by adding your fingerprint.
|
||||
# See https://github.com/commaai/openpilot/wiki/Fingerprinting for more information
|
||||
EventName.carUnrecognized: {
|
||||
ET.PERMANENT: NormalPermanentAlert("Dashcam Mode",
|
||||
"Car Unrecognized",
|
||||
priority=Priority.LOWEST),
|
||||
},
|
||||
|
||||
EventName.aeb: {
|
||||
ET.PERMANENT: Alert(
|
||||
"BRAKE!",
|
||||
"Emergency Braking: Risk of Collision",
|
||||
AlertStatus.critical, AlertSize.full,
|
||||
Priority.HIGHEST, VisualAlert.fcw, AudibleAlert.none, 2.),
|
||||
ET.NO_ENTRY: NoEntryAlert("AEB: Risk of Collision"),
|
||||
},
|
||||
|
||||
EventName.stockAeb: {
|
||||
ET.PERMANENT: Alert(
|
||||
"BRAKE!",
|
||||
"Stock AEB: Risk of Collision",
|
||||
AlertStatus.critical, AlertSize.full,
|
||||
Priority.HIGHEST, VisualAlert.fcw, AudibleAlert.none, 2.),
|
||||
ET.NO_ENTRY: NoEntryAlert("Stock AEB: Risk of Collision"),
|
||||
},
|
||||
|
||||
EventName.stockLkas: {
|
||||
ET.NO_ENTRY: NoEntryAlert("Stock LKAS: Lane Departure Detected"),
|
||||
},
|
||||
|
||||
EventName.fcw: {
|
||||
ET.PERMANENT: Alert(
|
||||
"BRAKE!",
|
||||
"Risk of Collision",
|
||||
AlertStatus.critical, AlertSize.full,
|
||||
Priority.HIGHEST, VisualAlert.fcw, AudibleAlert.warningSoft, 2.),
|
||||
},
|
||||
|
||||
EventName.ldw: {
|
||||
ET.PERMANENT: Alert(
|
||||
"Lane Departure Detected",
|
||||
"",
|
||||
AlertStatus.userPrompt, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.ldw, AudibleAlert.prompt, 3.),
|
||||
},
|
||||
|
||||
# ********** events only containing alerts that display while engaged **********
|
||||
|
||||
EventName.steerTempUnavailableSilent: {
|
||||
ET.WARNING: Alert(
|
||||
"Steering Assist Temporarily Unavailable",
|
||||
"",
|
||||
AlertStatus.userPrompt, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.prompt, 1.8),
|
||||
},
|
||||
|
||||
EventName.driverDistracted1: {
|
||||
ET.PERMANENT: Alert(
|
||||
"Pay Attention",
|
||||
"",
|
||||
AlertStatus.normal, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, .1),
|
||||
},
|
||||
|
||||
EventName.driverDistracted2: {
|
||||
ET.PERMANENT: Alert(
|
||||
"Pay Attention",
|
||||
"Driver Distracted",
|
||||
AlertStatus.userPrompt, AlertSize.mid,
|
||||
Priority.MID, VisualAlert.steerRequired, AudibleAlert.promptDistracted, .1),
|
||||
},
|
||||
|
||||
EventName.driverDistracted3: {
|
||||
ET.PERMANENT: Alert(
|
||||
"DISENGAGE IMMEDIATELY",
|
||||
"Driver Distracted",
|
||||
AlertStatus.critical, AlertSize.full,
|
||||
Priority.HIGH, VisualAlert.steerRequired, AudibleAlert.warningImmediate, .1),
|
||||
},
|
||||
|
||||
EventName.driverUnresponsive1: {
|
||||
ET.PERMANENT: Alert(
|
||||
"Touch Steering Wheel: No Face Detected",
|
||||
"",
|
||||
AlertStatus.normal, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.none, .1),
|
||||
},
|
||||
|
||||
EventName.driverUnresponsive2: {
|
||||
ET.PERMANENT: Alert(
|
||||
"Touch Steering Wheel",
|
||||
"Driver Unresponsive",
|
||||
AlertStatus.userPrompt, AlertSize.mid,
|
||||
Priority.MID, VisualAlert.steerRequired, AudibleAlert.promptDistracted, .1),
|
||||
},
|
||||
|
||||
EventName.driverUnresponsive3: {
|
||||
ET.PERMANENT: Alert(
|
||||
"DISENGAGE IMMEDIATELY",
|
||||
"Driver Unresponsive",
|
||||
AlertStatus.critical, AlertSize.full,
|
||||
Priority.HIGH, VisualAlert.steerRequired, AudibleAlert.warningImmediate, .1),
|
||||
},
|
||||
|
||||
EventName.manualRestart: {
|
||||
ET.WARNING: Alert(
|
||||
"TAKE CONTROL",
|
||||
"Resume Driving Manually",
|
||||
AlertStatus.userPrompt, AlertSize.mid,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, .2),
|
||||
},
|
||||
|
||||
EventName.resumeRequired: {
|
||||
ET.WARNING: Alert(
|
||||
"Press Resume to Exit Standstill",
|
||||
"",
|
||||
AlertStatus.userPrompt, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, .2),
|
||||
},
|
||||
|
||||
EventName.belowSteerSpeed: {
|
||||
ET.WARNING: below_steer_speed_alert,
|
||||
},
|
||||
|
||||
EventName.preLaneChangeLeft: {
|
||||
ET.WARNING: Alert(
|
||||
"Steer Left to Start Lane Change Once Safe",
|
||||
"",
|
||||
AlertStatus.normal, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, .1),
|
||||
},
|
||||
|
||||
EventName.preLaneChangeRight: {
|
||||
ET.WARNING: Alert(
|
||||
"Steer Right to Start Lane Change Once Safe",
|
||||
"",
|
||||
AlertStatus.normal, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, .1),
|
||||
},
|
||||
|
||||
EventName.laneChangeBlocked: {
|
||||
ET.WARNING: Alert(
|
||||
"Car Detected in Blindspot",
|
||||
"",
|
||||
AlertStatus.userPrompt, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.prompt, .1),
|
||||
},
|
||||
|
||||
EventName.laneChange: {
|
||||
ET.WARNING: Alert(
|
||||
"Changing Lanes",
|
||||
"",
|
||||
AlertStatus.normal, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, .1),
|
||||
},
|
||||
|
||||
EventName.steerSaturated: {
|
||||
ET.WARNING: Alert(
|
||||
"Take Control",
|
||||
"Turn Exceeds Steering Limit",
|
||||
AlertStatus.userPrompt, AlertSize.mid,
|
||||
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.promptRepeat, 2.),
|
||||
},
|
||||
|
||||
# Thrown when the fan is driven at >50% but is not rotating
|
||||
EventName.fanMalfunction: {
|
||||
ET.PERMANENT: NormalPermanentAlert("Fan Malfunction", "Likely Hardware Issue"),
|
||||
},
|
||||
|
||||
# Camera is not outputting frames
|
||||
EventName.cameraMalfunction: {
|
||||
ET.PERMANENT: camera_malfunction_alert,
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Camera Malfunction"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Camera Malfunction: Reboot Your Device"),
|
||||
},
|
||||
# Camera framerate too low
|
||||
EventName.cameraFrameRate: {
|
||||
ET.PERMANENT: NormalPermanentAlert("Camera Frame Rate Low", "Reboot your Device"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Camera Frame Rate Low"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Camera Frame Rate Low: Reboot Your Device"),
|
||||
},
|
||||
|
||||
# Unused
|
||||
|
||||
EventName.locationdTemporaryError: {
|
||||
ET.NO_ENTRY: NoEntryAlert("locationd Temporary Error"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("locationd Temporary Error"),
|
||||
},
|
||||
|
||||
EventName.locationdPermanentError: {
|
||||
ET.NO_ENTRY: NoEntryAlert("locationd Permanent Error"),
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("locationd Permanent Error"),
|
||||
ET.PERMANENT: NormalPermanentAlert("locationd Permanent Error"),
|
||||
},
|
||||
|
||||
# openpilot tries to learn certain parameters about your car by observing
|
||||
# how the car behaves to steering inputs from both human and openpilot driving.
|
||||
# This includes:
|
||||
# - steer ratio: gear ratio of the steering rack. Steering angle divided by tire angle
|
||||
# - tire stiffness: how much grip your tires have
|
||||
# - angle offset: most steering angle sensors are offset and measure a non zero angle when driving straight
|
||||
# This alert is thrown when any of these values exceed a sanity check. This can be caused by
|
||||
# bad alignment or bad sensor data. If this happens consistently consider creating an issue on GitHub
|
||||
EventName.paramsdTemporaryError: {
|
||||
ET.NO_ENTRY: paramsd_invalid_alert,
|
||||
ET.SOFT_DISABLE: soft_disable_alert("paramsd Temporary Error"),
|
||||
},
|
||||
|
||||
EventName.paramsdPermanentError: {
|
||||
ET.NO_ENTRY: NoEntryAlert("paramsd Permanent Error"),
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("paramsd Permanent Error"),
|
||||
ET.PERMANENT: NormalPermanentAlert("paramsd Permanent Error"),
|
||||
},
|
||||
|
||||
# ********** events that affect controls state transitions **********
|
||||
|
||||
EventName.pcmEnable: {
|
||||
ET.ENABLE: EngagementAlert(AudibleAlert.engage),
|
||||
},
|
||||
|
||||
EventName.buttonEnable: {
|
||||
ET.ENABLE: EngagementAlert(AudibleAlert.engage),
|
||||
},
|
||||
|
||||
EventName.pcmDisable: {
|
||||
ET.USER_DISABLE: EngagementAlert(AudibleAlert.disengage),
|
||||
},
|
||||
|
||||
EventName.buttonCancel: {
|
||||
ET.USER_DISABLE: EngagementAlert(AudibleAlert.disengage),
|
||||
ET.NO_ENTRY: NoEntryAlert("Cancel Pressed"),
|
||||
},
|
||||
|
||||
EventName.brakeHold: {
|
||||
ET.WARNING: Alert(
|
||||
"Press Resume to Exit Brake Hold",
|
||||
"",
|
||||
AlertStatus.userPrompt, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, .2),
|
||||
},
|
||||
|
||||
EventName.parkBrake: {
|
||||
ET.USER_DISABLE: EngagementAlert(AudibleAlert.disengage),
|
||||
ET.NO_ENTRY: NoEntryAlert("Parking Brake Engaged"),
|
||||
},
|
||||
|
||||
EventName.pedalPressed: {
|
||||
ET.USER_DISABLE: EngagementAlert(AudibleAlert.disengage),
|
||||
ET.NO_ENTRY: NoEntryAlert("Pedal Pressed",
|
||||
visual_alert=VisualAlert.brakePressed),
|
||||
},
|
||||
|
||||
EventName.steerDisengage: {
|
||||
ET.USER_DISABLE: EngagementAlert(AudibleAlert.disengage),
|
||||
ET.NO_ENTRY: NoEntryAlert("Steering Pressed"),
|
||||
},
|
||||
|
||||
EventName.preEnableStandstill: {
|
||||
ET.PRE_ENABLE: Alert(
|
||||
"Release Brake to Engage",
|
||||
"",
|
||||
AlertStatus.normal, AlertSize.small,
|
||||
Priority.LOWEST, VisualAlert.none, AudibleAlert.none, .1, creation_delay=1.),
|
||||
},
|
||||
|
||||
EventName.gasPressedOverride: {
|
||||
ET.OVERRIDE_LONGITUDINAL: Alert(
|
||||
"",
|
||||
"",
|
||||
AlertStatus.normal, AlertSize.none,
|
||||
Priority.LOWEST, VisualAlert.none, AudibleAlert.none, .1),
|
||||
},
|
||||
|
||||
EventName.steerOverride: {
|
||||
ET.OVERRIDE_LATERAL: Alert(
|
||||
"",
|
||||
"",
|
||||
AlertStatus.normal, AlertSize.none,
|
||||
Priority.LOWEST, VisualAlert.none, AudibleAlert.none, .1),
|
||||
},
|
||||
|
||||
EventName.wrongCarMode: {
|
||||
ET.USER_DISABLE: EngagementAlert(AudibleAlert.disengage),
|
||||
ET.NO_ENTRY: wrong_car_mode_alert,
|
||||
},
|
||||
|
||||
EventName.resumeBlocked: {
|
||||
ET.NO_ENTRY: NoEntryAlert("Press Set to Engage"),
|
||||
},
|
||||
|
||||
EventName.wrongCruiseMode: {
|
||||
ET.USER_DISABLE: EngagementAlert(AudibleAlert.disengage),
|
||||
ET.NO_ENTRY: NoEntryAlert("Adaptive Cruise Disabled"),
|
||||
},
|
||||
|
||||
EventName.steerTempUnavailable: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Steering Assist Temporarily Unavailable"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Steering Temporarily Unavailable"),
|
||||
},
|
||||
|
||||
EventName.steerTimeLimit: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Vehicle Steering Time Limit"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Vehicle Steering Time Limit"),
|
||||
},
|
||||
|
||||
EventName.outOfSpace: {
|
||||
ET.PERMANENT: out_of_space_alert,
|
||||
ET.NO_ENTRY: NoEntryAlert("Out of Storage"),
|
||||
},
|
||||
|
||||
EventName.belowEngageSpeed: {
|
||||
ET.NO_ENTRY: below_engage_speed_alert,
|
||||
},
|
||||
|
||||
EventName.sensorDataInvalid: {
|
||||
ET.PERMANENT: Alert(
|
||||
"Sensor Data Invalid",
|
||||
"Possible Hardware Issue",
|
||||
AlertStatus.normal, AlertSize.mid,
|
||||
Priority.LOWER, VisualAlert.none, AudibleAlert.none, .2, creation_delay=1.),
|
||||
ET.NO_ENTRY: NoEntryAlert("Sensor Data Invalid"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Sensor Data Invalid"),
|
||||
},
|
||||
|
||||
EventName.noGps: {
|
||||
},
|
||||
|
||||
EventName.tooDistracted: {
|
||||
ET.NO_ENTRY: NoEntryAlert("Distraction Level Too High"),
|
||||
},
|
||||
|
||||
EventName.excessiveActuation: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Excessive Actuation"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Excessive Actuation"),
|
||||
},
|
||||
|
||||
EventName.overheat: {
|
||||
ET.PERMANENT: overheat_alert,
|
||||
ET.SOFT_DISABLE: soft_disable_alert("System Overheated"),
|
||||
ET.NO_ENTRY: NoEntryAlert("System Overheated"),
|
||||
},
|
||||
|
||||
EventName.wrongGear: {
|
||||
ET.SOFT_DISABLE: user_soft_disable_alert("Gear not D"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Gear not D"),
|
||||
},
|
||||
|
||||
# This alert is thrown when the calibration angles are outside of the acceptable range.
|
||||
# For example if the device is pointed too much to the left or the right.
|
||||
# Usually this can only be solved by removing the mount from the windshield completely,
|
||||
# and attaching while making sure the device is pointed straight forward and is level.
|
||||
# See https://comma.ai/setup for more information
|
||||
EventName.calibrationInvalid: {
|
||||
ET.PERMANENT: calibration_invalid_alert,
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Calibration Invalid: Remount Device & Recalibrate"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Calibration Invalid: Remount Device & Recalibrate"),
|
||||
},
|
||||
|
||||
EventName.calibrationIncomplete: {
|
||||
ET.PERMANENT: calibration_incomplete_alert,
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Calibration Incomplete"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Calibration in Progress"),
|
||||
},
|
||||
|
||||
EventName.calibrationRecalibrating: {
|
||||
ET.PERMANENT: calibration_incomplete_alert,
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Device Remount Detected: Recalibrating"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Remount Detected: Recalibrating"),
|
||||
},
|
||||
|
||||
EventName.doorOpen: {
|
||||
ET.SOFT_DISABLE: user_soft_disable_alert("Door Open"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Door Open"),
|
||||
},
|
||||
|
||||
EventName.seatbeltNotLatched: {
|
||||
ET.SOFT_DISABLE: user_soft_disable_alert("Seatbelt Unlatched"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Seatbelt Unlatched"),
|
||||
},
|
||||
|
||||
EventName.espDisabled: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Electronic Stability Control Disabled"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Electronic Stability Control Disabled"),
|
||||
},
|
||||
|
||||
EventName.lowBattery: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Low Battery"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Low Battery"),
|
||||
},
|
||||
|
||||
# Different openpilot services communicate between each other at a certain
|
||||
# interval. If communication does not follow the regular schedule this alert
|
||||
# is thrown. This can mean a service crashed, did not broadcast a message for
|
||||
# ten times the regular interval, or the average interval is more than 10% too high.
|
||||
EventName.commIssue: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Communication Issue Between Processes"),
|
||||
ET.NO_ENTRY: comm_issue_alert,
|
||||
},
|
||||
EventName.commIssueAvgFreq: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Low Communication Rate Between Processes"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Low Communication Rate Between Processes"),
|
||||
},
|
||||
|
||||
EventName.selfdrivedLagging: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("System Lagging"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Selfdrive Process Lagging: Reboot Your Device"),
|
||||
},
|
||||
|
||||
# Thrown when manager detects a service exited unexpectedly while driving
|
||||
EventName.processNotRunning: {
|
||||
ET.NO_ENTRY: process_not_running_alert,
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Process Not Running"),
|
||||
},
|
||||
|
||||
EventName.radarFault: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Radar Error: Restart the Car"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Radar Error: Restart the Car"),
|
||||
},
|
||||
|
||||
EventName.radarTempUnavailable: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Radar Temporarily Unavailable"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Radar Temporarily Unavailable"),
|
||||
},
|
||||
|
||||
# Every frame from the camera should be processed by the model. If modeld
|
||||
# is not processing frames fast enough they have to be dropped. This alert is
|
||||
# thrown when over 20% of frames are dropped.
|
||||
EventName.modeldLagging: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Driving Model Lagging"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Driving Model Lagging"),
|
||||
ET.PERMANENT: modeld_lagging_alert,
|
||||
},
|
||||
|
||||
# Besides predicting the path, lane lines and lead car data the model also
|
||||
# predicts the current velocity and rotation speed of the car. If the model is
|
||||
# very uncertain about the current velocity while the car is moving, this
|
||||
# usually means the model has trouble understanding the scene. This is used
|
||||
# as a heuristic to warn the driver.
|
||||
EventName.posenetInvalid: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Posenet Speed Invalid"),
|
||||
ET.NO_ENTRY: posenet_invalid_alert,
|
||||
},
|
||||
|
||||
# When the localizer detects an acceleration of more than 40 m/s^2 (~4G) we
|
||||
# alert the driver the device might have fallen from the windshield.
|
||||
EventName.deviceFalling: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Device Fell Off Mount"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Device Fell Off Mount"),
|
||||
},
|
||||
|
||||
EventName.lowMemory: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Low Memory: Reboot Your Device"),
|
||||
ET.PERMANENT: low_memory_alert,
|
||||
ET.NO_ENTRY: NoEntryAlert("Low Memory: Reboot Your Device"),
|
||||
},
|
||||
|
||||
EventName.accFaulted: {
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("Cruise Fault: Restart the Car"),
|
||||
ET.PERMANENT: NormalPermanentAlert("Cruise Fault: Restart the car to engage"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Cruise Fault: Restart the Car"),
|
||||
},
|
||||
|
||||
EventName.espActive: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Electronic Stability Control Active"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Electronic Stability Control Active"),
|
||||
},
|
||||
|
||||
EventName.controlsMismatch: {
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("Controls Mismatch"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Controls Mismatch"),
|
||||
},
|
||||
|
||||
# Sometimes the USB stack on the device can get into a bad state
|
||||
# causing the connection to the panda to be lost
|
||||
EventName.usbError: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("USB Error: Reboot Your Device"),
|
||||
ET.PERMANENT: NormalPermanentAlert("USB Error: Reboot Your Device"),
|
||||
ET.NO_ENTRY: NoEntryAlert("USB Error: Reboot Your Device"),
|
||||
},
|
||||
|
||||
# This alert can be thrown for the following reasons:
|
||||
# - No CAN data received at all
|
||||
# - CAN data is received, but some message are not received at the right frequency
|
||||
# If you're not writing a new car port, this is usually cause by faulty wiring
|
||||
EventName.canError: {
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("Unknown Vehicle Variant"),
|
||||
ET.PERMANENT: Alert(
|
||||
"Unknown Vehicle Variant",
|
||||
"",
|
||||
AlertStatus.normal, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, 1., creation_delay=1.),
|
||||
ET.NO_ENTRY: NoEntryAlert("Unknown Vehicle Variant"),
|
||||
},
|
||||
|
||||
EventName.canBusMissing: {
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("CAN Bus Disconnected"),
|
||||
ET.PERMANENT: Alert(
|
||||
"CAN Bus Disconnected: Likely Faulty Cable",
|
||||
"",
|
||||
AlertStatus.normal, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, 1., creation_delay=1.),
|
||||
ET.NO_ENTRY: NoEntryAlert("CAN Bus Disconnected: Check Connections"),
|
||||
},
|
||||
|
||||
EventName.steerUnavailable: {
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("LKAS Fault: Restart the Car"),
|
||||
ET.PERMANENT: NormalPermanentAlert("LKAS Fault: Restart the car to engage"),
|
||||
ET.NO_ENTRY: NoEntryAlert("LKAS Fault: Restart the Car"),
|
||||
},
|
||||
|
||||
EventName.reverseGear: {
|
||||
ET.PERMANENT: Alert(
|
||||
"Reverse\nGear",
|
||||
"",
|
||||
AlertStatus.normal, AlertSize.full,
|
||||
Priority.LOWEST, VisualAlert.none, AudibleAlert.none, .2, creation_delay=0.5),
|
||||
ET.USER_DISABLE: ImmediateDisableAlert("Reverse Gear"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Reverse Gear"),
|
||||
},
|
||||
|
||||
# On cars that use stock ACC the car can decide to cancel ACC for various reasons.
|
||||
# When this happens we can no long control the car so the user needs to be warned immediately.
|
||||
EventName.cruiseDisabled: {
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("Cruise Is Off"),
|
||||
},
|
||||
|
||||
# When the relay in the harness box opens the CAN bus between the LKAS camera
|
||||
# and the rest of the car is separated. When messages from the LKAS camera
|
||||
# are received on the car side this usually means the relay hasn't opened correctly
|
||||
# and this alert is thrown.
|
||||
EventName.relayMalfunction: {
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("Harness Relay Malfunction"),
|
||||
ET.PERMANENT: NormalPermanentAlert("Harness Relay Malfunction", "Check Hardware"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Harness Relay Malfunction"),
|
||||
},
|
||||
|
||||
EventName.speedTooLow: {
|
||||
ET.IMMEDIATE_DISABLE: Alert(
|
||||
"openpilot Canceled",
|
||||
"Speed too low",
|
||||
AlertStatus.normal, AlertSize.mid,
|
||||
Priority.HIGH, VisualAlert.none, AudibleAlert.disengage, 3.),
|
||||
},
|
||||
|
||||
# When the car is driving faster than most cars in the training data, the model outputs can be unpredictable.
|
||||
EventName.speedTooHigh: {
|
||||
ET.WARNING: Alert(
|
||||
"Speed Too High",
|
||||
"Model uncertain at this speed",
|
||||
AlertStatus.userPrompt, AlertSize.mid,
|
||||
Priority.HIGH, VisualAlert.steerRequired, AudibleAlert.promptRepeat, 4.),
|
||||
ET.NO_ENTRY: NoEntryAlert("Slow down to engage"),
|
||||
},
|
||||
|
||||
EventName.vehicleSensorsInvalid: {
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("Vehicle Sensors Invalid"),
|
||||
ET.PERMANENT: NormalPermanentAlert("Vehicle Sensors Calibrating", "Drive to Calibrate"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Vehicle Sensors Calibrating"),
|
||||
},
|
||||
|
||||
EventName.personalityChanged: {
|
||||
ET.WARNING: personality_changed_alert,
|
||||
},
|
||||
|
||||
EventName.userBookmark: {
|
||||
ET.PERMANENT: NormalPermanentAlert("Bookmark Saved", duration=1.5),
|
||||
},
|
||||
|
||||
EventName.audioFeedback: {
|
||||
ET.PERMANENT: audio_feedback_alert,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
if HARDWARE.get_device_type() == 'mici':
|
||||
EVENTS.update({
|
||||
EventName.driverDistracted1: {
|
||||
ET.PERMANENT: Alert(
|
||||
"Pay Attention",
|
||||
"",
|
||||
AlertStatus.normal, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, 2),
|
||||
},
|
||||
EventName.driverDistracted2: {
|
||||
ET.PERMANENT: Alert(
|
||||
"Pay Attention",
|
||||
"Driver Distracted",
|
||||
AlertStatus.userPrompt, AlertSize.mid,
|
||||
Priority.MID, VisualAlert.steerRequired, AudibleAlert.promptDistracted, 1),
|
||||
},
|
||||
EventName.resumeRequired: {
|
||||
ET.WARNING: Alert(
|
||||
"Press Resume",
|
||||
"",
|
||||
AlertStatus.userPrompt, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, .2),
|
||||
},
|
||||
EventName.preLaneChangeLeft: {
|
||||
ET.WARNING: Alert(
|
||||
"Steer Left",
|
||||
"Confirm Lane Change",
|
||||
AlertStatus.normal, AlertSize.mid,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, .1),
|
||||
},
|
||||
EventName.preLaneChangeRight: {
|
||||
ET.WARNING: Alert(
|
||||
"Steer Right",
|
||||
"Confirm Lane Change",
|
||||
AlertStatus.normal, AlertSize.mid,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, .1),
|
||||
},
|
||||
EventName.laneChangeBlocked: {
|
||||
ET.WARNING: Alert(
|
||||
"Car in Blindspot",
|
||||
"",
|
||||
AlertStatus.userPrompt, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.prompt, .1),
|
||||
},
|
||||
EventName.steerSaturated: {
|
||||
ET.WARNING: Alert(
|
||||
"take control",
|
||||
"turn exceeds limit",
|
||||
AlertStatus.userPrompt, AlertSize.mid,
|
||||
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.promptRepeat, 2.),
|
||||
},
|
||||
EventName.calibrationIncomplete: {
|
||||
ET.PERMANENT: calibration_incomplete_alert,
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Calibration Incomplete"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Calibrating"),
|
||||
},
|
||||
EventName.reverseGear: {
|
||||
ET.PERMANENT: Alert(
|
||||
"Reverse",
|
||||
"",
|
||||
AlertStatus.normal, AlertSize.full,
|
||||
Priority.LOWEST, VisualAlert.none, AudibleAlert.none, .2, creation_delay=0.5),
|
||||
ET.USER_DISABLE: ImmediateDisableAlert("Reverse"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Reverse"),
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# print all alerts by type and priority
|
||||
from cereal.services import SERVICE_LIST
|
||||
from collections import defaultdict
|
||||
|
||||
event_names = {v: k for k, v in EventName.schema.enumerants.items()}
|
||||
alerts_by_type: dict[str, dict[Priority, list[str]]] = defaultdict(lambda: defaultdict(list))
|
||||
|
||||
CP = car.CarParams.new_message()
|
||||
CS = car.CarState.new_message()
|
||||
sm = messaging.SubMaster(list(SERVICE_LIST.keys()))
|
||||
|
||||
for i, alerts in EVENTS.items():
|
||||
for et, alert in alerts.items():
|
||||
if not isinstance(alert, Alert):
|
||||
alert = alert(CP, CS, sm, False, 1, log.LongitudinalPersonality.standard)
|
||||
alerts_by_type[et][alert.priority].append(event_names[i])
|
||||
|
||||
all_alerts: dict[str, list[tuple[Priority, list[str]]]] = {}
|
||||
for et, priority_alerts in alerts_by_type.items():
|
||||
all_alerts[et] = sorted(priority_alerts.items(), key=lambda x: x[0], reverse=True)
|
||||
|
||||
for status, evs in sorted(all_alerts.items(), key=lambda x: x[0]):
|
||||
print(f"**** {status} ****")
|
||||
for p, alert_list in evs:
|
||||
print(f" {repr(p)}:")
|
||||
print(" ", ', '.join(alert_list), "\n")
|
||||
@@ -0,0 +1,55 @@
|
||||
from pathlib import Path
|
||||
Import('env', 'arch', 'common')
|
||||
|
||||
# build the fonts
|
||||
generator = File("#selfdrive/assets/fonts/process.py")
|
||||
source_files = Glob("#selfdrive/assets/fonts/*.ttf") + Glob("#selfdrive/assets/fonts/*.otf")
|
||||
output_files = [
|
||||
(f"#{Path(f.path).with_suffix('.fnt')}", f"#{Path(f.path).with_suffix('.png')}")
|
||||
for f in source_files
|
||||
if "NotoColor" not in f.name
|
||||
]
|
||||
env.Command(
|
||||
target=output_files,
|
||||
source=[generator, source_files],
|
||||
action=f"python3 {generator}",
|
||||
)
|
||||
|
||||
|
||||
if GetOption('extras') and arch == "larch64":
|
||||
# build installers
|
||||
raylib_env = env.Clone()
|
||||
raylib_env['LIBPATH'] += [f'#third_party/raylib/{arch}/']
|
||||
raylib_env['LINKFLAGS'].append('-Wl,-strip-debug')
|
||||
|
||||
raylib_libs = common + ["raylib"]
|
||||
if arch == "larch64":
|
||||
raylib_libs += ["GLESv2", "EGL", "gbm", "drm"]
|
||||
else:
|
||||
raylib_libs += ["GL"]
|
||||
|
||||
release = "release3"
|
||||
installers = [
|
||||
("openpilot", release),
|
||||
("openpilot_test", f"{release}-staging"),
|
||||
("openpilot_nightly", "nightly"),
|
||||
("openpilot_internal", "nightly-dev"),
|
||||
]
|
||||
|
||||
cont = raylib_env.Command("installer/continue_openpilot.o", "installer/continue_openpilot.sh",
|
||||
"ld -r -b binary -o $TARGET $SOURCE")
|
||||
inter = raylib_env.Command("installer/inter_ttf.o", "installer/inter-ascii.ttf",
|
||||
"ld -r -b binary -o $TARGET $SOURCE")
|
||||
inter_bold = raylib_env.Command("installer/inter_bold.o", "../assets/fonts/Inter-Bold.ttf",
|
||||
"ld -r -b binary -o $TARGET $SOURCE")
|
||||
inter_light = raylib_env.Command("installer/inter_light.o", "../assets/fonts/Inter-Light.ttf",
|
||||
"ld -r -b binary -o $TARGET $SOURCE")
|
||||
for name, branch in installers:
|
||||
d = {'BRANCH': f"'\"{branch}\"'"}
|
||||
if "internal" in name:
|
||||
d['INTERNAL'] = "1"
|
||||
|
||||
obj = raylib_env.Object(f"installer/installers/installer_{name}.o", ["installer/installer.cc"], CPPDEFINES=d)
|
||||
f = raylib_env.Program(f"installer/installers/installer_{name}", [obj, cont, inter, inter_bold, inter_light], LIBS=raylib_libs)
|
||||
# keep installers small
|
||||
assert f[0].get_size() < 2500*1e3, f[0].get_size()
|
||||
@@ -181,8 +181,25 @@ class HomeLayout(Widget):
|
||||
gui_label(version_rect, self._version_text, 48, rl.WHITE, alignment=rl.GuiTextAlignment.TEXT_ALIGN_RIGHT)
|
||||
|
||||
def _render_home_content(self):
|
||||
self._render_left_column()
|
||||
self._render_right_column()
|
||||
# Display welcome text centered in content area
|
||||
font = gui_app.font(FontWeight.BOLD)
|
||||
text = "欢迎选用 MR.ONE"
|
||||
subtitle = "这不是自动驾驶,请注意行车安全"
|
||||
font_size = 100
|
||||
|
||||
text_size = measure_text_cached(font, text, font_size)
|
||||
sub_size = measure_text_cached(font, subtitle, font_size)
|
||||
|
||||
cx = self.content_rect.x + self.content_rect.width / 2
|
||||
cy = self.content_rect.y + self.content_rect.height / 2
|
||||
|
||||
x = int(cx - text_size.x / 2)
|
||||
y = int(cy - text_size.y - sub_size.y / 2 - 15)
|
||||
rl.draw_text_ex(font, text, rl.Vector2(x, y), font_size, 0, rl.WHITE)
|
||||
|
||||
sx = int(cx - sub_size.x / 2)
|
||||
sy = int(cy + text_size.y / 2 + 15)
|
||||
rl.draw_text_ex(font, subtitle, rl.Vector2(sx, sy), font_size, 0, rl.Color(255, 50, 50, 255))
|
||||
|
||||
def _render_update_view(self):
|
||||
self.update_alert.render(self.content_rect)
|
||||
|
||||
@@ -60,7 +60,7 @@ class SettingsLayout(Widget):
|
||||
PanelType.NETWORK: PanelInfo(tr_noop("Network"), NetworkUI(wifi_manager)),
|
||||
PanelType.TOGGLES: PanelInfo(tr_noop("Toggles"), TogglesLayout()),
|
||||
PanelType.SOFTWARE: PanelInfo(tr_noop("Software"), SoftwareLayout()),
|
||||
PanelType.FIREHOSE: PanelInfo(tr_noop("Firehose"), FirehoseLayout()),
|
||||
# PanelType.FIREHOSE: PanelInfo(tr_noop("Firehose"), FirehoseLayout()),
|
||||
PanelType.DEVELOPER: PanelInfo(tr_noop("Developer"), DeveloperLayout()),
|
||||
}
|
||||
|
||||
@@ -124,11 +124,11 @@ class SettingsLayout(Widget):
|
||||
text_color = TEXT_SELECTED if is_selected else TEXT_NORMAL
|
||||
# Draw button text (right-aligned)
|
||||
panel_name = tr(panel_info.name)
|
||||
text_size = measure_text_cached(self._font_medium, panel_name, 65)
|
||||
text_size = measure_text_cached(self._font_medium, panel_name, 85)
|
||||
text_pos = rl.Vector2(
|
||||
button_rect.x + button_rect.width - text_size.x, button_rect.y + (button_rect.height - text_size.y) / 2
|
||||
)
|
||||
rl.draw_text_ex(self._font_medium, panel_name, text_pos, 65, 0, text_color)
|
||||
rl.draw_text_ex(self._font_medium, panel_name, text_pos, 85, 0, text_color)
|
||||
|
||||
# Store button rect for click detection
|
||||
panel_info.button_rect = button_rect
|
||||
|
||||
@@ -123,21 +123,26 @@ class Sidebar(Widget, SidebarSP):
|
||||
self._net_strength = max(0, min(5, strength.raw + 1)) if strength.raw > 0 else 0
|
||||
|
||||
def _update_temperature_status(self, device_state):
|
||||
# Get max CPU temperature across all cores
|
||||
cpu_temps = device_state.cpuTempC
|
||||
max_temp = max(cpu_temps) if cpu_temps else 0.0
|
||||
temp_str = f"{max_temp:.0f}°C"
|
||||
|
||||
thermal_status = device_state.thermalStatus
|
||||
|
||||
if thermal_status == ThermalStatus.green:
|
||||
self._temp_status.update(tr_noop("TEMP"), tr_noop("GOOD"), Colors.GOOD)
|
||||
self._temp_status.update(tr_noop("TEMP"), temp_str, Colors.GOOD)
|
||||
elif thermal_status == ThermalStatus.yellow:
|
||||
self._temp_status.update(tr_noop("TEMP"), tr_noop("OK"), Colors.WARNING)
|
||||
self._temp_status.update(tr_noop("TEMP"), temp_str, Colors.WARNING)
|
||||
else:
|
||||
self._temp_status.update(tr_noop("TEMP"), tr_noop("HIGH"), Colors.DANGER)
|
||||
self._temp_status.update(tr_noop("TEMP"), temp_str, Colors.DANGER)
|
||||
|
||||
def _update_connection_status(self, device_state):
|
||||
last_ping = device_state.lastAthenaPingTime
|
||||
if last_ping == 0:
|
||||
self._connect_status.update(tr_noop("CONNECT"), tr_noop("OFFLINE"), Colors.WARNING)
|
||||
elif time.monotonic_ns() - last_ping < 80_000_000_000: # 80 seconds in nanoseconds
|
||||
self._connect_status.update(tr_noop("CONNECT"), tr_noop("ONLINE"), Colors.GOOD)
|
||||
self._connect_status.update("远程", "在线", Colors.GOOD)
|
||||
else:
|
||||
self._connect_status.update(tr_noop("CONNECT"), tr_noop("ERROR"), Colors.DANGER)
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ class TrainingGuidePreDMTutorial(NavScroller):
|
||||
continue_button.set_click_callback(continue_callback)
|
||||
|
||||
self._scroller.add_widgets([
|
||||
GreyBigButton("driver monitoring\ncheck", "scroll to continue",
|
||||
GreyBigButton(tr("driver monitoring\ncheck"), "scroll to continue",
|
||||
gui_app.texture("icons_mici/setup/green_dm.png", 64, 64)),
|
||||
GreyBigButton("", "Next, we'll check if comma four can detect the driver properly."),
|
||||
GreyBigButton("", "sunnypilot uses the cabin camera to check if the driver is distracted."),
|
||||
@@ -82,7 +82,7 @@ class DMBadFaceDetected(NavScroller):
|
||||
back_button.set_click_callback(self.dismiss)
|
||||
|
||||
self._scroller.add_widgets([
|
||||
GreyBigButton("looking for driver", "make sure comma\nfour can see your face",
|
||||
GreyBigButton(tr("looking for driver"), "make sure comma\nfour can see your face",
|
||||
gui_app.texture("icons_mici/setup/orange_dm.png", 64, 64)),
|
||||
GreyBigButton("", "Remount if your face is blocked, or driver monitoring has difficulty tracking your face."),
|
||||
back_button,
|
||||
@@ -233,7 +233,7 @@ class TrainingGuideRecordFront(NavScroller):
|
||||
exit_on_confirm=False)
|
||||
|
||||
self._scroller.add_widgets([
|
||||
GreyBigButton("driver camera data", "do you want to share video data for training?",
|
||||
GreyBigButton(tr("driver camera data"), "do you want to share video data for training?",
|
||||
gui_app.texture("icons_mici/setup/green_dm.png", 64, 64)),
|
||||
GreyBigButton("", "Sharing your data with comma helps improve openpilot and sunnypilot for everyone."),
|
||||
self._accept_button,
|
||||
@@ -249,7 +249,7 @@ class TrainingGuideAttentionNotice(Scroller):
|
||||
continue_button.set_click_callback(continue_callback)
|
||||
|
||||
self._scroller.add_widgets([
|
||||
GreyBigButton("what is sunnypilot?", "scroll to continue",
|
||||
GreyBigButton(tr("what is sunnypilot?"), "scroll to continue",
|
||||
gui_app.texture("icons_mici/setup/green_info.png", 64, 64)),
|
||||
GreyBigButton("", "1. sunnypilot is a driver assistance system."),
|
||||
GreyBigButton("", "2. You must pay attention at all times."),
|
||||
@@ -320,13 +320,13 @@ class TermsPage(Scroller):
|
||||
self._decline_button = BigConfirmationCircleButton("decline &\nuninstall", gui_app.texture("icons_mici/setup/cancel.png", 64, 64), on_decline,
|
||||
red=True, exit_on_confirm=False)
|
||||
|
||||
self._terms_header = GreyBigButton("terms of\nservice", "scroll to continue",
|
||||
self._terms_header = GreyBigButton(tr("terms of\nservice"), "scroll to continue",
|
||||
gui_app.texture("icons_mici/setup/green_info.png", 64, 64))
|
||||
self._must_accept_card = GreyBigButton("", "You must accept the Terms of Service to use sunnypilot.")
|
||||
|
||||
self._scroller.add_widgets([
|
||||
self._terms_header,
|
||||
GreyBigButton("swipe for QR code", "or go to https://sunnypilot.ai/terms",
|
||||
GreyBigButton(tr("swipe for QR code"), "or go to https://sunnypilot.ai/terms",
|
||||
gui_app.texture("icons_mici/setup/small_slider/slider_arrow.png", 64, 56, flip_x=True)),
|
||||
QRCodeWidget("https://sunnypilot.ai/terms"),
|
||||
self._must_accept_card,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from openpilot.common.time_helpers import system_time_valid
|
||||
from openpilot.system.ui.lib.multilang import tr
|
||||
from openpilot.system.ui.widgets.scroller import NavScroller
|
||||
from openpilot.selfdrive.ui.mici.widgets.button import BigButton, BigToggle, BigParamControl, BigCircleParamControl
|
||||
from openpilot.selfdrive.ui.mici.widgets.dialog import BigDialog, BigInputDialog
|
||||
@@ -42,26 +43,26 @@ class DeveloperLayoutMici(NavScroller):
|
||||
|
||||
txt_ssh = gui_app.texture("icons_mici/settings/developer/ssh.png", 56, 64)
|
||||
github_username = ui_state.params.get("GithubUsername") or ""
|
||||
self._ssh_keys_btn = BigButton("SSH keys", "Not set" if not github_username else github_username, icon=txt_ssh)
|
||||
self._ssh_keys_btn = BigButton(tr("SSH keys"), "Not set" if not github_username else github_username, icon=txt_ssh)
|
||||
self._ssh_keys_btn.set_click_callback(ssh_keys_callback)
|
||||
|
||||
# adb, ssh, ssh keys, debug mode, joystick debug mode, longitudinal maneuver mode, ip address
|
||||
# ******** Main Scroller ********
|
||||
self._adb_toggle = BigCircleParamControl(gui_app.texture("icons_mici/adb_short.png", 82, 82), "AdbEnabled", icon_offset=(0, 12))
|
||||
self._ssh_toggle = BigCircleParamControl(gui_app.texture("icons_mici/ssh_short.png", 82, 82), "SshEnabled", icon_offset=(0, 12))
|
||||
self._joystick_toggle = BigToggle("joystick debug mode",
|
||||
self._joystick_toggle = BigToggle(tr("joystick debug mode"),
|
||||
initial_state=ui_state.params.get_bool("JoystickDebugMode"),
|
||||
toggle_callback=self._on_joystick_debug_mode)
|
||||
self._long_maneuver_toggle = BigToggle("longitudinal maneuver mode",
|
||||
self._long_maneuver_toggle = BigToggle(tr("longitudinal maneuver mode"),
|
||||
initial_state=ui_state.params.get_bool("LongitudinalManeuverMode"),
|
||||
toggle_callback=self._on_long_maneuver_mode)
|
||||
self._lat_maneuver_toggle = BigToggle("lateral maneuver mode",
|
||||
self._lat_maneuver_toggle = BigToggle(tr("lateral maneuver mode"),
|
||||
initial_state=ui_state.params.get_bool("LateralManeuverMode"),
|
||||
toggle_callback=self._on_lat_maneuver_mode)
|
||||
self._alpha_long_toggle = BigToggle("alpha longitudinal",
|
||||
self._alpha_long_toggle = BigToggle(tr("alpha longitudinal"),
|
||||
initial_state=ui_state.params.get_bool("AlphaLongitudinalEnabled"),
|
||||
toggle_callback=self._on_alpha_long_enabled)
|
||||
self._debug_mode_toggle = BigParamControl("ui debug mode", "ShowDebugInfo",
|
||||
self._debug_mode_toggle = BigParamControl(tr("ui debug mode"), "ShowDebugInfo",
|
||||
toggle_callback=lambda checked: (gui_app.set_show_touches(checked),
|
||||
gui_app.set_show_fps(checked)))
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ class UpdaterState(IntEnum):
|
||||
|
||||
class PairBigButton(BigButton):
|
||||
def __init__(self):
|
||||
super().__init__("pair", "connect.comma.ai", gui_app.texture("icons_mici/settings/comma_icon.png", 33, 60))
|
||||
super().__init__(tr("pair"), "connect.comma.ai", gui_app.texture("icons_mici/settings/comma_icon.png", 33, 60))
|
||||
|
||||
def _get_label_font_size(self):
|
||||
return 64
|
||||
@@ -139,13 +139,13 @@ class PairBigButton(BigButton):
|
||||
super()._update_state()
|
||||
|
||||
if ui_state.prime_state.is_paired():
|
||||
self.set_text("paired")
|
||||
self.set_text(tr("paired"))
|
||||
if ui_state.prime_state.is_prime():
|
||||
self.set_value("subscribed")
|
||||
self.set_value(tr("subscribed"))
|
||||
else:
|
||||
self.set_value("upgrade to prime")
|
||||
self.set_value(tr("upgrade to prime"))
|
||||
else:
|
||||
self.set_text("pair")
|
||||
self.set_text(tr("pair"))
|
||||
self.set_value("connect.comma.ai")
|
||||
|
||||
def _handle_mouse_release(self, mouse_pos: MousePos):
|
||||
@@ -172,7 +172,7 @@ class UpdateOpenpilotBigButton(BigButton):
|
||||
self._txt_update_icon = gui_app.texture("icons_mici/settings/device/update.png", 64, 75)
|
||||
self._txt_reboot_icon = gui_app.texture("icons_mici/settings/device/reboot.png", 64, 70)
|
||||
self._txt_up_to_date_icon = gui_app.texture("icons_mici/settings/device/up_to_date.png", 64, 64)
|
||||
super().__init__("update sunnypilot", "", self._txt_update_icon)
|
||||
super().__init__(tr("update sunnypilot"), "", self._txt_update_icon)
|
||||
|
||||
self._waiting_for_updater_t: float | None = None
|
||||
self._hide_value_t: float | None = None
|
||||
@@ -323,18 +323,18 @@ class DeviceLayoutMici(NavScroller):
|
||||
power_off_callback, exit_on_confirm=False, red=True)
|
||||
self._power_off_btn.set_visible(lambda: not ui_state.ignition)
|
||||
|
||||
regulatory_btn = BigButton("regulatory info", "", gui_app.texture("icons_mici/settings/device/info.png", 64, 64))
|
||||
regulatory_btn = BigButton(tr("regulatory info"), "", gui_app.texture("icons_mici/settings/device/info.png", 64, 64))
|
||||
regulatory_btn.set_click_callback(self._on_regulatory)
|
||||
|
||||
driver_cam_btn = BigButton("driver\ncamera preview", "", gui_app.texture("icons_mici/settings/device/cameras.png", 64, 64))
|
||||
driver_cam_btn = BigButton(tr("driver\ncamera preview"), "", gui_app.texture("icons_mici/settings/device/cameras.png", 64, 64))
|
||||
driver_cam_btn.set_click_callback(lambda: gui_app.push_widget(DriverCameraDialog()))
|
||||
driver_cam_btn.set_enabled(lambda: ui_state.is_offroad())
|
||||
|
||||
review_training_guide_btn = BigButton("review\ntraining guide", "", gui_app.texture("icons_mici/settings/device/info.png", 64, 64))
|
||||
review_training_guide_btn = BigButton(tr("review\ntraining guide"), "", gui_app.texture("icons_mici/settings/device/info.png", 64, 64))
|
||||
review_training_guide_btn.set_click_callback(lambda: gui_app.push_widget(ReviewTrainingGuide(completed_callback=lambda: gui_app.pop_widgets_to(self))))
|
||||
review_training_guide_btn.set_enabled(lambda: ui_state.is_offroad())
|
||||
|
||||
terms_btn = BigButton("terms &\nconditions", "", gui_app.texture("icons_mici/settings/device/info.png", 64, 64))
|
||||
terms_btn = BigButton(tr("terms &\nconditions"), "", gui_app.texture("icons_mici/settings/device/info.png", 64, 64))
|
||||
terms_btn.set_click_callback(lambda: gui_app.push_widget(ReviewTermsPage()))
|
||||
|
||||
self._scroller.add_widgets([
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from openpilot.system.ui.lib.multilang import tr
|
||||
from openpilot.system.ui.widgets.scroller import NavScroller
|
||||
from openpilot.selfdrive.ui.mici.layouts.settings.network import WifiNetworkButton
|
||||
from openpilot.selfdrive.ui.mici.layouts.settings.network.wifi_ui import WifiUIMici
|
||||
@@ -28,7 +29,7 @@ class NetworkLayoutMici(NavScroller):
|
||||
self._network_metered_btn.set_enabled(False)
|
||||
self._wifi_manager.set_tethering_active(checked)
|
||||
|
||||
self._tethering_toggle_btn = BigToggle("enable tethering", "", toggle_callback=tethering_toggle_callback)
|
||||
self._tethering_toggle_btn = BigToggle(tr("enable tethering"), "", toggle_callback=tethering_toggle_callback)
|
||||
|
||||
def tethering_password_callback(password: str):
|
||||
if password:
|
||||
@@ -43,7 +44,7 @@ class NetworkLayoutMici(NavScroller):
|
||||
gui_app.push_widget(dlg)
|
||||
|
||||
txt_tethering = gui_app.texture("icons_mici/settings/network/tethering.png", 64, 54)
|
||||
self._tethering_password_btn = BigButton("tethering password", "", txt_tethering)
|
||||
self._tethering_password_btn = BigButton(tr("tethering password"), "", txt_tethering)
|
||||
self._tethering_password_btn.set_click_callback(tethering_password_clicked)
|
||||
|
||||
# ******** Network Metered ********
|
||||
@@ -58,7 +59,7 @@ class NetworkLayoutMici(NavScroller):
|
||||
|
||||
# TODO: signal for current network metered type when changing networks, this is wrong until you press it once
|
||||
# TODO: disable when not connected
|
||||
self._network_metered_btn = BigMultiToggle("network usage", ["default", "metered", "unmetered"], select_callback=network_metered_callback)
|
||||
self._network_metered_btn = BigMultiToggle(tr("network usage"), ["default", "metered", "unmetered"], select_callback=network_metered_callback)
|
||||
self._network_metered_btn.set_enabled(False)
|
||||
|
||||
self._wifi_button = WifiNetworkButton(self._wifi_manager)
|
||||
@@ -66,14 +67,14 @@ class NetworkLayoutMici(NavScroller):
|
||||
|
||||
# ******** Advanced settings ********
|
||||
# ******** Roaming toggle ********
|
||||
self._roaming_btn = BigParamControl("enable roaming", "GsmRoaming", toggle_callback=self._toggle_roaming)
|
||||
self._roaming_btn = BigParamControl(tr("enable roaming"), "GsmRoaming", toggle_callback=self._toggle_roaming)
|
||||
|
||||
# ******** APN settings ********
|
||||
self._apn_btn = BigButton("apn settings", "edit")
|
||||
self._apn_btn = BigButton(tr("apn settings"), "edit")
|
||||
self._apn_btn.set_click_callback(self._edit_apn)
|
||||
|
||||
# ******** Cellular metered toggle ********
|
||||
self._cellular_metered_btn = BigParamControl("cellular metered", "GsmMetered", toggle_callback=self._toggle_cellular_metered)
|
||||
self._cellular_metered_btn = BigParamControl(tr("cellular metered"), "GsmMetered", toggle_callback=self._toggle_cellular_metered)
|
||||
|
||||
# Main scroller ----------------------------------
|
||||
self._scroller.add_widgets([
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.system.ui.lib.multilang import tr
|
||||
from openpilot.system.ui.widgets.scroller import NavScroller
|
||||
from openpilot.selfdrive.ui.mici.widgets.button import BigButton
|
||||
from openpilot.selfdrive.ui.mici.layouts.settings.toggles import TogglesLayoutMici
|
||||
@@ -20,23 +21,23 @@ class SettingsLayout(NavScroller):
|
||||
self._params = Params()
|
||||
|
||||
toggles_panel = TogglesLayoutMici()
|
||||
toggles_btn = SettingsBigButton("toggles", "", gui_app.texture("icons_mici/settings.png", 64, 64))
|
||||
toggles_btn = SettingsBigButton(tr("toggles"), "", gui_app.texture("icons_mici/settings.png", 64, 64))
|
||||
toggles_btn.set_click_callback(lambda: gui_app.push_widget(toggles_panel))
|
||||
|
||||
network_panel = NetworkLayoutMici()
|
||||
network_btn = SettingsBigButton("network", "", gui_app.texture("icons_mici/settings/network/wifi_strength_full.png", 76, 56))
|
||||
network_btn = SettingsBigButton(tr("network"), "", gui_app.texture("icons_mici/settings/network/wifi_strength_full.png", 76, 56))
|
||||
network_btn.set_click_callback(lambda: gui_app.push_widget(network_panel))
|
||||
|
||||
device_panel = DeviceLayoutMici()
|
||||
device_btn = SettingsBigButton("device", "", gui_app.texture("icons_mici/settings/device_icon.png", 72, 58))
|
||||
device_btn = SettingsBigButton(tr("device"), "", gui_app.texture("icons_mici/settings/device_icon.png", 72, 58))
|
||||
device_btn.set_click_callback(lambda: gui_app.push_widget(device_panel))
|
||||
|
||||
developer_panel = DeveloperLayoutMici()
|
||||
developer_btn = SettingsBigButton("developer", "", gui_app.texture("icons_mici/settings/developer_icon.png", 64, 60))
|
||||
developer_btn = SettingsBigButton(tr("developer"), "", gui_app.texture("icons_mici/settings/developer_icon.png", 64, 60))
|
||||
developer_btn.set_click_callback(lambda: gui_app.push_widget(developer_panel))
|
||||
|
||||
firehose_panel = FirehoseLayout()
|
||||
firehose_btn = SettingsBigButton("firehose", "", gui_app.texture("icons_mici/settings/firehose.png", 52, 62))
|
||||
firehose_btn = SettingsBigButton(tr("firehose"), "", gui_app.texture("icons_mici/settings/firehose.png", 52, 62))
|
||||
firehose_btn.set_click_callback(lambda: gui_app.push_widget(firehose_panel))
|
||||
|
||||
self._scroller.add_widgets([
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from cereal import log
|
||||
|
||||
from openpilot.system.ui.lib.multilang import tr
|
||||
from openpilot.system.ui.widgets.scroller import NavScroller
|
||||
from openpilot.selfdrive.ui.mici.widgets.button import BigParamControl, BigMultiParamToggle
|
||||
from openpilot.system.ui.lib.application import gui_app
|
||||
@@ -13,14 +14,14 @@ class TogglesLayoutMici(NavScroller):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
self._personality_toggle = BigMultiParamToggle("driving personality", "LongitudinalPersonality", ["aggressive", "standard", "relaxed"])
|
||||
self._experimental_btn = BigParamControl("experimental mode", "ExperimentalMode")
|
||||
is_metric_toggle = BigParamControl("use metric units", "IsMetric")
|
||||
ldw_toggle = BigParamControl("lane departure warnings", "IsLdwEnabled")
|
||||
always_on_dm_toggle = BigParamControl("always-on driver monitor", "AlwaysOnDM")
|
||||
record_front = BigParamControl("record & upload driver camera", "RecordFront", toggle_callback=restart_needed_callback)
|
||||
record_mic = BigParamControl("record & upload mic audio", "RecordAudio", toggle_callback=restart_needed_callback)
|
||||
enable_openpilot = BigParamControl("enable sunnypilot", "OpenpilotEnabledToggle", toggle_callback=restart_needed_callback)
|
||||
self._personality_toggle = BigMultiParamToggle(tr("driving personality"), "LongitudinalPersonality", ["aggressive", "standard", "relaxed"])
|
||||
self._experimental_btn = BigParamControl(tr("experimental mode"), "ExperimentalMode")
|
||||
is_metric_toggle = BigParamControl(tr("use metric units"), "IsMetric")
|
||||
ldw_toggle = BigParamControl(tr("lane departure warnings"), "IsLdwEnabled")
|
||||
always_on_dm_toggle = BigParamControl(tr("always-on driver monitor"), "AlwaysOnDM")
|
||||
record_front = BigParamControl(tr("record & upload driver camera"), "RecordFront", toggle_callback=restart_needed_callback)
|
||||
record_mic = BigParamControl(tr("record & upload mic audio"), "RecordAudio", toggle_callback=restart_needed_callback)
|
||||
enable_openpilot = BigParamControl(tr("enable sunnypilot"), "OpenpilotEnabledToggle", toggle_callback=restart_needed_callback)
|
||||
|
||||
self._scroller.add_widgets([
|
||||
self._personality_toggle,
|
||||
|
||||
@@ -42,11 +42,11 @@ class OSMLayout(Widget):
|
||||
self._update_map_size()
|
||||
self._progress.set_visible(False)
|
||||
self._state_btn.set_visible(False)
|
||||
self._mapd_version.action_item.set_text(ui_state.params.get("MapdVersion") or "Loading...")
|
||||
self._mapd_version.action_item.set_text(ui_state.params.get("MapdVersion") or tr("Loading..."))
|
||||
self._scroller = Scroller(self.items, line_separator=True, spacing=0)
|
||||
|
||||
def _initialize_items(self):
|
||||
self._mapd_version = text_item(tr("Mapd Version"), lambda: ui_state.params.get("MapdVersion") or "Loading...")
|
||||
self._mapd_version = text_item(tr("Mapd Version"), lambda: ui_state.params.get("MapdVersion") or tr("Loading..."))
|
||||
self._delete_maps_btn = ListItemSP(tr("Downloaded Maps"), action_item=NoElideButtonAction(tr("DELETE"), enabled=True), callback=self._delete_maps)
|
||||
self._progress = progress_item(tr("Downloading Map"))
|
||||
self._update_btn = ListItemSP(tr("Database Update"), action_item=NoElideButtonAction(tr("CHECK"), enabled=True), callback=self._update_db)
|
||||
@@ -88,7 +88,7 @@ class OSMLayout(Widget):
|
||||
|
||||
def _on_confirm_delete_maps(self):
|
||||
self._delete_maps_btn.action_item.set_enabled(False)
|
||||
self._delete_maps_btn.action_item.set_text("DELETING...")
|
||||
self._delete_maps_btn.action_item.set_text(tr("DELETING..."))
|
||||
threading.Thread(target=self._do_delete_maps).start()
|
||||
|
||||
def _delete_maps(self):
|
||||
|
||||
@@ -25,7 +25,7 @@ from openpilot.selfdrive.ui.sunnypilot.layouts.settings.trips import TripsLayout
|
||||
from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle import VehicleLayout
|
||||
from openpilot.selfdrive.ui.sunnypilot.layouts.settings.visuals import VisualsLayout
|
||||
from openpilot.system.ui.lib.application import gui_app, MousePos
|
||||
from openpilot.system.ui.lib.multilang import tr_noop
|
||||
from openpilot.system.ui.lib.multilang import tr
|
||||
from openpilot.system.ui.lib.text_measure import measure_text_cached
|
||||
from openpilot.system.ui.lib.wifi_manager import WifiManager
|
||||
from openpilot.system.ui.sunnypilot.lib.styles import style
|
||||
@@ -71,7 +71,7 @@ class NavButton(Widget):
|
||||
is_selected = self.panel_type == self.parent._current_panel
|
||||
text_color = OP.TEXT_SELECTED if is_selected else OP.TEXT_NORMAL
|
||||
content_x = rect.x + 90
|
||||
text_size = measure_text_cached(self.parent._font_medium, self.panel_info.name, 65)
|
||||
text_size = measure_text_cached(self.parent._font_medium, tr(self.panel_info.name), 65)
|
||||
|
||||
# Draw background if selected
|
||||
if is_selected:
|
||||
@@ -90,7 +90,7 @@ class NavButton(Widget):
|
||||
content_x,
|
||||
rect.y + (OP.NAV_BTN_HEIGHT - text_size.y) / 2
|
||||
)
|
||||
rl.draw_text_ex(self.parent._font_medium, self.panel_info.name, text_pos, 55, 0, text_color)
|
||||
rl.draw_text_ex(self.parent._font_medium, tr(self.panel_info.name), text_pos, 55, 0, text_color)
|
||||
|
||||
# Store button rect for click detection
|
||||
self.panel_info.button_rect = rect
|
||||
@@ -109,22 +109,22 @@ class SettingsLayoutSP(OP.SettingsLayout):
|
||||
wifi_manager.set_active(False)
|
||||
|
||||
self._panels = {
|
||||
OP.PanelType.DEVICE: PanelInfo(tr_noop("Device"), DeviceLayoutSP(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_home.png"),
|
||||
OP.PanelType.NETWORK: PanelInfo(tr_noop("Network"), NetworkUISP(wifi_manager), icon="icons/network.png"),
|
||||
OP.PanelType.SUNNYLINK: PanelInfo(tr_noop("sunnylink"), SunnylinkLayout(), icon="icons/wifi_strength_full.png"),
|
||||
OP.PanelType.TOGGLES: PanelInfo(tr_noop("Toggles"), TogglesLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_toggle.png"),
|
||||
OP.PanelType.SOFTWARE: PanelInfo(tr_noop("Software"), SoftwareLayoutSP(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_software.png"),
|
||||
OP.PanelType.MODELS: PanelInfo(tr_noop("Models"), ModelsLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_models.png"),
|
||||
OP.PanelType.STEERING: PanelInfo(tr_noop("Steering"), SteeringLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_lateral.png"),
|
||||
OP.PanelType.CRUISE: PanelInfo(tr_noop("Cruise"), CruiseLayout(), icon="icons/speed_limit.png"),
|
||||
OP.PanelType.VISUALS: PanelInfo(tr_noop("Visuals"), VisualsLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_visuals.png"),
|
||||
OP.PanelType.DISPLAY: PanelInfo(tr_noop("Display"), DisplayLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_display.png"),
|
||||
OP.PanelType.OSM: PanelInfo(tr_noop("OSM"), OSMLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_map.png"),
|
||||
# OP.PanelType.NAVIGATION: PanelInfo(tr_noop("Navigation"), NavigationLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_map.png"),
|
||||
OP.PanelType.TRIPS: PanelInfo(tr_noop("Trips"), TripsLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_trips.png"),
|
||||
OP.PanelType.VEHICLE: PanelInfo(tr_noop("Vehicle"), VehicleLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_vehicle.png"),
|
||||
OP.PanelType.FIREHOSE: PanelInfo(tr_noop("Firehose"), FirehoseLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_firehose.png"),
|
||||
OP.PanelType.DEVELOPER: PanelInfo(tr_noop("Developer"), DeveloperLayoutSP(), icon="icons/shell.png"),
|
||||
OP.PanelType.DEVICE: PanelInfo(tr("Device"), DeviceLayoutSP(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_home.png"),
|
||||
OP.PanelType.NETWORK: PanelInfo(tr("Network"), NetworkUISP(wifi_manager), icon="icons/network.png"),
|
||||
# OP.PanelType.SUNNYLINK: PanelInfo(tr("sunnylink"), SunnylinkLayout(), icon="icons/wifi_strength_full.png"),
|
||||
OP.PanelType.TOGGLES: PanelInfo(tr("Toggles"), TogglesLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_toggle.png"),
|
||||
OP.PanelType.SOFTWARE: PanelInfo(tr("Software"), SoftwareLayoutSP(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_software.png"),
|
||||
# OP.PanelType.MODELS: PanelInfo(tr("Models"), ModelsLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_models.png"),
|
||||
OP.PanelType.STEERING: PanelInfo(tr("Steering"), SteeringLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_lateral.png"),
|
||||
OP.PanelType.CRUISE: PanelInfo(tr("Cruise"), CruiseLayout(), icon="icons/speed_limit.png"),
|
||||
OP.PanelType.VISUALS: PanelInfo(tr("Visuals"), VisualsLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_visuals.png"),
|
||||
OP.PanelType.DISPLAY: PanelInfo(tr("Display"), DisplayLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_display.png"),
|
||||
# OP.PanelType.OSM: PanelInfo(tr("OSM"), OSMLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_map.png"),
|
||||
# OP.PanelType.NAVIGATION: PanelInfo(tr("Navigation"), NavigationLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_map.png"),
|
||||
# OP.PanelType.TRIPS: PanelInfo(tr("Trips"), TripsLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_trips.png"),
|
||||
OP.PanelType.VEHICLE: PanelInfo(tr("Vehicle"), VehicleLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_vehicle.png"),
|
||||
# OP.PanelType.FIREHOSE: PanelInfo(tr("Firehose"), FirehoseLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_firehose.png"),
|
||||
OP.PanelType.DEVELOPER: PanelInfo(tr("Developer"), DeveloperLayoutSP(), icon="icons/shell.png"),
|
||||
}
|
||||
|
||||
def _draw_sidebar(self, rect: rl.Rectangle):
|
||||
|
||||
@@ -28,7 +28,7 @@ class SunnylinkHeader(Widget):
|
||||
super().__init__()
|
||||
|
||||
self._title = UnifiedLabel(
|
||||
text="🚀 sunnylink 🚀",
|
||||
text=tr("🚀 sunnylink 🚀"),
|
||||
font_size=90,
|
||||
font_weight=FontWeight.AUDIOWIDE,
|
||||
text_color=rl.WHITE,
|
||||
@@ -223,14 +223,14 @@ class SunnylinkLayout(Widget):
|
||||
gui_app.push_widget(self._sunnylink_pairing_dialog)
|
||||
|
||||
def _handle_backup_btn(self):
|
||||
backup_dialog = ConfirmDialog(text=tr("Are you sure you want to backup your current sunnypilot settings?"), confirm_text="Backup",
|
||||
backup_dialog = ConfirmDialog(text=tr("Are you sure you want to backup your current sunnypilot settings?"), confirm_text=tr("Backup"),
|
||||
callback=self._backup_handler)
|
||||
gui_app.push_widget(backup_dialog)
|
||||
|
||||
def _handle_restore_btn(self):
|
||||
self._restore_btn.set_enabled(False)
|
||||
restore_dialog = ConfirmDialog(text=tr("Are you sure you want to restore the last backed up sunnypilot settings?"),
|
||||
confirm_text="Restore", callback=self._restore_handler)
|
||||
confirm_text=tr("Restore"), callback=self._restore_handler)
|
||||
gui_app.push_widget(restore_dialog)
|
||||
|
||||
def _backup_handler(self, dialog_result: int):
|
||||
|
||||
@@ -79,7 +79,7 @@ class SidebarSP:
|
||||
self._sunnylink_status.update(tr_noop("SUNNYLINK"), status, color)
|
||||
|
||||
def _draw_metrics_w_sunnylink(self, rect: rl.Rectangle, _temp, _panda, _connect):
|
||||
metrics = [_temp, _panda, _connect, self._sunnylink_status]
|
||||
metrics = [_temp, _panda, _connect]
|
||||
start_y = int(rect.y) + METRIC_START_Y
|
||||
available_height = max(0, int(HOME_BTN.y) - METRIC_MARGIN - METRIC_HEIGHT - start_y)
|
||||
spacing = available_height / max(1, len(metrics) - 1)
|
||||
|
||||
@@ -7,6 +7,7 @@ See the LICENSE.md file in the root directory for more details.
|
||||
from collections.abc import Callable
|
||||
|
||||
from openpilot.selfdrive.ui.mici.widgets.dialog import BigConfirmationCircleButton
|
||||
from openpilot.system.ui.lib.multilang import tr
|
||||
from openpilot.system.ui.lib.application import gui_app
|
||||
from openpilot.system.ui.mici_setup import GreyBigButton
|
||||
from openpilot.system.ui.widgets.scroller import NavScroller
|
||||
@@ -16,14 +17,14 @@ class SunnylinkConsentPage(NavScroller):
|
||||
def __init__(self, on_accept: Callable | None = None, on_decline: Callable | None = None):
|
||||
super().__init__()
|
||||
|
||||
self._accept_button = BigConfirmationCircleButton("enable\nsunnylink", gui_app.texture("icons_mici/setup/driver_monitoring/dm_check.png", 64, 64),
|
||||
self._accept_button = BigConfirmationCircleButton(tr("enable\nsunnylink"), gui_app.texture("icons_mici/setup/driver_monitoring/dm_check.png", 64, 64),
|
||||
on_accept, exit_on_confirm=False)
|
||||
|
||||
self._decline_button = BigConfirmationCircleButton("disable\nsunnylink", gui_app.texture("icons_mici/setup/cancel.png", 64, 64),
|
||||
self._decline_button = BigConfirmationCircleButton(tr("disable\nsunnylink"), gui_app.texture("icons_mici/setup/cancel.png", 64, 64),
|
||||
on_decline, red=True, exit_on_confirm=False)
|
||||
|
||||
self._scroller.add_widgets([
|
||||
GreyBigButton("sunnylink", "scroll to continue",
|
||||
GreyBigButton(tr("sunnylink"), "scroll to continue",
|
||||
gui_app.texture("../../sunnypilot/selfdrive/assets/logo.png", 64, 64)),
|
||||
GreyBigButton("", "sunnylink enables secured remote access to your comma device from anywhere."),
|
||||
self._accept_button,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user