diff --git a/.gitignore b/.gitignore
index f1f1d431c..f4932ed4f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,6 +10,7 @@ venv/
.vscode*
model2.png
a.out
+.hypothesis
*.dylib
*.DSYM
@@ -59,6 +60,7 @@ notebooks
xx
hyperthneed
panda_jungle
+provisioning
.coverage*
coverage.xml
diff --git a/Jenkinsfile b/Jenkinsfile
index 78a3a0fa6..97633da80 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -36,7 +36,7 @@ EOF"""
def phone_steps(String device_type, steps) {
lock(resource: "", label: device_type, inversePrecedence: true, variable: 'device_ip', quantity: 1) {
- timeout(time: 60, unit: 'MINUTES') {
+ timeout(time: 90, unit: 'MINUTES') {
phone(device_ip, "git checkout", readFile("selfdrive/test/setup_device_ci.sh"),)
steps.each { item ->
phone(device_ip, item[0], item[1])
@@ -83,7 +83,6 @@ pipeline {
}
}
-
stages {
/*
@@ -113,6 +112,10 @@ pipeline {
stage('On-device Tests') {
agent {
docker {
+ /*
+ filename 'Dockerfile.ondevice_ci'
+ args "--privileged -v /dev:/dev --shm-size=1G --user=root"
+ */
image 'python:3.7.3'
args '--user=root'
}
@@ -121,17 +124,12 @@ pipeline {
stages {
stage('parallel tests') {
parallel {
- stage('Devel Build') {
- environment {
- CI_PUSH = "${env.BRANCH_NAME == 'master' ? 'master-ci' : ' '}"
- }
+ stage('Devel Tests') {
steps {
phone_steps("eon-build", [
- ["build", "SCONS_CACHE=1 scons -j4"],
- ["test athena", "nosetests -s selfdrive/athena/tests/test_athenad_old.py"],
+ ["build devel", "cd release && SCONS_CACHE=1 DEVEL_TEST=1 ./build_devel.sh"],
["test manager", "python selfdrive/manager/test/test_manager.py"],
["onroad tests", "cd selfdrive/test/ && ./test_onroad.py"],
- ["build devel", "cd release && CI_PUSH=${env.CI_PUSH} ./build_devel.sh"],
["test car interfaces", "cd selfdrive/car/tests/ && ./test_car_interfaces.py"],
])
}
@@ -150,6 +148,7 @@ pipeline {
steps {
phone_steps("eon", [
["build", "SCONS_CACHE=1 scons -j4"],
+ ["test athena", "nosetests -s selfdrive/athena/tests/test_athenad_old.py"],
["test sounds", "nosetests -s selfdrive/test/test_sounds.py"],
["test boardd loopback", "nosetests -s selfdrive/boardd/tests/test_boardd_loopback.py"],
["test loggerd", "python selfdrive/loggerd/tests/test_loggerd.py"],
@@ -160,6 +159,27 @@ pipeline {
}
}
+ /*
+ stage('Power Consumption Tests') {
+ steps {
+ lock(resource: "", label: "c2-zookeeper", inversePrecedence: true, variable: 'device_ip', quantity: 1) {
+ timeout(time: 90, unit: 'MINUTES') {
+ sh script: "/home/batman/tools/zookeeper/enable_and_wait.py $device_ip 120", label: "turn on device"
+ phone(device_ip, "git checkout", readFile("selfdrive/test/setup_device_ci.sh"),)
+ phone(device_ip, "build", "SCONS_CACHE=1 scons -j4 && sync")
+ sh script: "/home/batman/tools/zookeeper/disable.py $device_ip", label: "turn off device"
+ sh script: "/home/batman/tools/zookeeper/enable_and_wait.py $device_ip 120", label: "turn on device"
+ sh script: "/home/batman/tools/zookeeper/check_consumption.py 60 3", label: "idle power consumption after boot"
+ sh script: "/home/batman/tools/zookeeper/ignition.py 1", label: "go onroad"
+ sh script: "/home/batman/tools/zookeeper/check_consumption.py 60 10", label: "onroad power consumption"
+ sh script: "/home/batman/tools/zookeeper/ignition.py 0", label: "go offroad"
+ sh script: "/home/batman/tools/zookeeper/check_consumption.py 60 2", label: "idle power consumption offroad"
+ }
+ }
+ }
+ }
+ */
+
stage('Tici Build') {
environment {
R3_PUSH = "${env.BRANCH_NAME == 'master' ? '1' : ' '}"
@@ -169,6 +189,7 @@ pipeline {
["build", "SCONS_CACHE=1 scons -j16"],
["test loggerd", "python selfdrive/loggerd/tests/test_loggerd.py"],
["test encoder", "LD_LIBRARY_PATH=/usr/local/lib python selfdrive/loggerd/tests/test_encoder.py"],
+ ["onroad tests", "cd selfdrive/test/ && ./test_onroad.py"],
//["build release3-staging", "cd release && PUSH=${env.R3_PUSH} ./build_release3.sh"],
])
}
@@ -196,6 +217,18 @@ pipeline {
}
}
+
+ stage('Push master-ci') {
+ when {
+ branch 'master'
+ }
+ steps {
+ phone_steps("eon-build", [
+ ["push devel", "cd release && CI_PUSH='master-ci' ./build_devel.sh"],
+ ])
+ }
+ }
+
}
post {
diff --git a/README.md b/README.md
index 52c06169e..95a0897c1 100644
--- a/README.md
+++ b/README.md
@@ -66,7 +66,7 @@ Supported Cars
| ----------| ------------------------------| ------------------| -----------------| -------------------| ------------------|
| Acura | ILX 2016-19 | AcuraWatch Plus | openpilot | 25mph1 | 25mph |
| Acura | RDX 2016-18 | AcuraWatch Plus | openpilot | 25mph1 | 12mph |
-| Acura | RDX 2020-21 | All | Stock | 0mph | 3mph |
+| Acura | RDX 2019-21 | 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-21 | Honda Sensing | Stock | 0mph | 12mph |
@@ -86,18 +86,18 @@ Supported Cars
| Hyundai | Palisade 2020-21 | All | Stock | 0mph | 0mph |
| Hyundai | Sonata 2020-21 | All | Stock | 0mph | 0mph |
| Lexus | CT Hybrid 2017-18 | LSS | Stock3| 0mph | 0mph |
-| Lexus | ES 2019-20 | All | openpilot | 0mph | 0mph |
-| Lexus | ES Hybrid 2018 | LSS | Stock3| 0mph | 0mph |
-| Lexus | ES Hybrid 2019 | All | openpilot | 0mph | 0mph |
+| Lexus | ES 2019-21 | All | openpilot | 0mph | 0mph |
+| Lexus | ES Hybrid 2017-18 | LSS | Stock3| 0mph | 0mph |
+| Lexus | ES Hybrid 2019-21 | All | openpilot | 0mph | 0mph |
| Lexus | IS 2017-2019 | All | Stock | 22mph | 0mph |
-| Lexus | IS Hybrid 2017 | All | Stock | 0mph | 0mph |
| Lexus | NX 2018 | All | Stock3| 0mph | 0mph |
+| Lexus | NX 2020 | All | openpilot | 0mph | 0mph |
| Lexus | NX Hybrid 2018 | All | Stock3| 0mph | 0mph |
| Lexus | RX 2016-18 | All | Stock3| 0mph | 0mph |
| Lexus | RX 2020-21 | All | openpilot | 0mph | 0mph |
| Lexus | RX Hybrid 2016-19 | All | Stock3| 0mph | 0mph |
| Lexus | RX Hybrid 2020 | All | openpilot | 0mph | 0mph |
-| Toyota | Avalon 2016-18, 2020-21 | TSS-P | Stock3| 20mph1 | 0mph |
+| Toyota | Avalon 2016-21 | TSS-P | Stock3| 20mph1 | 0mph |
| Toyota | Camry 2018-20 | All | Stock | 0mph4 | 0mph |
| Toyota | Camry 2021 | All | openpilot | 0mph | 0mph |
| Toyota | Camry Hybrid 2018-20 | All | Stock | 0mph4 | 0mph |
@@ -112,6 +112,7 @@ Supported Cars
| Toyota | Highlander 2020-21 | All | openpilot | 0mph | 0mph |
| Toyota | Highlander Hybrid 2017-19 | All | Stock3| 0mph | 0mph |
| Toyota | Highlander Hybrid 2020-21 | All | openpilot | 0mph | 0mph |
+| Toyota | Mirai 2021 | All | openpilot | 0mph | 0mph |
| Toyota | Prius 2016-20 | TSS-P | Stock3| 0mph | 0mph |
| Toyota | Prius 2021 | All | openpilot | 0mph | 0mph |
| Toyota | Prius Prime 2017-20 | All | Stock3| 0mph | 0mph |
@@ -132,7 +133,8 @@ Community Maintained Cars and Features
| Make | Model (US Market Reference) | Supported Package | ACC | No ACC accel below | No ALC below |
| ----------| ------------------------------| ------------------| -----------------| -------------------| -------------|
-| Audi | A3 2015, 2017 | Prestige | Stock | 0mph | 0mph |
+| Audi | A3 2014-17 | Prestige | Stock | 0mph | 0mph |
+| Audi | A3 Sportback e-tron 2017-18 | Prestige | Stock | 0mph | 0mph |
| Buick | Regal 20181 | Adaptive Cruise | openpilot | 0mph | 7mph |
| Cadillac | ATS 20181 | Adaptive Cruise | openpilot | 0mph | 7mph |
| Chevrolet | Malibu 20171 | Adaptive Cruise | openpilot | 0mph | 7mph |
@@ -157,45 +159,48 @@ Community Maintained Cars and Features
| Hyundai | Veloster 2019 | SCC + LKAS | Stock | 5mph | 0mph |
| Jeep | Grand Cherokee 2016-18 | Adaptive Cruise | Stock | 0mph | 9mph |
| Jeep | Grand Cherokee 2019-20 | Adaptive Cruise | Stock | 0mph | 39mph |
-| Kia | Forte 2018-19, 2021 | SCC + LKAS | Stock | 0mph | 0mph |
+| Kia | Forte 2018-2021 | 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 | Seltos 2021 | SCC + LKAS | Stock | 0mph | 0mph |
-| Kia | Sorento 2018 | SCC + LKAS | Stock | 0mph | 0mph |
+| Kia | Sorento 2018-19 | SCC + LKAS | Stock | 0mph | 0mph |
| Kia | Stinger 2018 | SCC + LKAS | Stock | 0mph | 0mph |
| Kia | Ceed 2019 | SCC + LKAS | Stock | 0mph | 0mph |
| Nissan | Altima 2020 | ProPILOT | Stock | 0mph | 0mph |
| Nissan | Leaf 2018-20 | ProPILOT | Stock | 0mph | 0mph |
-| Nissan | Rogue 2018-19 | ProPILOT | Stock | 0mph | 0mph |
+| Nissan | Rogue 2018-20 | ProPILOT | Stock | 0mph | 0mph |
| Nissan | X-Trail 2017 | ProPILOT | Stock | 0mph | 0mph |
| SEAT | Ateca 2018 | Driver Assistance | Stock | 0mph | 0mph |
| Škoda | Kodiaq 2018 | Driver Assistance | Stock | 0mph | 0mph |
| Škoda | Scala 2020 | Driver Assistance | Stock | 0mph | 0mph |
-| Škoda | Superb 2018 | Driver Assistance | Stock | 0mph | 0mph |
+| Škoda | Superb 2015-18 | Driver Assistance | Stock | 0mph | 0mph |
| Subaru | Ascent 2019 | EyeSight | Stock | 0mph | 0mph |
| Subaru | Crosstrek 2018-19 | EyeSight | Stock | 0mph | 0mph |
-| Subaru | Forester 2019-20 | EyeSight | Stock | 0mph | 0mph |
+| Subaru | Forester 2019-21 | EyeSight | Stock | 0mph | 0mph |
| Subaru | Impreza 2017-19 | EyeSight | Stock | 0mph | 0mph |
-| Volkswagen| e-Golf 2014, 2020 | Driver Assistance | Stock | 0mph | 0mph |
+| Volkswagen| Atlas 2018-19 | Driver Assistance | Stock | 0mph | 0mph |
+| Volkswagen| e-Golf 2014, 2019-20 | Driver Assistance | Stock | 0mph | 0mph |
| Volkswagen| Golf 2015-19 | Driver Assistance | Stock | 0mph | 0mph |
+| Volkswagen| Golf Alltrack 2017-18 | Driver Assistance | Stock | 0mph | 0mph |
| Volkswagen| Golf GTE 2016 | Driver Assistance | Stock | 0mph | 0mph |
| Volkswagen| Golf GTI 2018-19 | Driver Assistance | Stock | 0mph | 0mph |
| Volkswagen| Golf R 2016-19 | Driver Assistance | Stock | 0mph | 0mph |
| Volkswagen| Golf SportsVan 2016 | Driver Assistance | Stock | 0mph | 0mph |
-| Volkswagen| Jetta 2018-21 | Driver Assistance | Stock | 0mph | 0mph |
+| Volkswagen| Jetta 2018-20 | Driver Assistance | Stock | 0mph | 0mph |
+| Volkswagen| Jetta GLI 2021 | Driver Assistance | Stock | 0mph | 0mph |
| Volkswagen| Passat 2016-172 | Driver Assistance | Stock | 0mph | 0mph |
| Volkswagen| Tiguan 2020 | Driver Assistance | Stock | 0mph | 0mph |
1Requires 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).***
2Only includes the MQB Passat sold outside of North America. The NMS Passat made in Chattanooga TN is not yet supported.
-Although it's not upstream, there's a community of people getting openpilot to run on Tesla's [here](https://tinkla.us/)
-
Community Maintained Cars and Features are not verified by comma to meet our [safety model](SAFETY.md). Be extra cautious using them. They are only available after enabling the toggle in `Settings->Developer->Enable Community Features`.
To promote a car from community maintained, it must meet a few requirements. We must own one from the brand, we must sell the harness for it, has full ISO26262 in both panda and openpilot, there must be a path forward for longitudinal control, it must have AEB still enabled, and it must support fingerprinting 2.0
+Although they're not upstream, the community has openpilot running on other makes and models. See the 'Community Supported Models' section of each make [on our wiki](https://wiki.comma.ai/).
+
Installation Instructions
------
@@ -327,7 +332,7 @@ Directory Structure
.
├── cereal # The messaging spec and libs used for all logs
├── common # Library like functionality we've developed here
- ├── installer/updater # Manages auto-updates of openpilot
+ ├── installer/updater # Manages auto-updates of NEOS
├── opendbc # Files showing how to interpret data from cars
├── panda # Code used to communicate on CAN
├── phonelibs # Libraries used on NEOS devices
diff --git a/RELEASES.md b/RELEASES.md
index 42b6379b4..bf764dd59 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,13 @@
+Version 0.8.4 (2021-05-17)
+========================
+ * Delay controls start until system is ready
+ * Fuzzy car identification, enabled with Community Features toggle
+ * Localizer optimized for increased precision and less CPU usage
+ * Retuned lateral control to be more aggressive when model is confident
+ * Toyota Mirai 2021 support
+ * Lexus NX 300 2020 support thanks to goesreallyfast!
+ * Volkswagen Atlas 2018-19 support thanks to jyoung8607!
+
Version 0.8.3 (2021-04-01)
========================
* New model
diff --git a/SConstruct b/SConstruct
index fc1ddfd66..138c6ab3f 100644
--- a/SConstruct
+++ b/SConstruct
@@ -13,6 +13,10 @@ AddOption('--test',
action='store_true',
help='build test files')
+AddOption('--kaitai',
+ action='store_true',
+ help='Regenerate kaitai struct parsers')
+
AddOption('--asan',
action='store_true',
help='turn on ASAN')
@@ -79,6 +83,9 @@ if arch == "aarch64" or arch == "larch64":
"#phonelibs/libyuv/larch64/lib",
"/usr/lib/aarch64-linux-gnu"
]
+ cpppath += [
+ "#selfdrive/camerad/include",
+ ]
cflags = ["-DQCOM2", "-mcpu=cortex-a57"]
cxxflags = ["-DQCOM2", "-mcpu=cortex-a57"]
rpath = ["/usr/local/lib"]
@@ -101,17 +108,22 @@ else:
cpppath = []
if arch == "Darwin":
+ yuv_dir = "mac" if real_arch != "arm64" else "mac_arm64"
libpath = [
- "#phonelibs/libyuv/mac/lib",
- "#cereal",
- "#selfdrive/common",
+ f"#phonelibs/libyuv/{yuv_dir}/lib",
"/usr/local/lib",
+ "/opt/homebrew/lib",
"/usr/local/opt/openssl/lib",
+ "/opt/homebrew/opt/openssl/lib",
"/System/Library/Frameworks/OpenGL.framework/Libraries",
]
cflags += ["-DGL_SILENCE_DEPRECATION"]
cxxflags += ["-DGL_SILENCE_DEPRECATION"]
- cpppath += ["/usr/local/opt/openssl/include"]
+ cpppath += [
+ "/opt/homebrew/include",
+ "/usr/local/opt/openssl/include",
+ "/opt/homebrew/opt/openssl/include"
+ ]
else:
libpath = [
"#phonelibs/snpe/x86_64-linux-clang",
@@ -141,6 +153,10 @@ else:
ccflags = []
ldflags = []
+# no --as-needed on mac linker
+if arch != "Darwin":
+ ldflags += ["-Wl,--as-needed"]
+
# change pythonpath to this
lenv["PYTHONPATH"] = Dir("#").path
@@ -162,7 +178,6 @@ env = Environment(
CPPPATH=cpppath + [
"#",
- "#selfdrive",
"#phonelibs/catch2/include",
"#phonelibs/bzip2",
"#phonelibs/libyuv/include",
@@ -177,14 +192,7 @@ env = Environment(
"#phonelibs/snpe/include",
"#phonelibs/nanovg",
"#phonelibs/qrcode",
- "#selfdrive/boardd",
- "#selfdrive/common",
- "#selfdrive/camerad",
- "#selfdrive/camerad/include",
- "#selfdrive/loggerd/include",
- "#selfdrive/modeld",
- "#selfdrive/sensord",
- "#selfdrive/ui",
+ "#phonelibs",
"#cereal",
"#cereal/messaging",
"#cereal/visionipc",
@@ -270,7 +278,10 @@ if arch != "aarch64":
qt_libs = []
if arch == "Darwin":
- qt_env['QTDIR'] = "/usr/local/opt/qt@5"
+ if real_arch == "arm64":
+ qt_env['QTDIR'] = "/opt/homebrew/opt/qt@5"
+ else:
+ qt_env['QTDIR'] = "/usr/local/opt/qt@5"
qt_dirs = [
os.path.join(qt_env['QTDIR'], "include"),
]
@@ -326,12 +337,8 @@ if GetOption("clazy"):
qt_env['CXX'] = 'clazy'
qt_env['ENV']['CLAZY_IGNORE_DIRS'] = qt_dirs[0]
qt_env['ENV']['CLAZY_CHECKS'] = ','.join(checks)
-Export('qt_env')
-
-# still needed for apks
-zmq = 'zmq'
-Export('env', 'arch', 'real_arch', 'zmq', 'SHARED', 'USE_WEBCAM', 'QCOM_REPLAY')
+Export('env', 'qt_env', 'arch', 'real_arch', 'SHARED', 'USE_WEBCAM', 'QCOM_REPLAY')
# cereal and messaging are shared with the system
SConscript(['cereal/SConscript'])
@@ -356,6 +363,28 @@ else:
Export('common', 'gpucommon', 'visionipc')
+# Build rednose library and ekf models
+
+rednose_config = {
+ 'generated_folder': '#selfdrive/locationd/models/generated',
+ 'to_build': {
+ 'live': ('#selfdrive/locationd/models/live_kf.py', True, ['live_kf_constants.h']),
+ 'car': ('#selfdrive/locationd/models/car_kf.py', True, []),
+ },
+}
+
+if arch != "aarch64":
+ rednose_config['to_build'].update({
+ 'gnss': ('#selfdrive/locationd/models/gnss_kf.py', True, []),
+ 'loc_4': ('#selfdrive/locationd/models/loc_kf.py', True, []),
+ 'pos_computer_4': ('#rednose/helpers/lst_sq_computer.py', False, []),
+ 'pos_computer_5': ('#rednose/helpers/lst_sq_computer.py', False, []),
+ 'feature_handler_5': ('#rednose/helpers/feature_handler.py', False, []),
+ 'lane': ('#xx/pipeline/lib/ekf/lane_kf.py', True, []),
+ })
+
+Export('rednose_config')
+SConscript(['rednose/SConscript'])
# Build openpilot
@@ -384,16 +413,12 @@ SConscript(['selfdrive/clocksd/SConscript'])
SConscript(['selfdrive/loggerd/SConscript'])
SConscript(['selfdrive/locationd/SConscript'])
-SConscript(['selfdrive/locationd/models/SConscript'])
SConscript(['selfdrive/sensord/SConscript'])
SConscript(['selfdrive/ui/SConscript'])
if arch != "Darwin":
SConscript(['selfdrive/logcatd/SConscript'])
-if real_arch == "x86_64":
- SConscript(['tools/nui/SConscript'])
-
external_sconscript = GetOption('external_sconscript')
if external_sconscript:
SConscript([external_sconscript])
diff --git a/cereal/SConscript b/cereal/SConscript
index bd2cde9c6..a671aeecc 100644
--- a/cereal/SConscript
+++ b/cereal/SConscript
@@ -1,4 +1,4 @@
-Import('env', 'envCython', 'arch', 'zmq', 'QCOM_REPLAY')
+Import('env', 'envCython', 'arch', 'QCOM_REPLAY')
import shutil
@@ -40,13 +40,6 @@ messaging_objects = env.SharedObject([
messaging_lib = env.Library('messaging', messaging_objects)
Depends('messaging/impl_zmq.cc', services_h)
-# note, this rebuilds the deps shared, zmq is statically linked to make APK happy
-# TODO: get APK to load system zmq to remove the static link
-if arch == "aarch64":
- zmq_static = FindFile("libzmq.a", "/usr/lib")
- shared_lib_shared_lib = [zmq_static, 'm', 'stdc++', "gnustl_shared", "kj", "capnp"]
- env.SharedLibrary('messaging_shared', messaging_objects, LIBS=shared_lib_shared_lib)
-
env.Program('messaging/bridge', ['messaging/bridge.cc'], LIBS=[messaging_lib, 'zmq'])
Depends('messaging/bridge.cc', services_h)
diff --git a/cereal/car.capnp b/cereal/car.capnp
index d5726f7c5..c98928190 100644
--- a/cereal/car.capnp
+++ b/cereal/car.capnp
@@ -53,7 +53,7 @@ struct CarEvent @0x9b1657f34caf3ad3 {
lowSpeedLockout @31;
plannerError @32;
debugAlert @34;
- steerTempUnavailableMute @35;
+ steerTempUnavailableUserOverride @35;
resumeRequired @36;
preDriverDistracted @37;
promptDriverDistracted @38;
@@ -64,7 +64,7 @@ struct CarEvent @0x9b1657f34caf3ad3 {
belowSteerSpeed @46;
lowBattery @48;
vehicleModelInvalid @50;
- controlsFailed @51;
+ accFaulted @51;
sensorDataInvalid @52;
commIssue @53;
tooDistracted @54;
@@ -89,6 +89,7 @@ struct CarEvent @0x9b1657f34caf3ad3 {
startupNoCar @76;
startupNoControl @77;
startupMaster @78;
+ startupFuzzyFingerprint @97;
fcw @79;
steerSaturated @80;
belowEngageSpeed @84;
@@ -101,6 +102,7 @@ struct CarEvent @0x9b1657f34caf3ad3 {
gpsMalfunction @94;
processNotRunning @95;
dashcamMode @96;
+ controlsInitializing @98;
radarCanErrorDEPRECATED @15;
radarCommIssueDEPRECATED @67;
@@ -351,12 +353,14 @@ struct CarControl {
struct CarParams {
carName @0 :Text;
carFingerprint @1 :Text;
+ fuzzyFingerprint @55 :Bool;
enableGasInterceptor @2 :Bool;
enableCruise @3 :Bool;
enableCamera @4 :Bool;
enableDsu @5 :Bool; # driving support unit
enableApgs @6 :Bool; # advanced parking guidance system
+ enableBsm @56 :Bool; # blind spot monitoring
minEnableSpeed @7 :Float32;
minSteerSpeed @8 :Float32;
@@ -412,6 +416,7 @@ struct CarParams {
dashcamOnly @41: Bool;
transmissionType @43 :TransmissionType;
carFw @44 :List(CarFw);
+
radarTimeStep @45: Float32 = 0.05; # time delta between radar updates, 20Hz is very standard
communityFeature @46: Bool; # true if a community maintained feature is detected
fingerprintSource @49: FingerprintSource;
diff --git a/cereal/log.capnp b/cereal/log.capnp
index aca7a9b35..41de42009 100644
--- a/cereal/log.capnp
+++ b/cereal/log.capnp
@@ -1070,6 +1070,7 @@ struct UbloxGnss {
aStatus @2 :AntennaSupervisorState;
aPower @3 :AntennaPowerStatus;
jamInd @4 :UInt8;
+ flags @5 :UInt8;
enum AntennaSupervisorState {
init @0;
@@ -1192,9 +1193,11 @@ struct DriverMonitoringState @0xb83cda094a1da284 {
struct Boot {
wallTimeNanos @0 :UInt64;
- lastKmsg @1 :Data;
- lastPmsg @2 :Data;
+ pstore @4 :Map(Text, Data);
launchLog @3 :Text;
+
+ lastKmsgDEPRECATED @1 :Data;
+ lastPmsgDEPRECATED @2 :Data;
}
struct LiveParametersData {
diff --git a/cereal/messaging/__init__.py b/cereal/messaging/__init__.py
index 0b1204b47..1628dd524 100644
--- a/cereal/messaging/__init__.py
+++ b/cereal/messaging/__init__.py
@@ -1,9 +1,11 @@
# must be build with scons
from .messaging_pyx import Context, Poller, SubSocket, PubSocket # pylint: disable=no-name-in-module, import-error
from .messaging_pyx import MultiplePublishersError, MessagingError # pylint: disable=no-name-in-module, import-error
+import os
import capnp
from typing import Optional, List, Union
+from collections import deque
from cereal import log
from cereal.services import service_list
@@ -11,6 +13,9 @@ from cereal.services import service_list
assert MultiplePublishersError
assert MessagingError
+AVG_FREQ_HISTORY = 100
+SIMULATION = "SIMULATION" in os.environ
+
# sec_since_boot is faster, but allow to run standalone too
try:
from common.realtime import sec_since_boot
@@ -126,12 +131,14 @@ def recv_one_retry(sock: SubSocket) -> capnp.lib.capnp._DynamicStructReader:
class SubMaster():
def __init__(self, services: List[str], poll: Optional[List[str]] = None,
- ignore_alive: Optional[List[str]] = None, addr:str ="127.0.0.1"):
+ ignore_alive: Optional[List[str]] = None, ignore_avg_freq: Optional[List[str]] = None,
+ addr: str = "127.0.0.1"):
self.frame = -1
self.updated = {s: False for s in services}
self.rcv_time = {s: 0. for s in services}
self.rcv_frame = {s: 0 for s in services}
self.alive = {s: False for s in services}
+ self.recv_dts = {s: deque([0.0] * AVG_FREQ_HISTORY, maxlen=AVG_FREQ_HISTORY) for s in services}
self.sock = {}
self.freq = {}
self.data = {}
@@ -142,10 +149,8 @@ class SubMaster():
self.non_polled_services = [s for s in services if poll is not None and
len(poll) and s not in poll]
- if ignore_alive is not None:
- self.ignore_alive = ignore_alive
- else:
- self.ignore_alive = []
+ self.ignore_average_freq = [] if ignore_avg_freq is None else ignore_avg_freq
+ self.ignore_alive = [] if ignore_alive is None else ignore_alive
for s in services:
if addr is not None:
@@ -184,20 +189,34 @@ class SubMaster():
s = msg.which()
self.updated[s] = True
+
+ if self.rcv_time[s] > 1e-5 and self.freq[s] > 1e-5 and (s not in self.non_polled_services) \
+ and (s not in self.ignore_average_freq):
+ self.recv_dts[s].append(cur_time - self.rcv_time[s])
+
self.rcv_time[s] = cur_time
self.rcv_frame[s] = self.frame
self.data[s] = getattr(msg, s)
self.logMonoTime[s] = msg.logMonoTime
self.valid[s] = msg.valid
- for s in self.data:
- # arbitrary small number to avoid float comparison. If freq is 0, we can skip the check
- if self.freq[s] > 1e-5:
- # alive if delay is within 10x the expected frequency
- self.alive[s] = (cur_time - self.rcv_time[s]) < (10. / self.freq[s])
- else:
+ if SIMULATION:
self.alive[s] = True
+ if not SIMULATION:
+ for s in self.data:
+ # arbitrary small number to avoid float comparison. If freq is 0, we can skip the check
+ if self.freq[s] > 1e-5:
+ # alive if delay is within 10x the expected frequency
+ self.alive[s] = (cur_time - self.rcv_time[s]) < (10. / self.freq[s])
+
+ # alive if average frequency is higher than 90% of expected frequency
+ avg_dt = sum(self.recv_dts[s]) / AVG_FREQ_HISTORY
+ expected_dt = 1 / (self.freq[s] * 0.90)
+ self.alive[s] = self.alive[s] and (avg_dt < expected_dt)
+ else:
+ self.alive[s] = True
+
def all_alive(self, service_list=None) -> bool:
if service_list is None: # check all
service_list = self.alive.keys()
@@ -223,3 +242,6 @@ class PubMaster():
if not isinstance(dat, bytes):
dat = dat.to_bytes()
self.sock[s].send(dat)
+
+ def all_readers_updated(self, s: str) -> bool:
+ return self.sock[s].all_readers_updated()
diff --git a/cereal/messaging/bridge.cc b/cereal/messaging/bridge.cc
index 8e29566ca..da923835a 100644
--- a/cereal/messaging/bridge.cc
+++ b/cereal/messaging/bridge.cc
@@ -8,8 +8,8 @@ typedef void (*sighandler_t)(int sig);
#include "services.h"
-#include "impl_msgq.hpp"
-#include "impl_zmq.hpp"
+#include "impl_msgq.h"
+#include "impl_zmq.h"
void sigpipe_handler(int sig) {
assert(sig == SIGPIPE);
diff --git a/cereal/messaging/impl_msgq.cc b/cereal/messaging/impl_msgq.cc
index e211d6abb..862c94cb3 100644
--- a/cereal/messaging/impl_msgq.cc
+++ b/cereal/messaging/impl_msgq.cc
@@ -6,7 +6,7 @@
#include
#include "services.h"
-#include "impl_msgq.hpp"
+#include "impl_msgq.h"
volatile sig_atomic_t msgq_do_exit = 0;
@@ -196,6 +196,10 @@ int MSGQPubSocket::send(char *data, size_t size){
return msgq_msg_send(&msg, q);
}
+bool MSGQPubSocket::all_readers_updated() {
+ return msgq_all_readers_updated(q);
+}
+
MSGQPubSocket::~MSGQPubSocket(){
if (q != NULL){
msgq_close_queue(q);
diff --git a/cereal/messaging/impl_msgq.hpp b/cereal/messaging/impl_msgq.h
similarity index 95%
rename from cereal/messaging/impl_msgq.hpp
rename to cereal/messaging/impl_msgq.h
index e89994852..b67aae622 100644
--- a/cereal/messaging/impl_msgq.hpp
+++ b/cereal/messaging/impl_msgq.h
@@ -1,6 +1,6 @@
#pragma once
-#include "messaging.hpp"
-#include "msgq.hpp"
+#include "messaging.h"
+#include "msgq.h"
#include
#include
@@ -48,6 +48,7 @@ public:
int connect(Context *context, std::string endpoint, bool check_endpoint=true);
int sendMessage(Message *message);
int send(char *data, size_t size);
+ bool all_readers_updated();
~MSGQPubSocket();
};
diff --git a/cereal/messaging/impl_zmq.cc b/cereal/messaging/impl_zmq.cc
index 605165fcf..aeed176ae 100644
--- a/cereal/messaging/impl_zmq.cc
+++ b/cereal/messaging/impl_zmq.cc
@@ -7,7 +7,7 @@
#include
#include "services.h"
-#include "impl_zmq.hpp"
+#include "impl_zmq.h"
static int get_port(std::string endpoint) {
int port = -1;
@@ -131,6 +131,11 @@ int ZMQPubSocket::send(char *data, size_t size){
return zmq_send(sock, data, size, ZMQ_DONTWAIT);
}
+bool ZMQPubSocket::all_readers_updated() {
+ assert(false); // TODO not implemented
+ return false;
+}
+
ZMQPubSocket::~ZMQPubSocket(){
zmq_close(sock);
}
diff --git a/cereal/messaging/impl_zmq.hpp b/cereal/messaging/impl_zmq.h
similarity index 96%
rename from cereal/messaging/impl_zmq.hpp
rename to cereal/messaging/impl_zmq.h
index f9f6deedb..bb232049e 100644
--- a/cereal/messaging/impl_zmq.hpp
+++ b/cereal/messaging/impl_zmq.h
@@ -1,5 +1,5 @@
#pragma once
-#include "messaging.hpp"
+#include "messaging.h"
#include
#include
@@ -47,6 +47,7 @@ public:
int connect(Context *context, std::string endpoint, bool check_endpoint=true);
int sendMessage(Message *message);
int send(char *data, size_t size);
+ bool all_readers_updated();
~ZMQPubSocket();
};
diff --git a/cereal/messaging/messaging.cc b/cereal/messaging/messaging.cc
index 06bc66ae1..bfa634e61 100644
--- a/cereal/messaging/messaging.cc
+++ b/cereal/messaging/messaging.cc
@@ -1,6 +1,6 @@
-#include "messaging.hpp"
-#include "impl_zmq.hpp"
-#include "impl_msgq.hpp"
+#include "messaging.h"
+#include "impl_zmq.h"
+#include "impl_msgq.h"
#ifdef __APPLE__
const bool MUST_USE_ZMQ = true;
diff --git a/cereal/messaging/messaging.hpp b/cereal/messaging/messaging.h
similarity index 93%
rename from cereal/messaging/messaging.hpp
rename to cereal/messaging/messaging.h
index e461f06d2..4acdbb484 100644
--- a/cereal/messaging/messaging.hpp
+++ b/cereal/messaging/messaging.h
@@ -48,6 +48,7 @@ public:
virtual int connect(Context *context, std::string endpoint, bool check_endpoint=true) = 0;
virtual int sendMessage(Message *message) = 0;
virtual int send(char *data, size_t size) = 0;
+ virtual bool all_readers_updated() = 0;
static PubSocket * create();
static PubSocket * create(Context * context, std::string endpoint, bool check_endpoint=true);
static PubSocket * create(Context * context, std::string endpoint, int port, bool check_endpoint=true);
@@ -67,7 +68,8 @@ class SubMaster {
public:
SubMaster(const std::initializer_list &service_list,
const char *address = nullptr, const std::initializer_list &ignore_alive = {});
- int update(int timeout = 1000);
+ void update(int timeout = 1000);
+ void update_msgs(uint64_t current_time, std::vector> messages);
inline bool allAlive(const std::initializer_list &service_list = {}) { return all_(service_list, false, true); }
inline bool allValid(const std::initializer_list &service_list = {}) { return all_(service_list, true, false); }
inline bool allAliveAndValid(const std::initializer_list &service_list = {}) { return all_(service_list, true, true); }
@@ -76,7 +78,10 @@ public:
uint64_t frame = 0;
bool updated(const char *name) const;
+ bool alive(const char *name) const;
+ bool valid(const char *name) const;
uint64_t rcv_frame(const char *name) const;
+ uint64_t rcv_time(const char *name) const;
cereal::Event::Reader &operator[](const char *name);
private:
diff --git a/cereal/messaging/messaging.pxd b/cereal/messaging/messaging.pxd
index 8bbb2c7ab..de232da5f 100644
--- a/cereal/messaging/messaging.pxd
+++ b/cereal/messaging/messaging.pxd
@@ -6,7 +6,7 @@ from libcpp.vector cimport vector
from libcpp cimport bool
-cdef extern from "messaging.hpp":
+cdef extern from "messaging.h":
cdef cppclass Context:
@staticmethod
Context * create()
@@ -31,6 +31,7 @@ cdef extern from "messaging.hpp":
int connect(Context *, string)
int sendMessage(Message *)
int send(char *, size_t)
+ bool all_readers_updated()
cdef cppclass Poller:
@staticmethod
diff --git a/cereal/messaging/messaging_pyx.pyx b/cereal/messaging/messaging_pyx.pyx
index fa220c435..eed548bb8 100644
--- a/cereal/messaging/messaging_pyx.pyx
+++ b/cereal/messaging/messaging_pyx.pyx
@@ -149,3 +149,6 @@ cdef class PubSocket:
raise MultiplePublishersError
else:
raise MessagingError
+
+ def all_readers_updated(self):
+ return self.socket.all_readers_updated()
diff --git a/cereal/messaging/msgq.cc b/cereal/messaging/msgq.cc
index a51aef8e8..0c17b2657 100644
--- a/cereal/messaging/msgq.cc
+++ b/cereal/messaging/msgq.cc
@@ -21,7 +21,7 @@
#include
-#include "msgq.hpp"
+#include "msgq.h"
void sigusr2_handler(int signal) {
assert(signal == SIGUSR2);
@@ -452,3 +452,13 @@ int msgq_poll(msgq_pollitem_t * items, size_t nitems, int timeout){
return num;
}
+
+bool msgq_all_readers_updated(msgq_queue_t *q) {
+ uint64_t num_readers = *q->num_readers;
+ for (uint64_t i = 0; i < num_readers; i++) {
+ if (*q->read_valids[i] && *q->write_pointer != *q->read_pointers[i]) {
+ return false;
+ }
+ }
+ return num_readers > 0;
+}
diff --git a/cereal/messaging/msgq.hpp b/cereal/messaging/msgq.h
similarity index 97%
rename from cereal/messaging/msgq.hpp
rename to cereal/messaging/msgq.h
index 3bead13d9..301d5d1a3 100644
--- a/cereal/messaging/msgq.hpp
+++ b/cereal/messaging/msgq.h
@@ -64,3 +64,5 @@ int msgq_msg_send(msgq_msg_t *msg, msgq_queue_t *q);
int msgq_msg_recv(msgq_msg_t *msg, msgq_queue_t *q);
int msgq_msg_ready(msgq_queue_t * q);
int msgq_poll(msgq_pollitem_t * items, size_t nitems, int timeout);
+
+bool msgq_all_readers_updated(msgq_queue_t *q);
diff --git a/cereal/messaging/socketmaster.cc b/cereal/messaging/socketmaster.cc
index 1240009fa..b10133e43 100644
--- a/cereal/messaging/socketmaster.cc
+++ b/cereal/messaging/socketmaster.cc
@@ -1,7 +1,12 @@
-#include
#include
-#include "messaging.hpp"
+#include
+#include
+#include
+
#include "services.h"
+#include "messaging.h"
+
+const bool SIMULATION = (getenv("SIMULATION") != nullptr) && (std::string(getenv("SIMULATION")) == "1");
static inline uint64_t nanos_since_boot() {
struct timespec t;
@@ -35,7 +40,7 @@ struct SubMaster::SubMessage {
std::string name;
SubSocket *socket = nullptr;
int freq = 0;
- bool updated = false, alive = false, valid = false, ignore_alive;
+ bool updated = false, alive = false, valid = true, ignore_alive;
uint64_t rcv_time = 0, rcv_frame = 0;
void *allocated_msg_reader = nullptr;
capnp::FlatArrayMessageReader *msg_reader = nullptr;
@@ -53,6 +58,7 @@ SubMaster::SubMaster(const std::initializer_list &service_list, co
assert(socket != 0);
poller_->registerSocket(socket);
SubMessage *m = new SubMessage{
+ .name = name,
.socket = socket,
.freq = serv->frequency,
.ignore_alive = inList(ignore_alive, name),
@@ -62,37 +68,54 @@ SubMaster::SubMaster(const std::initializer_list &service_list, co
}
}
-int SubMaster::update(int timeout) {
- if (++frame == UINT64_MAX) frame = 1;
+void SubMaster::update(int timeout) {
for (auto &kv : messages_) kv.second->updated = false;
- int updated = 0;
auto sockets = poller_->poll(timeout);
uint64_t current_time = nanos_since_boot();
+
+ std::vector> messages;
+
for (auto s : sockets) {
Message *msg = s->receive(true);
if (msg == nullptr) continue;
SubMessage *m = messages_.at(s);
+
if (m->msg_reader) {
m->msg_reader->~FlatArrayMessageReader();
}
m->msg_reader = new (m->allocated_msg_reader) capnp::FlatArrayMessageReader(m->aligned_buf.align(msg));
delete msg;
- m->event = m->msg_reader->getRoot();
+ messages.push_back({m->name, m->msg_reader->getRoot()});
+ }
+
+ update_msgs(current_time, messages);
+}
+
+void SubMaster::update_msgs(uint64_t current_time, std::vector> messages){
+ if (++frame == UINT64_MAX) frame = 1;
+
+ for(auto &kv : messages) {
+ auto m_find = services_.find(kv.first);
+ if (m_find == services_.end()){
+ continue;
+ }
+ SubMessage *m = m_find->second;
+ m->event = kv.second;
m->updated = true;
m->rcv_time = current_time;
m->rcv_frame = frame;
m->valid = m->event.getValid();
-
- ++updated;
+ if (SIMULATION) m->alive = true;
}
- for (auto &kv : messages_) {
- SubMessage *m = kv.second;
- m->alive = (m->freq <= (1e-5) || ((current_time - m->rcv_time) * (1e-9)) < (10.0 / m->freq));
+ if (!SIMULATION) {
+ for (auto &kv : messages_) {
+ SubMessage *m = kv.second;
+ m->alive = (m->freq <= (1e-5) || ((current_time - m->rcv_time) * (1e-9)) < (10.0 / m->freq));
+ }
}
- return updated;
}
bool SubMaster::all_(const std::initializer_list &service_list, bool valid, bool alive) {
@@ -100,7 +123,7 @@ bool SubMaster::all_(const std::initializer_list &service_list, bo
for (auto &kv : messages_) {
SubMessage *m = kv.second;
if (service_list.size() == 0 || inList(service_list, m->name.c_str())) {
- found += (!valid || m->valid) && (!alive || (m->alive && !m->ignore_alive));
+ found += (!valid || m->valid) && (!alive || (m->alive || m->ignore_alive));
}
}
return service_list.size() == 0 ? found == messages_.size() : found == service_list.size();
@@ -123,10 +146,22 @@ bool SubMaster::updated(const char *name) const {
return services_.at(name)->updated;
}
+bool SubMaster::alive(const char *name) const {
+ return services_.at(name)->alive;
+}
+
+bool SubMaster::valid(const char *name) const {
+ return services_.at(name)->valid;
+}
+
uint64_t SubMaster::rcv_frame(const char *name) const {
return services_.at(name)->rcv_frame;
}
+uint64_t SubMaster::rcv_time(const char *name) const {
+ return services_.at(name)->rcv_time;
+}
+
cereal::Event::Reader &SubMaster::operator[](const char *name) {
return services_.at(name)->event;
};
diff --git a/cereal/services.py b/cereal/services.py
old mode 100755
new mode 100644
index 98f80acda..a30436bcd
--- a/cereal/services.py
+++ b/cereal/services.py
@@ -3,6 +3,14 @@ import os
from typing import Optional
EON = os.path.isfile('/EON')
+RESERVED_PORT = 8022 # sshd
+STARTING_PORT = 8001
+
+
+def new_port(port: int):
+ port += STARTING_PORT
+ return port + 1 if port >= RESERVED_PORT else port
+
class Service:
def __init__(self, port: int, should_log: bool, frequency: float, decimation: Optional[int] = None):
@@ -11,55 +19,58 @@ class Service:
self.frequency = frequency
self.decimation = decimation
-service_list = {
- "roadCameraState": Service(8002, True, 20., 1),
- "sensorEvents": Service(8003, True, 100., 100),
- "gpsNMEA": Service(8004, True, 9.),
- "deviceState": Service(8005, True, 2., 1),
- "can": Service(8006, True, 100.),
- "controlsState": Service(8007, True, 100., 100),
- "features": Service(8010, True, 0.),
- "pandaState": Service(8011, True, 2., 1),
- "radarState": Service(8012, True, 20., 5),
- "roadEncodeIdx": Service(8015, True, 20., 1),
- "liveTracks": Service(8016, True, 20.),
- "sendcan": Service(8017, True, 100.),
- "logMessage": Service(8018, True, 0.),
- "liveCalibration": Service(8019, True, 4., 4),
- "androidLog": Service(8020, True, 0., 1),
- "carState": Service(8021, True, 100., 10),
- "carControl": Service(8023, True, 100., 10),
- "longitudinalPlan": Service(8024, True, 20., 2),
- "liveLocation": Service(8025, True, 0., 1),
- "procLog": Service(8031, True, 0.5),
- "gpsLocationExternal": Service(8032, True, 10., 1),
- "ubloxGnss": Service(8033, True, 10.),
- "clocks": Service(8034, True, 1., 1),
- "liveMpc": Service(8035, False, 20.),
- "liveLongitudinalMpc": Service(8036, False, 20.),
- "ubloxRaw": Service(8042, True, 20.),
- "liveLocationKalman": Service(8054, True, 20., 2),
- "uiLayoutState": Service(8060, True, 0.),
- "liveParameters": Service(8064, True, 20., 2),
- "cameraOdometry": Service(8066, True, 20., 5),
- "lateralPlan": Service(8067, True, 20., 2),
- "thumbnail": Service(8069, True, 0.2, 1),
- "carEvents": Service(8070, True, 1., 1),
- "carParams": Service(8071, True, 0.02, 1),
- "driverCameraState": Service(8072, True, 10. if EON else 20., 1),
- "driverEncodeIdx": Service(8061, True, 10. if EON else 20., 1),
- "driverState": Service(8063, True, 10. if EON else 20., 1),
- "driverMonitoringState": Service(8073, True, 10. if EON else 20., 1),
- "offroadLayout": Service(8074, False, 0.),
- "wideRoadEncodeIdx": Service(8075, True, 20., 1),
- "wideRoadCameraState": Service(8076, True, 20., 1),
- "modelV2": Service(8077, True, 20., 20),
- "managerState": Service(8078, True, 2., 1),
- "testModel": Service(8040, False, 0.),
- "testLiveLocation": Service(8045, False, 0.),
- "testJoystick": Service(8056, False, 0.),
+services = {
+ "roadCameraState": (True, 20., 1), # should_log, frequency, decimation (optional)
+ "sensorEvents": (True, 100., 100),
+ "gpsNMEA": (True, 9.),
+ "deviceState": (True, 2., 1),
+ "can": (True, 100.),
+ "controlsState": (True, 100., 100),
+ "features": (True, 0.),
+ "pandaState": (True, 2., 1),
+ "radarState": (True, 20., 5),
+ "roadEncodeIdx": (True, 20., 1),
+ "liveTracks": (True, 20.),
+ "sendcan": (True, 100.),
+ "logMessage": (True, 0.),
+ "liveCalibration": (True, 4., 4),
+ "androidLog": (True, 0., 1),
+ "carState": (True, 100., 10),
+ "carControl": (True, 100., 10),
+ "longitudinalPlan": (True, 20., 2),
+ "liveLocation": (True, 0., 1),
+ "procLog": (True, 0.5),
+ "gpsLocationExternal": (True, 10., 1),
+ "ubloxGnss": (True, 10.),
+ "clocks": (True, 1., 1),
+ "liveMpc": (False, 20.),
+ "liveLongitudinalMpc": (False, 20.),
+ "ubloxRaw": (True, 20.),
+ "liveLocationKalman": (True, 20., 2),
+ "uiLayoutState": (True, 0.),
+ "liveParameters": (True, 20., 2),
+ "cameraOdometry": (True, 20., 5),
+ "lateralPlan": (True, 20., 2),
+ "thumbnail": (True, 0.2, 1),
+ "carEvents": (True, 1., 1),
+ "carParams": (True, 0.02, 1),
+ "driverCameraState": (True, 10. if EON else 20., 1),
+ "driverEncodeIdx": (True, 10. if EON else 20., 1),
+ "driverState": (True, 10. if EON else 20., 1),
+ "driverMonitoringState": (True, 10. if EON else 20., 1),
+ "offroadLayout": (False, 0.),
+ "wideRoadEncodeIdx": (True, 20., 1),
+ "wideRoadCameraState": (True, 20., 1),
+ "modelV2": (True, 20., 20),
+ "managerState": (True, 2., 1),
+
+ "testModel": (False, 0.),
+ "testLiveLocation": (False, 0.),
+ "testJoystick": (False, 0.),
}
+service_list = {name: Service(new_port(idx), *vals) for # type: ignore
+ idx, (name, vals) in enumerate(services.items())}
def build_header():
diff --git a/cereal/visionipc/visionipc_client.h b/cereal/visionipc/visionipc_client.h
index 469976239..d2c0085ad 100644
--- a/cereal/visionipc/visionipc_client.h
+++ b/cereal/visionipc/visionipc_client.h
@@ -3,7 +3,7 @@
#include
#include
-#include "messaging.hpp"
+#include "messaging.h"
#include "visionipc.h"
#include "visionbuf.h"
diff --git a/cereal/visionipc/visionipc_server.cc b/cereal/visionipc/visionipc_server.cc
index 7c64cd839..f4020133d 100644
--- a/cereal/visionipc/visionipc_server.cc
+++ b/cereal/visionipc/visionipc_server.cc
@@ -7,7 +7,7 @@
#include
#include
-#include "messaging.hpp"
+#include "messaging.h"
#include "ipc.h"
#include "visionipc_server.h"
diff --git a/cereal/visionipc/visionipc_server.h b/cereal/visionipc/visionipc_server.h
index 4472acf61..05c517b16 100644
--- a/cereal/visionipc/visionipc_server.h
+++ b/cereal/visionipc/visionipc_server.h
@@ -5,7 +5,7 @@
#include
#include