mirror of
https://github.com/dragonpilot/dragonpilot.git
synced 2026-06-26 08:22:05 +08:00
Merge branch 'devel' of https://github.com/commaai/openpilot into testing
This commit is contained in:
@@ -1,3 +1,8 @@
|
||||
dragonpilot 0.8.0
|
||||
========================
|
||||
* 基於最新 openpilot 0.8.0 devel.
|
||||
* Based on latest openpilot 0.8.0 devel.
|
||||
|
||||
dragonpilot 0.7.10.1
|
||||
========================
|
||||
* HYUNDAI_GENESIS 使用 INDI 控制器。(感謝 @donfyffe 提供)
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
dragonpilot 0.8.0
|
||||
========================
|
||||
* 基於最新 openpilot 0.8.0 devel.
|
||||
* Based on latest openpilot 0.8.0 devel.
|
||||
|
||||
dragonpilot 0.7.10.0
|
||||
========================
|
||||
* 基於最新 openpilot 0.7.10 devel.
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
2020-12-02 (0.8.0.0)
|
||||
========================
|
||||
* 基於最新 openpilot 0.8.0 devel.
|
||||
* Based on latest openpilot 0.8.0 devel.
|
||||
|
||||
2020-11-28 (0.7.10.0)
|
||||
========================
|
||||
* 加入來自 afa 的 Honda inspire, accord, crv SnG 優化。(感謝 @menwenliang 提供)
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ Code is automatically checked for style by Github Actions as part of the automat
|
||||
|
||||
We've released a [Model Port guide](https://medium.com/@comma_ai/openpilot-port-guide-for-toyota-models-e5467f4b5fe6) for porting to Toyota/Lexus models.
|
||||
|
||||
If you port openpilot to a substantially new car brand, see this more generic [Brand Port guide](https://medium.com/@comma_ai/how-to-write-a-car-port-for-openpilot-7ce0785eda84). You might also be eligible for a bounty.
|
||||
If you port openpilot to a substantially new car brand, see this more generic [Brand Port guide](https://medium.com/@comma_ai/how-to-write-a-car-port-for-openpilot-7ce0785eda84). You might also be eligible for a bounty.
|
||||
|
||||
## Pull Requests
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ Supported Cars
|
||||
| ----------| ------------------------------| ------------------| -----------------| -------------------| ------------------|
|
||||
| Acura | ILX 2016-18 | AcuraWatch Plus | openpilot | 25mph<sup>1</sup> | 25mph |
|
||||
| Acura | RDX 2016-18 | AcuraWatch Plus | openpilot | 25mph<sup>1</sup> | 12mph |
|
||||
| Acura | RDX 2020 | AcuraWatch | Stock | 0mph | 3mph |
|
||||
| Acura | RDX 2020 | All | Stock | 0mph | 3mph |
|
||||
| Honda | Accord 2018-20 | All | Stock | 0mph | 3mph |
|
||||
| Honda | Accord Hybrid 2018-20 | All | Stock | 0mph | 3mph |
|
||||
| Honda | Civic Hatchback 2017-19 | Honda Sensing | Stock | 0mph | 12mph |
|
||||
@@ -78,6 +78,7 @@ Supported Cars
|
||||
| Honda | Fit 2018-19 | Honda Sensing | openpilot | 25mph<sup>1</sup> | 12mph |
|
||||
| Honda | HR-V 2019 | Honda Sensing | openpilot | 25mph<sup>1</sup> | 12mph |
|
||||
| Honda | Insight 2019-20 | All | Stock | 0mph | 3mph |
|
||||
| Honda | Inspire 2018 | All | Stock | 0mph | 3mph |
|
||||
| Honda | Odyssey 2018-20 | Honda Sensing | openpilot | 25mph<sup>1</sup> | 0mph |
|
||||
| Honda | Passport 2019 | All | openpilot | 25mph<sup>1</sup> | 12mph |
|
||||
| Honda | Pilot 2016-19 | Honda Sensing | openpilot | 25mph<sup>1</sup> | 12mph |
|
||||
@@ -85,10 +86,11 @@ Supported Cars
|
||||
| Hyundai | Palisade 2020 | All | Stock | 0mph | 0mph |
|
||||
| Hyundai | Sonata 2020 | All | Stock | 0mph | 0mph |
|
||||
| Lexus | CT Hybrid 2017-18 | LSS | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Lexus | ES 2019 | All | openpilot | 0mph | 0mph |
|
||||
| Lexus | ES 2019-20 | All | openpilot | 0mph | 0mph |
|
||||
| Lexus | ES Hybrid 2019 | All | openpilot | 0mph | 0mph |
|
||||
| Lexus | IS 2017-2019 | All | Stock | 22mph | 0mph |
|
||||
| Lexus | IS Hybrid 2017 | All | Stock | 0mph | 0mph |
|
||||
| Lexus | NX 2018 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Lexus | NX Hybrid 2018 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Lexus | RX 2016-18 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Lexus | RX 2020 | All | openpilot | 0mph | 0mph |
|
||||
@@ -96,11 +98,11 @@ Supported Cars
|
||||
| Lexus | RX Hybrid 2020 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Avalon 2016-18 | TSS-P | Stock<sup>3</sup>| 20mph<sup>1</sup> | 0mph |
|
||||
| Toyota | Camry 2018-20 | All | Stock | 0mph<sup>4</sup> | 0mph |
|
||||
| Toyota | Camry Hybrid 2018-19 | All | Stock | 0mph<sup>4</sup> | 0mph |
|
||||
| Toyota | Camry Hybrid 2018-20 | All | Stock | 0mph<sup>4</sup> | 0mph |
|
||||
| Toyota | C-HR 2017-19 | All | Stock | 0mph | 0mph |
|
||||
| Toyota | C-HR Hybrid 2017-19 | All | Stock | 0mph | 0mph |
|
||||
| Toyota | Corolla 2017-19 | All | Stock<sup>3</sup>| 20mph<sup>1</sup> | 0mph |
|
||||
| Toyota | Corolla 2020 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Corolla 2020-21 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Corolla Hatchback 2019-20 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Corolla Hybrid 2020-21 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Highlander 2017-19 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
@@ -108,11 +110,12 @@ Supported Cars
|
||||
| Toyota | Highlander Hybrid 2017-19 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Toyota | Highlander Hybrid 2020 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Prius 2016-20 | TSS-P | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Toyota | Prius 2021 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Prius Prime 2017-20 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Toyota | Rav4 2016-18 | TSS-P | Stock<sup>3</sup>| 20mph<sup>1</sup> | 0mph |
|
||||
| Toyota | Rav4 2019-21 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Rav4 Hybrid 2016-18 | TSS-P | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
| Toyota | Rav4 Hybrid 2019-20 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Rav4 Hybrid 2019-21 | All | openpilot | 0mph | 0mph |
|
||||
| Toyota | Sienna 2018-20 | All | Stock<sup>3</sup>| 0mph | 0mph |
|
||||
|
||||
<sup>1</sup>[Comma Pedal](https://github.com/commaai/openpilot/wiki/comma-pedal) is used to provide stop-and-go capability to some of the openpilot-supported cars that don't currently support stop-and-go. ***NOTE: The Comma Pedal is not officially supported by [comma](https://comma.ai).*** <br />
|
||||
@@ -136,7 +139,7 @@ Community Maintained Cars and Features
|
||||
| Genesis | G70 2018 | All | Stock | 0mph | 0mph |
|
||||
| Genesis | G80 2018 | All | Stock | 0mph | 0mph |
|
||||
| Genesis | G90 2018 | All | Stock | 0mph | 0mph |
|
||||
| GMC | Acadia Denali 2018<sup>2</sup>| Adaptive Cruise | openpilot | 0mph | 7mph |
|
||||
| GMC | Acadia 2018<sup>1</sup> | Adaptive Cruise | openpilot | 0mph | 7mph |
|
||||
| Holden | Astra 2017<sup>1</sup> | Adaptive Cruise | openpilot | 0mph | 7mph |
|
||||
| Hyundai | Elantra 2017-19 | SCC + LKAS | Stock | 19mph | 34mph |
|
||||
| Hyundai | Genesis 2015-16 | SCC + LKAS | Stock | 19mph | 37mph |
|
||||
@@ -149,6 +152,7 @@ Community Maintained Cars and Features
|
||||
| Jeep | Grand Cherokee 2016-18 | Adaptive Cruise | Stock | 0mph | 9mph |
|
||||
| Jeep | Grand Cherokee 2019-20 | Adaptive Cruise | Stock | 0mph | 39mph |
|
||||
| Kia | Forte 2018-19 | SCC + LKAS | Stock | 0mph | 0mph |
|
||||
| Kia | Niro EV 2020 | SCC + LKAS | Stock | 0mph | 0mph |
|
||||
| Kia | Optima 2017 | SCC + LKAS | Stock | 0mph | 32mph |
|
||||
| Kia | Optima 2019 | SCC + LKAS | Stock | 0mph | 0mph |
|
||||
| Kia | Sorento 2018 | SCC + LKAS | Stock | 0mph | 0mph |
|
||||
@@ -162,8 +166,7 @@ Community Maintained Cars and Features
|
||||
| Subaru | Impreza 2017-19 | EyeSight | Stock | 0mph | 0mph |
|
||||
| Volkswagen| Golf 2015-19 | Driver Assistance | Stock | 0mph | 0mph |
|
||||
|
||||
<sup>1</sup>Requires an [OBD-II car harness](https://comma.ai/shop/products/comma-car-harness) and [community built giraffe](https://github.com/commaai/openpilot/wiki/GM). ***NOTE: disconnecting the ASCM disables Automatic Emergency Braking (AEB).*** <br />
|
||||
<sup>2</sup>Requires a custom connector for the developer [car harness](https://comma.ai/shop/products/car-harness) <br />
|
||||
<sup>1</sup>Requires an [OBD-II car harness](https://comma.ai/shop/products/comma-car-harness) and [community built ASCM harness](https://github.com/commaai/openpilot/wiki/GM#hardware). ***NOTE: disconnecting the ASCM disables Automatic Emergency Braking (AEB).*** <br />
|
||||
|
||||
Although it's not upstream, there's a community of people getting openpilot to run on Tesla's [here](https://tinkla.us/)
|
||||
|
||||
@@ -239,7 +242,6 @@ Many factors can impact the performance of openpilot DM, causing it to be unable
|
||||
* Low light conditions, such as driving at night or in dark tunnels.
|
||||
* Bright light (due to oncoming headlights, direct sunlight, etc.).
|
||||
* The driver's face is partially or completely outside field of view of the driver facing camera.
|
||||
* Right hand driving vehicles.
|
||||
* The driver facing camera is obstructed, covered, or damaged.
|
||||
|
||||
The list above does not represent an exhaustive list of situations that may interfere with proper operation of openpilot components. A driver should not rely on openpilot DM to assess their level of attention.
|
||||
@@ -269,7 +271,7 @@ Safety and Testing
|
||||
|
||||
Testing on PC
|
||||
------
|
||||
For simplified development and experimentation, openpilot can be run in the CARLA driving simulator, which allows you to develop openpilot without a car. The whole setup should only take a few minutes.
|
||||
For simplified development and experimentation, openpilot can be run in the CARLA driving simulator, which allows you to develop openpilot without a car. The whole setup should only take a few minutes.
|
||||
|
||||
Steps:
|
||||
1) Start the CARLA server on first terminal
|
||||
|
||||
+12
@@ -1,3 +1,15 @@
|
||||
Version 0.8.0 (2020-11-30)
|
||||
========================
|
||||
* New driving model: fully 3D and improved cut-in detection
|
||||
* UI draws 2 road edges, 4 lanelines and paths in 3D
|
||||
* Major fixes to cut-in detection for openpilot longitudinal
|
||||
* Grey panda is no longer supported, upgrade to comma two or black panda
|
||||
* Lexus NX 2018 support thanks to matt12eagles!
|
||||
* Kia Niro EV 2020 support thanks to nickn17!
|
||||
* Toyota Prius 2021 support thanks to rav4kumar!
|
||||
* Improved lane positioning with uncertain lanelines, wide lanes and exits
|
||||
* Improved lateral control for Prius and Subaru
|
||||
|
||||
Version 0.7.10 (2020-10-29)
|
||||
========================
|
||||
* Grey panda is deprecated, upgrade to comma two or black panda
|
||||
|
||||
+34
-42
@@ -5,6 +5,8 @@ import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import platform
|
||||
import numpy as np
|
||||
from sysconfig import get_paths
|
||||
|
||||
TICI = os.path.isfile('/TICI')
|
||||
Decider('MD5-timestamp')
|
||||
@@ -128,6 +130,10 @@ else:
|
||||
# change pythonpath to this
|
||||
lenv["PYTHONPATH"] = Dir("#").path
|
||||
|
||||
#Get the path for Python.h for cython linking
|
||||
python_path = get_paths()['include']
|
||||
numpy_path = np.get_include()
|
||||
|
||||
env = Environment(
|
||||
ENV=lenv,
|
||||
CCFLAGS=[
|
||||
@@ -159,6 +165,7 @@ env = Environment(
|
||||
"#phonelibs/linux/include",
|
||||
"#phonelibs/snpe/include",
|
||||
"#phonelibs/nanovg",
|
||||
"#selfdrive/boardd",
|
||||
"#selfdrive/common",
|
||||
"#selfdrive/camerad",
|
||||
"#selfdrive/camerad/include",
|
||||
@@ -181,50 +188,14 @@ env = Environment(
|
||||
CXXFLAGS=["-std=c++1z"] + cxxflags,
|
||||
LIBPATH=libpath + [
|
||||
"#cereal",
|
||||
"#selfdrive/boardd",
|
||||
"#selfdrive/common",
|
||||
"#phonelibs",
|
||||
]
|
||||
],
|
||||
CYTHONCFILESUFFIX=".cpp",
|
||||
tools=["default", "cython"]
|
||||
)
|
||||
|
||||
qt_env = None
|
||||
if arch in ["x86_64", "Darwin", "larch64"]:
|
||||
qt_env = env.Clone()
|
||||
|
||||
if arch == "Darwin":
|
||||
qt_env['QTDIR'] = "/usr/local/opt/qt"
|
||||
QT_BASE = "/usr/local/opt/qt/"
|
||||
qt_dirs = [
|
||||
QT_BASE + "include/",
|
||||
QT_BASE + "include/QtWidgets",
|
||||
QT_BASE + "include/QtGui",
|
||||
QT_BASE + "include/QtCore",
|
||||
QT_BASE + "include/QtDBus",
|
||||
QT_BASE + "include/QtMultimedia",
|
||||
]
|
||||
qt_env["LINKFLAGS"] += ["-F" + QT_BASE + "lib"]
|
||||
else:
|
||||
qt_env['QTDIR'] = "/usr"
|
||||
qt_dirs = [
|
||||
f"/usr/include/{real_arch}-linux-gnu/qt5",
|
||||
f"/usr/include/{real_arch}-linux-gnu/qt5/QtWidgets",
|
||||
f"/usr/include/{real_arch}-linux-gnu/qt5/QtGui",
|
||||
f"/usr/include/{real_arch}-linux-gnu/qt5/QtCore",
|
||||
f"/usr/include/{real_arch}-linux-gnu/qt5/QtDBus",
|
||||
f"/usr/include/{real_arch}-linux-gnu/qt5/QtMultimedia",
|
||||
f"/usr/include/{real_arch}-linux-gnu/qt5/QtGui/5.5.1/QtGui",
|
||||
]
|
||||
|
||||
qt_env.Tool('qt')
|
||||
qt_env['CPPPATH'] += qt_dirs
|
||||
qt_flags = [
|
||||
"-D_REENTRANT",
|
||||
"-DQT_NO_DEBUG",
|
||||
"-DQT_WIDGETS_LIB",
|
||||
"-DQT_GUI_LIB",
|
||||
"-DQT_CORE_LIB"
|
||||
]
|
||||
qt_env['CXXFLAGS'] += qt_flags
|
||||
|
||||
if os.environ.get('SCONS_CACHE'):
|
||||
cache_dir = '/tmp/scons_cache'
|
||||
|
||||
@@ -238,6 +209,9 @@ if os.environ.get('SCONS_CACHE'):
|
||||
if not os.path.isdir(cache_dir_branch) and os.path.isdir(cache_dir):
|
||||
shutil.copytree(cache_dir, cache_dir_branch)
|
||||
cache_dir = cache_dir_branch
|
||||
elif TICI:
|
||||
cache_dir = '/data/scons_cache'
|
||||
|
||||
CacheDir(cache_dir)
|
||||
|
||||
node_interval = 5
|
||||
@@ -261,9 +235,28 @@ def abspath(x):
|
||||
# rpath works elsewhere
|
||||
return x[0].path.rsplit("/", 1)[1][:-3]
|
||||
|
||||
#Cython build enviroment
|
||||
envCython = env.Clone()
|
||||
envCython["CPPPATH"] += [python_path, numpy_path]
|
||||
envCython["CCFLAGS"] += ["-Wno-#warnings", "-Wno-deprecated-declarations"]
|
||||
|
||||
python_libs = []
|
||||
if arch == "Darwin":
|
||||
envCython["LINKFLAGS"]=["-bundle", "-undefined", "dynamic_lookup"]
|
||||
elif arch == "aarch64":
|
||||
envCython["LINKFLAGS"]=["-shared"]
|
||||
|
||||
python_libs.append(os.path.basename(python_path))
|
||||
else:
|
||||
envCython["LINKFLAGS"]=["-pthread", "-shared"]
|
||||
|
||||
envCython["LIBS"] = python_libs
|
||||
|
||||
Export('envCython')
|
||||
|
||||
# still needed for apks
|
||||
zmq = 'zmq'
|
||||
Export('env', 'qt_env', 'arch', 'zmq', 'SHARED', 'USE_WEBCAM', 'QCOM_REPLAY')
|
||||
Export('env', 'arch', 'real_arch', 'zmq', 'SHARED', 'USE_WEBCAM', 'QCOM_REPLAY')
|
||||
|
||||
# cereal and messaging are shared with the system
|
||||
SConscript(['cereal/SConscript'])
|
||||
@@ -316,6 +309,5 @@ SConscript(['selfdrive/ui/SConscript'])
|
||||
if arch != "Darwin":
|
||||
SConscript(['selfdrive/logcatd/SConscript'])
|
||||
|
||||
|
||||
if arch == "x86_64":
|
||||
SConscript(['tools/lib/index_log/SConscript'])
|
||||
|
||||
+3
-2
@@ -2,6 +2,7 @@ Import('env', 'arch', 'zmq', 'cython_dependencies')
|
||||
|
||||
import shutil
|
||||
|
||||
cereal_dir = Dir('.')
|
||||
gen_dir = Dir('gen')
|
||||
messaging_dir = Dir('messaging')
|
||||
|
||||
@@ -9,12 +10,12 @@ messaging_dir = Dir('messaging')
|
||||
env.Command(["gen/c/include/c++.capnp.h", "gen/c/include/java.capnp.h"], [], "mkdir -p " + gen_dir.path + "/c/include && touch $TARGETS")
|
||||
env.Command(['gen/cpp/car.capnp.c++', 'gen/cpp/log.capnp.c++', 'gen/cpp/car.capnp.h', 'gen/cpp/log.capnp.h'],
|
||||
['car.capnp', 'log.capnp'],
|
||||
'capnpc $SOURCES --src-prefix=cereal -o c++:' + gen_dir.path + '/cpp/')
|
||||
f"capnpc --src-prefix={cereal_dir.path} $SOURCES -o c++:{gen_dir.path}/cpp/")
|
||||
|
||||
if shutil.which('capnpc-java'):
|
||||
env.Command(['gen/java/Car.java', 'gen/java/Log.java'],
|
||||
['car.capnp', 'log.capnp'],
|
||||
'capnpc $SOURCES --src-prefix=cereal -o java:' + gen_dir.path + '/java/')
|
||||
f"capnpc $SOURCES --src-prefix={cereal_dir.path} -o java:{gen_dir.path}/java/")
|
||||
|
||||
# TODO: remove non shared cereal and messaging
|
||||
cereal_objects = env.SharedObject([
|
||||
|
||||
+3
-3
@@ -73,7 +73,6 @@ struct CarEvent @0x9b1657f34caf3ad3 {
|
||||
preLaneChangeLeft @57;
|
||||
preLaneChangeRight @58;
|
||||
laneChange @59;
|
||||
invalidGiraffeToyota @60;
|
||||
internetConnectivityNeeded @61;
|
||||
communityFeatureDisallowed @62;
|
||||
lowMemory @63;
|
||||
@@ -94,8 +93,6 @@ struct CarEvent @0x9b1657f34caf3ad3 {
|
||||
startupMaster @78;
|
||||
fcw @79;
|
||||
steerSaturated @80;
|
||||
whitePandaUnsupported @81;
|
||||
startupGreyPanda @82;
|
||||
belowEngageSpeed @84;
|
||||
noGps @85;
|
||||
wrongCruiseMode @87;
|
||||
@@ -113,6 +110,9 @@ struct CarEvent @0x9b1657f34caf3ad3 {
|
||||
driverMonitorOffDEPRECATED @42;
|
||||
calibrationProgressDEPRECATED @47;
|
||||
invalidGiraffeHondaDEPRECATED @49;
|
||||
invalidGiraffeToyotaDEPRECATED @60;
|
||||
whitePandaUnsupportedDEPRECATED @81;
|
||||
startupGreyPandaDEPRECATED @82;
|
||||
canErrorPersistentDEPRECATED @83;
|
||||
focusRecoverActiveDEPRECATED @86;
|
||||
neosUpdateRequiredDEPRECATED @88;
|
||||
|
||||
+3
-13
@@ -1,14 +1,4 @@
|
||||
Import('env', 'cython_dependencies')
|
||||
Import('envCython')
|
||||
|
||||
# Build cython clock module
|
||||
env.Command(['common_pyx.so', 'clock.cpp'],
|
||||
cython_dependencies + ['common_pyx_setup.py', 'clock.pyx'],
|
||||
"cd common && python3 common_pyx_setup.py build_ext --inplace")
|
||||
|
||||
# Build cython params module
|
||||
env.Command(['params_pyx.so', 'params_pyx.cpp'],
|
||||
cython_dependencies + [
|
||||
'params_pyx_setup.py', 'params_pyx.pyx', 'params_pxd.pxd',
|
||||
'#selfdrive/common/params.cc', '#selfdrive/common/params.h',
|
||||
'#selfdrive/common/util.c', '#selfdrive/common/util.h'],
|
||||
"cd common && python3 params_pyx_setup.py build_ext --inplace")
|
||||
envCython.Program('clock.so', 'clock.pyx')
|
||||
envCython.Program('params_pyx.so', 'params_pyx.pyx')
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# distutils: language = c++
|
||||
# cython: language_level = 3
|
||||
from posix.time cimport clock_gettime, timespec, CLOCK_MONOTONIC_RAW, clockid_t
|
||||
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
from distutils.core import Extension, setup # pylint: disable=import-error,no-name-in-module
|
||||
from Cython.Build import cythonize
|
||||
|
||||
from common.cython_hacks import BuildExtWithoutPlatformSuffix
|
||||
|
||||
sourcefiles = ['clock.pyx']
|
||||
extra_compile_args = ["-std=c++1z"]
|
||||
|
||||
setup(name='common',
|
||||
cmdclass={'build_ext': BuildExtWithoutPlatformSuffix},
|
||||
ext_modules=cythonize(
|
||||
Extension(
|
||||
"common_pyx",
|
||||
language="c++",
|
||||
sources=sourcefiles,
|
||||
extra_compile_args=extra_compile_args,
|
||||
),
|
||||
nthreads=4,
|
||||
),
|
||||
)
|
||||
@@ -1,6 +1,3 @@
|
||||
Import('env', 'cython_dependencies')
|
||||
|
||||
env.Command(['simple_kalman_impl.so'],
|
||||
cython_dependencies + ['simple_kalman_impl.pyx', 'simple_kalman_impl.pxd', 'simple_kalman_setup.py'],
|
||||
"cd common/kalman && python3 simple_kalman_setup.py build_ext --inplace")
|
||||
Import('envCython')
|
||||
|
||||
envCython.Program('simple_kalman_impl.so', 'simple_kalman_impl.pyx')
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# distutils: language = c++
|
||||
# cython: language_level=3
|
||||
|
||||
cdef class KF1D:
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
from distutils.core import Extension, setup
|
||||
|
||||
from Cython.Build import cythonize
|
||||
|
||||
from common.cython_hacks import BuildExtWithoutPlatformSuffix
|
||||
|
||||
setup(name='Simple Kalman Implementation',
|
||||
cmdclass={'build_ext': BuildExtWithoutPlatformSuffix},
|
||||
ext_modules=cythonize(Extension("simple_kalman_impl",
|
||||
["simple_kalman_impl.pyx"])))
|
||||
@@ -82,3 +82,6 @@ kf = KF1D(x0=[[x0_0], [x1_0]],
|
||||
kf_speed = timeit.timeit("kf.update(1234)", setup=setup, number=10000)
|
||||
kf_old_speed = timeit.timeit("kf_old.update(1234)", setup=setup, number=10000)
|
||||
self.assertTrue(kf_speed < kf_old_speed / 4)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# cython: language_level = 3
|
||||
from libcpp cimport bool
|
||||
from libcpp.string cimport string
|
||||
from params_pxd cimport Params as c_Params
|
||||
from common.params_pxd cimport Params as c_Params
|
||||
from common.dp_conf import init_params_keys
|
||||
|
||||
import os
|
||||
@@ -70,6 +70,7 @@ keys = {
|
||||
b"Offroad_IsTakingSnapshot": [TxType.CLEAR_ON_MANAGER_START],
|
||||
b"Offroad_NeosUpdate": [TxType.CLEAR_ON_MANAGER_START],
|
||||
b"Offroad_UpdateFailed": [TxType.CLEAR_ON_MANAGER_START],
|
||||
b"Offroad_HardwareUnsupported": [TxType.CLEAR_ON_MANAGER_START],
|
||||
}
|
||||
|
||||
keys = init_params_keys(keys, [TxType.PERSISTENT])
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
import os
|
||||
import subprocess
|
||||
from distutils.core import Extension, setup
|
||||
from Cython.Build import cythonize
|
||||
|
||||
from common.cython_hacks import BuildExtWithoutPlatformSuffix
|
||||
from common.basedir import BASEDIR
|
||||
from common.hardware import TICI
|
||||
|
||||
ARCH = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip() # pylint: disable=unexpected-keyword-arg
|
||||
|
||||
sourcefiles = ['params_pyx.pyx']
|
||||
extra_compile_args = ["-std=c++11"]
|
||||
|
||||
if ARCH == "aarch64":
|
||||
if TICI:
|
||||
extra_compile_args += ["-DQCOM2"]
|
||||
else:
|
||||
extra_compile_args += ["-DQCOM"]
|
||||
|
||||
|
||||
setup(name='common',
|
||||
cmdclass={'build_ext': BuildExtWithoutPlatformSuffix},
|
||||
ext_modules=cythonize(
|
||||
Extension(
|
||||
"params_pyx",
|
||||
language="c++",
|
||||
sources=sourcefiles,
|
||||
include_dirs=[BASEDIR, os.path.join(BASEDIR, 'selfdrive')],
|
||||
extra_compile_args=extra_compile_args
|
||||
)
|
||||
)
|
||||
)
|
||||
+1
-1
@@ -5,7 +5,7 @@ import time
|
||||
import multiprocessing
|
||||
|
||||
from common.hardware import PC
|
||||
from common.common_pyx import sec_since_boot # pylint: disable=no-name-in-module, import-error
|
||||
from common.clock import sec_since_boot # pylint: disable=no-name-in-module, import-error
|
||||
|
||||
|
||||
# time step for each process
|
||||
|
||||
+8
-11
@@ -4,17 +4,14 @@ from common.basedir import BASEDIR
|
||||
|
||||
|
||||
class Spinner():
|
||||
def __init__(self, noop=False):
|
||||
# spinner is currently only implemented for android
|
||||
self.spinner_proc = None
|
||||
if not noop:
|
||||
try:
|
||||
self.spinner_proc = subprocess.Popen(["./spinner"],
|
||||
stdin=subprocess.PIPE,
|
||||
cwd=os.path.join(BASEDIR, "selfdrive", "ui", "spinner"),
|
||||
close_fds=True)
|
||||
except OSError:
|
||||
self.spinner_proc = None
|
||||
def __init__(self):
|
||||
try:
|
||||
self.spinner_proc = subprocess.Popen(["./spinner"],
|
||||
stdin=subprocess.PIPE,
|
||||
cwd=os.path.join(BASEDIR, "selfdrive", "ui"),
|
||||
close_fds=True)
|
||||
except OSError:
|
||||
self.spinner_proc = None
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
+8
-11
@@ -6,17 +6,14 @@ from common.basedir import BASEDIR
|
||||
|
||||
|
||||
class TextWindow:
|
||||
def __init__(self, s, noop=False):
|
||||
# text window is only implemented for android currently
|
||||
self.text_proc = None
|
||||
if not noop:
|
||||
try:
|
||||
self.text_proc = subprocess.Popen(["./text", s],
|
||||
stdin=subprocess.PIPE,
|
||||
cwd=os.path.join(BASEDIR, "selfdrive", "ui", "text"),
|
||||
close_fds=True)
|
||||
except OSError:
|
||||
self.text_proc = None
|
||||
def __init__(self, text):
|
||||
try:
|
||||
self.text_proc = subprocess.Popen(["./text", text],
|
||||
stdin=subprocess.PIPE,
|
||||
cwd=os.path.join(BASEDIR, "selfdrive", "ui"),
|
||||
close_fds=True)
|
||||
except OSError:
|
||||
self.text_proc = None
|
||||
|
||||
def get_status(self):
|
||||
if self.text_proc is not None:
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
Import('env', 'cython_dependencies')
|
||||
Import('envCython')
|
||||
|
||||
d = Dir('.')
|
||||
|
||||
env.Command(['transformations.so'],
|
||||
cython_dependencies + ['transformations.pxd', 'transformations.pyx',
|
||||
'coordinates.cc', 'orientation.cc', 'coordinates.hpp', 'orientation.hpp'],
|
||||
'cd ' + d.path + ' && python3 setup.py build_ext --inplace')
|
||||
envCython.Program('transformations.so', 'transformations.pyx')
|
||||
|
||||
@@ -178,7 +178,7 @@ def img_from_device(pt_device):
|
||||
def get_camera_frame_from_calib_frame(camera_frame_from_road_frame, intrinsics=fcam_intrinsics):
|
||||
camera_frame_from_ground = camera_frame_from_road_frame[:, (0, 1, 3)]
|
||||
calib_frame_from_ground = np.dot(intrinsics,
|
||||
get_view_frame_from_road_frame(0, 0, 0, 1.22))[:, (0, 1, 3)]
|
||||
get_view_frame_from_road_frame(0, 0, 0, 1.22))[:, (0, 1, 3)]
|
||||
ground_from_calib_frame = np.linalg.inv(calib_frame_from_ground)
|
||||
camera_frame_from_calib_frame = np.dot(camera_frame_from_ground, ground_from_calib_frame)
|
||||
return camera_frame_from_calib_frame
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
import numpy
|
||||
|
||||
from Cython.Build import cythonize
|
||||
from distutils.core import Extension, setup # pylint: disable=import-error,no-name-in-module
|
||||
from common.cython_hacks import BuildExtWithoutPlatformSuffix
|
||||
|
||||
setup(
|
||||
name='Cython transformations wrapper',
|
||||
cmdclass={'build_ext': BuildExtWithoutPlatformSuffix},
|
||||
ext_modules=cythonize(
|
||||
Extension(
|
||||
"transformations",
|
||||
sources=["transformations.pyx"],
|
||||
language="c++",
|
||||
extra_compile_args=["-std=c++1z", "-Wno-cpp"],
|
||||
include_dirs=[numpy.get_include()],
|
||||
),
|
||||
nthreads=4,
|
||||
)
|
||||
)
|
||||
@@ -1,18 +1,20 @@
|
||||
from transformations cimport Matrix3, Vector3, Quaternion
|
||||
from transformations cimport ECEF, NED, Geodetic
|
||||
# distutils: language = c++
|
||||
# cython: language_level = 3
|
||||
from common.transformations.transformations cimport Matrix3, Vector3, Quaternion
|
||||
from common.transformations.transformations cimport ECEF, NED, Geodetic
|
||||
|
||||
from transformations cimport euler2quat as euler2quat_c
|
||||
from transformations cimport quat2euler as quat2euler_c
|
||||
from transformations cimport quat2rot as quat2rot_c
|
||||
from transformations cimport rot2quat as rot2quat_c
|
||||
from transformations cimport euler2rot as euler2rot_c
|
||||
from transformations cimport rot2euler as rot2euler_c
|
||||
from transformations cimport rot_matrix as rot_matrix_c
|
||||
from transformations cimport ecef_euler_from_ned as ecef_euler_from_ned_c
|
||||
from transformations cimport ned_euler_from_ecef as ned_euler_from_ecef_c
|
||||
from transformations cimport geodetic2ecef as geodetic2ecef_c
|
||||
from transformations cimport ecef2geodetic as ecef2geodetic_c
|
||||
from transformations cimport LocalCoord_c
|
||||
from common.transformations.transformations cimport euler2quat as euler2quat_c
|
||||
from common.transformations.transformations cimport quat2euler as quat2euler_c
|
||||
from common.transformations.transformations cimport quat2rot as quat2rot_c
|
||||
from common.transformations.transformations cimport rot2quat as rot2quat_c
|
||||
from common.transformations.transformations cimport euler2rot as euler2rot_c
|
||||
from common.transformations.transformations cimport rot2euler as rot2euler_c
|
||||
from common.transformations.transformations cimport rot_matrix as rot_matrix_c
|
||||
from common.transformations.transformations cimport ecef_euler_from_ned as ecef_euler_from_ned_c
|
||||
from common.transformations.transformations cimport ned_euler_from_ecef as ned_euler_from_ecef_c
|
||||
from common.transformations.transformations cimport geodetic2ecef as geodetic2ecef_c
|
||||
from common.transformations.transformations cimport ecef2geodetic as ecef2geodetic_c
|
||||
from common.transformations.transformations cimport LocalCoord_c
|
||||
|
||||
|
||||
import cython
|
||||
|
||||
@@ -97,18 +97,17 @@ unsigned int volkswagen_crc(unsigned int address, uint64_t d, int l) {
|
||||
// a magic variable padding byte tacked onto the end of the payload.
|
||||
// https://www.autosar.org/fileadmin/user_upload/standards/classic/4-3/AUTOSAR_SWS_CRCLibrary.pdf
|
||||
|
||||
uint8_t *dat = (uint8_t *)&d;
|
||||
uint8_t crc = 0xFF; // Standard init value for CRC8 8H2F/AUTOSAR
|
||||
|
||||
// CRC the payload first, skipping over the first byte where the CRC lives.
|
||||
for (int i = 1; i < l; i++) {
|
||||
crc ^= dat[i];
|
||||
crc ^= (d >> (i*8)) & 0xFF;
|
||||
crc = crc8_lut_8h2f[crc];
|
||||
}
|
||||
|
||||
// Look up and apply the magic final CRC padding byte, which permutes by CAN
|
||||
// address, and additionally (for SOME addresses) by the message counter.
|
||||
uint8_t counter = dat[1] & 0x0F;
|
||||
uint8_t counter = ((d >> 8) & 0xFF) & 0x0F;
|
||||
switch(address) {
|
||||
case 0x86: // LWI_01 Steering Angle
|
||||
crc ^= (uint8_t[]){0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86}[counter];
|
||||
@@ -176,11 +175,9 @@ unsigned int pedal_checksum(uint64_t d, int l) {
|
||||
d >>= ((8-l)*8); // remove padding
|
||||
d >>= 8; // remove checksum
|
||||
|
||||
uint8_t *dat = (uint8_t *)&d;
|
||||
|
||||
int i, j;
|
||||
for (i = 0; i < l - 1; i++) {
|
||||
crc ^= dat[i];
|
||||
crc ^= (d >> (i*8)) & 0xFF;
|
||||
for (j = 0; j < 8; j++) {
|
||||
if ((crc & 0x80) != 0) {
|
||||
crc = (uint8_t)((crc << 1) ^ poly);
|
||||
|
||||
@@ -424,14 +424,6 @@ BO_ 956 GEAR_PACKET: 8 XXX
|
||||
SG_ GEAR : 13|6@0+ (1,0) [0|63] "" XXX
|
||||
SG_ ECON_ON : 40|1@0+ (1,0) [0|1] "" XXX
|
||||
|
||||
BO_ 1653 Date_Time: 8 XXX
|
||||
SG_ Year : 23|8@0+ (1,0) [0|255] "" XXX
|
||||
SG_ Month : 31|8@0+ (1,0) [0|255] "" XXX
|
||||
SG_ Day : 39|8@0+ (1,0) [0|255] "" XXX
|
||||
SG_ Hour : 47|8@0+ (1,0) [0|255] "" XXX
|
||||
SG_ Minute : 55|8@0+ (1,0) [0|255] "" XXX
|
||||
SG_ Second : 63|8@0+ (1,0) [0|255] "" XXX
|
||||
|
||||
CM_ SG_ 548 BRAKE_PRESSURE "seems prop to pedal force";
|
||||
CM_ SG_ 548 BRAKE_POSITION "seems proportional to pedal displacement, unclear the max value of 0x1c8";
|
||||
CM_ SG_ 610 TYPE "seems 1 on Corolla, 0 on all others";
|
||||
|
||||
@@ -72,11 +72,9 @@ void uno_set_usb_power_mode(uint8_t mode) {
|
||||
bool valid = false;
|
||||
switch (mode) {
|
||||
case USB_POWER_CLIENT:
|
||||
uno_set_phone_power(false);
|
||||
valid = true;
|
||||
break;
|
||||
case USB_POWER_CDP:
|
||||
uno_set_phone_power(true);
|
||||
uno_bootkick();
|
||||
valid = true;
|
||||
break;
|
||||
|
||||
@@ -35,7 +35,9 @@ else
|
||||
git checkout --orphan release2-staging
|
||||
fi
|
||||
|
||||
VERSION=$(cat selfdrive/common/version.h | awk -F\" '{print $2}')
|
||||
VERSION=$(cat selfdrive/common/version.h | awk -F[\"-] '{print $2}')
|
||||
echo "#define COMMA_VERSION \"$VERSION-release\"" > selfdrive/common/version.h
|
||||
|
||||
git commit -m "openpilot v$VERSION"
|
||||
|
||||
# Build signed panda firmware
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
@@ -1,4 +1,4 @@
|
||||
Import('env', 'common', 'cereal', 'messaging', 'cython_dependencies')
|
||||
Import('env', 'envCython', 'common', 'cereal', 'messaging')
|
||||
# dp - Add read dp_disable_relay value
|
||||
if FindFile('dp_disable_relay', '/data/params/d') != None:
|
||||
with open('/data/params/d/dp_disable_relay') as f:
|
||||
@@ -7,6 +7,4 @@ if FindFile('dp_disable_relay', '/data/params/d') != None:
|
||||
env.Program('boardd', ['boardd.cc', 'panda.cc', 'pigeon.cc'], LIBS=['usb-1.0', common, cereal, messaging, 'pthread', 'zmq', 'capnp', 'kj'])
|
||||
env.Library('libcan_list_to_can_capnp', ['can_list_to_can_capnp.cc'])
|
||||
|
||||
env.Command(['boardd_api_impl.so', 'boardd_api_impl.cpp'],
|
||||
cython_dependencies + ['libcan_list_to_can_capnp.a', 'boardd_api_impl.pyx', 'boardd_setup.py'],
|
||||
"cd selfdrive/boardd && python3 boardd_setup.py build_ext --inplace")
|
||||
envCython.Program('boardd_api_impl.so', 'boardd_api_impl.pyx', LIBS=["can_list_to_can_capnp", 'capnp', 'kj'] + envCython["LIBS"])
|
||||
|
||||
@@ -56,7 +56,9 @@ struct tm get_time(){
|
||||
}
|
||||
|
||||
bool time_valid(struct tm sys_time){
|
||||
return 1900 + sys_time.tm_year >= 2019;
|
||||
int year = 1900 + sys_time.tm_year;
|
||||
int month = 1 + sys_time.tm_mon;
|
||||
return (year > 2020) || (year == 2020 && month >= 10);
|
||||
}
|
||||
|
||||
void safety_setter_thread() {
|
||||
@@ -107,8 +109,9 @@ void safety_setter_thread() {
|
||||
capnp::FlatArrayMessageReader cmsg(amsg);
|
||||
cereal::CarParams::Reader car_params = cmsg.getRoot<cereal::CarParams>();
|
||||
cereal::CarParams::SafetyModel safety_model = car_params.getSafetyModel();
|
||||
LOGW("setting unsafe mode");
|
||||
panda->set_unsafe_mode(9);
|
||||
|
||||
panda->set_unsafe_mode(9); // see safety_declarations.h for allowed values
|
||||
|
||||
auto safety_param = car_params.getSafetyParam();
|
||||
LOGW("setting safety model: %d with param %d", (int)safety_model, safety_param);
|
||||
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
from distutils.core import Extension, setup
|
||||
from Cython.Build import cythonize
|
||||
|
||||
from common.cython_hacks import BuildExtWithoutPlatformSuffix
|
||||
|
||||
libraries = ['can_list_to_can_capnp', 'capnp', 'kj']
|
||||
|
||||
setup(name='Boardd API Implementation',
|
||||
cmdclass={'build_ext': BuildExtWithoutPlatformSuffix},
|
||||
ext_modules=cythonize(
|
||||
Extension(
|
||||
"boardd_api_impl",
|
||||
libraries=libraries,
|
||||
library_dirs=[
|
||||
'./',
|
||||
],
|
||||
sources=['boardd_api_impl.pyx'],
|
||||
language="c++",
|
||||
extra_compile_args=["-std=c++1z", "-Wno-nullability-completeness"],
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -188,8 +188,8 @@ void Panda::set_safety_model(cereal::CarParams::SafetyModel safety_model, int sa
|
||||
usb_write(0xdc, (uint16_t)safety_model, safety_param);
|
||||
}
|
||||
|
||||
void Panda::set_unsafe_mode(uint16_t wValue){
|
||||
usb_write(0xdf, wValue, 0);
|
||||
void Panda::set_unsafe_mode(uint16_t unsafe_mode) {
|
||||
usb_write(0xdf, unsafe_mode, 0);
|
||||
}
|
||||
|
||||
cereal::HealthData::HwType Panda::get_hw_type() {
|
||||
@@ -283,7 +283,6 @@ const char* Panda::get_serial(){
|
||||
|
||||
delete[] serial_buf;
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
void Panda::set_power_saving(bool power_saving){
|
||||
|
||||
@@ -63,7 +63,7 @@ class Panda {
|
||||
// Panda functionality
|
||||
cereal::HealthData::HwType get_hw_type();
|
||||
void set_safety_model(cereal::CarParams::SafetyModel safety_model, int safety_param=0);
|
||||
void set_unsafe_mode(uint16_t wValue);
|
||||
void set_unsafe_mode(uint16_t unsafe_mode);
|
||||
void set_rtc(struct tm sys_time);
|
||||
struct tm get_rtc();
|
||||
void set_fan_speed(uint16_t fan_speed);
|
||||
|
||||
@@ -11,10 +11,6 @@ if arch == "aarch64":
|
||||
elif arch == "larch64":
|
||||
libs += ['atomic']
|
||||
cameras = ['cameras/camera_qcom2.cc']
|
||||
# no screen
|
||||
# env = env.Clone()
|
||||
# env.Append(CXXFLAGS = '-DNOSCREEN')
|
||||
# env.Append(CFLAGS = '-DNOSCREEN')
|
||||
else:
|
||||
if USE_WEBCAM:
|
||||
libs += ['opencv_core', 'opencv_highgui', 'opencv_imgproc', 'opencv_videoio']
|
||||
@@ -28,8 +24,9 @@ else:
|
||||
|
||||
if arch == "Darwin":
|
||||
del libs[libs.index('OpenCL')]
|
||||
del libs[libs.index(gpucommon)][gpucommon.index('GL')]
|
||||
env = env.Clone()
|
||||
env['FRAMEWORKS'] = ['OpenCL']
|
||||
env['FRAMEWORKS'] = ['OpenCL', 'OpenGL']
|
||||
|
||||
env.SharedLibrary('snapshot/visionipc',
|
||||
["#selfdrive/common/visionipc.c", "#selfdrive/common/ipc.c"])
|
||||
|
||||
@@ -24,6 +24,12 @@
|
||||
#include "common/util.h"
|
||||
#include "imgproc/utils.h"
|
||||
|
||||
const int env_xmin = getenv("XMIN") ? atoi(getenv("XMIN")) : 0;
|
||||
const int env_xmax = getenv("XMAX") ? atoi(getenv("XMAX")) : -1;
|
||||
const int env_ymin = getenv("YMIN") ? atoi(getenv("YMIN")) : 0;
|
||||
const int env_ymax = getenv("YMAX") ? atoi(getenv("YMAX")) : -1;
|
||||
const int env_scale = getenv("SCALE") ? atoi(getenv("SCALE")) : 1;
|
||||
|
||||
static cl_program build_debayer_program(cl_device_id device_id, cl_context context, const CameraInfo *ci, const CameraBuf *b) {
|
||||
char args[4096];
|
||||
snprintf(args, sizeof(args),
|
||||
@@ -207,7 +213,6 @@ void CameraBuf::stop() {
|
||||
|
||||
void fill_frame_data(cereal::FrameData::Builder &framed, const FrameMetadata &frame_data, uint32_t cnt) {
|
||||
framed.setFrameId(frame_data.frame_id);
|
||||
framed.setEncodeId(cnt);
|
||||
framed.setTimestampEof(frame_data.timestamp_eof);
|
||||
framed.setFrameLength(frame_data.frame_length);
|
||||
framed.setIntegLines(frame_data.integ_lines);
|
||||
@@ -219,6 +224,27 @@ void fill_frame_data(cereal::FrameData::Builder &framed, const FrameMetadata &fr
|
||||
framed.setGainFrac(frame_data.gain_frac);
|
||||
}
|
||||
|
||||
void fill_frame_image(cereal::FrameData::Builder &framed, uint8_t *dat, int w, int h, int stride) {
|
||||
if (dat != nullptr) {
|
||||
int scale = env_scale;
|
||||
int x_min = env_xmin; int y_min = env_ymin; int x_max = w-1; int y_max = h-1;
|
||||
if (env_xmax != -1) x_max = env_xmax;
|
||||
if (env_ymax != -1) y_max = env_ymax;
|
||||
int new_width = (x_max - x_min + 1) / scale;
|
||||
int new_height = (y_max - y_min + 1) / scale;
|
||||
uint8_t *resized_dat = new uint8_t[new_width*new_height*3];
|
||||
|
||||
int goff = x_min*3 + y_min*stride;
|
||||
for (int r=0;r<new_height;r++) {
|
||||
for (int c=0;c<new_width;c++) {
|
||||
memcpy(&resized_dat[(r*new_width+c)*3], &dat[goff+r*stride*scale+c*3*scale], 3*sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
framed.setImage(kj::arrayPtr((const uint8_t*)resized_dat, new_width*new_height*3));
|
||||
delete[] resized_dat;
|
||||
}
|
||||
}
|
||||
|
||||
void create_thumbnail(MultiCameraState *s, CameraState *c, uint8_t *bgr_ptr) {
|
||||
const CameraBuf *b = &c->buf;
|
||||
|
||||
@@ -402,5 +428,8 @@ void common_camera_process_front(SubMaster *sm, PubMaster *pm, CameraState *c, i
|
||||
auto framed = msg.initEvent().initFrontFrame();
|
||||
framed.setFrameType(cereal::FrameData::FrameType::FRONT);
|
||||
fill_frame_data(framed, b->cur_frame_data, cnt);
|
||||
if (env_send_front) {
|
||||
fill_frame_image(framed, (uint8_t*)b->cur_rgb_buf->addr, b->rgb_width, b->rgb_height, b->rgb_stride);
|
||||
}
|
||||
pm->send("frontFrame", msg);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
@@ -2141,6 +2140,9 @@ void camera_process_frame(MultiCameraState *s, CameraState *c, int cnt) {
|
||||
MessageBuilder msg;
|
||||
auto framed = msg.initEvent().initFrame();
|
||||
fill_frame_data(framed, b->cur_frame_data, cnt);
|
||||
if (env_send_rear) {
|
||||
fill_frame_image(framed, (uint8_t*)b->cur_rgb_buf->addr, b->rgb_width, b->rgb_height, b->rgb_stride);
|
||||
}
|
||||
framed.setFocusVal(kj::ArrayPtr<const int16_t>(&s->rear.focus[0], NUM_FOCUS));
|
||||
framed.setFocusConf(kj::ArrayPtr<const uint8_t>(&s->rear.confidence[0], NUM_FOCUS));
|
||||
framed.setSharpnessScore(kj::ArrayPtr<const uint16_t>(&s->lapres[0], ARRAYSIZE(s->lapres)));
|
||||
|
||||
@@ -13,24 +13,20 @@ from common.dp_common import is_online
|
||||
import threading
|
||||
import selfdrive.crash as crash
|
||||
|
||||
from cereal import car, log
|
||||
from cereal import car
|
||||
EventName = car.CarEvent.EventName
|
||||
HwType = log.HealthData.HwType
|
||||
|
||||
|
||||
def get_startup_event(car_recognized, controller_available, hw_type):
|
||||
# if comma_remote and tested_branch:
|
||||
# event = EventName.startup
|
||||
# else:
|
||||
# event = EventName.startupMaster
|
||||
event = EventName.startup
|
||||
def get_startup_event(car_recognized, controller_available):
|
||||
if comma_remote and tested_branch:
|
||||
event = EventName.startup
|
||||
else:
|
||||
event = EventName.startupMaster
|
||||
|
||||
if not car_recognized:
|
||||
event = EventName.startupNoCar
|
||||
elif car_recognized and not controller_available:
|
||||
event = EventName.startupNoControl
|
||||
# elif hw_type == HwType.greyPanda:
|
||||
# event = EventName.startupGreyPanda
|
||||
return event
|
||||
|
||||
|
||||
@@ -89,15 +85,22 @@ def only_toyota_left(candidate_cars):
|
||||
|
||||
|
||||
# **** for use live only ****
|
||||
def fingerprint(logcan, sendcan, has_relay):
|
||||
fixed_fingerprint = os.environ.get('FINGERPRINT', "") or Params().get('dp_car_selected', encoding='utf8')
|
||||
def fingerprint(logcan, sendcan):
|
||||
params = Params()
|
||||
car_selected = params.get('dp_car_selected', encoding='utf8')
|
||||
car_detected = params.get('dp_car_detected', encoding='utf8')
|
||||
if car_selected == "" and car_detected != "":
|
||||
params.put('dp_car_selected', car_detected)
|
||||
params.put('dp_car_detected', "")
|
||||
|
||||
fixed_fingerprint = os.environ.get('FINGERPRINT', "") or params.get('dp_car_selected', encoding='utf8')
|
||||
skip_fw_query = os.environ.get('SKIP_FW_QUERY', False)
|
||||
|
||||
if has_relay and not fixed_fingerprint and not skip_fw_query:
|
||||
if not fixed_fingerprint and not skip_fw_query:
|
||||
# Vin query only reliably works thorugh OBDII
|
||||
bus = 1
|
||||
|
||||
cached_params = Params().get("CarParamsCache")
|
||||
cached_params = params.get("CarParamsCache")
|
||||
if cached_params is not None:
|
||||
cached_params = car.CarParams.from_bytes(cached_params)
|
||||
if cached_params.carName == "mock":
|
||||
@@ -149,8 +152,7 @@ def fingerprint(logcan, sendcan, has_relay):
|
||||
# Toyota needs higher time to fingerprint, since DSU does not broadcast immediately
|
||||
if only_toyota_left(candidate_cars[b]):
|
||||
frame_fingerprint = 100 # 1s
|
||||
if len(candidate_cars[b]) == 1:
|
||||
if frame > frame_fingerprint:
|
||||
if len(candidate_cars[b]) == 1 and frame > frame_fingerprint:
|
||||
# fingerprint done
|
||||
car_fingerprint = candidate_cars[b][0]
|
||||
|
||||
@@ -177,8 +179,8 @@ def fingerprint(logcan, sendcan, has_relay):
|
||||
return car_fingerprint, finger, vin, car_fw, source
|
||||
|
||||
|
||||
def get_car(logcan, sendcan, has_relay=False):
|
||||
candidate, fingerprints, vin, car_fw, source = fingerprint(logcan, sendcan, has_relay)
|
||||
def get_car(logcan, sendcan):
|
||||
candidate, fingerprints, vin, car_fw, source = fingerprint(logcan, sendcan)
|
||||
|
||||
if candidate is None:
|
||||
cloudlog.warning("car doesn't match any fingerprints: %r", fingerprints)
|
||||
@@ -189,7 +191,7 @@ def get_car(logcan, sendcan, has_relay=False):
|
||||
x.start()
|
||||
|
||||
CarInterface, CarController, CarState = interfaces[candidate]
|
||||
car_params = CarInterface.get_params(candidate, fingerprints, has_relay, car_fw)
|
||||
car_params = CarInterface.get_params(candidate, fingerprints, car_fw)
|
||||
car_params.carVin = vin
|
||||
car_params.carFw = car_fw
|
||||
car_params.fingerprintSource = source
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
from cereal import car
|
||||
from selfdrive.car.chrysler.values import Ecu, ECU_FINGERPRINT, CAR, FINGERPRINTS
|
||||
from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, is_ecu_disconnected, gen_empty_fingerprint
|
||||
from selfdrive.car.chrysler.values import CAR
|
||||
from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint
|
||||
from selfdrive.car.interfaces import CarInterfaceBase
|
||||
from common.dp_common import common_interface_atl, common_interface_get_params_lqr
|
||||
|
||||
@@ -11,11 +11,11 @@ class CarInterface(CarInterfaceBase):
|
||||
return float(accel) / 3.0
|
||||
|
||||
@staticmethod
|
||||
def get_params(candidate, fingerprint=None, has_relay=False, car_fw=None):
|
||||
def get_params(candidate, fingerprint=None, car_fw=None):
|
||||
if fingerprint is None:
|
||||
fingerprint = gen_empty_fingerprint()
|
||||
|
||||
ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay)
|
||||
ret = CarInterfaceBase.get_std_params(candidate, fingerprint)
|
||||
ret.carName = "chrysler"
|
||||
ret.safetyModel = car.CarParams.SafetyModel.chrysler
|
||||
ret.lateralTuning.init('pid')
|
||||
@@ -56,8 +56,7 @@ class CarInterface(CarInterfaceBase):
|
||||
# mass and CG position, so all cars will have approximately similar dyn behaviors
|
||||
ret.tireStiffnessFront, ret.tireStiffnessRear = scale_tire_stiffness(ret.mass, ret.wheelbase, ret.centerToFront)
|
||||
|
||||
ret.enableCamera = is_ecu_disconnected(fingerprint[0], FINGERPRINTS, ECU_FINGERPRINT, candidate, Ecu.fwdCamera) or has_relay
|
||||
print("ECU Camera Simulated: {0}".format(ret.enableCamera))
|
||||
ret.enableCamera = True
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
@@ -91,8 +91,3 @@ DBC = {
|
||||
}
|
||||
|
||||
STEER_THRESHOLD = 120
|
||||
|
||||
|
||||
ECU_FINGERPRINT = {
|
||||
Ecu.fwdCamera: [0x292], # lkas cmd
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
from cereal import car
|
||||
from selfdrive.swaglog import cloudlog
|
||||
from selfdrive.config import Conversions as CV
|
||||
from selfdrive.car.ford.values import MAX_ANGLE, Ecu, ECU_FINGERPRINT, FINGERPRINTS
|
||||
from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, is_ecu_disconnected, gen_empty_fingerprint
|
||||
from selfdrive.car.ford.values import MAX_ANGLE
|
||||
from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint
|
||||
from selfdrive.car.interfaces import CarInterfaceBase
|
||||
from common.dp_common import common_interface_atl, common_interface_get_params_lqr
|
||||
|
||||
@@ -14,8 +14,8 @@ class CarInterface(CarInterfaceBase):
|
||||
return float(accel) / 3.0
|
||||
|
||||
@staticmethod
|
||||
def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=None):
|
||||
ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay)
|
||||
def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None):
|
||||
ret = CarInterfaceBase.get_std_params(candidate, fingerprint)
|
||||
ret.carName = "ford"
|
||||
ret.safetyModel = car.CarParams.SafetyModel.ford
|
||||
ret.dashcamOnly = True
|
||||
@@ -47,7 +47,7 @@ class CarInterface(CarInterfaceBase):
|
||||
|
||||
ret.steerControlType = car.CarParams.SteerControlType.angle
|
||||
|
||||
ret.enableCamera = is_ecu_disconnected(fingerprint[0], FINGERPRINTS, ECU_FINGERPRINT, candidate, Ecu.fwdCamera) or has_relay
|
||||
ret.enableCamera = True
|
||||
cloudlog.warning("ECU Camera Simulated: %r", ret.enableCamera)
|
||||
|
||||
return ret
|
||||
|
||||
@@ -15,10 +15,6 @@ FINGERPRINTS = {
|
||||
}],
|
||||
}
|
||||
|
||||
ECU_FINGERPRINT = {
|
||||
Ecu.fwdCamera: [970, 973, 984]
|
||||
}
|
||||
|
||||
DBC = {
|
||||
CAR.FUSION: dbc_dict('ford_fusion_2018_pt', 'ford_fusion_2018_adas'),
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#!/usr/bin/env python3
|
||||
from cereal import car
|
||||
from selfdrive.config import Conversions as CV
|
||||
from selfdrive.car.gm.values import CAR, Ecu, ECU_FINGERPRINT, CruiseButtons, \
|
||||
AccState, FINGERPRINTS
|
||||
from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, is_ecu_disconnected, gen_empty_fingerprint
|
||||
from selfdrive.car.gm.values import CAR, CruiseButtons, \
|
||||
AccState
|
||||
from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint
|
||||
from selfdrive.car.interfaces import CarInterfaceBase
|
||||
from common.dp_common import common_interface_atl, common_interface_get_params_lqr
|
||||
|
||||
@@ -17,8 +17,8 @@ class CarInterface(CarInterfaceBase):
|
||||
return float(accel) / 4.0
|
||||
|
||||
@staticmethod
|
||||
def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=None):
|
||||
ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay)
|
||||
def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None):
|
||||
ret = CarInterfaceBase.get_std_params(candidate, fingerprint)
|
||||
ret.carName = "gm"
|
||||
ret.safetyModel = car.CarParams.SafetyModel.gm
|
||||
ret.enableCruise = False # stock cruise control is kept off
|
||||
@@ -31,7 +31,7 @@ class CarInterface(CarInterfaceBase):
|
||||
# Presence of a camera on the object bus is ok.
|
||||
# Have to go to read_only if ASCM is online (ACC-enabled cars),
|
||||
# or camera is on powertrain bus (LKA cars without ACC).
|
||||
ret.enableCamera = is_ecu_disconnected(fingerprint[0], FINGERPRINTS, ECU_FINGERPRINT, candidate, Ecu.fwdCamera) or has_relay
|
||||
ret.enableCamera = True
|
||||
ret.openpilotLongitudinalControl = ret.enableCamera
|
||||
tire_stiffness_factor = 0.444 # not optimized yet
|
||||
|
||||
|
||||
@@ -70,10 +70,6 @@ FINGERPRINTS = {
|
||||
|
||||
STEER_THRESHOLD = 1.0
|
||||
|
||||
ECU_FINGERPRINT = {
|
||||
Ecu.fwdCamera: [384, 715] # 384 = "ASCMLKASteeringCmd", 715 = "ASCMGasRegenCmd"
|
||||
}
|
||||
|
||||
DBC = {
|
||||
CAR.HOLDEN_ASTRA: dbc_dict('gm_global_a_powertrain', 'gm_global_a_object', chassis_dbc='gm_global_a_chassis'),
|
||||
CAR.VOLT: dbc_dict('gm_global_a_powertrain', 'gm_global_a_object', chassis_dbc='gm_global_a_chassis'),
|
||||
|
||||
@@ -179,37 +179,35 @@ class CarController():
|
||||
# Send steering command.
|
||||
idx = frame % 4
|
||||
can_sends.append(hondacan.create_steering_control(self.packer, apply_steer,
|
||||
lkas_active, CS.CP.carFingerprint, idx, CS.CP.isPandaBlack, CS.CP.openpilotLongitudinalControl))
|
||||
lkas_active, CS.CP.carFingerprint, idx, CS.CP.openpilotLongitudinalControl))
|
||||
|
||||
# Send dashboard UI commands.
|
||||
if not dragonconf.dpAtl and (frame % 10) == 0:
|
||||
idx = (frame//10) % 4
|
||||
can_sends.extend(hondacan.create_ui_commands(self.packer, pcm_speed, hud, CS.CP.carFingerprint, CS.is_metric, idx, CS.CP.isPandaBlack, CS.CP.openpilotLongitudinalControl, CS.stock_hud))
|
||||
can_sends.extend(hondacan.create_ui_commands(self.packer, pcm_speed, hud, CS.CP.carFingerprint, CS.is_metric, idx, CS.CP.openpilotLongitudinalControl, CS.stock_hud))
|
||||
|
||||
if not CS.CP.openpilotLongitudinalControl:
|
||||
if (frame % 2) == 0:
|
||||
idx = frame // 2
|
||||
can_sends.append(hondacan.create_bosch_supplemental_1(self.packer, CS.CP.carFingerprint, idx, CS.CP.isPandaBlack))
|
||||
can_sends.append(hondacan.create_bosch_supplemental_1(self.packer, CS.CP.carFingerprint, idx))
|
||||
if dragonconf.dpAtl:
|
||||
pass
|
||||
# If using stock ACC, spam cancel command to kill gas when OP disengages.
|
||||
elif not dragonconf.dpAllowGas and pcm_cancel_cmd:
|
||||
can_sends.append(hondacan.spam_buttons_command(self.packer, CruiseButtons.CANCEL, idx, CS.CP.carFingerprint, CS.CP.isPandaBlack))
|
||||
can_sends.append(hondacan.spam_buttons_command(self.packer, CruiseButtons.CANCEL, idx, CS.CP.carFingerprint))
|
||||
elif CS.out.cruiseState.standstill:
|
||||
if CS.CP.carFingerprint in (CAR.ACCORD, CAR.ACCORD_15, CAR.ACCORDH):
|
||||
rough_lead_speed = self.rough_speed(CS.lead_distance)
|
||||
if CS.lead_distance > (self.stopped_lead_distance + 15.0) or rough_lead_speed > 0.1:
|
||||
self.stopped_lead_distance = 0.0
|
||||
can_sends.append(
|
||||
hondacan.spam_buttons_command(self.packer, CruiseButtons.RES_ACCEL, idx, CS.CP.carFingerprint,
|
||||
CS.CP.isPandaBlack))
|
||||
hondacan.spam_buttons_command(self.packer, CruiseButtons.RES_ACCEL, idx, CS.CP.carFingerprint))
|
||||
elif CS.CP.carFingerprint in (CAR.CIVIC_BOSCH, CAR.CRV_HYBRID):
|
||||
if CS.hud_lead == 1:
|
||||
can_sends.append(
|
||||
hondacan.spam_buttons_command(self.packer, CruiseButtons.RES_ACCEL, idx, CS.CP.carFingerprint,
|
||||
CS.CP.isPandaBlack))
|
||||
hondacan.spam_buttons_command(self.packer, CruiseButtons.RES_ACCEL, idx, CS.CP.carFingerprint))
|
||||
else:
|
||||
can_sends.append(hondacan.spam_buttons_command(self.packer, CruiseButtons.RES_ACCEL, idx, CS.CP.carFingerprint,CS.CP.isPandaBlack))
|
||||
can_sends.append(hondacan.spam_buttons_command(self.packer, CruiseButtons.RES_ACCEL, idx, CS.CP.carFingerprint))
|
||||
else:
|
||||
self.stopped_lead_distance = CS.lead_distance
|
||||
self.prev_lead_distance = CS.lead_distance
|
||||
@@ -226,7 +224,7 @@ class CarController():
|
||||
apply_brake = int(clip(self.brake_last * P.BRAKE_MAX, 0, P.BRAKE_MAX - 1))
|
||||
pump_on, self.last_pump_ts = brake_pump_hysteresis(apply_brake, self.apply_brake_last, self.last_pump_ts, ts)
|
||||
can_sends.append(hondacan.create_brake_command(self.packer, apply_brake, pump_on,
|
||||
pcm_override, pcm_cancel_cmd, hud.fcw, idx, CS.CP.carFingerprint, CS.CP.isPandaBlack, CS.stock_brake))
|
||||
pcm_override, pcm_cancel_cmd, hud.fcw, idx, CS.CP.carFingerprint, CS.stock_brake))
|
||||
self.apply_brake_last = apply_brake
|
||||
|
||||
if CS.CP.enableGasInterceptor:
|
||||
|
||||
@@ -361,7 +361,7 @@ class CarState(CarStateBase):
|
||||
@staticmethod
|
||||
def get_can_parser(CP):
|
||||
signals, checks = get_can_signals(CP)
|
||||
bus_pt = 1 if CP.isPandaBlack and CP.carFingerprint in HONDA_BOSCH else 0
|
||||
bus_pt = 1 if CP.carFingerprint in HONDA_BOSCH else 0
|
||||
checks = []
|
||||
return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, bus_pt)
|
||||
|
||||
@@ -386,10 +386,8 @@ class CarState(CarStateBase):
|
||||
checks = [(0xe4, 100)]
|
||||
if CP.carFingerprint in [CAR.CRV, CAR.CRV_EU, CAR.ACURA_RDX, CAR.ODYSSEY_CHN]:
|
||||
checks = [(0x194, 100)]
|
||||
|
||||
bus_cam = 1 if CP.carFingerprint in HONDA_BOSCH and not CP.isPandaBlack else 2
|
||||
checks = []
|
||||
return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, bus_cam)
|
||||
return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 2)
|
||||
|
||||
@staticmethod
|
||||
def get_body_can_parser(CP):
|
||||
|
||||
@@ -7,24 +7,19 @@ from selfdrive.car.honda.values import HONDA_BOSCH
|
||||
# 2 = ACC-CAN - camera side
|
||||
# 3 = F-CAN A - OBDII port
|
||||
|
||||
# CAN bus layout with giraffe
|
||||
# 0 = F-CAN B - powertrain
|
||||
# 1 = ACC-CAN - camera side
|
||||
# 2 = ACC-CAN - radar side
|
||||
|
||||
def get_pt_bus(car_fingerprint, has_relay):
|
||||
return 1 if car_fingerprint in HONDA_BOSCH and has_relay else 0
|
||||
def get_pt_bus(car_fingerprint):
|
||||
return 1 if car_fingerprint in HONDA_BOSCH else 0
|
||||
|
||||
|
||||
def get_lkas_cmd_bus(car_fingerprint, has_relay, radar_disabled=False):
|
||||
def get_lkas_cmd_bus(car_fingerprint, radar_disabled=False):
|
||||
if radar_disabled:
|
||||
# when radar is disabled, steering commands are sent directly to powertrain bus
|
||||
return get_pt_bus(car_fingerprint, has_relay)
|
||||
return get_pt_bus(car_fingerprint)
|
||||
# normally steering commands are sent to radar, which forwards them to powertrain bus
|
||||
return 2 if car_fingerprint in HONDA_BOSCH and not has_relay else 0
|
||||
return 0
|
||||
|
||||
|
||||
def create_brake_command(packer, apply_brake, pump_on, pcm_override, pcm_cancel_cmd, fcw, idx, car_fingerprint, has_relay, stock_brake):
|
||||
def create_brake_command(packer, apply_brake, pump_on, pcm_override, pcm_cancel_cmd, fcw, idx, car_fingerprint, stock_brake):
|
||||
# TODO: do we loose pressure if we keep pump off for long?
|
||||
brakelights = apply_brake > 0
|
||||
brake_rq = apply_brake > 0
|
||||
@@ -45,13 +40,13 @@ def create_brake_command(packer, apply_brake, pump_on, pcm_override, pcm_cancel_
|
||||
"AEB_REQ_2": 0,
|
||||
"AEB_STATUS": 0,
|
||||
}
|
||||
bus = get_pt_bus(car_fingerprint, has_relay)
|
||||
bus = get_pt_bus(car_fingerprint)
|
||||
return packer.make_can_msg("BRAKE_COMMAND", bus, values, idx)
|
||||
|
||||
|
||||
def create_acc_commands(packer, enabled, accel, gas, idx, stopping, starting, car_fingerprint, has_relay):
|
||||
def create_acc_commands(packer, enabled, accel, gas, idx, stopping, starting, car_fingerprint):
|
||||
commands = []
|
||||
bus = get_pt_bus(car_fingerprint, has_relay)
|
||||
bus = get_pt_bus(car_fingerprint)
|
||||
|
||||
control_on = 5 if enabled else 0
|
||||
# no gas = -30000
|
||||
@@ -84,31 +79,31 @@ def create_acc_commands(packer, enabled, accel, gas, idx, stopping, starting, ca
|
||||
|
||||
return commands
|
||||
|
||||
def create_steering_control(packer, apply_steer, lkas_active, car_fingerprint, idx, has_relay, radar_disabled):
|
||||
def create_steering_control(packer, apply_steer, lkas_active, car_fingerprint, idx, radar_disabled):
|
||||
values = {
|
||||
"STEER_TORQUE": apply_steer if lkas_active else 0,
|
||||
"STEER_TORQUE_REQUEST": lkas_active,
|
||||
}
|
||||
bus = get_lkas_cmd_bus(car_fingerprint, has_relay, radar_disabled)
|
||||
bus = get_lkas_cmd_bus(car_fingerprint, radar_disabled)
|
||||
return packer.make_can_msg("STEERING_CONTROL", bus, values, idx)
|
||||
|
||||
|
||||
def create_bosch_supplemental_1(packer, car_fingerprint, idx, has_relay):
|
||||
def create_bosch_supplemental_1(packer, car_fingerprint, idx):
|
||||
# non-active params
|
||||
values = {
|
||||
"SET_ME_X04": 0x04,
|
||||
"SET_ME_X80": 0x80,
|
||||
"SET_ME_X10": 0x10,
|
||||
}
|
||||
bus = get_lkas_cmd_bus(car_fingerprint, has_relay)
|
||||
bus = get_lkas_cmd_bus(car_fingerprint)
|
||||
return packer.make_can_msg("BOSCH_SUPPLEMENTAL_1", bus, values, idx)
|
||||
|
||||
|
||||
def create_ui_commands(packer, pcm_speed, hud, car_fingerprint, is_metric, idx, has_relay, openpilot_longitudinal_control, stock_hud):
|
||||
def create_ui_commands(packer, pcm_speed, hud, car_fingerprint, is_metric, idx, openpilot_longitudinal_control, stock_hud):
|
||||
commands = []
|
||||
bus_pt = get_pt_bus(car_fingerprint, has_relay)
|
||||
bus_pt = get_pt_bus(car_fingerprint)
|
||||
radar_disabled = car_fingerprint in HONDA_BOSCH and openpilot_longitudinal_control
|
||||
bus_lkas = get_lkas_cmd_bus(car_fingerprint, has_relay, radar_disabled)
|
||||
bus_lkas = get_lkas_cmd_bus(car_fingerprint, radar_disabled)
|
||||
|
||||
if openpilot_longitudinal_control:
|
||||
if car_fingerprint in HONDA_BOSCH:
|
||||
@@ -158,10 +153,10 @@ def create_ui_commands(packer, pcm_speed, hud, car_fingerprint, is_metric, idx,
|
||||
return commands
|
||||
|
||||
|
||||
def spam_buttons_command(packer, button_val, idx, car_fingerprint, has_relay):
|
||||
def spam_buttons_command(packer, button_val, idx, car_fingerprint):
|
||||
values = {
|
||||
'CRUISE_BUTTONS': button_val,
|
||||
'CRUISE_SETTING': 0,
|
||||
}
|
||||
bus = get_pt_bus(car_fingerprint, has_relay)
|
||||
bus = get_pt_bus(car_fingerprint)
|
||||
return packer.make_can_msg("SCM_BUTTONS", bus, values, idx)
|
||||
|
||||
@@ -6,8 +6,8 @@ from common.realtime import DT_CTRL
|
||||
from selfdrive.swaglog import cloudlog
|
||||
from selfdrive.config import Conversions as CV
|
||||
from selfdrive.controls.lib.events import ET
|
||||
from selfdrive.car.honda.values import CruiseButtons, CAR, HONDA_BOSCH, Ecu, ECU_FINGERPRINT, FINGERPRINTS
|
||||
from selfdrive.car import STD_CARGO_KG, CivicParams, scale_rot_inertia, scale_tire_stiffness, is_ecu_disconnected, gen_empty_fingerprint
|
||||
from selfdrive.car.honda.values import CruiseButtons, CAR, HONDA_BOSCH
|
||||
from selfdrive.car import STD_CARGO_KG, CivicParams, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint
|
||||
from selfdrive.controls.lib.planner import _A_CRUISE_MAX_V_FOLLOWING
|
||||
from selfdrive.car.interfaces import CarInterfaceBase
|
||||
from common.dp_common import common_interface_atl, common_interface_get_params_lqr
|
||||
@@ -121,20 +121,19 @@ class CarInterface(CarInterfaceBase):
|
||||
return float(max(max_accel, a_target / A_ACC_MAX)) * min(speedLimiter, accelLimiter)
|
||||
|
||||
@staticmethod
|
||||
def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): # pylint: disable=dangerous-default-value
|
||||
ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay)
|
||||
def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[]): # pylint: disable=dangerous-default-value
|
||||
ret = CarInterfaceBase.get_std_params(candidate, fingerprint)
|
||||
ret.carName = "honda"
|
||||
ret.lateralTuning.init('pid')
|
||||
|
||||
if candidate in HONDA_BOSCH:
|
||||
ret.safetyModel = car.CarParams.SafetyModel.hondaBoschHarness if has_relay else car.CarParams.SafetyModel.hondaBoschGiraffe
|
||||
rdr_bus = 0 if has_relay else 2
|
||||
ret.enableCamera = is_ecu_disconnected(fingerprint[rdr_bus], FINGERPRINTS, ECU_FINGERPRINT, candidate, Ecu.fwdCamera) or has_relay
|
||||
ret.safetyModel = car.CarParams.SafetyModel.hondaBoschHarness
|
||||
ret.enableCamera = True
|
||||
ret.radarOffCan = True
|
||||
ret.openpilotLongitudinalControl = False
|
||||
else:
|
||||
ret.safetyModel = car.CarParams.SafetyModel.hondaNidec
|
||||
ret.enableCamera = is_ecu_disconnected(fingerprint[0], FINGERPRINTS, ECU_FINGERPRINT, candidate, Ecu.fwdCamera) or has_relay
|
||||
ret.enableCamera = True
|
||||
ret.enableGasInterceptor = 0x201 in fingerprint[0]
|
||||
ret.openpilotLongitudinalControl = ret.enableCamera
|
||||
|
||||
|
||||
@@ -1065,10 +1065,4 @@ SPEED_FACTOR = {
|
||||
CAR.INSIGHT: 1.,
|
||||
}
|
||||
|
||||
# msgs sent for steering controller by camera module on can 0.
|
||||
# those messages are mutually exclusive on CRV and non-CRV cars
|
||||
ECU_FINGERPRINT = {
|
||||
Ecu.fwdCamera: [0xE4, 0x194], # steer torque cmd
|
||||
}
|
||||
|
||||
HONDA_BOSCH = set([CAR.ACCORD, CAR.ACCORD_15, CAR.ACCORDH, CAR.CIVIC_BOSCH, CAR.CIVIC_BOSCH_DIESEL, CAR.CRV_5G, CAR.CRV_HYBRID, CAR.INSIGHT, CAR.ACURA_RDX_3G])
|
||||
|
||||
@@ -17,10 +17,7 @@ def process_hud_alert(enabled, fingerprint, visual_alert, left_lane,
|
||||
# initialize to no line visible
|
||||
sys_state = 1
|
||||
if left_lane and right_lane or sys_warning: # HUD alert only display when LKAS status is active
|
||||
if enabled or sys_warning:
|
||||
sys_state = 3
|
||||
else:
|
||||
sys_state = 4
|
||||
sys_state = 3 if enabled or sys_warning else 4
|
||||
elif left_lane:
|
||||
sys_state = 5
|
||||
elif right_lane:
|
||||
@@ -71,7 +68,7 @@ class CarController():
|
||||
|
||||
self.apply_steer_last = apply_steer
|
||||
|
||||
sys_warning, sys_state, left_lane_warning, right_lane_warning =\
|
||||
sys_warning, sys_state, left_lane_warning, right_lane_warning = \
|
||||
process_hud_alert(enabled, self.car_fingerprint, visual_alert,
|
||||
left_lane, right_lane, left_lane_depart, right_lane_depart)
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/env python3
|
||||
from cereal import car
|
||||
from selfdrive.config import Conversions as CV
|
||||
from selfdrive.car.hyundai.values import Ecu, ECU_FINGERPRINT, CAR, FINGERPRINTS
|
||||
from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, is_ecu_disconnected, gen_empty_fingerprint
|
||||
from selfdrive.car.hyundai.values import CAR
|
||||
from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint
|
||||
from selfdrive.car.interfaces import CarInterfaceBase
|
||||
from common.dp_common import common_interface_atl, common_interface_get_params_lqr
|
||||
from common.params import Params
|
||||
@@ -14,8 +14,8 @@ class CarInterface(CarInterfaceBase):
|
||||
return float(accel) / 3.0
|
||||
|
||||
@staticmethod
|
||||
def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): # pylint: disable=dangerous-default-value
|
||||
ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay)
|
||||
def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[]): # pylint: disable=dangerous-default-value
|
||||
ret = CarInterfaceBase.get_std_params(candidate, fingerprint)
|
||||
|
||||
ret.carName = "hyundai"
|
||||
ret.safetyModel = car.CarParams.SafetyModel.hyundai
|
||||
@@ -155,7 +155,7 @@ class CarInterface(CarInterfaceBase):
|
||||
ret.steerRatio = 13.75
|
||||
tire_stiffness_factor = 0.5
|
||||
ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]]
|
||||
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.25], [0.05]]
|
||||
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.25], [0.05]]
|
||||
|
||||
# Genesis
|
||||
elif candidate == CAR.GENESIS_G70:
|
||||
@@ -191,7 +191,7 @@ class CarInterface(CarInterfaceBase):
|
||||
|
||||
# these cars require a special panda safety mode due to missing counters and checksums in the messages
|
||||
if candidate in [CAR.HYUNDAI_GENESIS, CAR.IONIQ_EV_LTD, CAR.IONIQ, CAR.KONA_EV, CAR.KIA_SORENTO, CAR.SONATA_2019,
|
||||
CAR.KIA_NIRO_EV, CAR.KIA_OPTIMA, CAR.VELOSTER, CAR.KIA_STINGER, CAR.GENESIS_G70]:
|
||||
CAR.KIA_NIRO_EV, CAR.KIA_OPTIMA, CAR.VELOSTER, CAR.KIA_STINGER, CAR.GENESIS_G70, CAR.GENESIS_G80]:
|
||||
ret.safetyModel = car.CarParams.SafetyModel.hyundaiLegacy
|
||||
|
||||
ret.centerToFront = ret.wheelbase * 0.4
|
||||
@@ -210,7 +210,7 @@ class CarInterface(CarInterfaceBase):
|
||||
ret.tireStiffnessFront, ret.tireStiffnessRear = scale_tire_stiffness(ret.mass, ret.wheelbase, ret.centerToFront,
|
||||
tire_stiffness_factor=tire_stiffness_factor)
|
||||
|
||||
ret.enableCamera = is_ecu_disconnected(fingerprint[0], FINGERPRINTS, ECU_FINGERPRINT, candidate, Ecu.fwdCamera) or has_relay
|
||||
ret.enableCamera = True
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
@@ -156,12 +156,8 @@ FINGERPRINTS = {
|
||||
}]
|
||||
}
|
||||
|
||||
ECU_FINGERPRINT = {
|
||||
Ecu.fwdCamera: [832, 1156, 1191, 1342]
|
||||
}
|
||||
|
||||
# Don't use these fingerprints for fingerprinting, they are still used for ECU detection
|
||||
IGNORED_FINGERPRINTS = [CAR.VELOSTER, CAR.KONA]
|
||||
IGNORED_FINGERPRINTS = [CAR.VELOSTER, CAR.GENESIS_G70, CAR.KONA]
|
||||
|
||||
FW_VERSIONS = {
|
||||
CAR.SONATA: {
|
||||
|
||||
@@ -44,15 +44,15 @@ class CarInterfaceBase():
|
||||
raise NotImplementedError
|
||||
|
||||
@staticmethod
|
||||
def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=None):
|
||||
def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None):
|
||||
raise NotImplementedError
|
||||
|
||||
# returns a set of default params to avoid repetition in car specific params
|
||||
@staticmethod
|
||||
def get_std_params(candidate, fingerprint, has_relay):
|
||||
def get_std_params(candidate, fingerprint):
|
||||
ret = car.CarParams.new_message()
|
||||
ret.carFingerprint = candidate
|
||||
ret.isPandaBlack = has_relay
|
||||
ret.isPandaBlack = True # TODO: deprecate this field
|
||||
|
||||
# standard ALC params
|
||||
ret.steerControlType = car.CarParams.SteerControlType.torque
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/env python3
|
||||
from cereal import car
|
||||
from selfdrive.config import Conversions as CV
|
||||
from selfdrive.car.mazda.values import CAR, LKAS_LIMITS, FINGERPRINTS, ECU_FINGERPRINT, Ecu
|
||||
from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, is_ecu_disconnected
|
||||
from selfdrive.car.mazda.values import CAR, LKAS_LIMITS
|
||||
from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint
|
||||
from selfdrive.car.interfaces import CarInterfaceBase
|
||||
from common.dp_common import common_interface_atl, common_interface_get_params_lqr
|
||||
|
||||
@@ -16,8 +16,8 @@ class CarInterface(CarInterfaceBase):
|
||||
return float(accel) / 4.0
|
||||
|
||||
@staticmethod
|
||||
def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=None):
|
||||
ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay)
|
||||
def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None):
|
||||
ret = CarInterfaceBase.get_std_params(candidate, fingerprint)
|
||||
|
||||
ret.carName = "mazda"
|
||||
ret.safetyModel = car.CarParams.SafetyModel.mazda
|
||||
@@ -72,7 +72,7 @@ class CarInterface(CarInterfaceBase):
|
||||
ret.tireStiffnessFront, ret.tireStiffnessRear = scale_tire_stiffness(ret.mass, ret.wheelbase, ret.centerToFront,
|
||||
tire_stiffness_factor=tire_stiffness_factor)
|
||||
|
||||
ret.enableCamera = is_ecu_disconnected(fingerprint[0], FINGERPRINTS, ECU_FINGERPRINT, candidate, Ecu.fwdCamera) or has_relay
|
||||
ret.enableCamera = True
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
@@ -71,10 +71,6 @@ FINGERPRINTS = {
|
||||
],
|
||||
}
|
||||
|
||||
ECU_FINGERPRINT = {
|
||||
Ecu.fwdCamera: [579], # steer torque cmd
|
||||
}
|
||||
|
||||
|
||||
DBC = {
|
||||
CAR.CX5: dbc_dict('mazda_2017', None),
|
||||
|
||||
@@ -33,8 +33,8 @@ class CarInterface(CarInterfaceBase):
|
||||
return accel
|
||||
|
||||
@staticmethod
|
||||
def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=None):
|
||||
ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay)
|
||||
def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None):
|
||||
ret = CarInterfaceBase.get_std_params(candidate, fingerprint)
|
||||
ret.carName = "mock"
|
||||
ret.safetyModel = car.CarParams.SafetyModel.noOutput
|
||||
ret.mass = 1700.
|
||||
|
||||
@@ -15,9 +15,9 @@ class CarInterface(CarInterfaceBase):
|
||||
return float(accel) / 4.0
|
||||
|
||||
@staticmethod
|
||||
def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=None):
|
||||
def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None):
|
||||
|
||||
ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay)
|
||||
ret = CarInterfaceBase.get_std_params(candidate, fingerprint)
|
||||
ret.carName = "nissan"
|
||||
ret.safetyModel = car.CarParams.SafetyModel.nissan
|
||||
ret.lateralTuning.init('pid')
|
||||
|
||||
@@ -12,8 +12,8 @@ class CarInterface(CarInterfaceBase):
|
||||
return float(accel) / 4.0
|
||||
|
||||
@staticmethod
|
||||
def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=None):
|
||||
ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay)
|
||||
def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None):
|
||||
ret = CarInterfaceBase.get_std_params(candidate, fingerprint)
|
||||
|
||||
ret.carName = "subaru"
|
||||
ret.radarOffCan = True
|
||||
@@ -26,11 +26,8 @@ class CarInterface(CarInterfaceBase):
|
||||
|
||||
# Subaru port is a community feature, since we don't own one to test
|
||||
ret.communityFeature = True
|
||||
|
||||
ret.dashcamOnly = candidate in PREGLOBAL_CARS
|
||||
|
||||
# force openpilot to fake the stock camera, since car harness is not supported yet and old style giraffe (with switches)
|
||||
# was never released
|
||||
ret.enableCamera = True
|
||||
|
||||
ret.steerRateCost = 0.7
|
||||
|
||||
@@ -78,10 +78,6 @@ STEER_THRESHOLD = {
|
||||
CAR.OUTBACK_PREGLOBAL_2018: 75,
|
||||
}
|
||||
|
||||
ECU_FINGERPRINT = {
|
||||
Ecu.fwdCamera: [290, 356], # steer torque cmd
|
||||
}
|
||||
|
||||
DBC = {
|
||||
CAR.ASCENT: dbc_dict('subaru_global_2017_generated', None),
|
||||
CAR.IMPREZA: dbc_dict('subaru_global_2017_generated', None),
|
||||
|
||||
@@ -25,36 +25,35 @@ class TestCarInterfaces(unittest.TestCase):
|
||||
|
||||
car_fw = []
|
||||
|
||||
for has_relay in [True, False]:
|
||||
car_params = CarInterface.get_params(car_name, fingerprints, has_relay, car_fw)
|
||||
car_interface = CarInterface(car_params, CarController, CarState)
|
||||
assert car_params
|
||||
assert car_interface
|
||||
car_params = CarInterface.get_params(car_name, fingerprints, car_fw)
|
||||
car_interface = CarInterface(car_params, CarController, CarState)
|
||||
assert car_params
|
||||
assert car_interface
|
||||
|
||||
self.assertGreater(car_params.mass, 1)
|
||||
self.assertGreater(car_params.steerRateCost, 1e-3)
|
||||
self.assertGreater(car_params.mass, 1)
|
||||
self.assertGreater(car_params.steerRateCost, 1e-3)
|
||||
|
||||
tuning = car_params.lateralTuning.which()
|
||||
if tuning == 'pid':
|
||||
self.assertTrue(len(car_params.lateralTuning.pid.kpV))
|
||||
elif tuning == 'lqr':
|
||||
self.assertTrue(len(car_params.lateralTuning.lqr.a))
|
||||
elif tuning == 'indi':
|
||||
self.assertGreater(car_params.lateralTuning.indi.outerLoopGain, 1e-3)
|
||||
tuning = car_params.lateralTuning.which()
|
||||
if tuning == 'pid':
|
||||
self.assertTrue(len(car_params.lateralTuning.pid.kpV))
|
||||
elif tuning == 'lqr':
|
||||
self.assertTrue(len(car_params.lateralTuning.lqr.a))
|
||||
elif tuning == 'indi':
|
||||
self.assertGreater(car_params.lateralTuning.indi.outerLoopGain, 1e-3)
|
||||
|
||||
# Run car interface
|
||||
CC = car.CarControl.new_message()
|
||||
for _ in range(10):
|
||||
car_interface.update(CC, [])
|
||||
car_interface.apply(CC)
|
||||
car_interface.apply(CC)
|
||||
# Run car interface
|
||||
CC = car.CarControl.new_message()
|
||||
for _ in range(10):
|
||||
car_interface.update(CC, [])
|
||||
car_interface.apply(CC)
|
||||
car_interface.apply(CC)
|
||||
|
||||
CC = car.CarControl.new_message()
|
||||
CC.enabled = True
|
||||
for _ in range(10):
|
||||
car_interface.update(CC, [])
|
||||
car_interface.apply(CC)
|
||||
car_interface.apply(CC)
|
||||
CC = car.CarControl.new_message()
|
||||
CC.enabled = True
|
||||
for _ in range(10):
|
||||
car_interface.update(CC, [])
|
||||
car_interface.apply(CC)
|
||||
car_interface.apply(CC)
|
||||
|
||||
# Test radar interface
|
||||
RadarInterface = importlib.import_module('selfdrive.car.%s.radar_interface' % car_params.carName).RadarInterface
|
||||
|
||||
@@ -22,8 +22,8 @@ class CarInterface(CarInterfaceBase):
|
||||
return float(accel) / 3.0
|
||||
|
||||
@staticmethod
|
||||
def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): # pylint: disable=dangerous-default-value
|
||||
ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay)
|
||||
def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=[]): # pylint: disable=dangerous-default-value
|
||||
ret = CarInterfaceBase.get_std_params(candidate, fingerprint)
|
||||
|
||||
ret.carName = "toyota"
|
||||
ret.safetyModel = car.CarParams.SafetyModel.toyota
|
||||
@@ -325,7 +325,7 @@ class CarInterface(CarInterfaceBase):
|
||||
ret.tireStiffnessFront, ret.tireStiffnessRear = scale_tire_stiffness(ret.mass, ret.wheelbase, ret.centerToFront,
|
||||
tire_stiffness_factor=tire_stiffness_factor)
|
||||
|
||||
ret.enableCamera = is_ecu_disconnected(fingerprint[0], FINGERPRINTS, ECU_FINGERPRINT, candidate, Ecu.fwdCamera) or has_relay
|
||||
ret.enableCamera = True
|
||||
# Detect smartDSU, which intercepts ACC_CMD from the DSU allowing openpilot to send it
|
||||
smartDsu = 0x2FF in fingerprint[0]
|
||||
# In TSS2 cars the camera does long control
|
||||
@@ -390,8 +390,6 @@ class CarInterface(CarInterfaceBase):
|
||||
# events
|
||||
events = self.create_common_events(ret)
|
||||
|
||||
if self.cp_cam.can_invalid_cnt >= 200 and self.CP.enableCamera and not self.CP.isPandaBlack:
|
||||
events.add(EventName.invalidGiraffeToyota)
|
||||
if self.CS.low_speed_lockout and self.CP.openpilotLongitudinalControl:
|
||||
events.add(EventName.lowSpeedLockout)
|
||||
if ret.vEgo < self.CP.minEnableSpeed and self.CP.openpilotLongitudinalControl:
|
||||
|
||||
@@ -347,7 +347,7 @@ FINGERPRINTS = {
|
||||
}
|
||||
|
||||
# Don't use theses fingerprints for fingerprinting, they are still needed for ECU detection
|
||||
IGNORED_FINGERPRINTS = [CAR.HIGHLANDERH_TSS2, CAR.LEXUS_RXH_TSS2, CAR.PRIUS_TSS2, CAR.LEXUS_NX]
|
||||
IGNORED_FINGERPRINTS = [CAR.RAV4H_TSS2, CAR.HIGHLANDERH_TSS2, CAR.LEXUS_RXH_TSS2, CAR.PRIUS_TSS2, CAR.LEXUS_NX]
|
||||
|
||||
FW_VERSIONS = {
|
||||
CAR.AVALON: {
|
||||
|
||||
@@ -30,9 +30,8 @@ class CarInterface(CarInterfaceBase):
|
||||
return float(accel) / 4.0
|
||||
|
||||
@staticmethod
|
||||
def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=None):
|
||||
ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay)
|
||||
ret.lateralTuning.init('pid')
|
||||
def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None):
|
||||
ret = CarInterfaceBase.get_std_params(candidate, fingerprint)
|
||||
|
||||
# Set global default parameters
|
||||
ret.radarOffCan = True
|
||||
|
||||
@@ -39,7 +39,7 @@ void clu_init(void) {
|
||||
cl_device_id cl_get_device_id(cl_device_type device_type) {
|
||||
bool opencl_platform_found = false;
|
||||
cl_device_id device_id = NULL;
|
||||
|
||||
|
||||
cl_uint num_platforms = 0;
|
||||
int err = clGetPlatformIDs(0, NULL, &num_platforms);
|
||||
assert(err == 0);
|
||||
@@ -66,7 +66,7 @@ cl_device_id cl_get_device_id(cl_device_type device_type) {
|
||||
break;
|
||||
}
|
||||
free(platform_ids);
|
||||
|
||||
|
||||
if (!opencl_platform_found) {
|
||||
printf("No valid openCL platform found\n");
|
||||
assert(opencl_platform_found);
|
||||
|
||||
@@ -12,7 +12,10 @@
|
||||
|
||||
#ifdef QCOM2
|
||||
// TODO: decide if we want to isntall libi2c-dev everywhere
|
||||
#include <linux/i2c-dev.h>
|
||||
extern "C" {
|
||||
#include <linux/i2c-dev.h>
|
||||
#include <i2c/smbus.h>
|
||||
}
|
||||
|
||||
I2CBus::I2CBus(uint8_t bus_id){
|
||||
char bus_name[20];
|
||||
|
||||
@@ -49,30 +49,17 @@ void params_sig_handler(int signal) {
|
||||
}
|
||||
|
||||
static int fsync_dir(const char* path){
|
||||
int result = 0;
|
||||
int fd = open(path, O_RDONLY, 0755);
|
||||
|
||||
if (fd < 0){
|
||||
result = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
result = fsync(fd);
|
||||
if (result < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
int result_close = 0;
|
||||
if (fd >= 0){
|
||||
result_close = close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int result = fsync(fd);
|
||||
int result_close = close(fd);
|
||||
if (result_close < 0) {
|
||||
return result_close;
|
||||
} else {
|
||||
return result;
|
||||
result = result_close;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static int mkdir_p(std::string path) {
|
||||
@@ -237,10 +224,6 @@ cleanup:
|
||||
}
|
||||
|
||||
int Params::delete_db_value(std::string key) {
|
||||
return delete_db_value(key.c_str());
|
||||
}
|
||||
|
||||
int Params::delete_db_value(const char* key) {
|
||||
int lock_fd = -1;
|
||||
int result;
|
||||
std::string path;
|
||||
@@ -256,7 +239,7 @@ int Params::delete_db_value(const char* key) {
|
||||
}
|
||||
|
||||
// Delete value.
|
||||
path = params_path + "/d/" + std::string(key);
|
||||
path = params_path + "/d/" + key;
|
||||
result = remove(path.c_str());
|
||||
if (result != 0) {
|
||||
result = ERR_NO_VALUE;
|
||||
|
||||
@@ -33,7 +33,6 @@ public:
|
||||
// Delete a value from the params database.
|
||||
// Inputs are the same as read_db_value, without value and value_sz.
|
||||
int delete_db_value(std::string key);
|
||||
int delete_db_value(const char* key);
|
||||
|
||||
// Reads a value from the params database, blocking until successful.
|
||||
// Inputs are the same as read_db_value.
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#ifndef COMMON_SPINNER_H
|
||||
#define COMMON_SPINNER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int spin(int argc, char** argv);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1 +1 @@
|
||||
#define COMMA_VERSION "0.7.10-release"
|
||||
#define COMMA_VERSION "0.8.0-d56e04c0-2020-11-24T21:53:22"
|
||||
|
||||
@@ -69,12 +69,10 @@ class Controls:
|
||||
self.can_sock = messaging.sub_sock('can', timeout=can_timeout)
|
||||
|
||||
# wait for one health and one CAN packet
|
||||
hw_type = messaging.recv_one(self.sm.sock['health']).health.hwType
|
||||
has_relay = hw_type in [HwType.blackPanda, HwType.uno, HwType.dos]
|
||||
print("Waiting for CAN messages...")
|
||||
get_one_can(self.can_sock)
|
||||
|
||||
self.CI, self.CP = get_car(self.can_sock, self.pm.sock['sendcan'], has_relay)
|
||||
self.CI, self.CP = get_car(self.can_sock, self.pm.sock['sendcan'])
|
||||
|
||||
# read params
|
||||
params = Params()
|
||||
@@ -141,7 +139,7 @@ class Controls:
|
||||
self.sm['dMonitoringState'].awarenessStatus = 1.
|
||||
self.sm['dMonitoringState'].faceDetected = False
|
||||
|
||||
self.startup_event = get_startup_event(car_recognized, controller_available, hw_type)
|
||||
self.startup_event = get_startup_event(car_recognized, controller_available)
|
||||
|
||||
# if not sounds_available:
|
||||
# self.events.add(EventName.soundsUnavailable, static=True)
|
||||
@@ -151,8 +149,6 @@ class Controls:
|
||||
self.events.add(EventName.communityFeatureDisallowed, static=True)
|
||||
if not car_recognized:
|
||||
self.events.add(EventName.carUnrecognized, static=True)
|
||||
# if hw_type == HwType.whitePanda:
|
||||
# self.events.add(EventName.whitePandaUnsupported, static=True)
|
||||
|
||||
# controlsd is driven by can recv, expected at 100Hz
|
||||
self.rk = Ratekeeper(100, print_delay_threshold=None)
|
||||
@@ -228,7 +224,8 @@ class Controls:
|
||||
|
||||
if self.can_rcv_error or (not CS.canValid and self.sm.frame > 5 / DT_CTRL):
|
||||
self.events.add(EventName.pcmDisable if self.sm['dragonConf'].dpAtl else EventName.canError)
|
||||
if self.mismatch_counter >= 200:
|
||||
if (self.sm['health'].safetyModel != self.CP.safetyModel and self.sm.frame > 2 / DT_CTRL) or \
|
||||
self.mismatch_counter >= 200:
|
||||
self.events.add(EventName.controlsMismatch)
|
||||
if not self.sm.alive['plan'] and self.sm.alive['pathPlan']:
|
||||
# only plan not being received: radar not communicating
|
||||
@@ -520,7 +517,7 @@ class Controls:
|
||||
self.pm.send('sendcan', can_list_to_can_capnp(can_sends, msgtype='sendcan', valid=CS.canValid))
|
||||
|
||||
force_decel = (self.sm['dMonitoringState'].awarenessStatus < 0.) or \
|
||||
(self.state == State.softDisabling)
|
||||
(self.state == State.softDisabling)
|
||||
|
||||
steer_angle_rad = (CS.steeringAngle - self.sm['pathPlan'].angleOffset) * CV.DEG_TO_RAD
|
||||
|
||||
|
||||
@@ -36,5 +36,9 @@
|
||||
"Offroad_NeosUpdate": {
|
||||
"text": "An update to your device's operating system is downloading in the background. You will be prompted to update when it's ready to install.",
|
||||
"severity": 0
|
||||
},
|
||||
"Offroad_HardwareUnsupported": {
|
||||
"text": "White and grey panda are unsupported. Upgrade to comma two or black panda.",
|
||||
"severity": 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,31 +257,6 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo
|
||||
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., 15.),
|
||||
},
|
||||
|
||||
EventName.startupGreyPanda: {
|
||||
ET.PERMANENT: Alert(
|
||||
"WARNING: Grey panda is deprecated",
|
||||
"Upgrade to comma two or black panda",
|
||||
AlertStatus.userPrompt, AlertSize.mid,
|
||||
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., 15.),
|
||||
},
|
||||
|
||||
EventName.invalidGiraffeToyota: {
|
||||
ET.PERMANENT: Alert(
|
||||
_("Unsupported Giraffe Configuration"),
|
||||
_("Visit comma.ai/tg"),
|
||||
AlertStatus.normal, AlertSize.mid,
|
||||
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2),
|
||||
},
|
||||
|
||||
EventName.whitePandaUnsupported: {
|
||||
ET.PERMANENT: Alert(
|
||||
_("White Panda No Longer Supported"),
|
||||
_("Upgrade to comma two or black panda"),
|
||||
AlertStatus.normal, AlertSize.mid,
|
||||
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2),
|
||||
ET.NO_ENTRY: NoEntryAlert(_("Unsupported Hardware")),
|
||||
},
|
||||
|
||||
EventName.invalidLkasSetting: {
|
||||
ET.PERMANENT: Alert(
|
||||
_("Stock LKAS is turned on"),
|
||||
@@ -489,6 +464,10 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo
|
||||
ET.PERMANENT: NormalPermanentAlert(_("Camera Malfunction"), _("Contact Support")),
|
||||
},
|
||||
|
||||
EventName.cameraMalfunction: {
|
||||
ET.PERMANENT: NormalPermanentAlert("Camera Malfunction", "Contact Support"),
|
||||
},
|
||||
|
||||
# ********** events that affect controls state transitions **********
|
||||
|
||||
EventName.pcmEnable: {
|
||||
|
||||
@@ -103,6 +103,24 @@ class LanePlanner:
|
||||
l_prob *= l_std_mod
|
||||
r_prob *= r_std_mod
|
||||
|
||||
# Reduce reliance on lanelines that are too far apart or
|
||||
# will be in a few seconds
|
||||
l_prob, r_prob = self.l_prob, self.r_prob
|
||||
width_poly = self.l_poly - self.r_poly
|
||||
prob_mods = []
|
||||
for t_check in [0.0, 1.5, 3.0]:
|
||||
width_at_t = eval_poly(width_poly, t_check * (v_ego + 7))
|
||||
prob_mods.append(interp(width_at_t, [4.0, 5.0], [1.0, 0.0]))
|
||||
mod = min(prob_mods)
|
||||
l_prob *= mod
|
||||
r_prob *= mod
|
||||
|
||||
# Reduce reliance on uncertain lanelines
|
||||
l_std_mod = interp(self.l_std, [.15, .3], [1.0, 0.0])
|
||||
r_std_mod = interp(self.r_std, [.15, .3], [1.0, 0.0])
|
||||
l_prob *= l_std_mod
|
||||
r_prob *= r_std_mod
|
||||
|
||||
# Find current lanewidth
|
||||
self.lane_width_certainty += 0.05 * (l_prob * r_prob - self.lane_width_certainty)
|
||||
current_lane_width = abs(self.l_poly[3] - self.r_poly[3])
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
# - connect to a Panda
|
||||
# - run selfdrive/boardd/boardd
|
||||
# - launching this script
|
||||
# - turn on the car in STOCK MODE (set giraffe switches properly).
|
||||
# Note: it's very important that the car is in stock mode, in order to collect a complete fingerprint
|
||||
# - since some messages are published at low frequency, keep this script running for at least 30s,
|
||||
# until all messages are received at least once
|
||||
|
||||
@@ -37,7 +37,7 @@ if __name__ == "__main__":
|
||||
for route in tqdm(routes):
|
||||
route = route.rstrip()
|
||||
dongle_id, time = route.split('|')
|
||||
qlog_path = f"cd:/{dongle_id}/{time}/1/qlog.bz2"
|
||||
qlog_path = f"cd:/{dongle_id}/{time}/0/qlog.bz2"
|
||||
|
||||
if dongle_id in dongles:
|
||||
continue
|
||||
@@ -65,7 +65,7 @@ if __name__ == "__main__":
|
||||
live_fingerprint = args.car
|
||||
|
||||
if live_fingerprint not in list(TOYOTA_FINGERPRINTS.keys()) + list(HONDA_FINGERPRINTS.keys()) + list(HYUNDAI_FINGERPRINTS.keys()):
|
||||
continue
|
||||
break
|
||||
|
||||
candidates = match_fw_to_car(car_fw)
|
||||
if (len(candidates) == 1) and (list(candidates)[0] == live_fingerprint):
|
||||
|
||||
@@ -80,8 +80,10 @@ import traceback
|
||||
from multiprocessing import Process
|
||||
|
||||
# Run scons
|
||||
spinner = Spinner(noop=(__name__ != "__main__" or not ANDROID))
|
||||
spinner = Spinner()
|
||||
spinner.update("0")
|
||||
if __name__ != "__main__":
|
||||
spinner.close()
|
||||
|
||||
if not prebuilt:
|
||||
for retry in [True, False]:
|
||||
@@ -147,9 +149,8 @@ if not prebuilt:
|
||||
ip = 'N/A'
|
||||
|
||||
# Show TextWindow
|
||||
no_ui = __name__ != "__main__" or not ANDROID
|
||||
error_s = "\n \n".join(["\n".join(textwrap.wrap(e, 65)) for e in errors])
|
||||
with TextWindow(("openpilot failed to build (IP: %s)\n \n" % ip) + error_s, noop=no_ui) as t:
|
||||
with TextWindow(("openpilot failed to build (IP: %s)\n \n" % ip) + error_s) as t:
|
||||
t.wait_for_exit()
|
||||
|
||||
exit(1)
|
||||
@@ -386,11 +387,8 @@ def kill_managed_process(name):
|
||||
join_process(running[name], 15)
|
||||
if running[name].exitcode is None:
|
||||
cloudlog.critical("unkillable process %s failed to die!" % name)
|
||||
# TODO: Use method from HARDWARE
|
||||
if ANDROID:
|
||||
cloudlog.critical("FORCE REBOOTING PHONE!")
|
||||
os.system("date >> /sdcard/unkillable_reboot")
|
||||
os.system("reboot")
|
||||
os.system("date >> /sdcard/unkillable_reboot")
|
||||
HARDWARE.reboot()
|
||||
raise RuntimeError
|
||||
else:
|
||||
cloudlog.info("killing %s with SIGKILL" % name)
|
||||
@@ -413,8 +411,10 @@ def cleanup_all_processes(signal, frame):
|
||||
|
||||
|
||||
def send_managed_process_signal(name, sig):
|
||||
if name not in running or name not in managed_processes:
|
||||
if name not in running or name not in managed_processes or \
|
||||
running[name].exitcode is not None:
|
||||
return
|
||||
|
||||
cloudlog.info(f"sending signal {sig} to {name}")
|
||||
os.kill(running[name].pid, sig)
|
||||
|
||||
|
||||
@@ -201,7 +201,7 @@ int main(int argc, char **argv) {
|
||||
// tracked dropped frames
|
||||
uint32_t vipc_dropped_frames = extra.frame_id - last_vipc_frame_id - 1;
|
||||
frames_dropped = (1. - frame_filter_k) * frames_dropped + frame_filter_k * (float)std::min(vipc_dropped_frames, 10U);
|
||||
if (run_count < 10) frames_dropped = 0; // let frame drops warm up
|
||||
if (run_count < 10) frames_dropped = 0; // let frame drops warm up
|
||||
float frame_drop_ratio = frames_dropped / (1 + frames_dropped);
|
||||
|
||||
model_publish(pm, extra.frame_id, frame_id, vipc_dropped_frames, frame_drop_ratio, model_buf, extra.timestamp_eof, model_execution_time);
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
#ifdef QCOM
|
||||
#define DefaultRunModel SNPEModel
|
||||
#else
|
||||
#ifdef USE_TF_MODEL
|
||||
#include "tfmodel.h"
|
||||
#define DefaultRunModel TFModel
|
||||
#ifdef USE_ONNX_MODEL
|
||||
#include "onnxmodel.h"
|
||||
#define DefaultRunModel ONNXModel
|
||||
#else
|
||||
#define DefaultRunModel SNPEModel
|
||||
#endif
|
||||
|
||||
@@ -15,7 +15,7 @@ def dmonitoringd_thread(sm=None, pm=None):
|
||||
pm = messaging.PubMaster(['dMonitoringState'])
|
||||
|
||||
if sm is None:
|
||||
sm = messaging.SubMaster(['driverState', 'liveCalibration', 'carState', 'model', 'dragonConf'], poll=['driverState'])
|
||||
sm = messaging.SubMaster(['driverState', 'liveCalibration', 'carState', 'controlsState', 'model', 'dragonConf'], poll=['driverState'])
|
||||
|
||||
driver_status = DriverStatus()
|
||||
driver_status.is_rhd_region = Params().get("IsRHD") == b"1"
|
||||
@@ -25,7 +25,6 @@ def dmonitoringd_thread(sm=None, pm=None):
|
||||
sm['liveCalibration'].calStatus = Calibration.INVALID
|
||||
sm['liveCalibration'].rpyCalib = [0, 0, 0]
|
||||
sm['carState'].vEgo = 0.
|
||||
sm['carState'].cruiseState.enabled = False
|
||||
sm['carState'].cruiseState.speed = 0.
|
||||
sm['carState'].buttonEvents = []
|
||||
sm['carState'].steeringPressed = False
|
||||
@@ -72,7 +71,7 @@ def dmonitoringd_thread(sm=None, pm=None):
|
||||
sm['carState'].gasPressed or \
|
||||
sm['carState'].brakePressed
|
||||
if driver_engaged:
|
||||
driver_status.update(Events(), True, sm['carState'].cruiseState.enabled, sm['carState'].standstill)
|
||||
driver_status.update(Events(), True, sm['controlsState'].enabled, sm['carState'].standstill)
|
||||
v_cruise_last = v_cruise
|
||||
|
||||
if sm.updated['model']:
|
||||
@@ -81,14 +80,14 @@ def dmonitoringd_thread(sm=None, pm=None):
|
||||
# Get data from dmonitoringmodeld
|
||||
events = Events()
|
||||
if sm['dragonConf'].dpDriverMonitor:
|
||||
driver_status.get_pose(sm['driverState'], sm['liveCalibration'].rpyCalib, sm['carState'].vEgo, sm['carState'].cruiseState.enabled)
|
||||
driver_status.get_pose(sm['driverState'], sm['liveCalibration'].rpyCalib, sm['carState'].vEgo, sm['controlsState'].enabled)
|
||||
|
||||
# Block engaging after max number of distrations
|
||||
if driver_status.terminal_alert_cnt >= MAX_TERMINAL_ALERTS or driver_status.terminal_time >= MAX_TERMINAL_DURATION:
|
||||
events.add(car.CarEvent.EventName.tooDistracted)
|
||||
|
||||
# Update events from driver state
|
||||
driver_status.update(events, driver_engaged, sm['carState'].cruiseState.enabled, sm['carState'].standstill)
|
||||
driver_status.update(events, driver_engaged, sm['controlsState'].enabled, sm['carState'].standstill)
|
||||
|
||||
# build dMonitoringState packet
|
||||
dat = messaging.new_message('dMonitoringState')
|
||||
|
||||
@@ -15,8 +15,8 @@ EventName = car.CarEvent.EventName
|
||||
# ******************************************************************************************
|
||||
|
||||
_AWARENESS_TIME = 35. # passive wheel touch total timeout
|
||||
_AWARENESS_PRE_TIME_TILL_TERMINAL = 7.
|
||||
_AWARENESS_PROMPT_TIME_TILL_TERMINAL = 5.
|
||||
_AWARENESS_PRE_TIME_TILL_TERMINAL = 12.
|
||||
_AWARENESS_PROMPT_TIME_TILL_TERMINAL = 6.
|
||||
_DISTRACTED_TIME = 11.
|
||||
_DISTRACTED_PRE_TIME_TILL_TERMINAL = 8.
|
||||
_DISTRACTED_PROMPT_TIME_TILL_TERMINAL = 6.
|
||||
@@ -251,13 +251,13 @@ class DriverStatus():
|
||||
if self.awareness <= 0.:
|
||||
# terminal red alert: disengagement required
|
||||
alert = EventName.driverDistracted if self.active_monitoring_mode else EventName.driverUnresponsive
|
||||
self.hi_std_alert_enabled = True
|
||||
self.terminal_time += 1
|
||||
if awareness_prev > 0.:
|
||||
self.terminal_alert_cnt += 1
|
||||
elif self.awareness <= self.threshold_prompt:
|
||||
# prompt orange alert
|
||||
alert = EventName.promptDriverDistracted if self.active_monitoring_mode else EventName.promptDriverUnresponsive
|
||||
self.hi_std_alert_enabled = True
|
||||
elif self.awareness <= self.threshold_pre:
|
||||
# pre green alert
|
||||
alert = EventName.preDriverDistracted if self.active_monitoring_mode else EventName.preDriverUnresponsive
|
||||
|
||||
Regular → Executable
+1
@@ -17,3 +17,4 @@ def main():
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
||||
@@ -17,4 +17,7 @@ else:
|
||||
'sensors/lsm6ds3_gyro.cc',
|
||||
'sensors/lsm6ds3_temp.cc',
|
||||
]
|
||||
env.Program('_sensord', ['sensors_qcom2.cc'] + sensors, LIBS=[common, cereal, messaging, 'capnp', 'zmq', 'kj'])
|
||||
libs = [common, cereal, messaging, 'capnp', 'zmq', 'kj']
|
||||
if arch == "larch64":
|
||||
libs.append('i2c')
|
||||
env.Program('_sensord', ['sensors_qcom2.cc'] + sensors, LIBS=libs)
|
||||
|
||||
@@ -15,11 +15,11 @@ def cputime_total(ct):
|
||||
|
||||
def print_cpu_usage(first_proc, last_proc):
|
||||
procs = [
|
||||
("selfdrive.controls.controlsd", 45.0),
|
||||
("./loggerd", 33.90),
|
||||
("selfdrive.locationd.locationd", 29.5),
|
||||
("selfdrive.controls.plannerd", 11.84),
|
||||
("selfdrive.locationd.paramsd", 10.5),
|
||||
("selfdrive.controls.controlsd", 47.0),
|
||||
("./loggerd", 42.0),
|
||||
("selfdrive.locationd.locationd", 35.0),
|
||||
("selfdrive.locationd.paramsd", 12.0),
|
||||
("selfdrive.controls.plannerd", 10.0),
|
||||
("./_modeld", 7.12),
|
||||
("./camerad", 7.07),
|
||||
("./_sensord", 6.17),
|
||||
@@ -102,5 +102,7 @@ if __name__ == "__main__":
|
||||
passed = False
|
||||
try:
|
||||
passed = test_cpu_usage()
|
||||
except Exception as e:
|
||||
print("\n\n\n", "TEST FAILED:", str(e), "\n\n\n")
|
||||
finally:
|
||||
sys.exit(int(not passed))
|
||||
|
||||
@@ -9,7 +9,6 @@ from common.params import Params, put_nonblocking
|
||||
from common.hardware import TICI
|
||||
from selfdrive.swaglog import cloudlog
|
||||
|
||||
PANDA_OUTPUT_VOLTAGE = 5.28
|
||||
CAR_VOLTAGE_LOW_PASS_K = 0.091 # LPF gain for 5s tau (dt/tau / (dt/tau + 1))
|
||||
|
||||
# A C2 uses about 1W while idling, and 30h seens like a good shutoff for most cars
|
||||
@@ -62,11 +61,6 @@ def _read_param(path, parser, default=0):
|
||||
return default
|
||||
|
||||
|
||||
def panda_current_to_actual_current(panda_current):
|
||||
# From white/grey panda schematic
|
||||
return (3.3 - (panda_current * 3.3 / 4096)) / 8.25
|
||||
|
||||
|
||||
class PowerMonitoring:
|
||||
def __init__(self):
|
||||
self.params = Params()
|
||||
@@ -135,11 +129,6 @@ class PowerMonitoring:
|
||||
# If the battery is discharging, we can use this measurement
|
||||
# On C2: this is low by about 10-15%, probably mostly due to UNO draw not being factored in
|
||||
current_power = ((get_battery_voltage() / 1000000) * (get_battery_current() / 1000000))
|
||||
elif (health.health.hwType in [log.HealthData.HwType.whitePanda, log.HealthData.HwType.greyPanda]) and (health.health.current > 1):
|
||||
# If white/grey panda, use the integrated current measurements if the measurement is not 0
|
||||
# If the measurement is 0, the current is 400mA or greater, and out of the measurement range of the panda
|
||||
# This seems to be accurate to about 5%
|
||||
current_power = (PANDA_OUTPUT_VOLTAGE * panda_current_to_actual_current(health.health.current))
|
||||
elif (self.next_pulsed_measurement_time is not None) and (self.next_pulsed_measurement_time <= now):
|
||||
# TODO: Figure out why this is off by a factor of 3/4???
|
||||
FUDGE_FACTOR = 1.33
|
||||
|
||||
@@ -136,6 +136,7 @@ else:
|
||||
# max fan speed only allowed if battery is hot
|
||||
_BAT_TEMP_THRESHOLD = 45.
|
||||
|
||||
|
||||
def handle_fan_eon(max_cpu_temp, bat_temp, fan_speed, ignition):
|
||||
new_speed_h = next(speed for speed, temp_h in zip(_FAN_SPEEDS, _TEMP_THRS_H) if temp_h > max_cpu_temp)
|
||||
new_speed_l = next(speed for speed, temp_l in zip(_FAN_SPEEDS, _TEMP_THRS_L) if temp_l > max_cpu_temp)
|
||||
@@ -211,7 +212,6 @@ def thermald_thread():
|
||||
should_start_prev = False
|
||||
handle_fan = None
|
||||
is_uno = False
|
||||
has_relay = False
|
||||
|
||||
pm = PowerMonitoring()
|
||||
no_panda_cnt = 0
|
||||
@@ -262,7 +262,6 @@ def thermald_thread():
|
||||
# Setup fan handler on first connect to panda
|
||||
if handle_fan is None and health.health.hwType != log.HealthData.HwType.unknown:
|
||||
is_uno = health.health.hwType == log.HealthData.HwType.uno
|
||||
has_relay = health.health.hwType in [log.HealthData.HwType.blackPanda, log.HealthData.HwType.uno, log.HealthData.HwType.dos]
|
||||
|
||||
if (not EON) or is_uno:
|
||||
cloudlog.info("Setting up UNO fan handler")
|
||||
@@ -319,7 +318,7 @@ def thermald_thread():
|
||||
# since going onroad increases load and can make temps go over 107
|
||||
# We only do this if there is a relay that prevents the car from faulting
|
||||
is_offroad_for_5_min = (started_ts is None) and ((not started_seen) or (off_ts is None) or (sec_since_boot() - off_ts > 60 * 5))
|
||||
if max_cpu_temp > 107. or bat_temp >= 63. or (has_relay and is_offroad_for_5_min and max_cpu_temp > 70.0):
|
||||
if max_cpu_temp > 107. or bat_temp >= 63. or (is_offroad_for_5_min and max_cpu_temp > 70.0):
|
||||
# onroad not allowed
|
||||
thermal_status = ThermalStatus.danger
|
||||
elif max_comp_temp > 96.0 or bat_temp > 60.:
|
||||
@@ -346,7 +345,7 @@ def thermald_thread():
|
||||
# now = datetime.datetime.utcnow()
|
||||
#
|
||||
# # show invalid date/time alert
|
||||
# startup_conditions["time_valid"] = now.year >= 2019
|
||||
# startup_conditions["time_valid"] = (now.year > 2020) or (now.year == 2020 and now.month >= 10)
|
||||
# set_offroad_alert_if_changed("Offroad_InvalidTime", (not startup_conditions["time_valid"]))
|
||||
#
|
||||
# # Show update prompt
|
||||
@@ -382,18 +381,18 @@ def thermald_thread():
|
||||
# set_offroad_alert_if_changed("Offroad_UpdateFailed", False)
|
||||
# set_offroad_alert_if_changed("Offroad_ConnectivityNeeded", False)
|
||||
# set_offroad_alert_if_changed("Offroad_ConnectivityNeededPrompt", False)
|
||||
#
|
||||
|
||||
startup_conditions["not_uninstalling"] = not params.get("DoUninstall") == b"1"
|
||||
startup_conditions["accepted_terms"] = params.get("HasAcceptedTerms") == terms_version
|
||||
completed_training = params.get("CompletedTrainingVersion") == training_version
|
||||
|
||||
panda_signature = params.get("PandaFirmware")
|
||||
startup_conditions["fw_version_match"] = (panda_signature is None) or (panda_signature == FW_SIGNATURE) # don't show alert is no panda is connected (None)
|
||||
set_offroad_alert_if_changed("Offroad_PandaFirmwareMismatch", (not startup_conditions["fw_version_match"]))
|
||||
#
|
||||
# # with 2% left, we killall, otherwise the phone will take a long time to boot
|
||||
|
||||
# with 2% left, we killall, otherwise the phone will take a long time to boot
|
||||
startup_conditions["free_space"] = msg.thermal.freeSpace > 0.02
|
||||
startup_conditions["completed_training"] = completed_training or (current_branch in ['dashcam', 'dashcam-staging'])
|
||||
startup_conditions["completed_training"] = params.get("CompletedTrainingVersion") == training_version or \
|
||||
(current_branch in ['dashcam', 'dashcam-staging'])
|
||||
startup_conditions["not_driver_view"] = not params.get("IsDriverViewEnabled") == b"1"
|
||||
startup_conditions["not_taking_snapshot"] = not params.get("IsTakingSnapshot") == b"1"
|
||||
# if any CPU gets above 107 or the battery gets above 63, kill all processes
|
||||
@@ -402,6 +401,10 @@ def thermald_thread():
|
||||
set_offroad_alert_if_changed("Offroad_TemperatureTooHigh", (not startup_conditions["device_temp_good"]))
|
||||
should_start = all(startup_conditions.values())
|
||||
|
||||
startup_conditions["hardware_supported"] = health is not None and health.health.hwType not in [log.HealthData.HwType.whitePanda,
|
||||
log.HealthData.HwType.greyPanda]
|
||||
set_offroad_alert_if_changed("Offroad_HardwareUnsupported", health is not None and not startup_conditions["hardware_supported"])
|
||||
|
||||
if should_start:
|
||||
if not should_start_prev:
|
||||
params.delete("IsOffroad")
|
||||
|
||||
@@ -21,7 +21,9 @@ def get_tombstones():
|
||||
|
||||
# Loop over first 1000 directory entries
|
||||
for _, f in zip(range(1000), d):
|
||||
if f.name.startswith("tombstone") or f.name.endswith(".crash"):
|
||||
if f.name.startswith("tombstone"):
|
||||
files.append((f.path, int(f.stat().st_ctime)))
|
||||
elif f.name.endswith(".crash") and f.stat().st_mode == 0o100640:
|
||||
files.append((f.path, int(f.stat().st_ctime)))
|
||||
return files
|
||||
|
||||
|
||||
+63
-9
@@ -1,30 +1,84 @@
|
||||
Import('env', 'qt_env', 'arch', 'common', 'messaging', 'gpucommon', 'visionipc', 'cereal')
|
||||
import os
|
||||
Import('env', 'arch', 'real_arch', 'common', 'messaging', 'gpucommon', 'visionipc', 'cereal')
|
||||
|
||||
qt_env = None
|
||||
if arch in ["x86_64", "Darwin", "larch64"]:
|
||||
qt_env = env.Clone()
|
||||
|
||||
if arch == "Darwin":
|
||||
qt_env['QTDIR'] = "/usr/local/opt/qt"
|
||||
QT_BASE = "/usr/local/opt/qt/"
|
||||
qt_dirs = [
|
||||
QT_BASE + "include/",
|
||||
QT_BASE + "include/QtWidgets",
|
||||
QT_BASE + "include/QtGui",
|
||||
QT_BASE + "include/QtCore",
|
||||
QT_BASE + "include/QtDBus",
|
||||
QT_BASE + "include/QtMultimedia",
|
||||
]
|
||||
qt_env["LINKFLAGS"] += ["-F" + QT_BASE + "lib"]
|
||||
else:
|
||||
qt_env['QTDIR'] = "/usr"
|
||||
qt_dirs = [
|
||||
f"/usr/include/{real_arch}-linux-gnu/qt5",
|
||||
f"/usr/include/{real_arch}-linux-gnu/qt5/QtWidgets",
|
||||
f"/usr/include/{real_arch}-linux-gnu/qt5/QtGui",
|
||||
f"/usr/include/{real_arch}-linux-gnu/qt5/QtCore",
|
||||
f"/usr/include/{real_arch}-linux-gnu/qt5/QtDBus",
|
||||
f"/usr/include/{real_arch}-linux-gnu/qt5/QtMultimedia",
|
||||
f"/usr/include/{real_arch}-linux-gnu/qt5/QtGui/5.5.1/QtGui",
|
||||
f"/usr/include/{real_arch}-linux-gnu/qt5/QtGui/5.12.8/QtGui",
|
||||
]
|
||||
|
||||
qt_env.Tool('qt')
|
||||
qt_env['CPPPATH'] += qt_dirs
|
||||
qt_flags = [
|
||||
"-D_REENTRANT",
|
||||
"-DQT_NO_DEBUG",
|
||||
"-DQT_WIDGETS_LIB",
|
||||
"-DQT_GUI_LIB",
|
||||
"-DQT_CORE_LIB"
|
||||
]
|
||||
qt_env['CXXFLAGS'] += qt_flags
|
||||
|
||||
|
||||
|
||||
src = ['ui.cc', 'paint.cc', 'sidebar.cc', 'paint_dp.cc', '#phonelibs/nanovg/nanovg.c']
|
||||
libs = [common, 'zmq', 'capnp', 'kj', 'm', cereal, messaging, gpucommon, visionipc]
|
||||
|
||||
|
||||
if qt_env is None:
|
||||
libs += ['EGL', 'GLESv3', 'gnustl_shared', 'log', 'utils', 'gui', 'hardware', 'ui', 'CB', 'gsl', 'adreno_utils', 'OpenSLES', 'cutils', 'uuid', 'OpenCL']
|
||||
libs += ['EGL', 'GLESv3', 'gnustl_shared', 'log', 'utils', 'gui', 'hardware',
|
||||
'ui', 'CB', 'gsl', 'adreno_utils', 'OpenSLES', 'cutils', 'uuid', 'OpenCL']
|
||||
linkflags = ['-Wl,-rpath=/system/lib64,-rpath=/system/comma/usr/lib']
|
||||
|
||||
src += ["android/ui.cc", "android/sl_sound.cc"]
|
||||
env.Program('_ui', src,
|
||||
LINKFLAGS=linkflags,
|
||||
LIBS=libs)
|
||||
|
||||
else:
|
||||
qt_libs = ["pthread"]
|
||||
|
||||
if arch == "Darwin":
|
||||
qt_env["FRAMEWORKS"] += ["QtWidgets", "QtGui", "QtCore", "QtDBus", "QtMultimedia"]
|
||||
else:
|
||||
qt_libs += ["Qt5Widgets", "Qt5Gui", "Qt5Core", "Qt5DBus", "Qt5Multimedia"]
|
||||
qt_modules = ["Widgets", "Gui", "Core", "DBus", "Multimedia"]
|
||||
|
||||
if arch == "larch64":
|
||||
qt_libs += ["GLESv2", "wayland-client"]
|
||||
else:
|
||||
elif arch != "Darwin":
|
||||
qt_libs += ["GL"]
|
||||
|
||||
qt_src = ["qt/ui.cc", "qt/window.cc", "qt/settings.cc", "qt/qt_sound.cc"] + src
|
||||
if arch == "Darwin":
|
||||
qt_env["FRAMEWORKS"] += [f"Qt{m}" for m in qt_modules] + ["OpenGL"]
|
||||
else:
|
||||
qt_libs += [f"Qt5{m}" for m in qt_modules]
|
||||
|
||||
qt_src = ["qt/ui.cc", "qt/window.cc", "qt/qt_sound.cc", "qt//offroad/keyboard.cc", "qt/offroad/input_field.cc", "qt/offroad/settings.cc", "qt/offroad/onboarding.cc", "qt/offroad/wifi.cc", "qt/offroad/wifiManager.cc"] + src
|
||||
qt_env.Program("_ui", qt_src, LIBS=qt_libs + libs)
|
||||
|
||||
# spinner and text window
|
||||
qt_env.Program("qt/text", ["qt/text.cc"], LIBS=qt_libs + libs)
|
||||
qt_env.Program("qt/spinner", ["qt/spinner.cc"], LIBS=qt_libs + libs)
|
||||
|
||||
# setup and installer
|
||||
if "BUILD_SETUP" in os.environ:
|
||||
qt_env.Program("qt/setup/setup", ["qt/setup/setup.cc"], LIBS=qt_libs + libs + ['curl'])
|
||||
qt_env.Program("qt/setup/installer", ["qt/setup/installer.cc"], LIBS=qt_libs + libs)
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
CC = clang
|
||||
CXX = clang++
|
||||
|
||||
PHONELIBS = ../../../phonelibs
|
||||
ROOT_DIR = ../../..
|
||||
PHONELIBS = $(ROOT_DIR)/phonelibs
|
||||
COMMON = $(ROOT)/selfdrive/common
|
||||
|
||||
WARN_FLAGS = -Werror=implicit-function-declaration \
|
||||
-Werror=incompatible-pointer-types \
|
||||
@@ -19,10 +21,10 @@ OPENGL_LIBS = -lGLESv3
|
||||
FRAMEBUFFER_LIBS = -lutils -lgui -lEGL
|
||||
|
||||
OBJS = spinner.o \
|
||||
../../common/framebuffer.o \
|
||||
../../common/util.o \
|
||||
$(COMMON)/framebuffer.o \
|
||||
$(COMMON)/util.o \
|
||||
$(PHONELIBS)/nanovg/nanovg.o \
|
||||
../../common/spinner.o \
|
||||
$(COMMON)/spinner.o \
|
||||
opensans_semibold.o \
|
||||
img_spinner_track.o \
|
||||
img_spinner_comma.o
|
||||
@@ -41,7 +43,7 @@ spinner: $(OBJS)
|
||||
$(OPENGL_LIBS) \
|
||||
-lm -llog
|
||||
|
||||
../../common/framebuffer.o: ../../common/framebuffer.cc
|
||||
$(COMMON)/framebuffer.o: $(COMMON)/framebuffer.cc
|
||||
@echo "[ CXX ] $@"
|
||||
$(CXX) $(CXXFLAGS) -MMD \
|
||||
-I$(PHONELIBS)/android_frameworks_native/include \
|
||||
@@ -49,15 +51,15 @@ spinner: $(OBJS)
|
||||
-I$(PHONELIBS)/android_hardware_libhardware/include \
|
||||
-c -o '$@' '$<'
|
||||
|
||||
opensans_semibold.o: ../../assets/fonts/opensans_semibold.ttf
|
||||
opensans_semibold.o: $(ROOT_DIR)/selfdrive/assets/fonts/opensans_semibold.ttf
|
||||
@echo "[ bin2o ] $@"
|
||||
cd '$(dir $<)' && ld -r -b binary '$(notdir $<)' -o '$(abspath $@)'
|
||||
|
||||
img_spinner_track.o: ../../assets/img_spinner_track.png
|
||||
img_spinner_track.o: $(ROOT_DIR)/selfdrive/assets/img_spinner_track.png
|
||||
@echo "[ bin2o ] $@"
|
||||
cd '$(dir $<)' && ld -r -b binary '$(notdir $<)' -o '$(abspath $@)'
|
||||
|
||||
img_spinner_comma.o: ../../assets/img_spinner_comma.png
|
||||
img_spinner_comma.o: $(ROOT_DIR)/selfdrive/assets/img_spinner_comma.png
|
||||
@echo "[ bin2o ] $@"
|
||||
cd '$(dir $<)' && ld -r -b binary '$(notdir $<)' -o '$(abspath $@)'
|
||||
|
||||
@@ -42,8 +42,7 @@ bool stdin_input_available() {
|
||||
return (FD_ISSET(0, &fds));
|
||||
}
|
||||
|
||||
int spin(int argc, char** argv) {
|
||||
int err;
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
bool draw_progress = false;
|
||||
float progress_val = 0.0;
|
||||
@@ -1,7 +1,8 @@
|
||||
CC = clang
|
||||
CXX = clang++
|
||||
|
||||
PHONELIBS = ../../../phonelibs
|
||||
PHONELIBS = ../../../../phonelibs
|
||||
COMMON = ../../../common
|
||||
|
||||
WARN_FLAGS = -Werror=implicit-function-declaration \
|
||||
-Werror=incompatible-pointer-types \
|
||||
@@ -19,9 +20,9 @@ OPENGL_LIBS = -lGLESv3
|
||||
FRAMEBUFFER_LIBS = -lutils -lgui -lEGL
|
||||
|
||||
OBJS = text.o \
|
||||
../../common/framebuffer.o \
|
||||
../../common/util.o \
|
||||
../../../selfdrive/common/touch.o \
|
||||
$(COMMON)/framebuffer.o \
|
||||
$(COMMON)/util.o \
|
||||
$(COMMON)/touch.o \
|
||||
$(PHONELIBS)/nanovg/nanovg.o \
|
||||
opensans_regular.o \
|
||||
|
||||
@@ -39,7 +40,7 @@ text: $(OBJS)
|
||||
$(OPENGL_LIBS) \
|
||||
-lm -llog
|
||||
|
||||
opensans_regular.o: ../../assets/fonts/opensans_regular.ttf
|
||||
opensans_regular.o: ../../../assets/fonts/opensans_regular.ttf
|
||||
@echo "[ bin2o ] $@"
|
||||
cd '$(dir $<)' && ld -r -b binary '$(notdir $<)' -o '$(abspath $@)'
|
||||
|
||||
@@ -47,7 +48,7 @@ opensans_regular.o: ../../assets/fonts/opensans_regular.ttf
|
||||
mkdir -p $(@D)
|
||||
@echo "[ CC ] $@"
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) \
|
||||
-I../.. \
|
||||
-I../../.. \
|
||||
-I$(PHONELIBS)/android_frameworks_native/include \
|
||||
-I$(PHONELIBS)/android_system_core/include \
|
||||
-I$(PHONELIBS)/android_hardware_libhardware/include \
|
||||
@@ -58,8 +59,8 @@ opensans_regular.o: ../../assets/fonts/opensans_regular.ttf
|
||||
mkdir -p $(@D)
|
||||
@echo "[ CXX ] $@"
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) \
|
||||
-I../../selfdrive \
|
||||
-I../../ \
|
||||
-I../../../selfdrive \
|
||||
-I../../../ \
|
||||
-I$(PHONELIBS)/android_frameworks_native/include \
|
||||
-I$(PHONELIBS)/android_system_core/include \
|
||||
-I$(PHONELIBS)/android_hardware_libhardware/include \
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "common/util.h"
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
#define NANOVG_GLES3_IMPLEMENTATION
|
||||
#include "nanovg_gl.h"
|
||||
#include "nanovg_gl_utils.h"
|
||||
@@ -56,6 +57,7 @@ bool car_space_to_full_frame(const UIState *s, float in_x, float in_y, float in_
|
||||
return *out_x >= 0 && *out_x <= s->fb_w && *out_y >= 0 && *out_y <= s->fb_h;
|
||||
}
|
||||
|
||||
|
||||
static void ui_draw_text(NVGcontext *vg, float x, float y, const char* string, float size, NVGcolor color, int font){
|
||||
nvgFontFaceId(vg, font);
|
||||
nvgFontSize(vg, size);
|
||||
@@ -260,7 +262,9 @@ static void ui_draw_world(UIState *s) {
|
||||
const UIScene *scene = &s->scene;
|
||||
|
||||
nvgSave(s->vg);
|
||||
nvgScissor(s->vg, s->video_rect.x, s->video_rect.y, s->video_rect.w, s->video_rect.h);
|
||||
|
||||
// Don't draw on top of sidebar
|
||||
nvgScissor(s->vg, scene->viz_rect.x, scene->viz_rect.y, scene->viz_rect.w, scene->viz_rect.h);
|
||||
|
||||
// Apply transformation such that video pixel coordinates match video
|
||||
// 1) Put (0, 0) in the middle of the video
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
#include <QEvent>
|
||||
#include <QVBoxLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
|
||||
#include "input_field.hpp"
|
||||
#include "keyboard.hpp"
|
||||
|
||||
InputField::InputField(QWidget *parent): QWidget(parent) {
|
||||
l = new QVBoxLayout();
|
||||
QHBoxLayout *r = new QHBoxLayout();
|
||||
label = new QLabel(this);
|
||||
label->setText("password");
|
||||
r->addWidget(label);
|
||||
QPushButton* cancel = new QPushButton("cancel");
|
||||
QObject::connect(cancel, SIGNAL(released()), this, SLOT(emitEmpty()));
|
||||
cancel->setFixedHeight(150);
|
||||
cancel->setFixedWidth(300);
|
||||
r->addWidget(cancel);
|
||||
l->addLayout(r);
|
||||
l->addSpacing(80);
|
||||
|
||||
line = new QLineEdit("");
|
||||
l->addWidget(line);
|
||||
l->addSpacing(200);
|
||||
|
||||
k = new Keyboard(this);
|
||||
QObject::connect(k, SIGNAL(emitButton(QString)), this, SLOT(getText(QString)));
|
||||
l->addWidget(k);
|
||||
setLayout(l);
|
||||
}
|
||||
|
||||
void InputField::emitEmpty(){
|
||||
emitText("");
|
||||
line->setText("");
|
||||
}
|
||||
void InputField::getText(QString s){
|
||||
if(!QString::compare(s,"⌫")){
|
||||
line->backspace();
|
||||
}
|
||||
|
||||
if(!QString::compare(s,"⏎")){
|
||||
emitText(line->text());
|
||||
line->setText("");
|
||||
}
|
||||
|
||||
QVector<QString> control_buttons {"⇧", "↑", "ABC", "⏎", "#+=", "⌫", "123"};
|
||||
for(QString c :control_buttons){
|
||||
if(!QString::compare(s, c)){
|
||||
return;
|
||||
}
|
||||
}
|
||||
line->insert(s.left(1));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QLineEdit>
|
||||
#include <QVBoxLayout>
|
||||
#include <QStackedLayout>
|
||||
#include <QLabel>
|
||||
|
||||
#include "keyboard.hpp"
|
||||
|
||||
class InputField : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit InputField(QWidget* parent = 0);
|
||||
QLabel *label;
|
||||
|
||||
private:
|
||||
QLineEdit *line;
|
||||
Keyboard *k;
|
||||
QVBoxLayout *l;
|
||||
|
||||
public slots:
|
||||
void emitEmpty();
|
||||
void getText(QString s);
|
||||
|
||||
signals:
|
||||
void emitText(QString s);
|
||||
};
|
||||
@@ -0,0 +1,120 @@
|
||||
#include <QDebug>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QPushButton>
|
||||
#include <QButtonGroup>
|
||||
#include <QStackedLayout>
|
||||
|
||||
#include "keyboard.hpp"
|
||||
|
||||
KeyboardLayout::KeyboardLayout(QWidget* parent, std::vector<QVector<QString>> layout) : QWidget(parent) {
|
||||
QVBoxLayout* vlayout = new QVBoxLayout;
|
||||
QButtonGroup* btn_group = new QButtonGroup(this);
|
||||
|
||||
QObject::connect(btn_group, SIGNAL(buttonClicked(QAbstractButton*)), parent, SLOT(handleButton(QAbstractButton*)));
|
||||
|
||||
int i = 0;
|
||||
for(auto s : layout){
|
||||
QHBoxLayout *hlayout = new QHBoxLayout;
|
||||
|
||||
if (i == 1){
|
||||
hlayout->addSpacing(50);
|
||||
}
|
||||
|
||||
for(QString p : s){
|
||||
QPushButton* btn = new QPushButton(p);
|
||||
btn->setFixedHeight(100);
|
||||
|
||||
if (p == QString(" ")){
|
||||
btn->setFixedWidth(1024);
|
||||
}
|
||||
|
||||
btn_group->addButton(btn);
|
||||
hlayout->addSpacing(5);
|
||||
hlayout->addWidget(btn);
|
||||
}
|
||||
|
||||
if (i == 1){
|
||||
hlayout->addSpacing(50);
|
||||
}
|
||||
|
||||
vlayout->addLayout(hlayout);
|
||||
i++;
|
||||
}
|
||||
|
||||
setLayout(vlayout);
|
||||
}
|
||||
|
||||
Keyboard::Keyboard(QWidget *parent) : QWidget(parent) {
|
||||
main_layout = new QStackedLayout;
|
||||
|
||||
// lowercase
|
||||
std::vector<QVector<QString>> lowercase = {
|
||||
{"q","w","e","r","t","y","u","i","o","p"},
|
||||
{"a","s","d","f","g","h","j","k","l"},
|
||||
{"⇧","z","x","c","v","b","n","m","⌫"},
|
||||
{"123"," ","⏎"},
|
||||
};
|
||||
main_layout->addWidget(new KeyboardLayout(this, lowercase));
|
||||
|
||||
// uppercase
|
||||
std::vector<QVector<QString>> uppercase = {
|
||||
{"Q","W","E","R","T","Y","U","I","O","P"},
|
||||
{"A","S","D","F","G","H","J","K","L"},
|
||||
{"↑","Z","X","C","V","B","N","M","⌫"},
|
||||
{"123"," ","⏎"},
|
||||
};
|
||||
main_layout->addWidget(new KeyboardLayout(this, uppercase));
|
||||
|
||||
// 1234567890
|
||||
std::vector<QVector<QString>> numbers = {
|
||||
{"1","2","3","4","5","6","7","8","9","0"},
|
||||
{"-","/",":",";","(",")","$","&&","@","\""},
|
||||
{"#+=",".",",","?","!","`","⌫"},
|
||||
{"ABC"," ","⏎"},
|
||||
};
|
||||
main_layout->addWidget(new KeyboardLayout(this, numbers));
|
||||
|
||||
// Special characters
|
||||
std::vector<QVector<QString>> specials = {
|
||||
{"[","]","{","}","#","%","^","*","+","="},
|
||||
{"_","\\","|","~","<",">","€","£","¥"," "},
|
||||
{"123",".",",","?","!","`","⌫"},
|
||||
{"ABC"," ","⏎"},
|
||||
};
|
||||
main_layout->addWidget(new KeyboardLayout(this, specials));
|
||||
|
||||
setLayout(main_layout);
|
||||
main_layout->setCurrentIndex(0);
|
||||
|
||||
setStyleSheet(R"(
|
||||
QPushButton { font-size: 40px }
|
||||
* {
|
||||
background-color: #99777777;
|
||||
}
|
||||
)");
|
||||
}
|
||||
|
||||
|
||||
void Keyboard::handleButton(QAbstractButton* m_button){
|
||||
QString id = m_button->text();
|
||||
if(!QString::compare(m_button->text(),"↑")||!QString::compare(m_button->text(),"ABC")){
|
||||
main_layout->setCurrentIndex(0);
|
||||
}
|
||||
if(!QString::compare(m_button->text(),"⇧")){
|
||||
main_layout->setCurrentIndex(1);
|
||||
}
|
||||
if(!QString::compare(m_button->text(),"123")){
|
||||
main_layout->setCurrentIndex(2);
|
||||
}
|
||||
if(!QString::compare(m_button->text(),"#+=")){
|
||||
main_layout->setCurrentIndex(3);
|
||||
}
|
||||
if(!QString::compare(m_button->text(),"⏎")){
|
||||
main_layout->setCurrentIndex(0);
|
||||
}
|
||||
if("A" <= id && id <= "Z"){
|
||||
main_layout->setCurrentIndex(0);
|
||||
}
|
||||
emit emitButton(m_button->text());
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <QString>
|
||||
#include <QWidget>
|
||||
#include <QStackedLayout>
|
||||
#include <QAbstractButton>
|
||||
|
||||
class KeyboardLayout : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit KeyboardLayout(QWidget *parent, std::vector<QVector<QString>> layout);
|
||||
};
|
||||
|
||||
class Keyboard : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Keyboard(QWidget *parent = 0);
|
||||
|
||||
private:
|
||||
QStackedLayout* main_layout;
|
||||
|
||||
private slots:
|
||||
void handleButton(QAbstractButton* m_button);
|
||||
|
||||
signals:
|
||||
void emitButton(QString s);
|
||||
};
|
||||
@@ -0,0 +1,115 @@
|
||||
#include <QLabel>
|
||||
#include <QString>
|
||||
#include <QPushButton>
|
||||
#include <QGridLayout>
|
||||
|
||||
#include "onboarding.hpp"
|
||||
#include "common/params.h"
|
||||
|
||||
|
||||
QLabel * title_label(QString text) {
|
||||
QLabel *l = new QLabel(text);
|
||||
l->setStyleSheet(R"(font-size: 100px;)");
|
||||
l->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
return l;
|
||||
}
|
||||
|
||||
QWidget * OnboardingWindow::terms_screen() {
|
||||
|
||||
QGridLayout *main_layout = new QGridLayout();
|
||||
main_layout->setMargin(30);
|
||||
main_layout->setSpacing(30);
|
||||
|
||||
main_layout->addWidget(title_label("Review Terms"), 0, 0, 1, -1);
|
||||
|
||||
QLabel *terms = new QLabel("See terms at https://my.comma.ai/terms");
|
||||
terms->setAlignment(Qt::AlignCenter);
|
||||
terms->setStyleSheet(R"(
|
||||
font-size: 75px;
|
||||
border-radius: 10px;
|
||||
background-color: #292929;
|
||||
)");
|
||||
main_layout->addWidget(terms, 1, 0, 1, -1);
|
||||
|
||||
main_layout->addWidget(new QPushButton("Decline"), 2, 0);
|
||||
|
||||
QPushButton *accept_btn = new QPushButton("Accept");
|
||||
main_layout->addWidget(accept_btn, 2, 1);
|
||||
QObject::connect(accept_btn, &QPushButton::released, [=]() {
|
||||
Params().write_db_value("HasAcceptedTerms", LATEST_TERMS_VERSION);
|
||||
updateActiveScreen();
|
||||
});
|
||||
|
||||
QWidget *widget = new QWidget;
|
||||
widget->setLayout(main_layout);
|
||||
widget->setStyleSheet(R"(
|
||||
QPushButton {
|
||||
font-size: 50px;
|
||||
padding: 50px;
|
||||
border-radius: 10px;
|
||||
background-color: #292929;
|
||||
}
|
||||
)");
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
QWidget * OnboardingWindow::training_screen() {
|
||||
|
||||
QGridLayout *main_layout = new QGridLayout();
|
||||
main_layout->setMargin(30);
|
||||
main_layout->setSpacing(30);
|
||||
|
||||
main_layout->addWidget(title_label("Training Guide"), 0, 0);
|
||||
|
||||
QPushButton *btn = new QPushButton("Continue");
|
||||
main_layout->addWidget(btn, 1, 0);
|
||||
QObject::connect(btn, &QPushButton::released, [=]() {
|
||||
Params().write_db_value("CompletedTrainingVersion", LATEST_TRAINING_VERSION);
|
||||
updateActiveScreen();
|
||||
});
|
||||
|
||||
QWidget *widget = new QWidget;
|
||||
widget->setLayout(main_layout);
|
||||
return widget;
|
||||
}
|
||||
|
||||
void OnboardingWindow::updateActiveScreen() {
|
||||
|
||||
Params params = Params();
|
||||
bool accepted_terms = params.get("HasAcceptedTerms", false).compare(LATEST_TERMS_VERSION) == 0;
|
||||
bool training_done = params.get("CompletedTrainingVersion", false).compare(LATEST_TRAINING_VERSION) == 0;
|
||||
|
||||
if (!accepted_terms) {
|
||||
swidget->setCurrentIndex(0);
|
||||
} else if (!training_done) {
|
||||
swidget->setCurrentIndex(1);
|
||||
} else {
|
||||
emit onboardingDone();
|
||||
}
|
||||
}
|
||||
|
||||
OnboardingWindow::OnboardingWindow(QWidget *parent) : QWidget(parent) {
|
||||
QVBoxLayout * top_layout = new QVBoxLayout;
|
||||
|
||||
swidget = new QStackedWidget();
|
||||
swidget->addWidget(terms_screen());
|
||||
swidget->addWidget(training_screen());
|
||||
|
||||
top_layout->addWidget(swidget);
|
||||
|
||||
setLayout(top_layout);
|
||||
setStyleSheet(R"(
|
||||
* {
|
||||
background-color: black;
|
||||
}
|
||||
QPushButton {
|
||||
font-size: 50px;
|
||||
padding: 50px;
|
||||
border-radius: 10px;
|
||||
background-color: #292929;
|
||||
}
|
||||
)");
|
||||
|
||||
updateActiveScreen();
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user